J2ME游戏代码示例(一)——俄罗斯方块

 
J2ME游戏代码示例(一)——俄罗斯方块
作者:陈跃峰
出自: http://blog.csdn.net/mailbomb
 
         下面是我写的一个简单的俄罗斯方块游戏代码,代码中主要包含3个类:
TerrisMIDlet——MIDlet类
GameCanvas——游戏界面类
GameEngine——游戏逻辑类
使用WTK2.5.1运行通过.
     具体代码如下:
//MIDlet类
import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.*;
 
public class TerrisMIDlet extends MIDlet {
         public TerrisMIDlet() {
                   Display.getDisplay(this).setCurrent(new GameCanvas());
         }
         protected void destroyApp(boolean arg0) {}
         protected void pauseApp() {}
         protected void startApp() {}
}
 
//界面类
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
 
/**
 * 俄罗斯方块游戏界面
 */
public class GameCanvas extends Canvas implements Runnable{
     GameEngine engine = new GameEngine();
     int width;
     int height;
     /**游戏结束变量*/
     boolean gameOver = false;
     /**游戏暂停变量*/
     boolean isPaused = false;
     String pauseStr = "暂停";
     String continueStr = "继续";
     public GameCanvas(){
              //全屏幕
              setFullScreenMode(true);       
              width = getWidth();
              height = getHeight();
              //启动线程
              Thread th = new Thread(this);
              th.start();
     }
    
     protected void paint(Graphics g) {
              //清屏
              clearScreen(g);
              //绘制边框
              paintBoard(g);
              //绘制背景
              engine.paintMap(g);
              //绘制当前下落方块
              engine.paintBrick(g);
              //绘制下一个方块
              engine.paintNextBrick(g);
              //绘制关卡和游戏得分
              engine.paintLevelAndScore(g);
              //绘制游戏结束
              if(gameOver){
                       g.drawString("Game Over", 30, 85,
                                          Graphics.TOP | Graphics.LEFT);
              }
              //绘制暂停按钮文字
              if(isPaused){
                       g.drawString(pauseStr,width,height,
                                          Graphics.RIGHT | Graphics.BOTTOM);
              }else{
                       g.drawString(continueStr,width,height,
                                          Graphics.RIGHT | Graphics.BOTTOM);
              }
     }
    
     public void keyPressed(int keyCode){
              if(keyCode == -7){ //右软键,暂停控制
                       isPaused = !isPaused;
              }
              if(!isPaused){
                       int action = getGameAction(keyCode);
                       switch(action){
                       case UP:
                       case FIRE:
                                 engine.changeShape();
                                 break;
                       case LEFT:
                                 engine.moveToLeft();
                                 break;
                       case RIGHT:
                                 engine.moveToRight();
                                 break;
                       case DOWN:
                                 engine.highSpeed(); //加速
                                 break;
                       }
              }
              repaint();         
     }
    
     public void keyReleased(int keyCode){
              int action = getGameAction(keyCode);
              switch(action){
              case DOWN:
                       engine.normalSpeed(); //恢复正常速度
                       break;
              }
     }
    
     /**
      * 绘制游戏区域边框
      * @param g 画笔
      */
     private void paintBoard(Graphics g){
              g.drawRect(0,0,
                                 engine.MAXCOL * engine.CELLWIDTH,
                                 engine.MAXROW * engine.CELLWIDTH);
     }
    
     /**
      * 清屏
      * @param g 画笔
      */
     private void clearScreen(Graphics g){
              g.setColor(0xffffff);
              g.fillRect(0,0,width,height);
              g.setColor(0);
     }
 
     public void run() {
              try{
                       while(true){
                                 //延时
                                 Thread.sleep(engine.speed / engine.times);
                                 //逻辑处理
                                 //如果不处于暂停状态
                                 if(!isPaused){
                                          //方块下落
                                          engine.brickDown();
                                          //游戏是否结束
                                          if(engine.isGameOver()){
                                                   //显示游戏结束
                                                   gameOver = true;
                                                   //重画
                                                   repaint();
                                                   //结束线程
                                                   break;
                                          }
                                 }
                                 //重绘
                                 repaint();
                       }
              }catch(Exception e){
                       e.printStackTrace();
              }                
     }
}
 
