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

📄 gamecanvas.java

📁 一个手机JAVA游戏,MDIP2的运行环境,包括所有的资源和源代码,俄罗撕方块
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * GameCanvas.java
 *
 * Copyright 2001 SkyArts. All Rights Reserved.
 */
import javax.microedition.lcdui.*;
import java.util.*;

/**
 * 游戏的操作与画面描绘使用的Canvas类
 *
 * @author  Hideki Yonekawa
 * @version 1.0
 */
class GameCanvas extends Canvas implements Runnable, CommandListener {
	/** 构造函数 */
	private int					screenWidth;
	/** 储存横向长度的变量  */
	private int					screenHeight;

	/** 储存纵向长度的变量 */
	private Cube				cube;

	/** 代表标题显示状态的常量 */
	private static final short	TITLE			= 0;
	/** 代表游戏开始显示状态的常量 */
	private static final short	GAME_START		= 1;
	/** 代表游戏中显示状态的常量 */
	private static final short	GAME_PLAYING	= 2;
	/** 代表游戏结束显示状态的常量 */
	private static final short	GAME_END		= 5;

	/** 储存现在显示状态的变量 */
	private short				gameState;
	/** 显示暂停状态的标志 */
	private	boolean				isPaused;	

	/** 储存使用在标题的图像的变量 */
	private Image				titleImg;

	/** Start指令变量 */
	private Command				startCmd		= new Command("Start", Command.SCREEN, 5);
	/** Exit指令变量 */
	private Command				exitCmd			= new Command("Exit", Command.SCREEN, 1);
	/** Pause指令变量 */
	private Command				pauseCmd		= new Command("Pause", Command.SCREEN, 5);
	/** Resume指令变量 */
	private Command				resumeCmd		= new Command("Resume", Command.SCREEN, 5);
	/** Quit指令变量 */
	private Command				quitCmd			= new Command("Quit", Command.SCREEN, 1);

	/** 成为方块的置入物的Piece数组变量 */
	private Piece[]				pieces;

	/** 储存方块的列(纵向)数目的常量 */
	private static final int	COLUMN_LENGTH		= 8;
	/** 储存方块的行(横向)数目的常量 */
	private static final int	ROW_LENGTH			= 6;

	/** 储存了落下方块组的中心点Index的变量 */
	private int					centerPoint;

	/** 储存了落下方块组的左侧Index的变量 */
	private static final short	FALL_START_INDEX1	= 2;
	/** 储存了落下方块组的右侧Index的变量 */
	private static final short	FALL_START_INDEX2	= 3;

	//落下方块的方向常量
	/** 代表落下方块组的方向为上的常量 */
	private static final short	DIRECTION_UP		= 0;
	/** 代表落下方块组的方向为右的常量 */
	private static final short	DIRECTION_RIGHT		= 1;
	/** 代表落下方块组的方向为下的常量 */
	private static final short	DIRECTION_DOWN		= 2;
	/** 代表落下方块组的方向为左的常量 */
	private static final short	DIRECTION_LEFT		= 3;
	/** 代表落下方块组之默认方向的常量 */
	private static final short	DIRECTION_DEFAULT= DIRECTION_RIGHT;

	/** 储存了落下方块组现在方向的变量 */
	private short				currentDirection;

	/** 储存下一个方块资讯的Piece数组变量 */
	private Piece[]				nextPieces;

	/** 在制作下一个方块组时所使用的Random变量 */
	private Random				random				= new Random();

	/** 代表按键输入是否有效的标志变量 */
	private boolean				isKeyEnable;

	private static final int	DEFAULT_FALL_TICK_COUNT=10;
	/** 储存用来调整方块组落下速度用的Tick计数的变量 */
	private int					tickCount4Speed;
	/** 储存用来计算落下方块组时机的Tick计数的变量 */
	private int					tickCount4Fall;
	/** 储存方块组落下次数的变量 */
	private int					fallCount;
	/** 代表游戏循环是否停止的变量 */
	private boolean				isStopped;
	/** 判断是否要落下下一个方块组的标志变量 */
	private boolean				isNextFall;

	/** 存放描绘间隔(INTERVAL)的常量 */
	private static final long	DRAW_INTERVAL		= 100;

	/** 存放默认分数增加值的常量 */
	private static final int	DEFAULT_SCORE_VALUE	= 100;

