分享
 
 
 

MIDP1.0游戏完整实现-双人扫雷1.0(二)

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

作者:yinowl

2005年2月

帮助界面

帮助界面很简单,把需要的文字排好宽度放在一个String数组里,然后绘制在屏幕上,假如一屏放不下就增加按键响应来翻屏,其实只是重新画出数组前面或后面的几个值,源代码如下:

在MiningCanvas.java中添加如下代码

final String[] strGamehelp =new String[10];

public MiningCanvas(MiningMIDlet miningMIDlet){

...

strGamehelp[0]="此游戏为双人对战游戏";

strGamehelp[1]=",和经典的扫雷不同,这";

strGamehelp[2]="个游戏中,我们要挖出";

strGamehelp[3]="雷,挖错雷则交换玩家.";

strGamehelp[4]="一共有52颗雷,256个格";

strGamehelp[5]="子,最先挖到27颗雷者";

strGamehelp[6]="获胜.1.上,下,左,右分";

strGamehelp[7]="别为数字键2,8,4,6,挖";

strGamehelp[8]="雷为5;2.屏幕外框的颜";

strGamehelp[9]="色为当前下玩家;";

}

PRivate void paintHelpScreen(Graphics g){

g.setColor(0x00FFFFFF);

g.fillRect(0,0,canvasW,canvasH);

g.setFont(lowFont);

g.setColor(0x00000000);

for(int i=0;i<strGamehelp.length;i++){

g.drawString(strGamehelp[i],5,5+(lowFont.getHeight()+3)*i,Graphics.TOPGraphics.LEFT);

}

}

在keyPressed方法中的switch结构中添加

case GAMESTATE_HELP://假如游戏现在的状态为帮助状态,那个不管玩家按哪个键都会跳转到主菜单状态

gamestate=GAMESTATE_MENU;

break;

游戏主界面

主界面的绘制分成几个部分,一个是雷区棋盘的绘制,根据雷区二位数组中的每一个Bomb对象中的变量值绘出整个棋盘,假如hasFound值为false,画出

;假如hasFound值为true且isBomb值为false,那么会画出这个雷位四周的雷数
;假如hasFound值为true且isBomb值为true,那么会画出这个雷位是哪一个玩家所挖出的,分别是
。第二个部分是玩家的选择框。第三个部分是游戏的信息框,也就是两个玩家目前的分值,还剩几颗雷,信息框的图片为
。最后一个部分是提示当前轮到哪一个玩家扫雷,在雷区的外框用玩家的颜色提示,和在信息框中画出玩家的旗帜

这里有几个注重点:

1.雷区不能全部在屏幕中画下,所以会通过卷轴滚动。整个雷区是16x16,我们的屏幕预备画出10x12,用两个变量(paintX和paintY)来控制当前要画出的雷区左上角的雷位坐标,例如这两个变量的值分别为3和4,那么会画出横轴3-10,纵轴4-13的雷位,选择框的坐标(selectedX和selectedY)不用担心,当他超出了屏幕,只需要增加或减少paintX和paintY的值即可,只要保证选择框的坐标和paintX/Y坐标值得距离不超过9(10-1)和11(12-1)即可。这里要十分小心的是,我们这里所有的坐标值和雷区的二位数组bombs中的坐标正好相反,也就是选择框(5,6)是类位bombs[6][5]。

2.在创建雷区二维Bomb数组时,二位数组的大小是18x18(new Bomb[miningMapGrid+2][miningMapGrid+2]),目的是在大小16x16的真正雷区外加一圈雷位,以避免bombOut()方法和其他需要周边搜索雷位时不会出现超越边界异常。

3.因为bombs数组中的索引1-16才是真正代表雷区中坐标(1,1)至(16,16)的雷位,所以在整个程序中,所有有关坐标和数组索引值的地方都要十分小心,不要出现位置错误

4.消息框中需要绘制的几个数值的坐标变量(Player1X/Y,Player2X/Y,bombnowX/Y)的值都是相对于整个消息框的左上角的相对坐标,我们也可以为消息框的坐标单独定义一对变量,这样就更清楚了。

源代码如下:

在MiningCanvas.java中添加如下代码

int empty;

static final int miningMapGrid=16;//雷区为16格x16格

static final int bombNum=52;//共有52颗雷

int miningMapLength,miningGridLength;//整个雷区的边长,每一个雷位格子的边长

int miningMapX,miningMapY;//雷区的左上角坐标

int selectedX,selectedY;//选择框的坐标,是在雷区里的坐标(1-16)

int player1Found,player2Found;//两个玩家的分值,即已经找到的雷数

int paintX,paintY;//要画出的区域的左上角坐标,是在雷区里的坐标(1-16)

int bombLeft;//剩下未扫出的雷数

static final int Player1X=10,Player1Y=30;//信息框中画出玩家一分数的坐标位置,相对于信息框左上角