//游戏逻辑类
import java.util.*;
import javax.microedition.lcdui.*;
/**
 * 游戏数据和逻辑类
 * 未实现关卡变化的逻辑
 */
public class GameEngine {
     /**方块的信息, 0代表无内容,1代表有内容 */
     int[][][][] brick = {
                       {
                                 {
                                          { 0, 1, 0, 0 },
                                          { 0, 1, 0, 0 },
                                          { 0, 1, 1, 0 },
                                     { 0, 0, 0, 0 }
                                 },
                                 {
                                          { 0, 0, 0, 0 },
                                          { 0, 1, 1, 1 },
                                          { 0, 1, 0, 0 },
                                     { 0, 0, 0, 0 }
                                 },
                                 {
                                          { 0, 1, 1, 0 },
                                          { 0, 0, 1, 0 },
                                          { 0, 0, 1, 0 },
                                     { 0, 0, 0, 0 }
                                 },
                                 {
                                          { 0, 0, 0, 0 },
                                          { 0, 0, 1, 0 },
                                          { 1, 1, 1, 0 },
                                     { 0, 0, 0, 0 }
                                 }
                       },
                       {
                                 {
                                          { 0, 0, 1, 0 },
                                          { 0, 0, 1, 0 },
                                          { 0, 1, 1, 0 },
                                     { 0, 0, 0, 0 }
                                 },
                                 {
                                          { 0, 0, 0, 0 },
                                          { 0, 1, 0, 0 },
                                          { 0, 1, 1, 1 },
                                     { 0, 0, 0, 0 }
                                 },
                                 {
                                          { 0, 0, 0, 0 },
                                          { 0, 1, 1, 0 },
                                          { 0, 1, 0, 0 },
                                     { 0, 1, 0, 0 }
                                 },
                                 {
                                          { 0, 0, 0, 0 },
                                          { 1, 1, 1, 0 },
                                          { 0, 0, 1, 0 },
                                     { 0, 0, 0, 0 }
                                 }
                       },
                       {
                                 {
                                          {0,1,0,0},
                                          {0,1,0,0},
                                          {0,1,0,0},
                                          {0,1,0,0}
                                 },
                                 {
                                          {0,0,0,0},
                                          {1,1,1,1},
                                          {0,0,0,0},
                                          {0,0,0,0}
                                 }
                       },
                       {
                                 {
                                          {0,0,0,0},
                                          {0,1,1,0},
                                          {0,1,1,0},
                                          {0,0,0,0}
                                 }
                       },
                       {
                                 {
                                          {0,0,1,0},
                                          {0,1,1,0},
                                          {0,1,0,0},
                                          {0,0,0,0}
                                 },
                                 {
                                          {0,0,0,0},
                                          {0,1,1,0},
                                          {0,0,1,1},
                                          {0,0,0,0}
                                 }
                       },
                       {
                                 {
                                          {0,1,0,0},
                                          {0,1,1,0},
                                          {0,0,1,0},
                                          {0,0,0,0}
                                 },
                                 {
                                          {0,0,0,0},
                                          {0,1,1,0},
                                          {1,1,0,0},
                                          {0,0,0,0}
                                 }
                       },
                       {
                                 {
                                          {0,0,0,0},
                                          {0,0,1,0},
                                          {0,1,1,1},
                                          {0,0,0,0}
                                 },
                                 {
                                          {0,0,0,0},
                                          {0,1,0,0},
                                          {0,1,1,0},
                                          {0,1,0,0}
                                 },
                                 {
                                          {0,0,0,0},
                                          {0,1,1,1},
                                          {0,0,1,0},
                                          {0,0,0,0}
                                 },
                                 {
                                          {0,0,1,0},
                                          {0,1,1,0},
                                          {0,0,1,0},
                                          {0,0,0,0}
                                 }
                       }
     };
     /**行数*/
     final int MAXROW = 19;
     /**列数*/
     final int MAXCOL = 10;
     /**
      * 游戏界面信息,0代表无内容,1代表有内容
      */
     int[][] map = new int[MAXROW][MAXCOL];
     /**每个单元格的宽度和高度*/
     public static final int CELLWIDTH = 10;
     /**下一个方块的类型*/
     int nextBrickType = 0;
     //当前下落的方块
     /**当前格子的类型*/
     int brickType;
     /**当前变形信息*/
     int index;
     /**当前行*/
     int cRow;
     /**当前列*/
     int cCol;
     /**速度*/
     int speed = 500;
     /**加速度*/
     int times = 1;
     /**当前关卡*/
     int level = 0;
     /**积分,每消一行加10分*/
     int score = 0;
     Random r = new Random();
     public GameEngine(){
              //产生方块
              gernerateBrick();
     }
    