	/** 存放分数的变量 */
	private long				score;

	/** 存放最高分数的变量 */
	private long				highScore			= 0;

	/** 存放默认字体的变量 */
	private Font				defFont				= Font.getDefaultFont();

	/** 构造函数 */
	GameCanvas(Cube cube) {
		this.cube = cube;

		//取得画面的可描绘范围
		screenWidth = getWidth();
		screenHeight = getHeight();

		//取得标题图像
		try {
			titleImg = Image.createImage("/title.png");
		}catch(java.io.IOException e) {}

		//登录指令监听
		setCommandListener(this);

		//将游戏的状态变成显示标题
		gameState = TITLE;
	}

	/** 进行游戏初始化的方法 */
	private void doGameInit() {
		//清除分数
		score = 0;
		//取得下一个方块组
		nextPieces = getNextPieces();
		//清除方块置入数组
		pieces = new Piece[COLUMN_LENGTH * ROW_LENGTH];

		//将调整方块组速度用的Tick计数设为默认值
		tickCount4Speed = DEFAULT_FALL_TICK_COUNT;
		//清除用来计算落下方块组时机的Tick计数
		tickCount4Fall = 0;
		//清除落下方块组的数目
		fallCount = 0;
		//清除停止循环标志
		isStopped = false;
		//清除暂停标志
		isPaused = false;
		//建立是否落下下一个方块组的标志
		isNextFall = true;
		//让按键有效
		isKeyEnable = true;
	}

	/** 指令的事件发生时被调用出来的方法 */
	public void commandAction(Command c, Displayable s) {
		if(c == startCmd) {//Start指令
			//初始化游戏以开始游戏
			doGameInit();
			gameState = GAME_START;
			doThreadStart();

		}else if(c == exitCmd) {//EXIT指令
			//调用出Cube类的doExit方法以结束MIDlet本身
			cube.doExit();

		}else if(c == pauseCmd) {//Pause指令
			//交换Pause指令与Resume指令,调用出Pause、Resume处理方法
			removeCommand(pauseCmd);
			addCommand(resumeCmd);
			doPauseOrResume();

		}else if(c == resumeCmd) {//Resume指令
			//交换Resume指令与Pause指令,调用出Pause、Resume处理方法
			removeCommand(resumeCmd);
			addCommand(pauseCmd);
			doPauseOrResume();

		}else if(c == quitCmd) {//Quit指令
			//调用出游戏结束方法
			doGameStop();
			//删除指令
			removeCommand(pauseCmd);
			removeCommand(resumeCmd);
			removeCommand(quitCmd);
			//显示标题
			doTitle();
		}
	}

	/** MIDlet的startApp()被调用出来时所调用的方法 */
	void doStartApp() {
		//根据现在的状态来操作运作
		switch(gameState) {
			case TITLE:			//显示标题时
				doTitle();
			break;

			case GAME_START:	//游戏开始时
			case GAME_PLAYING:	//游戏中
				//进行暂停
				isPaused = true;
				//停止游戏循环
				isStopped = true;

				//以防万一先删除关卡中的指令
				removeCommand(pauseCmd);
				removeCommand(resumeCmd);
				//新增Resume指令
				addCommand(resumeCmd);
			break;

			default:			//上述情形以外时
				//解除暂停
				isPaused = false;
			break;
		}
	}

	/** 进行标题显示的方法 */
	private void doTitle() {
		//将游戏的状态设为显示标题
		gameState = TITLE;

		//以防万一先将关卡中的指令删除
		removeCommand(pauseCmd);
		removeCommand(resumeCmd);
		removeCommand(quitCmd);

		//显示标题画面
		repaint();
		//新增指令
		addCommand(exitCmd);
		addCommand(startCmd);
	}

	/** MIDlet的pauseApp()方法被调用出来时所调用的方法 */
	void doPauseApp() {
		switch(gameState) {
			case TITLE:					//显示标题时
			break;

			default:					//上述情形以外时
				//暂停
				isPaused = true;
				//停止游戏循环
				isStopped = true;
			break;
		}
	}

