`
MouseLearnJava
  • 浏览: 465957 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Swing俄罗斯方块游戏(二): 需要处理的关键点

阅读更多

上一篇博文介绍了俄罗斯方块游戏的图形选择与变换:
Swing俄罗斯方块游戏(一): 图形选择与变换 --> [url]http://mouselearnjava.iteye.com/blog/1914513 [/url]
.

本文将介绍实现俄罗斯方块需要处理的关键点,这些关键点有如下几点:

1. 键盘事件的处理
2. 满行及其消行操作
3. 游戏结束判断
4. 游戏进度存储和加载
5. 游戏玩家得分排行榜
... ...

下面就结合代码一个一个地介绍这些点的实现:
1. 键盘事件的处理
键盘事件的处理包括5个部分:
a)向左
	public void moveLeft(int flag[][]) {
		if (!isAlive) {
			return;
		}

		for (int i = 0; i < grid.length; i++) {
			tempX[i] = grid[i].x - 1;
			tempY[i] = grid[i].y;
		}

		if (tempX[0] >= RussiaGameConstant.LEFT
				&& flag[tempX[0]][tempY[0]] == 0
				&& tempX[1] >= RussiaGameConstant.LEFT
				&& flag[tempX[1]][tempY[1]] == 0
				&& tempX[2] >= RussiaGameConstant.LEFT
				&& flag[tempX[2]][tempY[2]] == 0
				&& tempX[3] >= RussiaGameConstant.LEFT
				&& flag[tempX[3]][tempY[3]] == 0) {
			for (int i = 0; i < grid.length; i++) {
				grid[i].x = tempX[i];
			}
		}
	}


b)向右与向左类似
c)向下与向下类似
d)空格键直接下降到底部

按下空格键一直向下的操作,其实就是在可以动的范围下,一直调用moveDown()方法e)向上键处理图形变换

每个图形,或有一种变换,或者有2种或者有四种变换,可以根据图形的特性进行处理。
比如,将“T字型”图型按照顺时针旋转,拥有四种变换,创建对象的时候已经确定了state是多少(state确定初始的位置是哪里),此后的变换只要对state加1并对4求余就可以知道怎么变换。
/**
 * @author Eric
 * @vesion 1.0
 * @desc T字型方块
 */
public class RussiaSquareThree extends RussiaSquare {

	private static final long serialVersionUID = -180232612076846292L;

	public RussiaSquareThree(){
		state = (int)(Math.random() * 4);
		switch(state)
		{
			case 0:
				grid[0].x = 4;
				grid[0].y = 0;
				grid[1].x = grid[0].x - 1;
				grid[1].y = grid[0].y + 1;
				grid[2].x = grid[0].x;
				grid[2].y = grid[0].y + 1;
				grid[3].x = grid[0].x + 1;
				grid[3].y = grid[0].y + 1;
				break;
				
			case 1:
				grid[0].x = 4;
				grid[0].y = 0;
				grid[1].x = grid[0].x;
				grid[1].y = grid[0].y + 1;
				grid[2].x = grid[0].x + 1;
				grid[2].y = grid[0].y + 1;
				grid[3].x = grid[0].x;
				grid[3].y = grid[0].y + 2;
				break;
				
			case 2:
				grid[0].x = 4;
				grid[0].y = 0;
				grid[1].x = grid[0].x + 1;
				grid[1].y = grid[0].y;
				grid[2].x = grid[0].x + 2;
				grid[2].y = grid[0].y;
				grid[3].x = grid[0].x + 1;
				grid[3].y = grid[0].y + 1;
				break;
				
			case 3:
				grid[0].x = 4;
				grid[0].y = 0;
				grid[1].x = grid[0].x - 1;
				grid[1].y = grid[0].y + 1;
				grid[2].x = grid[0].x;
				grid[2].y = grid[0].y + 1;
				grid[3].x = grid[0].x;
				grid[3].y = grid[0].y + 2;
				break;
				
			default:
				break;
		}
	}
	
	public void changeState(int flag[][])
	{
		switch(state)
		{
			case 0:
				tempX[0] = grid[0].x;
				tempY[0] = grid[0].y;
				tempX[1] = tempX[0];
				tempY[1] = tempY[0] + 1;
				tempX[2] = tempX[0] + 1;
				tempY[2] = tempY[0] + 1;
				tempX[3] = tempX[0];
				tempY[3] = tempY[0] + 2;
				isAllowChangeState(flag, 4);
				break;
				
			case 1:
				tempX[0] = grid[0].x - 1;
				tempY[0] = grid[0].y + 1;
				tempX[1] = tempX[0] + 1;
				tempY[1] = tempY[0];
				tempX[2] = tempX[0] + 2;
				tempY[2] = tempY[0];
				tempX[3] = tempX[0] + 1;
				tempY[3] = tempY[0] + 1;
				isAllowChangeState(flag, 4);
				break;
			case 2:
				tempX[0] = grid[0].x + 1;
				tempY[0] = grid[0].y - 1;
				tempX[1] = tempX[0] - 1;
				tempY[1] = tempY[0] + 1;
				tempX[2] = tempX[0];
				tempY[2] = tempY[0] + 1;
				tempX[3] = tempX[0];
				tempY[3] = tempY[0] + 2;
				isAllowChangeState(flag, 4);
				break;
				
			case 3:
				tempX[0] = grid[0].x;
				tempY[0] = grid[0].y;
				tempX[1] = tempX[0] - 1;
				tempY[1] = tempY[0] + 1;
				tempX[2] = tempX[0];
				tempY[2] = tempY[0] + 1;
				tempX[3] = tempX[0] + 1;
				tempY[3] = tempY[0] + 1;
				isAllowChangeState(flag, 4);
				break;
				
			default:
				break;
		}
	}
}


private class KeyHandler implements KeyListener {
		public void keyPressed(KeyEvent event) {
			if (!gameState.isRunState()) {
				return;
			}

			int keyCode = event.getKeyCode();
			switch (keyCode) {
			case KeyEvent.VK_LEFT:
				sr1.moveLeft(flag);
				break;

			case KeyEvent.VK_RIGHT:
				sr1.moveRight(flag);
				break;

			case KeyEvent.VK_UP:
				sr1.changeState(flag);
				break;

			case KeyEvent.VK_DOWN:
				sr1.moveDown(flag);
				break;
			case KeyEvent.VK_SPACE:
				while (sr1.isAlive) {
					sr1.moveDown(flag);
				}
			default:
				break;
			}
			repaint();
		}

		public void keyReleased(KeyEvent event) {
		}

		public void keyTyped(KeyEvent event) {
		}
	}


2. 满行及其消行操作
用一个二维数组记录当前屏幕上的方块状态,0表示没有方块,1表示有方块。
满行的判断就归结到某一行1的个数是否等于该行列的总数,如果是就满足满行条件。

当有满行情况出现的时候,需要进行消除和计分操作。

消除行的一个做法就是将该行以上的行通通往下移,移动之后在将第一行的flag全部置为0.
public class RussiaGamePanel extends JPanel {
	private class TimerAction implements ActionListener, Serializable {

		private static final long serialVersionUID = -6117702515382009989L;

		public void actionPerformed(ActionEvent event) {
			if (!gameState.isRunState()) {
				return;
			}

			//满行的个数
			int num = 0;
			
			sr1.moveDown(flag);

			if (!sr1.isAlive) {
				for (int i = 0; i < 4; i++) {
					flag[sr1.grid[i].x][sr1.grid[i].y] = 1;
					color[sr1.grid[i].x][sr1.grid[i].y] = sr1.color;
				}

				judgeGameOver();

				for (int i = RussiaGameConstant.UP; i <= RussiaGameConstant.DOWN; i++) {
					int count = 0;
					for (int j = RussiaGameConstant.LEFT; j <= RussiaGameConstant.RIGHT; j++) {
						count += flag[j][i];
					}

					/*
					 * flag[i][j] =1 表示这个位置有小方块,如果一行的位置都有小方块,那么满行的个数num加1.
					 * 并且消除行。
					 */
					if (count == RussiaGameConstant.GRID_COLUMN_NUMBER) {
						num++;

						/**
						 * 消除行操作。
						 */
						for (int m = i; m > RussiaGameConstant.UP; m--) {
							for (int n = RussiaGameConstant.LEFT; n <= RussiaGameConstant.RIGHT; n++) {
								flag[n][m] = flag[n][m - 1];
								color[n][m] = color[n][m - 1];
							}
						}
						/*
						 * 重新将第一行的flag[s][0]置为0
						 */
						for (int s = RussiaGameConstant.LEFT; s <= RussiaGameConstant.RIGHT; s++) {
							flag[s][RussiaGameConstant.UP] = 0;
						}
					}
				}
				
				/*
				 * 将下一个图形作为当前运动的图形,并随机产生下一个图形。
				 */
				sr1 = sr2;
				sr2 = RussiaSquareFactory.generateNextRussiaSquareByRandom();
			}
			// 计算分数
			calculateScore(num);

			repaint();
		}
	}
	
	/**
	 * @param num
	 *            方块满行的个数
	 */
	private void calculateScore(int num)
	{
		switch(num)
		{
		case 1: score += 10; break;
		case 2: score += 20; break;
		case 3: score += 50; break;
		case 4: score += 100; break;
		default: break;
		
		}
	}

}


3. 游戏结束判断

俄罗斯方块游戏结束的判断其实很简单,只要判断第一行的标记位是否有1即可。
	private boolean isTopTouched() {
		for (int i = RussiaGameConstant.LEFT; i <= RussiaGameConstant.RIGHT; i++) {
			if (flag[i][RussiaGameConstant.UP] == 1) {
				return true;
			}
		}
		return false;
	}


4. 游戏进度存储和加载
5. 游戏玩家得分排行榜


关于4,5两点,本文不在这里展开,因为这些功能以前在写贪吃蛇游戏的博文中介绍了。
Swing贪吃蛇游戏(三):增加游戏进度存储和加载功能 >>>
http://mouselearnjava.iteye.com/blog/1914225

Swing贪吃蛇游戏(四):增加游戏得分排行榜功能  >>>
http://mouselearnjava.iteye.com/blog/1914316

拥有所有功能的详细代码请参考附件MyRussiaGame.7z

俄罗斯方块游戏的界面如下:










  • 大小: 34.2 KB
  • 大小: 24.4 KB
  • 大小: 9.9 KB
1
0
分享到:
评论

相关推荐

    java swing开发俄罗斯方块游戏

    以下是一些关于使用Java Swing开发俄罗斯方块游戏的关键知识点: 1. **Java Swing基础**:首先,开发者需要对Swing的基本组件有深入理解,如JFrame(窗口),JPanel(面板),以及JButton,JLabel等。Swing通过继承...

    基于Java-swing的俄罗斯方块游戏:源码+答辩文档+PPT.zip

    【标题】"基于Java-swing的俄罗斯方块游戏:源码+答辩文档+PPT"是一个展示Java编程技能和游戏开发能力的项目。这个项目利用Java的Swing库来实现经典的俄罗斯方块游戏,提供了完整的源代码供学习者研究和使用。Swing...

    Swing俄罗斯方块源代码

    在Swing俄罗斯方块中,主要涉及以下关键知识点: 1. **JFrame**: JFrame是Swing中的顶级容器,通常作为应用程序的主窗口。在这个游戏中,所有的游戏元素都将被添加到JFrame上。 2. **JPanel**: JPanel是一个可以...

    精选_基于Java.Swing实现的俄罗斯方块_源码打包

    在Java.Swing中实现俄罗斯方块游戏,开发者可能使用了以下关键知识点: 1. **JFrame**:作为应用程序的主要窗口,显示游戏界面。 2. **JPanel**:用于创建自定义的画布,绘制游戏板和方块。 3. **KeyListener** 或 ...

    用java Swing做的俄罗斯方块

    Java Swing是Java GUI(图形用户界面)库,用于...以上是基于Java Swing开发俄罗斯方块游戏的关键技术点。通过学习和理解这些概念,你可以深入了解Swing如何用于创建复杂的交互式应用程序,并提升你的Java编程技能。

    java开发俄罗斯方块单机版

    总结,这个Java开发的俄罗斯方块游戏项目,不仅涵盖了Swing GUI的基本用法,还涉及到了游戏开发中的基本逻辑、渲染技巧和事件处理等关键知识点,是Java初学者提升技能的好材料。通过深入学习和实践,开发者可以对...

    纯Java版本Swing俄罗斯方块MyTetris测试版1.0

    在“俄罗斯方块”的实现中,开发者需要处理的关键知识点包括: 1. **图形绘制**:使用Java的Graphics类进行方块的绘制,包括不同形状的方块以及它们的旋转。这涉及到坐标系统、颜色填充以及线性变换等基础知识。 2...

    Java+Swing实现俄罗斯方块游戏

    在Java+Swing中实现这一游戏,主要涉及以下几个关键点: 1. **游戏逻辑**:这是实现游戏的基础,包括方块的生成、旋转、移动、消除行等。这部分通常用面向对象编程实现,每个方块是一个对象,具有位置、形状和旋转...

    swing实现的俄罗斯方块 学习java基础很好 包含面向对象和设计模式

    《基于Swing实现的俄罗斯方块游戏:Java基础与编程理念的综合实践》 Java Swing是Java提供的一个用于创建桌面应用程序的图形用户界面(GUI)工具包,它基于Java Foundation Classes (JFC)。在本项目中,"swing实现...

    俄罗斯方块游戏java版

    在Java编程中实现俄罗斯方块,主要涉及以下几个关键知识点: 1. **图形用户界面(GUI)**:游戏界面通常使用Java的Swing或JavaFX库构建。开发者需要创建一个窗口,绘制游戏区域,并实现方块的显示和移动。例如,使用`...

    Java Swing实现俄罗斯方块游戏.zip

    游戏的核心逻辑会涉及到以下几个关键知识点: 1. **游戏循环**:游戏的每一帧都需要更新和渲染,这通常通过一个循环来实现。在Java中,可以使用定时器(javax.swing.Timer)或者线程(Thread.sleep())来控制游戏的...

    Java版俄罗斯方块游戏源程序

    Java版的俄罗斯方块游戏源程序是一套基于Java编程语言实现的经典休闲游戏。这个程序不仅提供了可执行的游戏体验,还为学习者提供了深入理解Java编程和游戏开发的宝贵资源。让我们一起探讨其中涉及的关键知识点。 ...

    俄罗斯方块游戏代码 本代码主要是俄罗斯方块的游戏的概要设计

    1. **图形用户界面(GUI)**:俄罗斯方块游戏通常会有一个显示游戏区域的窗口,这需要使用到GUI库,如Java的Swing或JavaFX。开发者可能创建了一个JFrame或Stage来作为游戏主窗口,并在其中添加了画布来绘制方块。 2...

    Java-俄罗斯方块游戏详细设计流程加源代码

    以下是关于这个Java-俄罗斯方块游戏设计和实现的一些关键知识点: 1. **Java编程基础**:Java是一种广泛使用的面向对象的编程语言,具有跨平台的特性。在这个项目中,我们将运用Java的基础语法,类和对象的概念,...

    JAVA俄罗斯方块游戏论文

    在Java中实现“俄罗斯方块”,首先需要设计一个游戏循环,这个循环不断地更新屏幕上的方块位置,处理用户输入,并检查游戏状态。游戏循环通常是一个无限循环,直到玩家选择退出游戏为止。 接着,我们需要创建一个...

    java做的俄罗斯方块游戏

    在Java中,俄罗斯方块的实现主要涉及到以下几个关键知识点: 1. **图形用户界面(GUI)设计**:游戏界面通常通过Java的Swing或JavaFX库构建。在这个项目中,可能使用了Swing来创建游戏窗口、按钮和对话框。例如,`...

    俄罗斯方块游戏12_增加游戏结束

    在Java编程中,实现俄罗斯方块的核心部分包括以下几个关键知识点: 1. **图形用户界面(GUI)**:使用Java的Swing或JavaFX库创建游戏窗口,展示游戏区域、分数显示、控制按钮等元素。你需要熟悉JFrame、JPanel、 ...

    俄罗斯方块 游戏源码

    通过研究这个"俄罗斯方块 游戏源码",开发者可以学到以下关键知识点: 1. **Java GUI编程**:了解如何使用Java的Swing或JavaFX库创建图形用户界面,设置窗口、按钮、面板等组件,并实现它们的交互功能。 2. **事件...

Global site tag (gtag.js) - Google Analytics