     /**
      * 绘制一个格子
      * @param g 画笔对象
      * @param x 格子左上角的x坐标
      * @param y 格子左上角的y坐标
      */
     private void paintCell(Graphics g,int x,int y){
              //绘制黑色边框
              g.setColor(0);
              g.drawRect(x,y,CELLWIDTH,CELLWIDTH);
              //绘制边框
              g.setColor(0xffffff);
              g.fillRect(x+1,y+1,CELLWIDTH-2,CELLWIDTH-2);
              //黑块
              g.setColor(0);
              g.fillRect(x + 2, y + 2,
                                 CELLWIDTH - 4, CELLWIDTH - 4);
     }
    
     public void paintMap(Graphics g){
              //循环绘制地图
              for(int row = 0;row < map.length;row++){
                       for(int col = 0;col < map[row].length;col++){
                                 //是否绘制
                                 if(map[row][col] == 1){
                                          paintCell(g,col * CELLWIDTH,row * CELLWIDTH);
                                 }
                       }
              }
     }
    
     /**
      * 绘制当前下落的方块
      * @param g 画笔
      */
     public void paintBrick(Graphics g){
              for(int row = 0;row < 4;row++){
                       for(int col = 0;col < 4;col++){
                                 //判断是否绘制
                                 if(brick[brickType][index][row][col] == 1){
                                          int cx = (cCol + col) * CELLWIDTH;
                                          int cy = (cRow + row) * CELLWIDTH;
                                          paintCell(g,cx,cy);
                                 }
                       }
              }
     }
    
     /**下一个方块左上角的x坐标*/
     int nextBrickX = 110;
     /**下一个方块左上角的y坐标*/
     int nextBrickY = 30;
     /**下一个方块文字*/
     String str = "下一个方块";
     /**
      * 绘制下一个方块
      * @param g 画笔
      */
     public void paintNextBrick(Graphics g){
              //绘制文字
              g.drawString(str, nextBrickX, nextBrickY,
                                 Graphics.LEFT | Graphics.TOP);
              //绘制方块
              for(int row = 0;row < 4;row++){
                       for(int col = 0;col < 4;col++){
                                 //判断是否绘制
                                 if(brick[nextBrickType][0][row][col] == 1){
                                          int cx =nextBrickX + col * CELLWIDTH;
                                          int cy =nextBrickY + 20 + row * CELLWIDTH;
                                          paintCell(g,cx,cy);
                                 }
                       }
              }
     }
    
     String scoreStr = "当前得分:";
     /**
      * 绘制游戏得分和关卡
      * @param g 画笔
      */
     public void paintLevelAndScore(Graphics g){
              //绘制得分
              g.drawString(scoreStr,nextBrickX,100,
                                 Graphics.TOP | Graphics.LEFT);
              g.drawString(String.valueOf(score), nextBrickX, 115,
                                 Graphics.LEFT | Graphics.TOP);
              //绘制关卡
              g.drawString("第" + level + "关", nextBrickX, 150,
                                 Graphics.TOP | Graphics.LEFT);
     }
    
