使用Java实现小游戏:俄罗斯方块

使用一个二维数组保存游戏的地图:

// 游戏地图格子,每个格子保存一个方块,数组纪录方块的状态

private State map[][] = new State[rows][columns];123

游戏前先将所有地图中的格子初始化为空:

/* 初始化所有的方块为空 */

for (int i = 0; i

for (int j = 0; j

map[i][j] = State.EMPTY;

}

}1234567

玩游戏过程中,我们能够看到界面上的方块,那么就得将地图中所有的方块绘制出来,当然,除了需要绘制方块外,游戏积分和游戏结束的字符串在必要的时候也需要绘制:

/**

* 绘制窗体内容,包括游戏方块,游戏积分或结束字符串

*/

@Override

public void paint(Graphics g) {

super.paint(g);

for (int i = 0; i

for (int j = 0; j

if (map[i][j] == State.ACTIVE) { // 绘制活动块

g.setColor(activeColor);

g.fillRoundRect(j * BLOCK_SIZE, i * BLOCK_SIZE + 25,

BLOCK_SIZE - 1, BLOCK_SIZE - 1, BLOCK_SIZE / 5,

BLOCK_SIZE / 5);

} else if (map[i][j] == State.STOPED) { // 绘制静止块

g.setColor(stopedColor);

g.fillRoundRect(j * BLOCK_SIZE, i * BLOCK_SIZE + 25,

BLOCK_SIZE - 1, BLOCK_SIZE - 1, BLOCK_SIZE / 5,

BLOCK_SIZE / 5);

}

}

}

/* 打印得分 */

g.setColor(scoreColor);

g.setFont(new Font("Times New Roman", Font.BOLD, 30));

g.drawString("SCORE : " + totalScore, 5, 70);

// 游戏结束,打印结束字符串

if (!isGoingOn) {

g.setColor(Color.RED);

g.setFont(new Font("Times New Roman", Font.BOLD, 40));

g.drawString("GAME OVER !", this.getWidth() / 2 - 140,

this.getHeight() / 2);

}

}123456789101112131415161718192021222324252627282930313233343536

通过随机数的方式产生方块所组成的几种图形,一般七种图形:条形、田形、正7形、反7形、T形、Z形和反Z形,如生成条形:

map[0][randPos] = map[0][randPos - 1] = map[0][randPos + 1]

= map[0][randPos + 2] = State.ACTIVE;123

生成图形后,实现下落的操作。如果遇到阻碍,则不能再继续下落:

isFall = true; // 是否能够下落

// 从当前行检查,如果遇到阻碍,则停止下落

for (int i = 0; i

for (int j = 0; j

// 遍历到行中块为活动块,而下一行块为静止块,则遇到阻碍

if (map[rowIndex - i][j] == State.ACTIVE

&& map[rowIndex - i + 1][j] == State.STOPED) {

isFall = false; // 停止下落

break;

}

}

if (!isFall)

break;

}123456789101112131415

如果未遇到阻碍,则下落的时候,方块图形整体向下移动一行:

// 图形下落一行

for (int i = 0; i

for (int j = 0; j

if (map[rowIndex - i][j] == State.ACTIVE) { // 活动块向下移动一行

map[rowIndex - i][j] = State.EMPTY; // 原活动块变成空块

map[rowIndex - i + 1][j] = State.ACTIVE; // 下一行块变成活动块

}

}

}12345678910

向左、向右方向移动时是类似的操作:

/**

* 向左走

*/

private void left() {

// 标记左边是否有阻碍

boolean hasBlock = false;

/* 判断是否左边有阻碍 */

for (int i = 0; i

if (map[rowIndex - i][0] == State.ACTIVE) { // 判断左边是否为墙

hasBlock = true;

break; // 有阻碍,不用再循环判断行

} else {

for (int j = 1; j

if (map[rowIndex - i][j] == State.ACTIVE

&& map[rowIndex - i][j - 1] == State.STOPED) {

hasBlock = true;

break; // 有阻碍,不用再循环判断列

}

}

if (hasBlock)

break; // 有阻碍,不用再循环判断行

}

}

/* 左边没有阻碍,则将图形向左移动一个块的距离 */

if (!hasBlock) {

for (int i = 0; i

for (int j = 1; j

if (map[rowIndex - i][j] == State.ACTIVE) {

map[rowIndex - i][j] = State.EMPTY;

map[rowIndex - i][j - 1] = State.ACTIVE;

}

}

}

// 重绘

repaint();

}

}1234567891011121314151617181920212223242526272829303132333435363738394041

向下加速移动时,就是减小每次正常状态下落的时间间隔:

/**

* 向下直走

*/

private void down() {

// 标记可以加速下落

immediate = true;

}12345678

如何变换图形方向,这里仅使用了非常简单的方法来实现方向变换,当然可以有更优的算法实现方向变换操作,大家可以自己研究:

/**

* 旋转方块图形

*/

private void rotate() {

try {

if (shape == 4) { // 方形,旋转前后是同一个形状

return;

} else if (shape == 0) { // 条状

// 临时数组,放置旋转后图形

State[][] tmp = new State[4][4];

int startColumn = 0;

// 找到图形开始的第一个方块位置

for (int i = 0; i

if (map[rowIndex][i] == State.ACTIVE) {

startColumn = i;

break;

}

}

// 查找旋转之后是否有阻碍,如果有阻碍,则不旋转

for (int i = 0; i

for (int j = 0; j

if (map[rowIndex - 3 + i][j + startColumn] == State.STOPED) {

return;

}

}

}

if (map[rowIndex][startColumn + 1] == State.ACTIVE) { // 横向条形,变换为竖立条形

for (int i = 0; i

tmp[i][0] = State.ACTIVE;

for (int j = 1; j

tmp[i][j] = State.EMPTY;

}

}

blockRows = 4;

} else { // 竖立条形,变换为横向条形

for (int j = 0; j

tmp[3][j] = State.ACTIVE;

for (int i = 0; i

tmp[i][j] = State.EMPTY;

}

}

blockRows = 1;

}

// 将原地图中图形修改为变换后图形

for (int i = 0; i

for (int j = 0; j

map[rowIndex - 3 + i][startColumn + j] = tmp[i][j];

}

}

} else {

// 临时数组,放置旋转后图形

State[][] tmp = new State[3][3];

int startColumn = columns;

// 找到图形开始的第一个方块位置

for (int j = 0; j

for (int i = 0; i

if (map[rowIndex - j][i] == State.ACTIVE) {

startColumn = i

}

}

}

// 判断变换后是否会遇到阻碍

for (int i = 0; i

for (int j = 0; j

if (map[rowIndex - 2 + j][startColumn + 2 - i] == State.STOPED)

return;

}

}

// 变换

for (int i = 0; i

for (int j = 0; j

tmp[2 - j][i] = map[rowIndex - 2 + i][startColumn + j];

}

}

// 将原地图中图形修改为变换后图形

for (int i = 0; i

for (int j = 0; j

map[rowIndex - 2 + i][startColumn + j] = tmp[i][j];

}

}

// 重绘

repaint();

// 重新修改行指针

for (int i = 0; i

for (int j = 0; j

if (map[rowIndex - i][startColumn + j] != null

|| map[rowIndex - i][startColumn + j] != State.EMPTY) {

rowIndex = rowIndex - i;

blockRows = 3;

return;

}

}

}

}

} catch (Exception e) {

// 遇到数组下标越界,说明不能变换图形形状,不作任何处理

}

}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101

当图形下落遇到阻碍时停止,我们就需要判断这时是否有某一行或几行可以消除掉,这时可以先获取每行中方块的个数,然后再进行判断:

int[] blocksCount = new int[rows]; // 记录每行有方块的列数

int eliminateRows = 0; // 消除的行数

/* 计算每行方块数量 */

for (int i = 0; i

blocksCount[i] = 0;

for (int j = 0; j

if (map[i][j] == State.STOPED)

blocksCount[i]++;

}

}1234567891011

如果有满行的方块,则消除掉该行方块:

/* 实现有满行的方块消除操作 */

for (int i = 0; i

if (blocksCount[i] == columns) {

// 清除一行

for (int m = i; m >= 0; m--) {

for (int n = 0; n

map[m][n] = (m == 0) ? State.EMPTY : map[m - 1][n];

}

}

eliminateRows++; // 记录消除行数

}

}12345678910111213

最后我们再重绘显示积分就可以了。

重复以上的生成图形、图形下落、左右下移动、判断消除行的操作,一个简单的俄罗斯方块就完成了。