static final int Player2X=10,Player2Y=90;//信息框中画出玩家二分数的坐标位置,相对于信息框左上角

static final int bombnowX=8,bombnowY=52;//信息框中画出剩余雷数的坐标位置,相对于信息框左上角

static final int bombMapW=10,bombMapH=12;//屏幕上能绘出的雷位的数量

Bomb[][] bombs;

boolean isPlayer1;//当前是否轮到玩家一扫雷

Alert winAlert;//显示输赢信息的Alert对象

String winString;//比出输赢后要输出的信息

boolean sbWon;//是否得出输赢

static final Font font = Font.getFont(Font.FACE_MONOSPACE,Font.STYLE_PLAIN,Font.SIZE_SMALL);

//消息框中使用的字体

Image infoImg,splashImage;

Image unFoundGroundImg;

Image foundGroundImg;

Image player1BombImg,player2BombImg,player1TurnImg,player2TurnImg;

Image bomb1Img,bomb2Img,bomb3Img,bomb4Img,bomb5Img,bomb6Img,bomb7Img,bomb8Img;

//所有要用到的图片

public MiningCanvas(MiningMIDlet miningMIDlet){

...

try{//实例化游戏中需要的Image对象

unFoundGroundImg=Image.createImage("/unfoundGroundbig.png");

foundGroundImg=Image.createImage("/foundGroundbig.png");

player1BombImg=Image.createImage("/player1bombbig.png");

player2BombImg=Image.createImage("/player2bombbig.png");

bomb1Img=Image.createImage("/bomb1big.png");

bomb2Img=Image.createImage("/bomb2big.png");

bomb3Img=Image.createImage("/bomb3big.png");

bomb4Img=Image.createImage("/bomb4big.png");

bomb5Img=Image.createImage("/bomb5big.png");

bomb6Img=Image.createImage("/bomb6big.png");

infoImg=Image.createImage("/info.png");

splashImage=Image.createImage("/occo.png");

player1TurnImg=Image.createImage("/player1turn.png");

player2TurnImg=Image.createImage("/player2turn.png");

}catch(IOException e){}

isPlayer1=true;//初始化玩家先后顺序

miningGridLength=14;//初始化每一个雷位的边长

miningMapLength=14*12;//整个扫雷棋盘的边长

miningMapX=(canvasW-miningMapLength)/2;//屏幕上棋盘左上角的X坐标

miningMapY=(canvasH-miningMapLength)/2;//屏幕上棋盘左上角的Y坐标

selectedX=selectedY=miningMapGrid/2;//初始化选择框的坐标为

player1Found=player2Found=0;//初始化两个玩家的得分

paintX=paintY=3;//初始化整个雷区一开始在屏幕上显示的范围

sbWon=false;//初始化没有玩家获胜

bombLeft=bombNum;//初始化剩余雷数为总雷数

bombs=new Bomb[miningMapGrid+2][miningMapGrid+2];

bombInit();//初始化雷区

}

private void paintGameScreen(Graphics g){

paintPlayer(g,isPlayer1);

paintMiningMap(g);

paintInfo(g);

paintSelected(g);

}

protected void paintInfo(Graphics g){

g.drawImage(infoImg,miningMapX+bombMapW*miningGridLength+1,

miningMapY,Graphics.TOPGraphics.LEFT);

g.setFont(font);

g.setColor(0x00FFFFFF);

g.drawString(String.valueOf(bombLeft),miningMapX+bombMapW*miningGridLength+bombnowX,

miningMapY+bombnowY,Graphics.TOPGraphics.LEFT);

g.drawString(String.valueOf(player1Found),miningMapX+bombMapW*miningGridLength+Player1X,

miningMapY+Player1Y,Graphics.TOPGraphics.LEFT);

g.drawString(String.valueOf(player2Found),miningMapX+bombMapW*miningGridLength+Player2X,

miningMapY+Player2Y,Graphics.TOPGraphics.LEFT);

//这个方法中接下来的代码是用来在信息框中画出小地图,也就是屏幕上显示的地雷区域在整个雷区

中的位置

g.setColor(0x00777777);

g.fillRect(miningMapX+bombMapW*miningGridLength+1,miningMapY+8*miningGridLength+1,

2*miningGridLength-2,2*miningGridLength-1);

g.setColor(0x00000000);

g.drawRect(miningMapX+bombMapW*miningGridLength+1,miningMapY+8*miningGridLength+1,

2*miningGridLength-2,2*miningGridLength-1);

g.setColor(0x00BBBBBB);

g.fillRect(miningMapX+bombMapW*miningGridLength+4+2*(paintX-1),

miningMapY+8*miningGridLength+4+2*(paintY-1),12,17);

g.setColor(0x00FFFFFF);

g.drawRect(miningMapX+bombMapW*miningGridLength+4+2*(paintX-1),

miningMapY+8*miningGridLength+4+2*(paintY-1),12,17);

}

