package Boom;
import java.util.*;
import java.io.IOException;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDletStateChangeException;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
public class MGame extends Canvas implements CommandListener{
private static final int GRIDSIZE = 8;
private static final int MINECOUNT = 15;
private static Mine pMain;
private static Display display;
private static int Width, Height, selx, sely, leftbomb;
private static byte grid[][];
private static boolean gameover;
private static Random rand;
private static Image offScreenImg;
private static Graphics Exg;
private static Image TitleImg, MineImg, fMineImg, HideImg, fHideImg, FlagImg, fFlagImg, NumImg[], fNumImg[];
private static Command ContCmd = new Command("继续游戏", Command.OK, 0);
private static Command StartCmd = new Command("新游戏", Command.OK, 1);
private static Command ExitCmd = new Command("退出", Command.EXIT, 2);
private static Command OKCmd = new Command("确定", Command.OK, 0);
public MGame(Mine pmine) {
pMain = pmine;
Width = 80 / GRIDSIZE;
Height = (getHeight() - 1) / GRIDSIZE;
grid = new byte[Height][Width];
rand = new Random((new Date()).getTime());
NumImg = new Image[8];
fNumImg = new Image[8];
gameover = true;
try
{
TitleImg = Image.createImage("/images/title.png");
MineImg = Image.createImage("/images/mine.png");
fMineImg = Image.createImage("/images/minef.png");
HideImg = Image.createImage("/images/hide.png");
fHideImg = Image.createImage("/images/hidef.png");
FlagImg = Image.createImage("/images/flag.png");
fFlagImg = Image.createImage("/images/flagf.png");
for (int i=8; i>0; i--)
{
NumImg[i-1] = Image.createImage("/images/n"+i+".png");
fNumImg[i-1] = Image.createImage("/images/n"+i+"f.png");
}
}
catch(Exception exception)
{
System.out.println(exception);
}
// if (!isDoubleBuffered())
// {
// System.out.println("不支持双缓冲区");
// 创建和屏幕大小一样的缓冲区
offScreenImg = Image.createImage(getWidth(), getHeight());
// }
// 获取自定义缓冲区的Graphics,用于在上面绘制图像
Exg = offScreenImg.getGraphics();
addCommand(StartCmd);
addCommand(ExitCmd);
Exg.drawImage(TitleImg, 0, 0, 20);
}
public void paint(Graphics parm1)
{
/**@todo Implement this javax.microedition.lcdui.Displayable abstract method*/
// 将自定义的缓冲区中的图像绘制到屏幕
parm1.drawImage(offScreenImg, 0, 0, 0);
}
/**
* 键按下事件的相应函数
* @param kcode
*/
protected void keyPressed(int kcode)
{
if (gameover) return;
int bomb = 0;
int oldx = selx;
int oldy = sely;
switch(kcode)
{
case '1':
// 按钮:数字1,表示挖雷
System.gc();
if (grid[sely][selx] >= 10 && grid[sely][selx] < 20)
{
grid[sely][selx] -= 10;
if (grid[sely][selx] == 0) Expand(selx, sely);
}
else if (grid[sely][selx] < 10)
{
if (!SafeExp(selx, sely)) bomb = 1;
}
break;
// 按钮:数字3,表示插下雷标签
case '3':
System.gc();
if (grid[sely][selx] >= 10)
{
if (grid[sely][selx] < 20)
{
grid[sely][selx] += 10;
leftbomb --;
}
}
break;
// 向上移动键
case '2':
case -1:
sely --;
break;
// 向左移动键
case '4':
case -3:
selx--;
break;
// 向右移动键
case '6':
case -4:
selx ++;
break;
// 向下移动键
case '5':
case '8':
case -2:
sely ++;
break;
}
if (selx < 0) selx = 0;
if (selx > Width - 1) selx = Width - 1;
if (sely < 0) sely = 0;
if (sely > Height - 1) sely = Height - 1;
// 重新绘制用户刚刚操作的焦点的雷的状态
DrawBlock(oldx, oldy, false);
if (bomb == 0)
bomb = DrawBlock(selx, sely, true);
else
DrawBlock(selx, sely, true);
// 输出游戏状态
Exg.setColor(0xffffff);
Exg.fillRect(89, 26, 13, 13);
Exg.setColor(0);
Exg.drawString("" + leftbomb, 95, 26, Graphics.RIGHT | Graphics.TOP);
if (bomb == 1)
{
gameover = true;
Exg.drawString("爆", 95, 39, Graphics.RIGHT | Graphics.TOP);
Exg.drawString("炸", 95, 52, Graphics.RIGHT | Graphics.TOP);
}
if (Judge())
{
gameover = true;
Exg.drawString("成", 95, 39, Graphics.RIGHT | Graphics.TOP);
Exg.drawString("功", 95, 52, Graphics.RIGHT | Graphics.TOP);
}
// 激活绘制paint事件
repaint();
}
/**
* 重复按下键盘的响应事件
* @param kcode
*/
protected void keyRepeated(int kcode)
{
if (gameover) return;
int oldx = selx;
int oldy = sely;
switch(kcode)
{
case '2':
case -59:
sely --;
break;
case '4':
case -61:
selx --;
break;
case '6':
case -62:
selx ++;
break;
case '5':
case '8':
case -60:
sely ++;
break;
}
if (selx < 0) selx = 0;
if (selx > Width - 1) selx = Width - 1;
if (sely < 0) sely = 0;
if (sely > Height - 1) sely = Height - 1;
DrawBlock(oldx, oldy, false);
DrawBlock(selx, sely, true);
repaint();
}
/**
* 命令键按下的事件响应
* @param cmd
* @param displayable
*/
public void commandAction(Command cmd, Displayable displayable)
{
if (cmd == ExitCmd)
{
pMain.destroyApp(true);
}
else if (cmd == StartCmd)
{
newGame();
}
else if (cmd == OKCmd)
{
activate(display);
}
}
/**
* 激活屏幕显示本类的图像,以及在本类中加入事件侦查
* @param disp
*/
public void activate(Display disp)
{
display = disp;
display.setCurrent(this);
setCommandListener(this);
}
/**
* 用于判断扫雷结果
* @return
*/
private boolean Judge()
{
if (leftbomb == 0)
{
int i, j;
for ( i = 0; i < Height; i++)
{
for(j = 0; j < Width; j++)
{
if (grid[i][j] >= 10 && grid[i][j] < 20) return false;
}
}
return true;
}
else
{
return false;
}
}
/**
* 开始运行新游戏时运行
* 作用:
* 1、初始化界面
* 2、初始化扫雷结果
*/
private void newGame()
{
gameover = false;
selx = 0;
sely = 0;
leftbomb = MINECOUNT;
int i, j, x, y;
for (i = 0; i < Height; i++)
{
for (j = 0; j < Width; j++)
{
grid[i][j] = 10;
}
}
for (i = 0; i < MINECOUNT; i++)
{
while(true)
{
x = Math.abs(rand.nextInt()) % Width;
y = Math.abs(rand.nextInt()) % Height;
if (grid[y][x] != 19)
{
grid[y][x] = 19;
break;
}
}
}
for(i = 0; i < Height; i++)
{
for (j = 0; j < Width; j++)
{
if (grid[i][j] == 19) continue;
int k, l;
for (k = -1; k < 2; k++)
{
if (i + k < 0) continue;
if (i + k >= Height) continue;
for (l = -1; l < 2; l++)
{
if (l + j < 0) continue;
if (l + j >= Width) continue;
if (k == 0 && l == 0) continue;
if (grid[i+k][j+l] == 19) grid[i][j]++;
}
}
}
}
Exg.setColor(255, 255, 255);
Exg.fillRect(0, 0, getWidth(), getHeight());
Exg.setColor(0, 0, 0);
for (i = 0; i <= Width; i++)
{
Exg.drawLine(i*GRIDSIZE, 0, i*GRIDSIZE, Height*GRIDSIZE);
}
for (i = 0; i <= Height; i++)
{
Exg.drawLine(0, i*GRIDSIZE, Width*GRIDSIZE, i*GRIDSIZE);
}
for (i = 0; i < Height; i++)
{
for (j = 0; j < Width; j++)
{
Exg.drawImage(HideImg, j*GRIDSIZE + 1, i*GRIDSIZE + 1, 20);
}
}
int temp = getWidth();
Exg.drawImage(fHideImg, selx*GRIDSIZE + 1, sely*GRIDSIZE + 1, 20);
Exg.drawString("剩", 95, 0, Graphics.RIGHT | Graphics.TOP);
Exg.drawString("余", 95, 13, Graphics.RIGHT | Graphics.TOP);
Exg.drawString(""+leftbomb, 95, 26, Graphics.RIGHT | Graphics.TOP);
repaint();
}
/**
* 绘制当前指定坐标的雷的图像
* @param x
* @param y
* @param focus
* @return
*/
private int DrawBlock(int x, int y, boolean focus)
{
int retval = 0;
if (grid[y][x] == 0)
{
if (!focus) Exg.setColor(0xffffff);
Exg.fillRect(x*GRIDSIZE+1, y*GRIDSIZE+1, GRIDSIZE-1, GRIDSIZE-1);
if (!focus) Exg.setColor(0);
}
else if (grid[y][x] > 0 && grid[y][x] < 9)
{
if (focus)
{
Exg.drawImage(fNumImg[grid[y][x] - 1], x*GRIDSIZE + 1, y*GRIDSIZE + 1, 20);
}
else
{
Exg.drawImage(NumImg[grid[y][x] - 1], x*GRIDSIZE + 1, y*GRIDSIZE + 1, 20);
}
}
else if (grid[y][x] == 9)
{
int i, j;
for(i = 0; i < Height; i++)
{
for(j = 0; j < Width; j++)
{
if (grid[i][j] == 19 || grid[i][j] == 29)
{
Exg.drawImage(MineImg, j*GRIDSIZE+1,i*GRIDSIZE+1, 20);
}
}
}
if (focus)
Exg.drawImage(fMineImg, x*GRIDSIZE+1, y*GRIDSIZE+1, 20);
retval = 1;
}
else if (grid[y][x] >= 10 && grid[y][x] < 20)
{
if (focus)
{
Exg.drawImage(fHideImg, x*GRIDSIZE+1, y*GRIDSIZE+1, 20);
}
else
{
Exg.drawImage(HideImg, x*GRIDSIZE+1, y*GRIDSIZE+1, 20);
}
}
else
{
if (focus)
{
Exg.drawImage(fFlagImg, x*GRIDSIZE+1, y*GRIDSIZE+1, 20);
}
else
{
Exg.drawImage(FlagImg, x*GRIDSIZE+1, y*GRIDSIZE+1, 20);
}
}
return retval;
}
/**
* 嵌套函数,用于自动挖开周围没有雷的格子
* @param x
* @param y
*/
private void Expand(int x, int y)
{
int i, j;
for (i = -1; i < 2; i++)
{
if (y + i < 0) continue;
if (y + i >= Height) continue;
for (j = -1; j < 2; j++)
{
if ( x + j < 0) continue;
if ( x + j >= Width) continue;
if ( i == 0 && j == 0) continue;
if (grid[y+i][x+j] >= 10 && grid[y+i][x+j] <20)
{
grid[y+i][x+j] -= 10;
DrawBlock(x+j, y+i, false);
if (grid[y+i][x+j] == 0) Expand(x+j, y+i);
}
}
}
}
/**
* 挖开指定格子的雷
* @param x
* @param y
* @return
*/
private boolean SafeExp(int x, int y)
{
int i, j, flag = 0;
for (i = -1; i < 2; i++)
{
if (y + i < 0) continue;
if (y + i >= Height) continue;
for (j = -1; j < 2; j++)
{
if (x + j < 0) continue;
if (x + j >= Width) continue;
if ( i == 0 && j == 0) continue;
if (grid[y+i][x+j] > 20) flag ++;
}
}
if (flag != grid[y][x]) return true;
boolean retval = true;
for (i = -1; i < 2; i++)
{
if (y + i < 0) continue;
if (y + i >= Height) continue;
for (j = -1; j < 2; j++)
{
if (x + j < 0) continue;
if (x + j >= Width) continue;
if (i == 0 && j == 0) continue;
if (grid[y+i][x+j] == 19)
{
grid[y+i][x+j] = 9;
DrawBlock(x+j, y+i, true);
retval = false;
}
else if (grid[y+i][x+j] > 20 && grid[y+i][x+j] != 29)
{
Exg.drawLine((x+j)*GRIDSIZE+1, (y+i)*GRIDSIZE+1, (x+j+1)*GRIDSIZE-1, (y+i+1)*GRIDSIZE-1);
Exg.drawLine((x+j)*GRIDSIZE+1, (y+i+1)*GRIDSIZE-1, (x+j+1)*GRIDSIZE-1, (y+i)*GRIDSIZE+1);
}
}
}
if (retval)
{
for (i = -1; i < 2; i++)
{
if (y + i < 0) continue;
if (y + i >= Height) continue;
for (j = -1; j < 2; j++)
{
if (x + j < 0) continue;
if (x + j >= Width) continue;
if (i == 0 && j == 0) continue;
if (grid[y+i][x+j] >= 10 && grid[y+i][x+j] < 20)
{
grid[y+i][x+j] -= 10;
DrawBlock(x+j, y+i, false);
if (grid[y+i][x+j] == 0) Expand(x+j, y+i);
}
}
}
}
return retval;
}
}