⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gamecanvas.java

📁 《J2ME实用教程》 源文件下载 本书没有仅仅局限于J2ME单机游戏的开发
💻 JAVA
字号:
import java.lang.System.*;

import java.util.Random;

import java.util.Vector;

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

/**

 * <p>标题: Canvas测试</p>

 * <p>描述: 游戏的界面</p>

 * @version 1.0*/

/** 游戏动作类 */

class gameCanvas

extends Canvas

implements CommandListener {

	/** 黑 */
	private static final int BLACK = 0x00000000;

	/** 白 */
	private static final int WHITE = 0x00FFFFFF;

	/** 红 */
	private static final int RED = 0x00FF0000;

	/** 蓝 */
	private static final int BLUE = 0x000000FF;

	/** 没有移动的标志 */
	private static final int NO_MOVE = -1;

	/** 主窗体类 */
	private final control midlet;

	/** 逻辑类 */
	private final gamelogic game;

	/** 退出菜单 */
	private final Command exitCommand;

	/** 重新开始菜单 */
	private final Command newGameCommand;

	/** 随机数 */
	private final Random random = new Random();

	/** 屏幕宽度 */
	private int screenWidth;

	/** 屏幕高度 */
	private int screenHeight;

	/**
	 * boardCellSize 正方形单元格的大小, boardTop 棋盘top的位置, boardLeft 棋盘left位置
	 */
	private int boardCellSize, boardTop, boardLeft;

	/** preCursorPosition 前一次光标选择的位置,cursorPosition 当前光标选择的位置 */
	private int preCursorPosition, cursorPosition;

	/** 用于存储被标记的地雷的位置 */
	private Vector BombVector = new Vector();

	private boolean isRestart;

	/**
	 * 构造器
	 * 
	 * @param midlet
	 *            主窗体类
	 */

	public gameCanvas(control midlet) {
		this.midlet = midlet;
		// game = new gamelogic(random);
		game = new gamelogic();
		initializeBoard();//

		/** 初始化菜单 */
		exitCommand = new Command("退出", Command.EXIT, 1);
		newGameCommand = new Command("新游戏", Command.SCREEN, 2);
		addCommand(exitCommand);
		addCommand(newGameCommand);
		setCommandListener(this);

		/** 开始游戏 */
		initialize();
	}

	/**
	 * 添加一个地雷位置标记
	 * 
	 * @param matrix
	 *            位置标记
	 */

	private void addBomb(int matrix) {
		BombVector.addElement(Integer.toString(matrix));
	}

	/**
	 * 删除一个地雷位置标记
	 * 
	 * @param matrix
	 *            位置标记
	 */

	private void delBomb(int matrix) {
		BombVector.removeElement(Integer.toString(matrix));
	}

	/**
	 * 搜索该位置是否被标记
	 * 
	 * @param matrix
	 *            位置标记
	 * 
	 * @return boolean 该位置是否被记录,false为被记录
	 */

	private boolean searchBomb(int matrix) {
		return BombVector.indexOf(Integer.toString(matrix)) == -1; // -1表示没有找到该位置的信息
	}

	/** 初始化屏幕,取得棋盘的初始位置 */

	private void initializeBoard() {
		screenWidth = getWidth(); // 取得屏幕宽度
		screenHeight = getHeight(); // 取得屏幕高度
		if (screenWidth > screenHeight) {
			boardCellSize = (screenHeight - 1) / 8;
			boardLeft = (screenWidth - (boardCellSize * 8)) / 2;
			boardTop = 1;
		} else {
			boardCellSize = (screenWidth - 1) / 8;
			boardLeft = 1;
			boardTop = (screenHeight - boardCellSize * 8) / 2;
		}
	}

	/** 初始化游戏和屏幕. 使游戏重新启动 */

	private void initialize() {
		preCursorPosition = cursorPosition = 0;

		game.setNewGame();

		game.InitArray();

		isRestart = true;
		BombVector.removeAllElements();

		repaint();
	}

	/**
	 * 重画canvas
	 * 
	 * @param g
	 *            重画的Graphics对象
	 */

	public void paint(Graphics g) {
		game.isWin();

		if (!game.isGameOver()) {
			paintGame(g);
		} else {
			paintGameOver(g);
		}
	}

	/**
	 * 游戏未结束时的重画动作
	 * 
	 * @param g
	 *            重画的Graphics对象
	 */

	private void paintGame(Graphics g) {
		if (isRestart) {
			/* 清除画板 */
			g.setColor(0xbbbbbb);
			g.fillRect(0, 0, screenWidth, screenHeight);
			drawBoard(g);// 画面板方格
			int i = game.Bomb();
			g.drawString("雷的总数是 " + i, screenWidth / 2, boardTop / 3,
					Graphics.TOP | Graphics.HCENTER);

			paintAll(g);
			// System.out.println("sss");//test
			drawBombTag(g);
		}

		drawCursor(g);
	}

	/**
	 * 游戏结束时的重画动作,画出游戏统计结果
	 * 
	 * @param g
	 *            重画的Graphics对象
	 */

	private void paintGameOver(Graphics g) {
		if (game.isGameOver()) {
			if (game.isWin()) {
				GameOver(g);
			} else {
				for (int i = 0; i < 8; i++) {
					for (int j = 0; j < 8; j++) {
						if (game.getBomb(i * 8 + j) == 20) {
							drawCircle(g, i * 8 + j);
						}
					}
				}
			}
		}
	}

	/**
	 * 游戏结束时的重画动作
	 * 
	 * @param g
	 *            重画的Graphics对象
	 */

	private void GameOver(Graphics g) {

		String tallyMsg = "你赢了,恭喜!";
		Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN,
				Font.SIZE_LARGE);
		int strHeight = font.getHeight();
		int tallyMsgWidth = font.stringWidth(tallyMsg);
		int strWidth = tallyMsgWidth;

		/* 计算绘制文本的起始位置 */
		int x = (screenWidth - strWidth) / 2;
		x = x < 0 ? 0 : x;
		int y = (screenHeight - 2 * strHeight) / 2;
		y = y < 0 ? 0 : y;

		/* 清除画板 */
		g.setColor(WHITE);
		g.fillRect(0, 0, screenWidth, screenHeight);

		/* 画出文本结果 */
		g.setColor(RED);
		g.drawString(tallyMsg, x + 5, (y + 1 + strHeight),
				(Graphics.TOP | Graphics.LEFT));
	}

	/**
	 * 监听器响应接口
	 * 
	 * @param c
	 *            命令
	 * 
	 * @param d
	 *            消息源
	 */

	public void commandAction(Command c, Displayable d) {
		if (c == exitCommand) {
			// midlet.destroyApp(false);
		} else if (c == newGameCommand) {
			initialize();
		}
	}

	/**
	 * 画圆,表示地雷位置
	 * 
	 * @param g
	 *            图形物件
	 * 
	 * @param matrix
	 *            位置
	 */

	private void drawCircle(Graphics g, int matrix) {
		int x, y;
		y = matrix / 8;
		x = matrix % 8;
		g.setColor(0xbbbbbb);// 清除背景
		g.fillRect(screenWidth / 4, screenHeight * 10 / 11, screenWidth,
				screenHeight);// 清除背景
		g.setColor(RED);
		g.drawString("加油啊!", screenWidth / 2, screenHeight, Graphics.BOTTOM
				| Graphics.HCENTER);
		g.fillArc(x * boardCellSize + boardLeft + 3, y * boardCellSize
				+ boardTop + 2, boardCellSize - 2, boardCellSize - 2, 0, 360);
	}

	/**
	 * 画叉,表示地雷爆炸
	 * 
	 * @param g
	 *            图形物件
	 * 
	 * @param x
	 *            x坐标
	 * 
	 * @param y
	 *            y坐标
	 */

	private void drawCross(Graphics g, int x, int y) {
		g.setColor(BLACK);
		g.drawLine(x + 1 + boardLeft, y + boardTop, x + boardCellSize - 4 - 4
				+ boardLeft, y + boardCellSize - 5 + boardTop);
		g.drawLine(x + 1 + boardLeft, y + boardCellSize - 5 + boardTop, x
				+ boardCellSize - 4 - 4 + boardLeft, y + boardTop);
	}

	/** 根据玩家的移动重画棋盘 */

	private void doPlayerMove() {
		if (game.isFree(cursorPosition)) {
			game.openpan(cursorPosition);
		}
		repaint(); // 画出移动的图形结果
	}

	/**
	 * 重画所有被揭开的文字
	 * 
	 * @param g
	 *            图形物件
	 */

	private void paintAll(Graphics g) {
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++) {
				if (game.getBomb(i * 8 + j) >= 10
						&& game.getBomb(i * 8 + j) < 20) {

					// paintCell(g, i * 8 + j);
					paintNum(g, i * 8 + j);
				}
			}
		}
	}

	/**
	 * 画出文字
	 * 
	 * @param g
	 *            图形物件
	 * 
	 * @param matrix
	 *            位置
	 */

	private void paintNum(Graphics g, int matrix) {
		int i, j, s;
		Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN,
				Font.SIZE_SMALL);
		s = game.getBomb(matrix);
		// System.out.println(s);
		i = matrix / 8;
		j = matrix % 8;
		g.setColor(WHITE);
		if (this.searchBomb(matrix)) {
			if (s != 20) {

				g.drawString(String.valueOf(s - 10), boardLeft + j
						* boardCellSize + 10, boardTop + i * boardCellSize + 2,
						(Graphics.TOP | Graphics.LEFT));
			}
		}
	}

	/**
	 * 捕获按键消息
	 * 
	 * @param keyCode
	 *            按键代码
	 */

	protected void keyPressed(int keyCode) {
		/** 当游戏结束时返回 */
		if (game.isGameOver()) {
			return;
		}

		int gameAction = getGameAction(keyCode);

		switch (gameAction) {
		case FIRE:
			if (searchBomb(cursorPosition)) { // 如果该位置被做出了地雷标志,则该位置不能被揭开
				doPlayerMove();

				// paintCell(cursorPosition);
			}
			break;
		case RIGHT:
			doMoveCursor(1, 0);
			break;
		case DOWN:
			doMoveCursor(0, 1);
			break;
		case LEFT:
			doMoveCursor(-1, 0);
			break;
		case UP:
			doMoveCursor(0, -1);
			break;
		default:
			if (searchBomb(cursorPosition)) {
				addBomb(cursorPosition);
			} else {
				delBomb(cursorPosition);
			}
			repaint();
			break;
		}
	}

	/**
	 * 画出棋盘上的地雷标志
	 * 
	 * @param g
	 *            图形物件
	 */

	private void drawBombTag(Graphics g) {
		int s, j, k, flagnum = 0;

		for (int i = 0; i < BombVector.size(); i++) {
			s = Integer.parseInt((String) BombVector.elementAt(i));
			j = s % 8;
			k = s / 8;
			g.setColor(RED);
			// drawFlag("!!!", boardLeft + j * boardCellSize + 7, boardTop + k *
			// boardCellSize - 2, (Graphics.TOP | Graphics.LEFT));
			drawFlag(g, boardLeft + j * boardCellSize, boardTop + k
					* boardCellSize);

			flagnum++;
			g.setColor(0xbbbbbb);// 清除背景
			g.fillRect(screenWidth / 4, screenHeight * 10 / 11, screenWidth,
					screenHeight);// 清除背景
			g.setColor(BLACK);
			g.drawString("你已经有了 " + flagnum + " 标志", screenWidth / 2,
					screenHeight, Graphics.BOTTOM | Graphics.HCENTER);
		}
	}

	/**
	 * 指定棋盘上的坐标
	 * 
	 * @param dx
	 *            左右偏移量x
	 * 
	 * @param dy
	 *            上下偏移量y
	 */

	private void doMoveCursor(int dx, int dy) {

		int newCursorPosition = cursorPosition + dx + 8 * dy;
		if ((newCursorPosition >= 0) && (newCursorPosition < 64)) {
			preCursorPosition = cursorPosition;
			cursorPosition = newCursorPosition;
			repaint();
		}
	}

	/**
	 * 在棋盘上画出选择光标
	 * 
	 * @param g
	 *            图形物件
	 */

	private void drawCursor(Graphics g) {

		/** 清除之前的选择光标 */
		g.setColor(0xbbbbbb);
		g.drawRect(((preCursorPosition % 8) * boardCellSize) + 3 + boardLeft,
				((preCursorPosition / 8) * boardCellSize) + 1 + boardTop,
				boardCellSize - 2, boardCellSize - 2);

		/** 在当前选择位置画出选择光标 */
		g.setColor(this.BLUE);
		g.drawRect(((cursorPosition % 8) * boardCellSize) + 3 + boardLeft,
				((cursorPosition / 8) * boardCellSize) + 1 + boardTop,
				boardCellSize - 2, boardCellSize - 2);
	}

	/**
	 * 画一个盘
	 * 
	 * @param g
	 *            图形物件
	 */

	private void drawBoard(Graphics g) {

		/** 清除盘 */
		g.setColor(0xbbbbbb);
		g.fillRect(0, 0, screenWidth, screenHeight);
		g.setColor(0xaaaaaa);
		g.fillRect(boardLeft + 2, boardTop, boardCellSize * 8,
				boardCellSize * 8);
		/** 画盘 */
		g.setColor(BLACK);
		for (int i = 0; i < 9; i++) {
			g.drawLine(boardLeft + 2, boardCellSize * i + boardTop,
					(boardCellSize * 8) + 1, boardCellSize * (1 + i) - 1); /* 画四条黑色的横线 */
			g.drawLine(boardCellSize * i + boardLeft, boardTop, boardCellSize
					* i + 1, boardCellSize * 9); /* 画四条黑色的竖线 */
		}
	}

	/**
	 * 打开后单元格改变颜色
	 * 
	 * @param g
	 *            图形物件
	 */

	private void paintCell(Graphics g, int matrix) {
		int i, j;

		i = matrix / 8;
		j = matrix % 8;
		g.setColor(0xbbbbbb);

		g.fillRect(boardLeft + j * boardCellSize + 2, 1 + boardTop + i
				* boardCellSize, boardLeft + (1 + j) * boardCellSize, boardTop
				+ (i) * boardCellSize);

	}

	public void drawFlag(Graphics g, int x, int y) {

		g.setColor(RED);
		g.fillRect(x + 8, y + 8, 16, 10);
		g.setColor(BLACK);
		g.drawLine(x + 8, y + 8, x + 8, y + 24);
		g.drawLine(x + 9, y + 8, x + 9, y + 24);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -