扫雷游戏源码(2)

类别:Java 点击:0 评论:0 推荐:

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;
  }
}

本文地址:http://com.8s8s.com/it/it15455.htm