The professional, friendly Java community. 21,500 members and growing!

The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.

Tetris Mobile Game is not Running

importjava.io.*;importjava.io.*;importjava.util.Random;importjavax.microedition.lcdui.*;importjavax.microedition.midlet.*;importjavax.microedition.rms.*;importtetris.model.TetrisBoard;importtetris.model.TetrisPiece;importtetris.ui.TetrisCanvas;/**
* Maintains game state. Handles input.
*/publicclass TetrisMidlet extends MIDlet implements CommandListener {private TetrisCanvas gameCanvas;// canvas on which the game is painted private TetrisBoard board;// holds the game stateprivate TetrisPiece activePiece;// holds the state of the active pieceprivateint score;// the current game scoreprivateint level;// the current levelprivateint lineCount;// the current number of lines clearedprivateint nextPieceType;// the next pieceprivateint tickSpeed;// the speed in milliseconds between dropsprivateint hiScore;// the current hi scoreprivate RecordStore tetrisStore;// the RecordStore holding the hi scoreprivateint hiScoreRecordId;// the record id in the RecordStore of the hi scoreprivateboolean[] completedRows;// array of booleans indicating the rows that have been cleared// store as an instance variable so we reuse without reallocatingprivateRandom rand;// generates pseudo random numbers to choose the next pieceprivate Command exitCommand;// Command to exit the appprivate Command pauseCommand;// Command to pause the appprivate Command resumeCommand;// Command to resume the app after a pauseprivateint gameState = TetrisConstants.UNINITIALIZED;// mark as unitialized at first, can check in startApp to see if init necessaryprivate DropThread dropThread;// the thread that drops the active piece one row per tick/**
* Start the app.
* @see MIDlet#startApp()
*/protectedvoid startApp()throws MIDletStateChangeException {if(TetrisConstants.UNINITIALIZED==this.gameState){// game is just starting up, need to initializethis.init();}elseif(TetrisConstants.RUNNING_STATE==this.gameState){// game is resuming from an external suspend// this puts it in the internal pause statethis.resumeGame();}else{// resumed from the title screen, just repaintthis.gameCanvas.reset();}
Display.getDisplay(this).setCurrent(this.gameCanvas);}/**
* Suspend the app.
* @see MIDlet#pauseApp()
*/protectedvoid pauseApp(){// put the game in its internal paused state before suspending the appif(TetrisConstants.RUNNING_STATE==this.gameState){this.pauseGame();}}/**
* Exit.
* @see MIDlet#destroyApp(boolean)
*/protectedvoid destroyApp(boolean unconditional)throws MIDletStateChangeException {if(null!=this.tetrisStore){// write out the hi score before exittingthis.writeAndCloseHiScore(this.hiScore);}}/**
* Initalization on app startup.
*/privatevoid init(){this.board=new TetrisBoard();this.gameCanvas=new TetrisCanvas(this);this.activePiece=new TetrisPiece();this.completedRows=newboolean[TetrisConstants.HEIGHT];this.hiScore=this.openAndReadHiScore();// get currently saved hi score from rmsthis.nextPieceType= TetrisConstants.UNINITIALIZED;this.rand=newRandom();// setup exit/pause/resume commandsthis.setupCommands();this.gameCanvas.addCommand(this.exitCommand);// put the app in a state to show the title screenthis.setGameState(TetrisConstants.TITLE_STATE);}/**
* Set up the game state so that a new game is started.
* @param level the initial level at which to start the game
*/privatevoid startNewGame(int level){this.gameCanvas.addCommand(this.pauseCommand);// during running, pause command should be availablethis.score=0;this.lineCount=0;this.level= level;this.nextPieceType=this.getRandomPieceType();this.tickSpeed=this.getInitialTickSpeed(this.level);this.board.clearBoard();this.tryAddNewPiece();this.setGameState(TetrisConstants.RUNNING_STATE);this.runDropThread();}/**
* Put the app in an end game state. Should redisplay the title screen.
*/privatevoid endGame(){// no commands needed, don't need to pause when not playingthis.gameCanvas.removeCommand(this.pauseCommand);this.hiScore=Math.max(this.hiScore, this.score);// set hi score if current score is higherthis.nextPieceType= TetrisConstants.UNINITIALIZED;this.setGameState(TetrisConstants.TITLE_STATE);// show the title screenthis.dropThread.stopThread();this.dropThread=null;// will have to replace it anyway, might as well gc as soon as possible}/**
* Put the game into a paused state during running.
*/privatevoid pauseGame(){// replace the pause command with a resume commandthis.gameCanvas.removeCommand(this.pauseCommand);this.gameCanvas.addCommand(this.resumeCommand);// put in paused state and stop droppingthis.setGameState(TetrisConstants.PAUSED_STATE);this.dropThread.stopThread();}/**
* Resume the game from a paused state.
*/privatevoid resumeGame(){// replace the resume command with a pause commandthis.gameCanvas.removeCommand(this.resumeCommand);this.gameCanvas.addCommand(this.pauseCommand);// put in running state and resume droppingthis.setGameState(TetrisConstants.RUNNING_STATE);this.runDropThread();}/**
* Run the drop thread. In MIDP 1.0 it doesn't seem possible to restart a thread.
* Instead just create a new one and start it.
*/privatevoid runDropThread(){this.dropThread=new DropThread(this);this.dropThread.start();}/**
* Set the initial tick speed according to the given level.
*
* @param level the initial level
* @return the initial tick speed
*/privateint getInitialTickSpeed(int level){int initialTickSpeed = TetrisConstants.BASE_SPEED;// multiply by fraction for each levelfor(int i =0; i < level; i++){
initialTickSpeed =(initialTickSpeed * TetrisConstants.SPEED_INCREASE_NUMERATOR)/ TetrisConstants.SPEED_INCREASE_DENOMINATOR;}return initialTickSpeed;}/**
* The MIDlet handles the key input.
* This is called by the Canvas' listening keyPressed.
*
* @param keyCode the keyCode from Canvas' keyPressed
*/publicvoid keyPressed(int keyCode){if(TetrisConstants.RUNNING_STATE==this.gameState){// if the app is in a running state, then we want the game actions
keyCode =this.gameCanvas.getGameAction(keyCode);if(Canvas.DOWN== keyCode){this.tryMoveDown();}elseif(Canvas.UP== keyCode){this.tryRotateLeft();}elseif(Canvas.LEFT== keyCode){this.tryMoveLeft();}elseif(Canvas.RIGHT== keyCode){this.tryMoveRight();}elseif(Canvas.FIRE== keyCode){this.quickDrop();}}elseif(TetrisConstants.TITLE_STATE==this.gameState){// if we're at the title screen, get the level number from inputif(Canvas.KEY_NUM0<= keyCode &&Canvas.KEY_NUM9>= keyCode){int level = keyCode -Canvas.KEY_NUM0;this.startNewGame(level);}}}/**
* Quick drop the active piece as far as it will go
*/privatesynchronizedvoid quickDrop(){int dropScore =0;// 1 point for each line droppedwhile(this.tryMoveDown()){
dropScore++;}this.score+= dropScore;if(null!=this.dropThread){// if the piece has been quick dropped, then the piece has been instantly dropped to the bottom.// since the new piece is immediately added, it will drop a row at the end of the current tick.// we specify to skip the next tick, the player gets the remainder of the current tick, plus// the whole next tick before the piece drops a row.this.dropThread.skipNextTick();}}/**
* Set the active piece as a new piece and choose the next piece
*
* @return the active piece, updated as a new piece
*/private TetrisPiece newPiece(){int pieceType =this.nextPieceType;this.nextPieceType=this.getRandomPieceType();
TetrisPiece activePiece =this.getActivePiece();
activePiece.setAsNewPiece(pieceType, TetrisConstants.START_X, TetrisConstants.START_Y);return activePiece;}/**
* @return a pseudo random piece type
*/privateint getRandomPieceType(){// MIDP 1.0 doesn't have Random.nextInt(int n)// this is a bad substitute, but good enough for us...returnMath.abs(rand.nextInt()% TetrisConstants.NUM_PIECE_TYPES)+1;}/**
* Clear the completed rows from the board.
* Wipes the filled rows and drops the rows above them.
*
* @param piece the piece in its final position
* @return number of rows cleared
*/privateint clearCompletedRows(TetrisPiece piece){
TetrisBoard board =this.getBoard();// check each row that the piece includes, see if completedfor(int i =0; i < TetrisConstants.FOUR_BLOCKS; i++){int rowY = piece.getBlockY(i);// mark rows completed that are filledif(board.checkRowCompleted(rowY)){this.markRowCompleted(rowY, true);}}int numClearedRows =0;for(int y = TetrisConstants.HEIGHT-1; y >=0; y--){// iterate from bottom up// each row should be dropped the current tally of completed rowsif(numClearedRows >0){
board.dropRow(y, numClearedRows);}if(this.isRowCompleted(y)){
numClearedRows++;this.markRowCompleted(y, false);// reset for next time}}// clear the top number of rows completed, these are new empty rowsfor(int i =0; i < numClearedRows; i++){
board.clearRow(i);}return numClearedRows;}/**
* Mark a row as completed, a setter accessor to the completedRows.
* We use the instance completedRows to reuse the array without reallocating.
*
* @param row the index of the row, lower indices at the top of the board
* @param isCompleted true if the row is completed false otherwise
*/privatevoid markRowCompleted(int row, boolean isCompleted){this.completedRows[row]= isCompleted;}/**
* Check if a row is completed, a getter accessor to the completedRows.
* @param row the index of the row, lower indices at the top of the board
* @return true if the row is completed false otherwise.
*/privateboolean isRowCompleted(int row){returnthis.completedRows[row];}/**
* Update the game state to reflect the completed rows (adjust score, etc).
* @param completedRows the number of completed rows
*/privatevoid updateRowState(int completedRows){this.lineCount+= completedRows;// increment the line count// formula for scores is (ROW_SCORE * level) + ROW_SCOREif(1== completedRows){this.score+=(this.level* TetrisConstants.ONE_ROW_SCORE)+ TetrisConstants.ONE_ROW_SCORE;}elseif(2== completedRows){this.score+=(this.level* TetrisConstants.TWO_ROW_SCORE)+ TetrisConstants.TWO_ROW_SCORE;}elseif(3== completedRows){this.score+=(this.level* TetrisConstants.THREE_ROW_SCORE)+ TetrisConstants.THREE_ROW_SCORE;}elseif(4== completedRows){this.score+=(this.level*TetrisConstants. FOUR_ROW_SCORE)+ TetrisConstants.FOUR_ROW_SCORE;}// integer division gets the levelint level =this.lineCount/ TetrisConstants.LEVEL_UNIT;if(level >this.level){this.level= level;// level increase, adjust tick speedthis.tickSpeed=(this.tickSpeed* TetrisConstants.SPEED_INCREASE_NUMERATOR)/ TetrisConstants.SPEED_INCREASE_DENOMINATOR;}}/**
* Try to add a new piece. Check that there is room on the board.
* If we can't add the piece, the game is over.
*
* @return true if the piece was added, false if couldn't add and the game is over.
*/privatesynchronizedboolean tryAddNewPiece(){
TetrisPiece newPiece =this.newPiece();// reset the active piece
TetrisBoard board =this.getBoard();if(board.canAddNewPiece(newPiece)){
board.addNewPiece(newPiece);// added successfullyreturntrue;}// no room to add, game overthis.endGame();returnfalse;}/**
* Try to move the current piece down one row.
* If we can't drop the piece any more, we try to add a new one.
*
* @return true if the piece was dropped, false otherwise
*/privatesynchronizedboolean tryMoveDown(){
TetrisPiece activePiece =this.getActivePiece();
TetrisBoard board =this.getBoard();if(board.canMoveDown(activePiece)){
board.moveDown(activePiece);this.gameCanvas.repaint();// piece moved downreturntrue;}// couldn't move down
board.lockPiece(activePiece);int numClearedRows =this.clearCompletedRows(activePiece);this.updateRowState(numClearedRows);this.tryAddNewPiece();this.gameCanvas.repaint();returnfalse;}/**
* Try to move the current piece left.
*
* @return true if we could move the piece left, false if couldn't
*/privatesynchronizedboolean tryMoveLeft(){if(this.getBoard().canMoveLeft(this.getActivePiece())){this.board.moveLeft(this.getActivePiece());this.gameCanvas.repaint();// piece moved leftreturntrue;}// couldn't move leftreturnfalse;}/**
* Try to move the current piece right.
*
* @return true if we could move the piece right, false if couldn't
*/privatesynchronizedboolean tryMoveRight(){if(this.getBoard().canMoveRight(this.getActivePiece())){this.board.moveRight(this.getActivePiece());this.gameCanvas.repaint();// piece moved rightreturntrue;}// couldn't move rightreturnfalse;}/**
* Try to rotate the piece left (counter-clockwise)
*
* @return true if we could rotate left, false if couldn't
*/privatesynchronizedboolean tryRotateLeft(){if(this.getBoard().canRotateLeft(this.getActivePiece())){this.board.rotateLeft(this.getActivePiece());this.gameCanvas.repaint();// rotated leftreturntrue;}// couldn't rotatereturnfalse;}/**
* Try to rotate the piece right (clockwise)
*
* @return true if we could rotate right, false if couldn't
*/privatesynchronizedboolean tryRotateRight(){if(this.getBoard().canRotateRight(this.getActivePiece())){this.board.rotateRight(this.getActivePiece());this.gameCanvas.repaint();// rotated rightreturntrue;}// couldn't rotatereturnfalse;}/**
* Handle commands. Implementation for CommandListener.
*
* @param c the Command input
* @param d the originating Displayable, not needed, since we only have the Canvass
*/publicvoid commandAction(Command c, Displayable d){if(c ==this.exitCommand){try{// on exit just destroy the appthis.destroyApp(true);this.notifyDestroyed();}catch(MIDletStateChangeException msce){// unconditional}}elseif(c ==this.pauseCommand){this.pauseGame();}elseif(c ==this.resumeCommand){this.resumeGame();}}/**
* Setup the commands.
* Once they're set up, add and remove pause/resume depending on the state.
*/privatevoid setupCommands(){this.exitCommand=new Command("exit", Command.EXIT, 1);this.pauseCommand=new Command("pause", Command.ITEM, 1);this.resumeCommand=new Command("resume", Command.ITEM, 1);this.gameCanvas.setCommandListener(this);}/**
* Drop thread periodically calls this method.
* We try to move down the active piece on each tick.
*/publicvoid tick(){this.tryMoveDown();}/**
* @return the board state object
*/public TetrisBoard getBoard(){returnthis.board;}/**
* @return the active piece state object
*/public TetrisPiece getActivePiece(){returnthis.activePiece;}/**
* @return the current game score
*/publicint getScore(){returnthis.score;}/**
* @return the current hi score
*/publicint getHiScore(){returnthis.hiScore;}/**
* @return the current line count
*/publicint getLineCount(){returnthis.lineCount;}/**
* @return the current level
*/publicint getLevel(){returnthis.level;}/**
* @return the upcoming piece once the current piece is dropped
*/publicint getNextPieceType(){returnthis.nextPieceType;}/**
* @return the current time between ticks (milliseconds)
*/publicint getTickSpeed(){returnthis.tickSpeed;}/**
* @return the current game state, should be a constant defined in the constants file
*/publicint getGameState(){returnthis.gameState;}/**
* Set the game state.
* Additionally resets the canvas so it will repaint one-time painting.
*
* @param gameState the new game state
*/publicvoid setGameState(int gameState){this.gameState= gameState;if(null!=this.gameCanvas){this.gameCanvas.reset();this.gameCanvas.repaint();}}/**
* Open the record store and try to read a hi score out of it.
*
* @return the hi score persisted in rms
*/privateint openAndReadHiScore(){int hiScore =0;try{this.tetrisStore= RecordStore.openRecordStore(TetrisConstants.TETRIS_RECORD_STORE, true);if(this.tetrisStore.getNumRecords()>0){// should be only one record, the hi score
RecordEnumeration recordEnum =this.tetrisStore.enumerateRecords(null, null, false);this.hiScoreRecordId= recordEnum.nextRecordId();byte[] hiScoreBytes =this.tetrisStore.getRecord(this.hiScoreRecordId);// wrap the bytes in a DataInputStream so we can readIntByteArrayInputStream byteIn =newByteArrayInputStream(hiScoreBytes);DataInputStream dataIn =newDataInputStream(byteIn);
hiScore = dataIn.readInt();// don't think this is necessary
dataIn.close();
byteIn.close();}}catch(Exception e){// nothing we can do, hiScore remains 0}return hiScore;}/**
* Try to write the current hi score to the record store and close it.
*
* @param score the current hi score
*/privatevoid writeAndCloseHiScore(int score){try{// use DataOutputStream so we can writeIntByteArrayOutputStream byteOut =newByteArrayOutputStream(4);// a single int, should be 4 bytesDataOutputStream dataOut =newDataOutputStream(byteOut);
dataOut.writeInt(this.hiScore);// get the bytes for the intbyte[] hiScoreBytes = byteOut.toByteArray();if(this.tetrisStore.getNumRecords()==0){// no previously stored record, created a new onethis.tetrisStore.addRecord(hiScoreBytes, 0, hiScoreBytes.length);}else{// overwrite the existing hi score recordthis.tetrisStore.setRecord(this.hiScoreRecordId, hiScoreBytes, 0, hiScoreBytes.length);}this.tetrisStore.closeRecordStore();
dataOut.close();
byteOut.close();}catch(Exception e){}}}

I dont know whats wrong with this,it compiles but it doesnt have anything to run.Please help me.(this is not mine).Below is the whole game source.I hope you'll help me with this.Thanks

Re: Tetris Mobile Game is not Running

Originally Posted by HacKofDeatH

i tried to debug this,but it doesnt have any errors..and in the phone,it only contains "Select one to launch".im still confused..

Why did you start a new thread instead of discussing your problems over there?
Debugging is never to see if there are any errors are not. Debugging can also be used to understand the flow of program/application.

Re: Tetris Mobile Game is not Running

Originally Posted by Mr.777

Why did you start a new thread instead of discussing your problems over there?
Debugging is never to see if there are any errors are not. Debugging can also be used to understand the flow of program/application.

I've post a new thread coz' i am eager to get some answers to my problem.Sorry if i'm too much noob here in forums.Have you tried my program?.If you please,try it and re-modify it if you want,it'll be a lot of help to me.Thanks in advance.

Re: Tetris Mobile Game is not Running

Originally Posted by Mr.777

Why don't you give it a try and if you get stuck, let us know and we might be able to help you.
Good Luck.

Now I'm really stuck in this.I made some changes,but it still doesn't work.It keeps on running without errors,unfortunately it doesn't do anything.Please help me,and if you have some idea, please let me know. I'll thank you always.

Re: Tetris Mobile Game is not Running

Very big THANKS. Those imports are (own defined imports)
-import tetris.ui.TetrisCanvas;
*Handles all of the UI and painting for the app.
* Delegates input to the Midlet instance itself.
* Makes an effort to adjust itself to the available screen dimensions.
* Also makes an effort to repaint only what is necessary.
* Uses manual double buffering if the Canvas doesn't automatically double buffer.
-import tetris.model.TetrisBoard;
* Defines the state of the grid of blocks.
* Has logic for manipulating supplied pieces' state on the board.
* Whenever the board adjusts its state to reflect that a piece has changed,
* it should also ensure that the piece's state is updated as well.
-import tetris.model.TetrisPiece;
* An instance of this defines the active piece that is being dropped.
* Rather than instantiating a new one all the time, we use the same object and just reset its type and blocks.
* Using a single instance saves in heap operations. This is really fairly negligible, so may consider
* refactoring with an abstract parent and concrete implementations for each piece type.
* This would allow custom rotating behavior, like two position rotating for I, S, and Z types, and no rotating for O.
* Note that this class has no knowledge of the board. Anything updating the piece state will also want to
* adjust the board. The adjusting logic can adjust the piece, and then examine the results to see how to
* adjust the board, however.