package com.javaonthebrain.choco; import javax.microedition.lcdui.*; import javax.microedition.lcdui.game.*; import javax.microedition.rms.*; import java.io.*; /** * * @author Karl H. */ public class ChocoCanvas extends GameCanvas implements Runnable { private ChocoBan m_owner; private SoundThread m_sounds; private Thread m_runner; private boolean m_running = false; // The various states that the game can be in private final static int MODE_START = 0; private final static int MODE_BLOTS = 1; private final static int MODE_PREPARE_MENU = 2; private final static int MODE_MENU = 3; private final static int MODE_SHOW_TEXT = 4; private final static int MODE_PREPARE_LEVEL_SELECTION = 5; private final static int MODE_LEVEL_SELECTION = 6; private final static int MODE_PREPARE_LEVEL = 7; private final static int MODE_GAME = 8; private final static int MODE_COMPLETED = 9; // Menu and info variables private final static String MENU_STRINGS[]={"Play","Help","About","Exit"}; private final static String LEVEL_STRING="Pick a level"; private final static String HELP_TEXT="Welcome to a delicious little game where life is like a box of chocolates!\n\nYour goal is to help the Easter Bunny re-arrange chocolate pieces so that the round ones end up in round holes and the square ones in square holes.\n\nUse the joystick or the numerical keys 2, 4, 6 and 8 to move around. If you make a mistake, the left soft key has an 'undo' function. You can undo as many moves as you want. In case you need to give up, just exit with the right soft key.\n\nGood luck!"; private final static String ABOUT_TEXT="ChocoBan was written and designed by Karl H\u00f6rnell. \u00a9 Eweguo AB, 2009. E-mail: karl@javaonthebrain.com\n\nThe game is based on the classic SokoBan, extended to use two different block types.\n\nMost of the level layouts were borrowed from Yoshio Murase's big collection of hand-made and computer-generated SokoBan maps.\n\nThe game is also available free of charge for the iPhone and iPod Touch at Apple's iTunes Store."; private int m_menuX[]=new int[4]; private int m_menuDX[]=new int[4]; private int m_menuSelection; private int m_scrollPos,m_numVisibleLines; private String m_textLines[]; private Font m_bigFont,m_smallFont; // Graphics-related objects private Graphics m_g; private Image m_blot,m_smallBlot,m_logo,m_tiles,m_header; private Sprite m_topPieces,m_bottomPieces,m_topContours,m_bottomContours; private Sprite m_symbols,m_shadows; private Sprite m_topRabbits,m_bottomRabbits,m_rabbitShadows; private TiledLayer m_bottomTiles,m_midTiles,m_topTiles; private int m_gameMode; private long m_sleepTime,m_nextTime; // Constants that mainly have to do with timing private final static int FRAME_TIME = 50; private final static int BLOT_INTERVAL = 18; private final static int CLICK_DELAY = 8; private final static int SCROLL_REPEAT_INTERVAL = 5; private final static int CHEER_FRAMES = 60; private final static int HALLELUJAH_DELAY = 20; private final static int BORED_FRAMES = 200; // The order of the level selection pieces private final static int LEVEL_NUMBERING[] = {0,1,2,3,7,6,5,4,8,9,10,11,3,2,1,0,4,5,6,7,11,10,9,8}; // Lots of useful game and animation variables private int m_map[][],m_mapW,m_mapH; private int m_tileX,m_tileY; private int m_targetX[]=new int[50],m_targetY[]=new int[50],m_targetType[]=new int[50]; private int m_numTargets; private int m_chocX[]=new int[50],m_chocY[]=new int[50],m_chocType[]=new int[50],m_chocData[]=new int[50]; private int m_chocPixX[]=new int[50],m_chocPixY[]=new int[50]; private int m_numChocs; private int m_selectionX,m_selectionY,m_selectedPiece,m_selectedTarget; private int m_movedPiece; private int m_rabbitX,m_rabbitY,m_rabbitPixX,m_rabbitPixY,m_rabbitLook; private int m_rabbitDir,m_blockWidth=2*Coords.TILE_W,m_blockHeight=2*Coords.TILE_H; private final static int RABBIT_SHADOW_INDEX[]={1,2,0,1,0,2,4,5,3,4,5,3,1,1}; private final static int WALK_LOOK[]={0,1,0,2},DIR_DX[]={0,0,0,-1,1},DIR_DY[]={0,-1,1,0,0}; private int m_level; private int m_softKeyCounter,m_boredomCounter; private int m_undoBuffer[]=new int[64],m_undoPos; // For the numbers drawn in the level selection screen private int m_levelNumX[]=new int[24],m_levelNumY[]=new int[24]; private String m_levelNumbers[]=new String[24]; private byte m_levelSolved[]; private final static String RECORDSTORE_NAME="solved_levels"; private int m_counter,m_keyPressed,m_softKey; public ChocoCanvas(ChocoBan o) { super(false); setFullScreenMode(true); m_owner=o; m_g=getGraphics(); } public void startUp() { m_running=true; m_runner=new Thread(this); m_runner.start(); } public void initialize() { m_sounds=new SoundThread(); m_sounds.start(); setMode(MODE_START); } private void setMode(int m) { m_gameMode = m; } /** * All the graphical resources are loaded here */ private void loadGraphics() { try{ m_blot=Image.createImage("/blot.png"); m_smallBlot=Image.createImage("/smallblot.png"); m_logo=Image.createImage("/logo.png"); m_header=Image.createImage("/header.png"); m_tiles=Image.createImage("/alltiles.png"); m_topPieces = new Sprite(Image.createImage("/toppieces.png"), Coords.TILE_W*2,Coords.TILE_H*2); m_bottomPieces = new Sprite(Image.createImage("/bottompieces.png"), Coords.TILE_W*2,Coords.TILE_H); m_topContours = new Sprite(Image.createImage("/topcontours.png"), Coords.TILE_W*2,Coords.TILE_H*2); m_bottomContours = new Sprite(Image.createImage("/bottomcontours.png"), Coords.TILE_W*2,Coords.TILE_H); m_symbols = new Sprite(Image.createImage("/symbols.png"), Coords.TILE_W*2,Coords.TILE_H*2); m_shadows = new Sprite(Image.createImage("/shadows.png"), Coords.SHADOW_W,Coords.SHADOW_H); m_topRabbits = new Sprite(Image.createImage("/toprabbits.png"), Coords.TILE_W*2,Coords.TILE_H*3); m_bottomRabbits = new Sprite(Image.createImage("/bottomrabbits.png"), Coords.TILE_W*2,Coords.TILE_H); m_rabbitShadows = new Sprite(Image.createImage("/rabbitshadows.png"), Coords.RABBIT_SHADOW_W,Coords.RABBIT_SHADOW_H); } catch(Exception e){e.printStackTrace();} } private void prepareFonts() { m_bigFont = Font.getFont(Coords.BIG_FACE,Coords.BIG_STYLE,Coords.BIG_SIZE); m_smallFont = Font.getFont(Coords.SMALL_FACE,Coords.SMALL_STYLE,Coords.SMALL_SIZE); for (int i=0;i<24;i++) { m_levelNumbers[i]=Integer.toString(i+1); m_levelNumX[i]=Coords.TILE_W*((i&3)*2+3)-m_bigFont.stringWidth(m_levelNumbers[i])/2; m_levelNumY[i]=Coords.TILE_H*((i/4)*2+4)-m_bigFont.getHeight()/2; } } /** * The main game loop */ public void run() { int i,j,k,l; while (m_running) { m_nextTime = System.currentTimeMillis() + FRAME_TIME; m_counter++; switch(m_gameMode) { case MODE_START: loadSolvedData(); m_g.setColor(0x000000); m_g.fillRect(0, 0, Coords.SCREEN_W, Coords.SCREEN_H); flushGraphics(); loadGraphics(); prepareFonts(); setMode(MODE_BLOTS); break; case MODE_BLOTS: if (m_counter < 6*BLOT_INTERVAL) { i = m_counter/BLOT_INTERVAL; j = m_counter%BLOT_INTERVAL; if (j==0) { if (i < 4) { m_g.drawImage(m_smallBlot, Coords.BLOTS_X[i-1], Coords.BLOTS_Y[i-1], 0); m_sounds.play(SoundThread.SOUND_DROP); } else if (i == 4) { m_g.drawImage(m_blot, Coords.BIGBLOT_X, Coords.BIGBLOT_Y, 0); m_sounds.play(SoundThread.SOUND_DROP); } else { m_g.drawImage(m_logo, Coords.LOGO_X, Coords.LOGO_Y, 0); m_sounds.play(SoundThread.SOUND_FADEIN); } } } else setMode(MODE_PREPARE_MENU); flushGraphics(); break; case MODE_PREPARE_MENU: m_g.setColor(0x000000); m_g.fillRect(0, 0, Coords.SCREEN_W, Coords.SCREEN_H); m_g.drawImage(m_blot, Coords.BIGBLOT_X,Coords.BIGBLOT_Y, 0); m_g.drawImage(m_logo, Coords.LOGO_X,Coords.LOGO_Y, 0); j=Coords.MENU_PIECE_BASE_X + Coords.MENU_TURN_DISTANCE; k=0; for (i=0;i<4;i++) { m_menuX[i]=j; m_menuDX[i]=k; for (l=0;l<3;l++) { if (j < Coords.MENU_PIECE_BASE_X) k++; else k--; j+=k; } } m_menuSelection = 0; setMode(MODE_MENU); break; case MODE_MENU: m_g.setColor(0x000000); m_g.fillRect(0, Coords.MENU_Y, Coords.SCREEN_W, Coords.SCREEN_H-Coords.MENU_Y); m_g.setColor(0xffffff); m_g.setFont(m_bigFont); for (i=0; i < 4; i++) { if (m_menuX[i] < Coords.MENU_PIECE_BASE_X) m_menuDX[i]++; else m_menuDX[i]--; m_menuX[i] += m_menuDX[i]; m_topPieces.setFrame(1+i); m_topPieces.setPosition(m_menuX[i],Coords.MENU_Y + i*Coords.MENU_LINE_H); m_topPieces.paint(m_g); m_bottomPieces.setFrame(1+i); m_bottomPieces.setPosition(m_menuX[i], Coords.MENU_Y + i*Coords.MENU_LINE_H + Coords.TILE_H*2); m_bottomPieces.paint(m_g); if (m_menuSelection == i) { m_topContours.setFrame(1+i); m_topContours.setPosition(m_menuX[i],Coords.MENU_Y + i*Coords.MENU_LINE_H); m_topContours.paint(m_g); m_bottomContours.setFrame(1+i); m_bottomContours.setPosition(m_menuX[i], Coords.MENU_Y + i*Coords.MENU_LINE_H + Coords.TILE_H*2); m_bottomContours.paint(m_g); } m_g.drawString(MENU_STRINGS[i],m_menuX[i]+Coords.MENU_TEXT_OFFSET_X, Coords.MENU_Y + i*Coords.MENU_LINE_H+Coords.MENU_TEXT_OFFSET_Y,0); } if (m_keyPressed == Coords.KEY_UP || m_keyPressed == Canvas.KEY_NUM2) { if (m_menuSelection > 0) m_menuSelection--; } else if (m_keyPressed == Coords.KEY_DOWN || m_keyPressed == Canvas.KEY_NUM8) { if (m_menuSelection < 3) m_menuSelection++; } else if (m_keyPressed == Coords.KEY_FIRE || m_keyPressed == Canvas.KEY_NUM5) { m_sounds.play(SoundThread.SOUND_SELECT); switch(m_menuSelection) { case 0: // Play setMode(MODE_PREPARE_LEVEL_SELECTION); break; case 1: // Help prepareTextView(MENU_STRINGS[1],HELP_TEXT); break; case 2: // About prepareTextView(MENU_STRINGS[2],ABOUT_TEXT); break; case 3: // Exit m_owner.exitMIDlet(); break; } } m_keyPressed = 0; flushGraphics(); break; case MODE_SHOW_TEXT: // Text screens if (m_softKey < 0) { if (m_keyPressed == Coords.KEY_SOFTRIGHT) { m_sounds.play(SoundThread.SOUND_SELECT); m_softKey = 1; m_counter = 0; m_symbols.setFrame(5); m_symbols.paint(m_g); } else if (m_counter>=0) { if (m_keyPressed == Coords.KEY_UP || m_keyPressed == Canvas.KEY_NUM2) { if (m_scrollPos>0) { m_scrollPos--; drawText(); } m_counter=-SCROLL_REPEAT_INTERVAL; } else if (m_keyPressed == Coords.KEY_DOWN || m_keyPressed == Canvas.KEY_NUM8) { if (m_scrollPos CLICK_DELAY) { setMode(MODE_PREPARE_MENU); } flushGraphics(); break; case MODE_PREPARE_LEVEL_SELECTION: prepareLevelSelectionLayout(); setUpTileMaps(); m_selectionX=1;m_selectionY=1; findSelectedObject(); setMode(MODE_LEVEL_SELECTION); break; case MODE_LEVEL_SELECTION: drawLayers(); m_g.setColor(0xffffff); m_g.setFont(m_bigFont); m_g.drawString(LEVEL_STRING,(Coords.SCREEN_W-m_bigFont.stringWidth(LEVEL_STRING))/2, (m_tileY-m_bigFont.getHeight())/2,0); if (m_keyPressed==Coords.KEY_UP || m_keyPressed==Canvas.KEY_NUM2) { if (m_selectionY>1) { m_selectionY--; findSelectedObject(); m_keyPressed=0; } } else if (m_keyPressed==Coords.KEY_DOWN || m_keyPressed==Canvas.KEY_NUM8) { if (m_selectionY<6) { m_selectionY++; findSelectedObject(); m_keyPressed=0; } } else if (m_keyPressed==Coords.KEY_LEFT || m_keyPressed==Canvas.KEY_NUM4) { if (m_selectionX>1) { m_selectionX--; findSelectedObject(); m_keyPressed=0; } } else if (m_keyPressed==Coords.KEY_RIGHT || m_keyPressed==Canvas.KEY_NUM6) { if (m_selectionX<4) { m_selectionX++; findSelectedObject(); m_keyPressed=0; } } else if (m_keyPressed==Coords.KEY_FIRE || m_keyPressed==Canvas.KEY_NUM5) { m_sounds.play(SoundThread.SOUND_SELECT); m_level=4*(m_selectionY-1)+m_selectionX-1; setMode(MODE_PREPARE_LEVEL); } flushGraphics(); break; case MODE_PREPARE_LEVEL: cleanUp(); loadLevel(); setUpTileMaps(); placeChocs(); setMode(MODE_GAME); break; case MODE_GAME: m_boredomCounter++; if (m_boredomCounter==BORED_FRAMES) m_rabbitLook=13; if (m_rabbitDir==0) { if (m_keyPressed==Coords.KEY_UP || m_keyPressed==Canvas.KEY_NUM2) { if (m_map[m_rabbitY-1][m_rabbitX]==0) { m_rabbitDir=1; } else if (m_map[m_rabbitY-1][m_rabbitX]>=256 && m_map[m_rabbitY-2][m_rabbitX]==0) { m_rabbitDir=1; m_movedPiece=m_map[m_rabbitY-1][m_rabbitX]-256; m_map[m_chocY[m_movedPiece]][m_chocX[m_movedPiece]]=0; } } else if (m_keyPressed==Coords.KEY_DOWN || m_keyPressed==Canvas.KEY_NUM8) { if (m_map[m_rabbitY+1][m_rabbitX]==0) { m_rabbitDir=2; } else if (m_map[m_rabbitY+1][m_rabbitX]>=256 && m_map[m_rabbitY+2][m_rabbitX]==0) { m_rabbitDir=2; m_movedPiece=m_map[m_rabbitY+1][m_rabbitX]-256; m_map[m_chocY[m_movedPiece]][m_chocX[m_movedPiece]]=0; } } else if (m_keyPressed==Coords.KEY_LEFT || m_keyPressed==Canvas.KEY_NUM4) { if (m_map[m_rabbitY][m_rabbitX-1]==0) { m_rabbitDir=3; } else if (m_map[m_rabbitY][m_rabbitX-1]>=256 && m_map[m_rabbitY][m_rabbitX-2]==0) { m_rabbitDir=3; m_movedPiece=m_map[m_rabbitY][m_rabbitX-1]-256; m_map[m_chocY[m_movedPiece]][m_chocX[m_movedPiece]]=0; } } else if (m_keyPressed==Coords.KEY_RIGHT || m_keyPressed==Canvas.KEY_NUM6) { if (m_map[m_rabbitY][m_rabbitX+1]==0) { m_rabbitDir=4; } else if (m_map[m_rabbitY][m_rabbitX+1]>=256 && m_map[m_rabbitY][m_rabbitX+2]==0) { m_rabbitDir=4; m_movedPiece=m_map[m_rabbitY][m_rabbitX+1]-256; m_map[m_chocY[m_movedPiece]][m_chocX[m_movedPiece]]=0; } } if (m_movedPiece>=0) m_sounds.play(SoundThread.SOUND_PUSH); } if (m_rabbitDir>0) { m_boredomCounter=0; m_rabbitPixX+=Coords.RABBIT_DX[m_rabbitDir]; m_rabbitPixY+=Coords.RABBIT_DY[m_rabbitDir]; m_rabbitLook=(m_rabbitDir-1)*3+WALK_LOOK[(m_counter>>>1)&3]; if (m_movedPiece>=0) { m_chocPixX[m_movedPiece]+=Coords.RABBIT_DX[m_rabbitDir]; m_chocPixY[m_movedPiece]+=Coords.RABBIT_DY[m_rabbitDir]; } if (m_blockWidth*(m_rabbitPixX/m_blockWidth)==m_rabbitPixX && m_blockHeight*(m_rabbitPixY/m_blockHeight)==m_rabbitPixY) { m_rabbitX+=DIR_DX[m_rabbitDir]; m_rabbitY+=DIR_DY[m_rabbitDir]; if (m_movedPiece>=0) { // Store undo information m_undoBuffer[m_undoPos]=m_rabbitDir+16*m_movedPiece; m_undoPos=(m_undoPos+1)&63; m_undoBuffer[m_undoPos]=-1; m_chocX[m_movedPiece]+=DIR_DX[m_rabbitDir]; m_chocY[m_movedPiece]+=DIR_DY[m_rabbitDir]; m_map[m_chocY[m_movedPiece]][m_chocX[m_movedPiece]]=256+m_movedPiece; // Check for matching holes boolean thisMatches=false; int numMatches=0; for (i=0;iCoords.MAX_X) m_tileX=Coords.MAX_X-m_rabbitPixX; else if (m_rabbitPixX+m_tileXCoords.MAX_Y) m_tileY=Coords.MAX_Y-m_rabbitPixY; else if (m_rabbitPixY+m_tileY0) { int piece=m_undoBuffer[m_undoPos]/16; int dir=(((m_undoBuffer[m_undoPos]&15)-1)^1)+1; // Reverse direction m_map[m_chocY[piece]][m_chocX[piece]]=0; m_chocX[piece]+=DIR_DX[dir]; m_chocY[piece]+=DIR_DY[dir]; m_rabbitX=m_chocX[piece]+DIR_DX[dir]; m_rabbitY=m_chocY[piece]+DIR_DY[dir]; m_chocPixX[piece]=m_chocX[piece]*m_blockWidth; m_chocPixY[piece]=m_chocY[piece]*m_blockHeight; m_rabbitPixX=m_rabbitX*m_blockWidth; m_rabbitPixY=m_rabbitY*m_blockHeight; m_map[m_chocY[piece]][m_chocX[piece]]=256+piece; m_rabbitLook=3; m_boredomCounter=0; } } else if (m_keyPressed == Coords.KEY_SOFTRIGHT) { m_sounds.play(SoundThread.SOUND_SELECT); m_softKey=1; m_softKeyCounter=CLICK_DELAY; } } if (m_softKey>=0) { m_softKeyCounter--; if (m_softKeyCounter==0) { if (m_softKey==1) { setMode(MODE_PREPARE_MENU); } m_softKey=-1; } } drawLayers(); flushGraphics(); break; case MODE_COMPLETED: if (m_counter==HALLELUJAH_DELAY) m_sounds.play(SoundThread.SOUND_HALLELUJAH); if (m_counter>=CHEER_FRAMES) { saveSolvedData(); setMode(MODE_PREPARE_MENU); } break; } try{ m_sleepTime = m_nextTime - System.currentTimeMillis(); if (m_sleepTime>15) Thread.sleep(m_sleepTime); else Thread.sleep(15); } catch(InterruptedException ie){} } } /** * Line break a given string for the text display screen */ private void cutText(String txt) { int numCuts = 0; int textCuts[]=new int[100]; int len=txt.length(); int lastSpace=0,width=0,lastWidth=0; char c; m_g.setFont(m_smallFont); for (int pos = 0; pos < len; pos++) { c=txt.charAt(pos); width += m_smallFont.charWidth(c); if (c==' ') { lastWidth = width; lastSpace = pos; } if (width > Coords.SCREEN_W-2*Coords.TEXT_MARGIN_W-Coords.SCROLLBAR_W) { textCuts[++numCuts]=lastSpace + 1; width -= lastWidth; } else if (c=='\n') { textCuts[++numCuts]=pos + 1; width = 0; } } if (textCuts[numCuts] < len) textCuts[++numCuts]=len; m_textLines=new String[numCuts]; for (int i=0;im_numVisibleLines) { int fullHeight = Coords.SCREEN_H-2*(Coords.HEADER_H + Coords.TEXT_MARGIN_H); m_g.setColor(0x7e4528); m_g.fillRect(Coords.SCREEN_W-Coords.SCROLLBAR_W, Coords.HEADER_H+ Coords.TEXT_MARGIN_H, Coords.SCROLLBAR_W, fullHeight); int barHeight = (fullHeight * m_numVisibleLines)/m_textLines.length; int barPos = (fullHeight * m_scrollPos)/m_textLines.length; m_g.setColor(0xffffff); m_g.fillRect(Coords.SCREEN_W-Coords.SCROLLBAR_W, Coords.HEADER_H+ Coords.TEXT_MARGIN_H+barPos, Coords.SCROLLBAR_W, barHeight); } } /** * Given some level data, prepare the tile maps and the chocolate pieces */ private void setUpTileMaps() { int x,y; m_bottomTiles=new TiledLayer(m_mapW*2,m_mapH*2,m_tiles,Coords.TILE_W,Coords.TILE_H); m_midTiles=new TiledLayer(m_mapW*2,m_mapH*2,m_tiles,Coords.TILE_W,Coords.TILE_H); m_topTiles=new TiledLayer(m_mapW*2,m_mapH*2,m_tiles,Coords.TILE_W,Coords.TILE_H); // Bottom layer for (int i=1;i0) m_bottomTiles.setCell(x+1, y, 4); else m_bottomTiles.setCell(x+1, y, 1); if (m_map[i][j-1]>0) m_bottomTiles.setCell(x, y+1, 6); else m_bottomTiles.setCell(x, y+1, 1); m_bottomTiles.setCell(x+1, y+1, 1); } } // Middle layer for (int i=1;i0) { if (m_map[i-1][j-1]>0) m_midTiles.setCell(x,y-1,10); else m_midTiles.setCell(x,y-1,9); if (m_map[i-1][j+1]>0) m_midTiles.setCell(x+1,y-1,10); else m_midTiles.setCell(x+1,y-1,11); } } } } for (int i=0;i0) { if (i>0 && j>0) m_topTiles.setCell(x, y, blockDist[m_map[i-1][j-1]+ 2*m_map[i-1][j]+4*m_map[i][j-1]]); else m_topTiles.setCell(x, y, 1); if (i>0 && j0) m_topTiles.setCell(x, y+1, blockDist[16+m_map[i][j-1]+ 2*m_map[i+1][j-1]+4*m_map[i+1][j]]); else m_topTiles.setCell(x, y+1, 1); if (i0 && j>0 && i<7 && j<5) m_map[i][j]=0; else m_map[i][j]=1; m_mapW=6; m_mapH=8; for (int i=0;i<24;i++) if (m_levelSolved[i]==1) { addTargetType(LEVEL_NUMBERING[i]&1,1+(i&3),1+(i/4)); } else { addChocType(LEVEL_NUMBERING[i],1+(i&3),1+(i/4)); } } /** * Get level data from the corresponding text file resource */ private void loadLevel() { try{ DataInputStream dis=new DataInputStream(getClass().getResourceAsStream("/level"+m_level+".txt")); char buf[]=new char[400]; int len=dis.available(); for (int i=0;i='a' && c<='l') // Plain piece { addChocType(c-'a',j,i); } else if (c>='A' && c<='L') // Standing on oppsite-shaped hole { addChocType(c-'A',j,i); addTargetType((c-'@')&1,j,i); } else if (c>='M' && c<='X') // Standing on same-shaped hole { addChocType(c-'M',j,i); addTargetType((c-'M')&1,j,i); } } } } catch(Exception e){e.printStackTrace();} } /** * Reset all game variables */ private void cleanUp() { m_numTargets=0; m_numChocs=0; m_selectionX=-1; m_selectionY=-1; m_selectedPiece=-1; m_selectedTarget=-1; m_rabbitX=-1; m_rabbitDir=0; m_movedPiece=-1; m_softKey=-1; m_undoBuffer[0]=-1; m_undoPos=1; m_boredomCounter=0; } /** * Build a hole * @param t 0 for round, 1 for square * @param x * @param y */ private void addTargetType(int t, int x, int y) { m_targetType[m_numTargets]=t; m_targetX[m_numTargets]=x; m_targetY[m_numTargets]=y; m_numTargets++; } /** * Build a chocolate piece * @param t 0-11 specifies the type * @param x * @param y */ private void addChocType(int t, int x, int y) { m_chocType[m_numChocs]=t; m_chocX[m_numChocs]=x; m_chocY[m_numChocs]=y; m_chocPixX[m_numChocs]=x*Coords.TILE_W*2; m_chocPixY[m_numChocs]=y*Coords.TILE_H*2; m_numChocs++; } /** * Mark the positions of the chocolate pieces in the array that holds * the level data. */ private void placeChocs() { for (int i=0;i0) { m_rabbitShadows.setFrame(RABBIT_SHADOW_INDEX[m_rabbitLook]); m_rabbitShadows.setPosition(m_tileX+m_rabbitPixX,m_tileY+m_rabbitPixY+Coords.TILE_H); m_rabbitShadows.paint(m_g); } m_midTiles.setPosition(m_tileX,m_tileY+Coords.TILE_H); m_midTiles.paint(m_g); // Draw level numbers during level selection if (m_gameMode==MODE_LEVEL_SELECTION) { m_g.setFont(m_bigFont); for (int i=0;i<24;i++) if (m_levelSolved[i]!=0) m_g.drawString(m_levelNumbers[i], m_tileX+m_levelNumX[i], m_tileY+m_levelNumY[i], 0); } if (m_selectedTarget>=0 && (m_counter&4)==0) { m_symbols.setFrame(0); m_symbols.setPosition(m_tileX+m_selectionX*Coords.TILE_W*2,m_tileY+(m_selectionY*2+1)*Coords.TILE_H); m_symbols.paint(m_g); } for (int i=0;i0) { m_bottomRabbits.setFrame(m_rabbitLook); m_bottomRabbits.setPosition(m_tileX+m_rabbitPixX,m_tileY+m_rabbitPixY+Coords.TILE_H*2); m_bottomRabbits.paint(m_g); } m_topTiles.setPosition(m_tileX,m_tileY); m_topTiles.paint(m_g); for (int i=0;i0) { m_topRabbits.setFrame(m_rabbitLook); m_topRabbits.setPosition(m_tileX+m_rabbitPixX,m_tileY+m_rabbitPixY-Coords.TILE_H); m_topRabbits.paint(m_g); m_symbols.setFrame(3); m_symbols.setPosition(Coords.SOFT_KEY_MARGIN,Coords.SCREEN_H-Coords.SOFT_KEY_MARGIN-Coords.TILE_H*2); m_symbols.paint(m_g); if (m_softKey==0) { m_symbols.setFrame(5); m_symbols.paint(m_g); } m_symbols.setFrame(4); m_symbols.setPosition(Coords.SCREEN_W-Coords.SOFT_KEY_MARGIN-Coords.TILE_W*2,Coords.SCREEN_H-Coords.SOFT_KEY_MARGIN-Coords.TILE_H*2); m_symbols.paint(m_g); if (m_softKey==1) { m_symbols.setFrame(5); m_symbols.paint(m_g); } } } private void loadSolvedData() { RecordStore rs; RecordEnumeration re; try { rs=RecordStore.openRecordStore(RECORDSTORE_NAME,false); re=rs.enumerateRecords(null,null,false); m_levelSolved=re.nextRecord(); rs.closeRecordStore(); } catch(Exception e) { m_levelSolved=new byte[24]; } } private void saveSolvedData() { RecordStore rs; try{ RecordStore.deleteRecordStore(RECORDSTORE_NAME); } catch(Exception e){} try { rs=RecordStore.openRecordStore(RECORDSTORE_NAME,true); rs.addRecord(m_levelSolved,0,24); rs.closeRecordStore(); } catch(Exception e){} } public void keyPressed(int k) { m_keyPressed=k; } public void keyReleased(int k) { m_keyPressed=0; } public void shutDown() { m_running = false; } }