J2ME手機(jī)開發(fā)游戲報(bào)告
《J2ME手機(jī)游戲開發(fā)技術(shù)》實(shí)驗(yàn)報(bào)告
實(shí)驗(yàn)名稱:益智類游戲——炸彈人
一. 實(shí)驗(yàn)?zāi)康?
利用J2ME有關(guān)知識,設(shè)計(jì)一款益智類(PUZ)炸彈人(Bombman)游戲程序,是我們能夠掌握J(rèn)avaME游戲開發(fā)的基本技巧。
二. 實(shí)驗(yàn)環(huán)境
Windows 7操作系統(tǒng),Eclipse,WTK2.5.1,JDK1.6
三. 實(shí)驗(yàn)內(nèi)容
利用自己所學(xué)的J2ME知識,進(jìn)行游戲開發(fā),該游戲的創(chuàng)意是游戲主角在一個(gè)隨機(jī)生存的地圖中放置炸彈,以消滅地圖中所有的敵人為目的。游戲地圖被設(shè)計(jì)成一個(gè)多行多列的棋盤,游戲中的主角和敵人每次都只能按照棋盤中相鄰的棋盤格進(jìn)行移動,而且在地圖中還存在不同的障礙物,用來阻擋游戲主角和敵人的移動。游戲主角可以在沒有障礙物的地方防止炸彈來引爆敵人或障礙物來獲得去路。從中有以下是幾個(gè)元素的詳細(xì)功能:
(1) 空白區(qū):是游戲主角和敵人可以移動的位置及放置炸彈的位置。
(2) 巖石:地圖中的障礙物,用來阻止游戲主角和敵人的且不能被炸彈摧毀。
(3) 磚墻:也是用來阻止的,不過能被炸彈摧毀變成空白區(qū)。
(4) 敵人:是消滅游戲主角的一方,它需要游戲主角用炸彈將其炸死,其所處 的地方也會變?yōu)榭瞻讌^(qū),敵人在空白區(qū)來去自如,一旦碰到游戲主 角,游戲主角會被殺死。
(5) 游戲主角:游戲中由玩家控制的一方,在空白區(qū)移動,可以放置炸彈。
四. 實(shí)驗(yàn)步驟(代碼分析)
該游戲是一個(gè)11*11的棋盤,用一個(gè)char型的二維數(shù)組來表示該棋盤,二維數(shù)組中的每一個(gè)數(shù)組元素就代表了游戲棋盤中的一個(gè)棋盤格。該游戲采用面向?qū)ο蟮某绦蛟O(shè)計(jì)方法,主要的功能都封裝到不同的類中,定義了以下幾個(gè)類:
1.Board類:該類作為程序的模型定義類,在其中定義了游戲中所使用的數(shù) 據(jù)結(jié)構(gòu)以及對這些數(shù)據(jù)結(jié)構(gòu)中的數(shù)據(jù)進(jìn)行設(shè)置和獲取的方法。
2.BoardView類:該類作為程序的視圖定義類,也是游戲的畫布屏幕類,在 該類中定義了如何根據(jù)用戶的游戲動作繪制對應(yīng)的游戲運(yùn) 行畫面的方法。
3. Bomb類:該類表示游戲中的炸彈,定義了如何顯示炸彈的爆炸效果以及炸 彈爆炸后對其他相關(guān)元素的影響的方法。
4.Enemy類:該類表示游戲中的敵人,具體定義了敵人如何移動以及判斷敵 人是否死亡的方法。
5.Player類:該類表示游戲中的主角,定義了游戲主角如何移動、如何防止 炸彈以及判斷游戲是否死亡的方法。
6.Img類:該類定義了游戲中各種圖像的構(gòu)造方法。
7.jBombMan類:該類是程序的MIDlet類。
(1)jBombMan.java
private Display oDisplay; //屏幕對象
private BoardView oBoardView; //棋盤視圖對象
private Board oBoard; //棋盤對象
private Player oPlayer; //主角對象
private Enemy oEnemy; //敵人對象
(2) Board.java
//定義棋盤的二維數(shù)組
public char[ ][ ] chBoard;
/*
N - None 表示什么也沒有
W - Wall 表示磚墻
L - Pillar 表示巖石
P - Player 表示游戲主角
E - Enemy 表示敵人
B - Bomb 表示炸彈
U - Bomb under player 表示主角正在放置炸彈
X - Exploding 表示炸彈爆炸
*/
//聲明一個(gè)隨機(jī)數(shù)對象
private Random random;
//聲明棋盤的行和列數(shù)
public int iCols, iRows;
//聲明判斷游戲是否結(jié)束的標(biāo)識
public volatile boolean isGameOver;
//聲明判斷是否玩家勝利的標(biāo)識
public volatile boolean isWin;
//構(gòu)造函數(shù),初始化棋盤的行數(shù)和列數(shù),并構(gòu)造隨機(jī)數(shù)對象
public Board( int cols, int rows )
//定義棋盤的初始化方法
public void init()
//判斷某個(gè)棋盤格中是否是給定的元素
public boolean isElement( char ch, int x, int y )
//獲取指定的某個(gè)棋盤格中的元素
public char getElement( int x, int y )
//設(shè)置指定的某個(gè)棋盤格中的元素
public void setElement( char ch, int x, int y )
//判斷給定的位置是否在敵人的攻擊范圍內(nèi)
public boolean near( char ch, int x, int y )
//判斷給定的位置是否可以向某個(gè)方向移動2步
public boolean near2( char ch, int x, int y )
(3)BoardView.java
private Board oBoard;
private Player oPlayer;
private Enemy oEnemy;
//定義背景色
private final int BackgroundColor = 0xffffff;
//定義每個(gè)棋盤格的大小
private final int iCellSize = 20;
//聲明內(nèi)部邊框距離坐標(biāo)原點(diǎn)的橫坐標(biāo)距離
private final int iLeft = 10;
//聲明內(nèi)部邊框距離坐標(biāo)原點(diǎn)的縱坐標(biāo)距離
private final int iTop = 10;
public BoardView( Board board )
public void setPlayer( Player player )
public void setEnemy( Enemy enemy )
//繪制游戲屏幕
public void paint( Graphics g )
//定義繪制游戲結(jié)束的方法
private void paintGameOver( Graphics g )
//定義繪制游戲玩家獲勝的方法
private void paintWin( Graphics g )
//繪制游戲棋盤邊框的方法
private void paintFrame( Graphics g )
//定義繪制棋盤的方法
private void paintBoard( Graphics g )
//定義響應(yīng)按鍵按下的事件處理方法
public void keyPressed( int code )
//定義游戲結(jié)束或者玩家勝利時(shí)的事件處理方法
private void keyForInit( int action )
//定義游戲過程中的事件處理方法
private void keyForPlay( int action )
//定義重新繪制棋盤格的方法
public void repaintCells( int x, int y, int w, int h )
(4)Player.java
private Board oBoard;
private BoardView oBoardView;
private Enemy oEnemy;
private Bomb oBomb;
private Random random;
private int iX, iY;
//游戲主角的構(gòu)造函數(shù)
public Player( Board board, BoardView boardview )
//游戲主角的初始化方法
public void init()
public void setEnemy( Enemy enemy )
//清除炸彈對象的方法
public void clearBomb()
//判斷游戲主角能否移動到給定的棋盤格上
private boolean canGo( int x, int y )
//定義放置炸彈的方法
public void fire()
//定義游戲主角向左移動的方法
public void left()
//定義游戲主角向右移動的方法
public void right()
//定義游戲主角向上移動的方法
public void up()
//定義游戲主角向下移動的方法
public void down()
//定義游戲主角死掉的方法
public void die()
(5)Enemy.java
private Board oBoard;
private BoardView oBoardView;
public Player oPlayer;
//設(shè)置敵人每次移動的間隔時(shí)間
private final int iMoveTime = 500;
private Random random;
//聲明游戲中敵人的數(shù)量
private int iNumbers;
//聲明所有敵人所在位置的二維數(shù)組
private int[][] arrPositions;
private volatile boolean stopThread = false;
//初始化敵人對象的構(gòu)造函數(shù)
public Enemy( Board board, BoardView boardview, Player player, int numbers )
//敵人對象的初始化方法
public void init()
public void stopThread()
//定義線程的方法體,在該方法中將定義敵人如何進(jìn)行移動
public void run()
//定義敵人的移動方法
private void move( int i )
//判斷能否移動到指定棋盤格位置上的方法
private boolean canGo( int x, int y )
//定義給定位置上的敵人死亡的方法
public void die( int x, int y )
//定義游戲中的所有敵人對象全部死亡的方法
public void dieAll()
(6) Bomb.java
private Board oBoard;
private BoardView oBoardView;
private Player oPlayer;
private Enemy oEnemy;
//定義炸彈爆炸前等待的時(shí)間
private final int iExplodingTime = 4000;
//定義爆炸效果顯示的時(shí)間
private final int iDisapearTime = 1000;
private int iX, iY;
private volatile boolean stopThread = false;
//炸彈類的構(gòu)造方法
public Bomb( Board board, BoardView boardview, Player player, Enemy enemy, int x, int y )
public void stopThread()
//根據(jù)給定的單元格判斷炸彈爆炸后的結(jié)果的方法
private void explode( int x, int y )
//清空給定的單元格中的元素
private void clear( int x, int y )
//定義線程的方法體,在該方法中將定義炸彈爆炸的效果
public void run()
(7) img.java
//創(chuàng)建游戲中炸彈圖像的方法,其余圖像方法一樣
public static Image imgBomb = Image.createImage(new byte[] {{...}, (int)0, (int)163} );
五. 實(shí)驗(yàn)結(jié)果與分析(包括代碼和實(shí)驗(yàn)總結(jié))
程序代碼:
1. 游戲的模型類實(shí)現(xiàn)
(1) Board.java
package com.mot.j2me.midlets.jbombman;
import java.util.*;
//定義游戲的模型的類,可以將其看做一個(gè)棋盤
public class Board {
//定義棋盤的二維數(shù)組
public char[][] chBoard;
/*
N - None 表示什么也沒有
W - Wall 表示磚墻
L - Pillar 表示巖石
P - Player 表示游戲主角
E - Enemy 表示敵人
B - Bomb 表示炸彈
U - Bomb under player 表示主角正在放置炸彈
X - Exploding 表示炸彈爆炸
*/
//聲明一個(gè)隨機(jī)數(shù)對象
private Random random;
//聲明棋盤的行和列數(shù)
public int iCols, iRows;
//聲明判斷游戲是否結(jié)束的標(biāo)識
public volatile boolean isGameOver;
//聲明判斷是否玩家勝利的標(biāo)識
public volatile boolean isWin;
//構(gòu)造函數(shù),初始化棋盤的行數(shù)和列數(shù),并構(gòu)造隨機(jī)數(shù)對象
public Board( int cols, int rows ) {
//構(gòu)造隨機(jī)數(shù)對象
random = new Random();
iCols = cols;
iRows = rows;
//構(gòu)造表示棋盤的二維數(shù)組
chBoard = new char[iCols][iRows];
//調(diào)用棋盤的初始化方法
init();
}
//定義棋盤的初始化方法
public void init() {
//表示游戲結(jié)束的標(biāo)識設(shè)置為false
isGameOver = false;
//表示玩家獲勝的標(biāo)識設(shè)置為false
isWin = false;
//遍歷二維數(shù)組,為數(shù)組的每個(gè)元素設(shè)置值為'N',表示游戲中每個(gè)棋盤格上都為空
for( int i=0; i<iCols; i++ )
for( int j=0; j<iRows; j++ )
chBoard[i][j] = 'N';
// 遍歷二維數(shù)組,每相隔一個(gè)元素設(shè)置值為'L',表示游戲中每相隔的棋盤格上放置一個(gè)巖石
for( int i=1; i<iCols; i+=2 )
for( int j=1; j<iRows; j+=2 )
chBoard[i][j] = 'L';
// 遍歷二維數(shù)組,在棋盤上非巖石的位置隨機(jī)放置磚墻
for( int i=0; i<iCols; i++ )
for( int j=0; j<iRows; j++ )
//判斷當(dāng)前遍歷到的棋盤格是否為空
if( chBoard[i][j] == 'N' )
//如果當(dāng)前棋盤格位置為空,則根據(jù)隨機(jī)數(shù)的判斷條件是否成立來判斷是否放置磚墻
if( Math.abs( random.nextInt() ) % 2 == 0 )
chBoard[i][j] = 'W';
}
//判斷某個(gè)棋盤格中是否是給定的元素
public boolean isElement( char ch, int x, int y ) {
if( x < 0 )
return false;
if( x >= iCols )
return false;
if( y < 0 )
return false;
if( y >= iRows )
return false;
return( chBoard[x][y] == ch );
}
//獲取指定的某個(gè)棋盤格中的元素
public char getElement( int x, int y ) {
if( x < 0 )
return '?';
if( x >= iCols )
return '?';
if( y < 0 )
return '?';
if( y >= iRows )
return '?';
return chBoard[x][y];
}
//設(shè)置指定的某個(gè)棋盤格中的元素
public void setElement( char ch, int x, int y ) {
if( ch == '?' )
return;
if( x < 0 )
return;
if( x >= iCols )
return;
if( y < 0 )
return;
if( y >= iRows )
return;
chBoard[x][y] = ch;
}
//判斷給定的位置是否在敵人的攻擊范圍內(nèi)
public boolean near( char ch, int x, int y ) {
return isElement( ch, x-1, y )||isElement( ch, x, y-1 )
||isElement( ch, x+1, y )||isElement( ch, x, y+1 );
}
//判斷給定的位置是否可以向某個(gè)方向移動2步
public boolean near2( char ch, int x, int y ) {
return ( isElement( ch, x-1, y )&&isElement( ch, x-2, y ) )
||( isElement( ch, x, y-1 )&&isElement( ch, x, y-2 ) )
||( isElement( ch, x+1, y )&&isElement( ch, x+2, y ) )
||( isElement( ch, x, y+1 )&&isElement( ch, x, y+2 ) );
}
}
2. 游戲的視圖類實(shí)現(xiàn)
(1) BoardView.java
package com.mot.j2me.midlets.jbombman;
import javax.microedition.lcdui.*;
//游戲的畫布屏幕類
public class BoardView extends Canvas {
private Board oBoard;
private Player oPlayer;
private Enemy oEnemy;
//定義背景色
private final int BackgroundColor = 0xffffff;
//定義每個(gè)棋盤格的大小
private final int iCellSize = 20;
//聲明內(nèi)部邊框距離坐標(biāo)原點(diǎn)的橫坐標(biāo)距離
private final int iLeft = 10;
//聲明內(nèi)部邊框距離坐標(biāo)原點(diǎn)的縱坐標(biāo)距離
private final int iTop = 10;
public BoardView( Board board ) {
oBoard = board;
}
public void setPlayer( Player player ) {
oPlayer = player;
}
public void setEnemy( Enemy enemy ) {
oEnemy = enemy;
}
//繪制游戲屏幕
public void paint( Graphics g ) {
//聲明同步塊,對Graphics對象g進(jìn)行同步
synchronized( g ) {
//如果游戲結(jié)束,則繪制游戲結(jié)束的界面
if( oBoard.isGameOver )
paintGameOver( g );
//如果玩家獲勝,則繪制玩家獲勝的界面
else if( oBoard.isWin )
paintWin( g );
//否則繪制當(dāng)前游戲運(yùn)行的界面
else
paintBoard( g );
}
}
//定義繪制游戲結(jié)束的方法
private void paintGameOver( Graphics g ) {
g.drawImage( Img.imgGameOver, 60, 100, Graphics.LEFT|Graphics.TOP );
}
//定義繪制游戲玩家獲勝的方法
private void paintWin( Graphics g ) {
g.drawImage( Img.imgCongratulation, 60, 100, Graphics.LEFT|Graphics.TOP );
}
//繪制游戲棋盤邊框的方法
private void paintFrame( Graphics g ) {
g.drawRect( 0, 0, 239, 239 );
g.drawRect( 1, 1, 237, 237 );
g.drawRect( 2, 2, 235, 235 );
g.drawRect( 3, 3, 233, 233 );
g.drawRect( 7, 7, 225, 225 );
g.drawRect( 8, 8, 223, 223 );
}
//定義繪制棋盤的方法
private void paintBoard( Graphics g ) {
//判斷畫布屏幕的工作區(qū)的原點(diǎn)是否在坐標(biāo)軸的原點(diǎn)上,如果是則直接繪制游戲棋盤的邊框
if( g.getClipX() == 0 )
paintFrame( g );
//設(shè)置畫布屏幕的工作區(qū)的左上角坐標(biāo)以及高度和寬度
int x = ( g.getClipX() - iLeft ) / iCellSize;
int y = ( g.getClipY() - iTop ) / iCellSize;
int w = g.getClipWidth() / iCellSize;
int h = g.getClipHeight() / iCellSize;
System.out.println( "paint: x=" + x + ", y=" + y
+ ", w=" + w + ", h=" + h );
//如果畫布屏幕的工作區(qū)的高度超過了棋盤的高,則將工作區(qū)的高度設(shè)置為棋盤的高度
if( h>oBoard.iRows )
h = oBoard.iRows;
//根據(jù)工作區(qū)的位置,開始繪制棋盤中的元素
for( int i=x; i<x+w; i++ )
for( int j=y; j<y+h; j++ )
//根據(jù)遍歷得到的數(shù)組中的元素類型進(jìn)行繪制
switch( oBoard.chBoard[i][j] ) {
case 'N': //當(dāng)前數(shù)組元素中的類型表示空白區(qū)域,則繪制空白區(qū)域的圖像
g.setColor( BackgroundColor );
g.fillRect( iLeft + i*iCellSize, iTop + j*iCellSize,
iCellSize, iCellSize );
break;
case 'W': //當(dāng)前數(shù)組元素中的類型表示磚墻,則繪制磚墻的圖像
g.drawImage( Img.imgWall, iLeft + i*iCellSize, iTop + j*iCellSize,
Graphics.LEFT|Graphics.TOP );
break;
case 'L': //當(dāng)前數(shù)組元素中的類型表示巖石,則繪制巖石的圖像
g.drawImage( Img.imgPillar, iLeft + i*iCellSize, iTop + j*iCellSize,
Graphics.LEFT|Graphics.TOP );
break;
case 'P': //當(dāng)前數(shù)組元素中的類型表示游戲主角,則繪制游戲主角的圖像
case 'U': //當(dāng)前數(shù)組元素中的類型表示主角正在放置炸彈,則繪制游戲主角的圖像
g.drawImage( Img.imgPlayer, iLeft + i*iCellSize, iTop + j*iCellSize,
Graphics.LEFT|Graphics.TOP );
break;
case 'E': //當(dāng)前數(shù)組元素中的類型表示敵人,則繪制敵人的圖像
g.drawImage( Img.imgEnemy, iLeft + i*iCellSize, iTop + j*iCellSize,
Graphics.LEFT|Graphics.TOP );
break;
case 'B': //當(dāng)前數(shù)組元素中的類型表示炸彈,則繪制炸彈的圖像
g.drawImage( Img.imgBomb, iLeft + i*iCellSize, iTop + j*iCellSize,
Graphics.LEFT|Graphics.TOP );
break;
case 'X': //當(dāng)前數(shù)組元素中的類型表示炸彈爆炸,則繪制炸彈爆炸的圖像
g.drawImage( Img.imgExploding, iLeft + i*iCellSize, iTop + j*iCellSize,
Graphics.LEFT|Graphics.TOP );
break;
}
}
//定義響應(yīng)按鍵按下的事件處理方法
public void keyPressed( int code ) {
//如果游戲結(jié)束或者玩家勝利,則調(diào)用keyForInit()方法響應(yīng)按鍵事件
if( oBoard.isGameOver||oBoard.isWin )
keyForInit( getGameAction(code) );
//否則調(diào)用keyForPlay()方法響應(yīng)按鍵事件
else
keyForPlay( getGameAction(code) );
}
//定義游戲結(jié)束或者玩家勝利時(shí)的事件處理方法
private void keyForInit( int action ) {
//如果用戶按下了手機(jī)中的Select按鍵,則游戲進(jìn)行初始化
if( action != FIRE )
return;
//棋盤初始化
oBoard.init();
//敵人初始化
oEnemy.init();
//游戲主角初始化
oPlayer.init();
//初始化完成后重新繪制屏幕
repaint();
}
//定義游戲過程中的事件處理方法
private void keyForPlay( int action ) {
switch( action ){
case FIRE:
oPlayer.fire();
break;
case LEFT:
oPlayer.left();
break;
case RIGHT:
oPlayer.right();
break;
case UP:
oPlayer.up();
break;
case DOWN:
oPlayer.down();
break;
}
}
//定義重新繪制棋盤格的方法
public void repaintCells( int x, int y, int w, int h ) {
if( x < 0 )
x = 0;
if( x >= oBoard.iCols )
x = oBoard.iCols - 1;
if( x + w > oBoard.iCols )
w = oBoard.iCols - x;
if( y < 0 )
y = 0;
if( y >= oBoard.iRows )
y = oBoard.iRows - 1;
if( y + h > oBoard.iRows )
h = oBoard.iRows - y;
repaint( iLeft + x*iCellSize, iTop + y*iCellSize,
w*iCellSize, h*iCellSize );
}
}
3. 游戲的主角類實(shí)現(xiàn)
(1) Player.java
package com.mot.j2me.midlets.jbombman;
import java.util.*;
//游戲中的主角類
public class Player {
private Board oBoard;
private BoardView oBoardView;
private Enemy oEnemy;
private Bomb oBomb;
private Random random;
private int iX, iY;
//游戲主角的構(gòu)造函數(shù)
public Player( Board board, BoardView boardview ) {
oBoard = board;
oBoardView = boardview;
random = new Random();
//調(diào)用游戲主角的初始化方法
init();
}
//游戲主角的初始化方法
public void init() {
while( true ) {
//獲取游戲主角初始化的隨機(jī)位置
iX = Math.abs( random.nextInt() ) % oBoard.iCols;
iY = Math.abs( random.nextInt() ) % oBoard.iRows;
//如果隨機(jī)位置上不為空,則跳出當(dāng)前本次循環(huán),再重新獲取隨機(jī)位置
if( oBoard.chBoard[iX][iY] != 'N' )
continue;
//如果隨機(jī)位置在敵人的攻擊范圍內(nèi),則跳出當(dāng)前本次循環(huán),再重新獲取隨機(jī)位置
if( oBoard.near( 'E', iX, iY ) )
continue;
//如果隨機(jī)位置不能夠向任何方向移動2步,則跳出當(dāng)前本次循環(huán),再重新獲取隨機(jī)位置
if( !oBoard.near2( 'N', iX, iY ) )
continue;
//如果獲得一個(gè)合適的隨機(jī)位置,則跳出死循環(huán),繼續(xù)向下執(zhí)行
break;
}
//在棋盤中根據(jù)獲取的隨機(jī)位置設(shè)置對應(yīng)的棋盤格中的元素為游戲主角
oBoard.chBoard[iX][iY] = 'P';
}
public void setEnemy( Enemy enemy ) {
oEnemy = enemy;
}
//清除炸彈對象的方法
public void clearBomb() {
oBomb = null;
System.out.println( "delete Bomb" );
}
//判斷游戲主角能否移動到給定的棋盤格上
private boolean canGo( int x, int y ) {
//如果要移動到的棋盤格中沒有元素,則返回true
if( oBoard.isElement( 'N', x, y ) )
return true;
//如果要移動到的棋盤格中是敵人,則游戲主角死掉
if( oBoard.isElement( 'E', x, y ) )
die();
//如果上述條件都不成立,則不能移動到給定的單元格中,返回false
return false;
}
//定義放置炸彈的方法
public void fire() {
//構(gòu)造一個(gè)炸彈對象
oBomb = new Bomb( oBoard, oBoardView, this, oEnemy, iX, iY );
//啟動炸彈對象中的線程方法體
oBomb.start();
System.out.println( "new Bomb: x=" + iX + ", y=" + iY );
}
//定義游戲主角向左移動的方法
public void left() {
//如果不能向左移動,則返回
if( !canGo( iX-1, iY ) )
return;
//如果移動之前的棋盤格中的元素是游戲主角放置炸彈,則移動之前的棋盤格中放置炸彈元素
if( oBoard.chBoard[iX][iY] == 'U' )
oBoard.chBoard[iX][iY] = 'B';
else //否則的話,移動之前的棋盤格中設(shè)置為空
oBoard.chBoard[iX][iY] = 'N';
//游戲主角的列數(shù)減1
iX--;
//設(shè)置移動后的棋盤格中的元素為游戲主角
oBoard.chBoard[iX][iY] = 'P';
//在畫布屏幕上重繪指定的區(qū)域
oBoardView.repaintCells( iX, iY, 2, 1 );
}
//定義游戲主角向右移動的方法
public void right() {
//如果不能向右移動,則返回
if( !canGo( iX+1, iY ) )
return;
//如果移動之前的棋盤格中的元素是游戲主角放置炸彈,則移動之前的棋盤格中放置炸彈元素
if( oBoard.chBoard[iX][iY] == 'U' )
oBoard.chBoard[iX][iY] = 'B';
else //否則的話,移動之前的棋盤格中設(shè)置為空
oBoard.chBoard[iX][iY] = 'N';
//游戲主角的列數(shù)加1
iX++;
//設(shè)置移動后的棋盤格中的元素為游戲主角
oBoard.chBoard[iX][iY] = 'P';
//在畫布屏幕上重繪指定的區(qū)域
oBoardView.repaintCells( iX-1, iY, 2, 1 );
}
//定義游戲主角向上移動的方法
public void up() {
//如果不能向上移動,則返回
if( !canGo( iX, iY-1 ) )
return;
//如果移動之前的棋盤格中的元素是游戲主角放置炸彈,則移動之前的棋盤格中放置炸彈元素
if( oBoard.chBoard[iX][iY] == 'U' )
oBoard.chBoard[iX][iY] = 'B';
else //否則的話,移動之前的棋盤格中設(shè)置為空
oBoard.chBoard[iX][iY] = 'N';
//游戲主角的行數(shù)減1
iY--;
//設(shè)置移動后的棋盤格中的元素為游戲主角
oBoard.chBoard[iX][iY] = 'P';
//在畫布屏幕上重繪指定的區(qū)域
oBoardView.repaintCells( iX, iY, 1, 2 );
}
//定義游戲主角向下移動的方法
public void down() {
//如果不能向上移動,則返回
if( !canGo( iX, iY+1 ) )
return;
//如果移動之前的棋盤格中的元素是游戲主角放置炸彈,則移動之前的棋盤格中放置炸彈元素
if( oBoard.chBoard[iX][iY] == 'U' )
oBoard.chBoard[iX][iY] = 'B';
else //否則的話,移動之前的棋盤格中設(shè)置為空
oBoard.chBoard[iX][iY] = 'N';
//游戲主角的行數(shù)加1
iY++;
//設(shè)置移動后的棋盤格中的元素為游戲主角
oBoard.chBoard[iX][iY] = 'P';
//在畫布屏幕上重繪指定的區(qū)域
oBoardView.repaintCells( iX, iY-1, 1, 2 );
}
//定義游戲主角死掉的方法
public void die() {
System.out.println( "Player die: x=" + iX + ", y=" + iY );
//殺死游戲中搜有的敵人
oEnemy.dieAll();
//設(shè)置游戲結(jié)束的標(biāo)識為true
oBoard.isGameOver = true;
//重新繪制畫布屏幕
oBoardView.repaint();}}
4. 游戲的敵人類實(shí)現(xiàn)
(1) Enemy.java
package com.mot.j2me.midlets.jbombman;
import java.util.*;
//游戲中的敵人類
public class Enemy extends Thread {
private Board oBoard;
private BoardView oBoardView;
public Player oPlayer;
//設(shè)置敵人每次移動的間隔時(shí)間
private final int iMoveTime = 500;
private Random random;
//聲明游戲中敵人的數(shù)量
private int iNumbers;
//聲明所有敵人所在位置的二維數(shù)組
private int[][] arrPositions;
private volatile boolean stopThread = false;
//初始化敵人對象的構(gòu)造函數(shù)
public Enemy( Board board, BoardView boardview, Player player, int numbers ) {
oBoard = board;
oBoardView = boardview;
oPlayer = player;
iNumbers = numbers;
arrPositions = new int[iNumbers][2];
random = new Random();
//調(diào)用敵人對象的初始化方法
init();
}
//敵人對象的初始化方法
public void init() {
int x, y;
//隨機(jī)將游戲中的敵人放置在棋盤中
for( int i=0; i<iNumbers; ) {
//隨機(jī)得到每個(gè)敵人在棋盤格中的位置
x = Math.abs( random.nextInt() ) % oBoard.iCols;
y = Math.abs( random.nextInt() ) % oBoard.iRows;
//如果得到的隨機(jī)位置上已經(jīng)有其他元素了,則跳出本次循環(huán)
if( oBoard.chBoard[x][y] != 'N' )
continue;
//如果得到的隨機(jī)位置上為空,則將敵人元素放置在該單元格中
oBoard.chBoard[x][y] = 'E';
//將敵人對象所處的單元格位置保存在數(shù)組中
arrPositions[i][0] = x;
arrPositions[i][1] = y;
//繼續(xù)本次循環(huán)
i++;
}
}
public void stopThread() {
stopThread = true;
}
//定義線程的方法體,在該方法中將定義敵人如何進(jìn)行移動
public void run() {
while (!stopThread) {
try {
//敵人對象靜止一段時(shí)間
sleep(iMoveTime);
//依次循環(huán)設(shè)置每個(gè)敵人對象是如何在期盼中進(jìn)行移動的
for( int i=0; i<iNumbers; i++ )
//如果該敵人對象沒有被消滅,則調(diào)用move()方法進(jìn)行移動
if( arrPositions[i][0] != -1 )
move( i );
}
catch (InterruptedException ie) {
}
}
}
//定義敵人的移動方法
private void move( int i ) {
int x, y;
//隨機(jī)獲得敵人移動的方向
switch( random.nextInt() % 4 ) {
case 0://向左移動
//當(dāng)前的棋盤格行不變,列減1
x = arrPositions[i][0] - 1;
y = arrPositions[i][1];
//判斷能否移動到給定的棋盤格位置
if( canGo( x, y ) ) {
System.out.println( "Enemy " + i + " Left: x=" + x + ", y=" + y );
//設(shè)置移動前的位置沒有任何元素,移動后的位置為敵人元素
oBoard.chBoard[x+1][y] = 'N';
oBoard.chBoard[x][y] = 'E';
//修改二維數(shù)組中表示該敵人對象的位置的值
arrPositions[i][0] = x;
//在畫布屏幕上重繪指定的區(qū)域
oBoardView.repaintCells( x, y, 2, 1);
}
break;
case 1://向右移動
//當(dāng)前的棋盤格行不變,列加1
x = arrPositions[i][0] + 1;
y = arrPositions[i][1];
//判斷能否移動到給定的棋盤格位置
if( canGo( x, y ) ) {
System.out.println( "Enemy " + i + " R