     /**
      * 方块下落
      */
     public void brickDown(){
              //达到底部
              if(reachBottom()){
                       addBrickToMap();
                       //System.out.println("添加到界面成功");
                       gernerateBrick();
                       //System.out.println(1);
                       //清除满行
                       clearAllFullRow();
              }else{
                       cRow++;
                       //是否和地图数据重叠
                       if(collisWithMap()){
                                 //后退一行
                                 cRow--;
                                 //添加到地图中
                                 addBrickToMap();
                                 //产生新的方块
                                 gernerateBrick();
                                 //清除满行
                                 clearAllFullRow();
                       }
              }
     }
    
     /**
      * 随机产生方块
      */
     public void gernerateBrick(){
              //把下一个方块的类型赋值给当前方块
              brickType = nextBrickType;
              //生成下一个的类型
              nextBrickType = Math.abs(r.nextInt() % brick.length);
              //初始化数据
              index = 0;
              //位置
              cRow = -3;
              cCol = 3;
     }
    
     /**
      * 判断方块是否下落到游戏区域底部
      * @return true代表下落到底部
      */
     private boolean reachBottom(){     
              int tempRow = getBottomNotEmptyRow();
              //是否是最后一行
              if(cRow + tempRow >= MAXROW - 1){
                       return true;
              }else{
                       return false;
              }
     }
    
     /**
      * 添加方块到地图数据
      */
     private void addBrickToMap(){
              for(int i = 0;i < 4;i++){
                       for(int j = 0;j < 4;j++){
                                 //判断数据未超出地图边界
                                 if(((cCol+j) >= 0) &&
                                                   ((cCol + j < MAXCOL)) &&
                                                   ((cRow + i < MAXROW))){
                                          //不添加0的数据
                                          if(brick[brickType][index][i][j] == 1){
                                                   map[cRow + i][cCol + j] =
                                                             brick[brickType][index][i][j];
                                          }
                                 }
                       }
              }
     }
    
     /**
      * 方块变形
      */
     public void changeShape(){
              //变形到下一种形状
              index++;
              if(index == brick[brickType].length){
                       index = 0;
              }
              //变形以后的位置是否超出边界
              if(testNewPosition()){
                       index--;//退回原来的形状
              }
              if(index < 0){
                       index = brick[brickType].length - 1;
              }
     }
    
     /**
      * 方块向左移动
      * 原则是:方块左侧的第一行非空列贴近边界
      */
     public void moveToLeft(){
             cCol--;
             //如果新的位置不可用
             if(testNewPosition()){
                         cCol++;
             }
     }
    
     /**
      * 获得方块左侧的非空列的序号
      * @return
      */
     private int getLeftNotEmptyLine(){
              for(int col = 0;col < 4;col++){
                       for(int row = 0;row < 4;row++){
                                 if(brick[brickType][index][row][col] == 1){
                                          return col;
                                 }
                       }
              }
              return 0;
     }
    
     /**
      * 方块向右移动
      */
     public void moveToRight(){
                cCol++;
                //如果新的位置不可用
                if(testNewPosition()){
                          cCol--;
               }
     }
    
     /**
      * 获得方块右侧第一个非空列的序号
      * @return 非空列的序号
      */
     private int getRightNotEmptyLine(){
              for(int col = 3;col >= 0;col--){
                       for(int row = 0;row < 4;row++){
                                 if(brick[brickType][index][row][col] == 1){
                                          return col;
                                 }
                       }
              }
              return 3;
     }
    
     /**
      * 方块底部的第一个非空行的行号
      * @return 行号
      */
     private int getBottomNotEmptyRow(){
              for(int row = 3;row >= 0;row--){
                       for(int col = 0;col < 4;col++){
                                 if(brick[brickType][index][row][col] == 1){
                                          //System.out.println("底部非空行:" + row);
                                          return row;
                                 }
                       }
              }
              return 3;
     }
    
     /**
      * 测试新的位置是否可用
      * @return true代表不可用,false代表可用
      */
     private boolean testNewPosition(){
              //左侧
              if((getLeftNotEmptyLine() + cCol) < 0){
                       return true;
              }
              //右侧
              if(cCol + getRightNotEmptyLine() > MAXCOL - 1){
                       return true;
              }
              //下边界
              if(getBottomNotEmptyRow() + cRow >= MAXROW - 1){
                       System.out.println(222);
                       return true;
              }
              //是否和地图重合
              if(collisWithMap()){
                       return true;
              }
              return false;
     }
    
     /**
      * 是否和已有的方块叠加
      * @return true代表叠加,false代表未叠加
      */
     private boolean collisWithMap(){
              for(int col = 0;col < 4;col++){
                       for(int row = 3;row >= 0;row--){
                                 //有格子
                                 if(brick[brickType][index][row][col] == 1){
                                          //下标未越界
                                          if((cRow +row >= 0) && (cRow + row <= MAXROW - 1) &&
                                                             (cCol + col >= 0) && (cCol + col <= MAXCOL - 1)){
                                                   //判别地图数据
                                                   if(map[cRow + row][cCol + col] == 1){ //重叠
                                                             return true;
                                                   }else{
                                                             break;
                                                   }
                                          }
                                 }
                       }
              }
              return false;
     }
    
     /**
      * 清除满行
      */
     private void clearAllFullRow(){
              for(int row = MAXROW - 1;row >= 0;row--){
                       //如果是满行
                       if(isFullRow(row)){
                                 //增加积分
                                 score += 10;
                                 //消当前行
                                 clearOneFullRow(row);
                                 row++; //继续处理当前行
                       }
              }
     }
    
     /**
      * 判断是否是满行
      * @param row 行号
      * @return true代表是满行,false代表不是满行
      */
     private boolean isFullRow(int row){
              int count = 0;
              for(int col = 0;col < MAXCOL;col++){
                       if(map[row][col] == 1){
                                 count++;
                       }
              }
              if(count == MAXCOL){
                       return true;
              }else{
                       return false;
              }
     }
    
     /**
      * 消掉一个满行
      * @param row 需要消的行号
      */
     private void clearOneFullRow(int row){
              //上面的行全部下落
              for(int i = row - 1;i >= 0;i--){ //循环上面所有的行
                       for(int col = 0;col < MAXCOL;col++){
                                 //下落
                                 map[i + 1][col] = map[i][col];
                       }
              }
              //把第一行数据全部初始化为空
              for(int col = 0;col < MAXCOL;col++){
                       map[0][col] = 0;
              }
     }
    
     /**
      * 游戏是否结束
      * @return true代表结束,false代表未结束
      */
     public boolean isGameOver(){
              //下一个位置是否和地图数据重合
              cRow++;
              if(collisWithMap()){
                       cRow--; //还原位置
                       //判断屏幕第一行以上是否有数据
                       if(cRow < 0){
                                 for(int row = 0;row < 4;row++){
                                          for(int col = 0;col < 4;col++){
                                                   if(row + cRow >= 0){
                                                             break;
                                                   }else{ //屏幕上面的行
                                                             if(brick[brickType][index][row][col] == 1){
                                                                      return true;
                                                             }
                                                   }
                                          }
                                 }
                       }
              }else{
                       cRow--;
              }
              return false;
     }
    
     /**
      * 高速下落,速度是正常速度的2倍
      */
     public void highSpeed(){
              times = 5;
     }
    
     /**
      * 正常速度
      */
     public void normalSpeed(){
              times = 1;
     }
}
 

你可能感兴趣的:(J2ME学习)