protected void paintPlayer(Graphics g,boolean isPlayer1){

if(isPlayer1)//在棋盘外围画出玩家颜色的外框

g.setColor(0x000000FF);

else

g.setColor(0x00FF0000);

for(int i=1;i<=5;i++){

g.drawRect(miningMapX-i,miningMapY-i,miningMapLength+2*i,miningMapLength+2*i);

}

if(isPlayer1)//在信息框中画出代表玩家的旗帜

g.drawImage(player1TurnImg,miningMapX+(bombMapW+1)*miningGridLength+1,

miningMapY+11*miningGridLength,Graphics.HCENTERGraphics.VCENTER);

else

g.drawImage(player2TurnImg,miningMapX+(bombMapW+1)*miningGridLength+1,

miningMapY+11*miningGridLength,Graphics.HCENTERGraphics.VCENTER);

}

public void paintMiningMap(Graphics g){

for(int i=0;i<bombMapH;i++){

for(int j=0;j<bombMapW;j++){//根据每个Bomb对象中的变量值画出不同的图片

if(!bombs[i+paintY+1][j+paintX+1].hasFound){

g.drawImage(unFoundGroundImg,miningMapX+j*miningGridLength,

miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT);

}

else {

if(!bombs[i+paintY+1][j+paintX+1].isBomb){

switch(bombs[i+paintY+1][j+paintX+1].bombaround){

case 0:

g.drawImage(foundGroundImg,miningMapX+j*miningGridLength,

miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT);

break;

case 1:

g.drawImage(bomb1Img,miningMapX+j*miningGridLength,

miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT);

break;

case 2:

g.drawImage(bomb2Img,miningMapX+j*miningGridLength,

miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT);

break;

case 3:

g.drawImage(bomb3Img,miningMapX+j*miningGridLength,

miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT);

break;

case 4:

g.drawImage(bomb4Img,miningMapX+j*miningGridLength,

miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT);

break;

case 5:

g.drawImage(bomb5Img,miningMapX+j*miningGridLength,

miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT);

break;

case 6:

g.drawImage(bomb6Img,miningMapX+j*miningGridLength,

miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT);

break;

default:

g.drawImage(foundGroundImg,miningMapX+j*miningGridLength,

miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT);

break;

}

}

else {

if(bombs[i+paintY+1][j+paintX+1].isPlayer1){

g.drawImage(player1BombImg,miningMapX+j*miningGridLength,

miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT);

}

else{

g.drawImage(player2BombImg,miningMapX+j*miningGridLength,

miningMapY+i*miningGridLength,Graphics.TOPGraphics.LEFT);

}

}

}

}

}

}

public void paintSelected(Graphics g){

g.setColor(0x00FF0000);//画出选择框,注重其与总雷区和能在屏幕上显示出的区域间的关系

g.drawRoundRect(miningMapX+(selectedX-paintX)*miningGridLength-1,

miningMapY+(selectedY-paintY)*miningGridLength-1,

miningGridLength+1,miningGridLength+1,2,2);

}

在keyPressed方法中的switch结构中添加

case GAMESTATE_GAMEING:

{

if(keyCode==FullCanvas.KEY_SOFTKEY1){

gamestate=GAMESTATE_GAMEMENU;

}

else if (action == FullCanvas.LEFT ) {

selectedX=(--selectedX+miningMapGrid)%(miningMapGrid);

}

else if (action == FullCanvas.RIGHT) {

selectedX=(++selectedX)%(miningMapGrid);

}

else if (action == FullCanvas.UP) {

selectedY=(--selectedY+miningMapGrid)%(miningMapGrid);

}

else if (action == FullCanvas.DOWN) {

selectedY=(++selectedY)%(miningMapGrid);

}

else if (action == FullCanvas.FIRE) {

if(!bombs[selectedY+1][selectedX+1].hasFound){

if(bombs[selectedY+1][selectedX+1].isBomb){

bombs[selectedY+1][selectedX+1].hasFound=true;

bombs[selectedY+1][selectedX+1].isPlayer1=this.isPlayer1;

if(isPlayer1)

player1Found++;

else

player2Found++;

bombLeft--;

checkWin();//每次有玩家挖到了雷就监测其是否胜出

}

else{

bombOut(selectedY+1,selectedX+1);

//假如此雷位及四周都无雷,打开所有与其相连的相同情况的雷位及此区域周边一圈雷位

isPlayer1=!isPlayer1;

}

}

}

//以下几行代码是调整显示在屏幕上的区域的坐标,以免选择框跑出屏幕范围

if((selectedX-paintX)<0)

paintX=selectedX;

else if((selectedX-paintX)>=bombMapW)

paintX=selectedX-bombMapW+1;

if((selectedY-paintY)<0)

paintY=selectedY;

else if((selectedY-paintY)>=bombMapH)

paintY=selectedY-bombMapH+1;

break;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有