	/**
	 *产生下一个落下方块组并传回的方法
	 *在@return	Piece[]	之后落下的Piece数组
	 */
	private Piece[] getNextPieces() {
		//以Random所产生的值为基础决定种类
		int kindNo= random.nextInt() % 10;
		//负数的时候就将其变为正数
		if(kindNo < 0) kindNo = kindNo * (-1);

		Piece[] retPieces = new Piece[] {
			new Piece(),
			new Piece()
		};

		switch(kindNo) {
			case 0://红红
				retPieces[0].currentColor = Piece.RED;
				retPieces[1].currentColor = Piece.RED;
			break;
			case 1://红绿
				retPieces[0].currentColor = Piece.RED;
				retPieces[1].currentColor = Piece.GREEN;
			break;
			case 2://红蓝
				retPieces[0].currentColor = Piece.RED;
				retPieces[1].currentColor = Piece.BLUE;
			break;
			case 3://红黄
			retPieces[0].currentColor = Piece.RED;
			retPieces[1].currentColor = Piece.YELLOW;
			break;
			case 4://绿绿
				retPieces[0].currentColor = Piece.GREEN;
				retPieces[1].currentColor = Piece.GREEN;
			break;
			case 5://绿蓝
				retPieces[0].currentColor = Piece.GREEN;
				retPieces[1].currentColor = Piece.BLUE;
			break;
			case 6://绿黄
				retPieces[0].currentColor = Piece.GREEN;
				retPieces[1].currentColor = Piece.YELLOW;
			break;
			case 7://蓝蓝
				retPieces[0].currentColor = Piece.BLUE;
				retPieces[1].currentColor = Piece.BLUE;
			break;
			case 8://蓝黄
				retPieces[0].currentColor = Piece.BLUE;
				retPieces[1].currentColor = Piece.YELLOW;
			break;
			case 9://黄黄
				retPieces[0].currentColor = Piece.YELLOW;
				retPieces[1].currentColor = Piece.YELLOW;
			break;
		}
		return retPieces;
	}

	/** 按键按下事件发生时被调用出来的方法 */
	protected synchronized void keyPressed(int keyCode) {
		if(	! isKeyEnable || gameState != GAME_PLAYING ||
			(gameState == GAME_PLAYING && isPaused)) {
 			//按键为无效、或是不在游戏中、在游戏中暂停时为return
			return;
		}

		//为清除按键时不处理
		if(keyCode == 0) return;	//for KDDI

		int gameCode = getGameAction(keyCode);
		switch(gameCode) {
			case UP:	//按下上按键时
			case FIRE:	//按下Fire键时
				doRotat();
			break;

			case LEFT:	//按下左按键时
				doLeft();
			break;

			case DOWN:	//按下下按键时
				doFall();
			break;

			case RIGHT:	//按下右按键时
				doRight();
			break;
		}
	}

	/** 压下按键状态时被重复调用的方法 */
	protected void keyRepeated(int keyCode) {
		keyPressed(keyCode);
	}

	/** 压下上按键、决定按键时所调用出来的方法 */
	private void doRotat() {
		switch(currentDirection) {
			case DIRECTION_UP:		//方向为上时
				//因为要作顺时钟旋转,所以要检查右边
				if(centerPoint % ROW_LENGTH != ROW_LENGTH -1) {
				//当不是在最右边时
					if( pieces[centerPoint +1] == null &&
						pieces[centerPoint -ROW_LENGTH +1] == null ) 
					{
					//若在右边以及右边上面都没有东西的话就向右转动
						pieces[centerPoint +1] = pieces[centerPoint -ROW_LENGTH];
						pieces[centerPoint -ROW_LENGTH] = null;
						//方向转向右
						currentDirection = DIRECTION_RIGHT;
					}
				}
			break;

			case DIRECTION_RIGHT:	//方向为右时
				//因为要作顺时钟旋转,所以要检查下方
				if(centerPoint < (COLUMN_LENGTH -1) * ROW_LENGTH) {
				//当不是在最下面时
					if( pieces[centerPoint +ROW_LENGTH] == null &&
						pieces[centerPoint +1 +ROW_LENGTH] == null)
					{
					//当右下与正下方什么都没有时向下移动
						pieces[centerPoint +ROW_LENGTH] = pieces[centerPoint +1];
						pieces[centerPoint +1] = null;

						//将方向变为向下
						currentDirection = DIRECTION_DOWN;
					}
				}
			break;

			case DIRECTION_DOWN:	//方向为向下时
				//因为要作顺时钟旋转,所以要检查左边
				if(centerPoint % ROW_LENGTH != 0) {
				//当不在最左边的时候

⌨️ 快捷键说明

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