俄罗斯方块是java_俄罗斯方块java相关推荐

  1. ai俄罗斯方块java_俄罗斯方块进阶--AI俄罗斯方块

    原标题:俄罗斯方块进阶--AI俄罗斯方块 人工智能大火的今天,如果还是自己玩俄罗斯方块未免显得太LOW,为什么不对游戏升级,让机器自己去玩俄罗斯方块呢?有了这个想法之后利用周六周日两天的时间去搜集了大 ...

  2. 学生专用计算机玩俄罗斯方块,c++编程俄罗斯方块计算机实习报告模板.doc

    c编程俄罗斯方块计算机实习报告模板 c++编程俄罗斯方块计算机实习报告模板c++编程俄罗斯方块计算机实习报告模板 姓名: 班级: 学号: 小班序号: 指导老师: 题目:用c++编程俄罗斯方块 邮箱: ...

  3. 俄罗斯方块java_编程练习——俄罗斯方块简单版(Java实现)

    1.目标需求分解 俄罗斯方块游戏基础版,我们可以分为四个小部分:1.随机方块.2.游戏背景(矩形方格).3.游戏规则控制系统.4.以及游戏界面. 1.1 随机方块 随机方块一共五种基本图形(基础图形如 ...

  4. 240320俄罗斯方块java_俄罗斯方块 Java源代码 Eclipse能运行的。要求如下图,谢谢...

    展开全部 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Els extends JFra ...

  5. java俄罗斯方块程序_使用JAVA编写的俄罗斯方块程序, 具有非常全面的功能.

    Lastsong-Tetris 使用JAVA编写的俄罗斯方块程序, 具有非常全面的功能. 游戏基本规则: 1.打开游戏窗口后, 点击开始按钮进行游戏; 2.每消一行就会增加10分和1消行数,当分数累计 ...

  6. java版的俄罗斯方块_Java版俄罗斯方块

    Java版俄罗斯方块 08年写的一个Java版俄罗斯方块程序 界面做的中规中矩,每种形状颜色都不相同 程序控制还可以,没什么大的Bug 消磨时间的时候可以Down下来玩玩 下载链接:http://do ...

  7. java俄罗斯方块设计报告,俄罗斯方块课程设计报告

    <俄罗斯方块课程设计报告>由会员分享,可在线阅读,更多相关<俄罗斯方块课程设计报告(26页珍藏版)>请在人人文库网上搜索. 1.一.系统概述1.1现状分析在个人电脑日益普及的今 ...

  8. 2048版俄罗斯方块java_俄罗斯方块版2048

    F)~15$NGC{)`PUWJ(RTH6.png (9.15 KB, 下载次数: 8) 2016-9-19 12:42 上传 ◆ 游 戏 简 介___________________________ ...

  9. java俄罗斯方块答辩_俄罗斯方块项目答辩.ppt

    俄罗斯方块项目答辩.ppt ,俄罗斯方块,小组杨洪松.杨明虹.严虹雨 组长杨洪松 组员杨明虹.严虹雨项目编写背景 项目开发进程 项目功能及项目效果 所运用的技术.开发工具 项目组各成员完成的内容 完成 ...

  10. 2048版俄罗斯方块java_俄罗斯方块2048

    俄罗斯方块和2048都是小伙伴们都玩过的游戏,那如果将两者相融合会产生什么样的效果呢>在<俄罗斯方块2048>中,玩家就将体验到结合了2048的俄罗斯方块,这款游戏不仅难度上更上一层 ...

最新文章

  1. java正则学习笔记三
  2. SUSE下双网卡IP同网段的烦恼
  3. w10计算机无法打印,老司机解答win10系统电脑无法打印的详细技巧
  4. php xampp bug,PHP网站访问慢的处理方法
  5. 无监督学习 | DBSCAN 原理及Sklearn实现
  6. C# ToString()和Convert.ToString()的区别【转】
  7. 你以为海淘产品能逃过海关法眼?大数据技术一网打尽
  8. Python学习笔记 之 变量进阶
  9. sew制动器操作手册_SEW减速机中文操作手册
  10. 在百度上搜不到的资源是在哪找的?就在这些强大的资源搜索网站呀
  11. Navicat 安装过程问题总结
  12. 【汇编程序】实现1-100求和(使用LOOP循环)
  13. 用电机进行简单的PID参数整定
  14. VScode 光标乱跳
  15. DELL存储SCv3020组件概念
  16. 新版mysql的下载教程_Mysql最新版8.0.21下载安装配置教程详解
  17. 代码审计--17--修复方案汇总(上)
  18. 巴拉特比印度大分水岭
  19. SAP SCC4 客户端设置的用法
  20. 2020.9.28(Hive视图、索引、权限管理)

热门文章

  1. NOSQL数据库习题
  2. JavaScript学习指南
  3. 磁力链转bt种子 python_Python实现BT种子转化为磁力链接
  4. Java项目:医院药品管理系统设计和实现(java+Springboot+ssm+mysql+jsp+maven)
  5. Newifi3(新路由3)刷潘多拉(Pandora)固件
  6. CSDN上传资料获得积分?
  7. 几种常见的图像模糊处理
  8. 兆易创新GD32系列单片机不同容量和启动文件之间的选择(GD32F10X_MD/GD32F10X_HD/GD32F10X_XD/GD32F10X_CL)
  9. 拉普拉斯(逆)变换的计算
  10. 多商户酒店预订小程序PMS管理系统成品源码