俄罗斯方块(Java)

前言

学完JavaSE内容的朋友们,不妨在自己空闲的时间写一个小游戏来巩固一下自己,学完还能在自己的好朋友面前装逼哈哈。废话不多说,咱们撸起袖子直接开干!

提示:以下是本篇文章正文内容,下面案例可供参考

一、游戏介绍和准备工作

游戏介绍:今天我们要写的是俄罗斯方块小游戏,这是一个界面性的小游戏,并不是在终端实现的。我个人觉得这个小游戏十分适合刚学完JavaSE内容的朋友,可以拿这个小游戏练练手。大家也不用担心哈,我会带着大家把我的游戏设计思路捋清楚,最后我也会把源码分享给大家。
准备工作:我用的是IntelliJ IDEA 2021.2.1 jdk17版本的

二、游戏设计逻辑

1.主框架和设计逻辑

主框架
我的游戏界面是在GameJFrame这个类这中实现的,由于这个类的作用是实现游戏界面的,所以我单独把这个放在了一个包下,日后大家想要实现登录和注册功能也可以放在这一个包下,domain这个包主要是存放游戏主要俄罗斯方块,util是一个工具包,并且俄罗斯方块行为和界面的行为我都封装成一个个函数以便于管理。
在这里插入图片描述设计逻辑在GameJFrame这个类中的空参构造实现以下
A.初始化游戏窗口
B.初始化游戏界面
C.初始化定时器(实现俄罗斯方块不断下落)
D.设置游戏界面和窗口可见
在这里插入图片描述
一.准备一个IDEA
二.准备好所需要的图片
三.创建游戏窗口(JFrame)
四.创建游戏界面(JPanel)

1.编写小方块类(构成俄罗斯方块的Cell)
2.编写俄罗斯方块父类(Tertis)
3.创建7个不同形状(I,J,L,O,S,T,Z)
4.在俄罗斯方块父类中创建一个随机生成7个子类的一种
5.加载游戏背景
6.绘制正在下落的俄罗斯方块
7.绘制下一个下落的俄罗斯方块
8.绘制游戏得分
9.绘制游戏状态
五.游戏运行主逻辑(Timer)
1.判断游戏状态
2.判断俄罗斯方块能不能下落 a.俄罗斯方块下落
3.将俄罗斯方块嵌入界面中
4.判断是否能消除行数
5.消除行数
6.判断游戏是否结束
六.添加键盘监听
A:俄罗斯方块逆时针旋转
D:俄罗斯方块顺时针旋转
R:游戏重新开始
P:游戏暂停
C:游戏继续
←:俄罗斯方块左移
→:俄罗斯方块右移
↓:俄罗斯方块下移
空格:俄罗斯方块瞬间下落

以上是我个人对这个游戏的设计思路

2.每一个部分实现

**

A.初始化游戏窗口

**

这部分比较简单,所以大家自行看以下图片。
在这里插入图片描述
**

B.初始化游戏界面

**
-------------------------------------------这一部分我会分两部分来叙述------------------------------------------------------------
第一部分:界面的组成
在这里我是实现JPanel这个类,并且我是以匿名内部类的这个方法,JPanel这个类可以理解成一个画板,在后面我们会经常用到里面的画笔Graphics来实现各种功能。
在这里我的游戏界面里面有两个俄罗斯方块,一个是正在下落的俄罗斯方块,另一个是下一个俄罗斯方块。其次是游戏的得分,并且消除每一行所具有的分数,以及游戏状态,所以接下来我们就要准备这些内容。
**a.**对于俄罗斯方块我们在游戏中的一共有7种形状,每一种形状就是一个类,所以就需要准备7个类,对应以下图片每一个类名分别是T,L,J,Z,S,O,I,其次是每一个类共有的内容提取到成一个父类Tetris,方便后面调用。对于每一个形状都是由一个小方格组成的,所以还需要一个类,这个类的作用就是来组成每一个俄罗斯方块,每一个俄罗斯方块由4个小方块组成,我将这个类Cell单独放在了一个工具包中。

–》7种形状:在这里插入图片描述

–》游戏的初始界面
在这里插入图片描述
**b.**说完了俄罗斯方块,我们继续说说剩下的三个,对于游戏的分和消除行数无非就是定义整形两个变量来记录,但有一个注意的地方就是,分数是不能乱加的,我们需要让分数和消除的行数一一对应,于是就有了一个得分池由数组组成,数组有索引,只要拿对应的行数作为索引去找得分就好了。然后是游戏状态有四个,一个是正在进行中,一个是暂停,一个是游戏结束,一个是游戏胜利,而这些游戏状态也是有规律的,如过游戏正在进行中,界面就会显示暂停提示,如果是胜利和结束就会显示R[restart],如果是游戏暂停,就会显示C【continue】,我们也是把这些游戏状态放在数组里管理,后面也是用索引找到他们。

–》游戏胜利和结束和暂停
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第二部分:设计逻辑
在这里插入图片描述
这里我已经将要执行的顺序给排序好了。这里的顺序不一定要这样排,我的只是供大家参考。我在这里会把要注意的地方和大家说一下,一些粗枝细沫大家参考我的源码理解,我在这里不在做过多的赘述,希望大家理解哈,文字很难将每个细节叙说到位😅。

a.第一个要注意的地方就是在设计主区域的时候我们要移动JFrame界面默认的坐标轴,这是因为我们的主区域并不是从坐标原点开始的
b.清空游戏界面是因为其实我们每一次绘画界面都只能画一次,为了让俄罗斯方块有移动的效果我们后面会用一个类似线程的Timer类,在这个类中我们调用repaint方法就能反复执行paint方法了,就有移动的效果了,所以在每一次画之前,我们都要先清空以前的啦。
在这C里插入图片描述

C.初始化定时器

---------------------------------------------这一部分我也会分两部分来叙述----------------------------------------------------------

第一部分:定时器组成
我是先实现了Timer这个类,然后也是以匿名内部类的方法来继承Timer这个类TimerTask里,这个类中我们要将游戏执行的逻辑放在执行任务里,最后就是用Timer.scheduleAtFixedRate反复执行我们的任务就好了
第二部分:俄罗斯方块移动的核心逻辑(即反复执行的任务)
首先是判断游戏的状态,如果是正在玩就再判断当前的俄罗斯方块能否下降,
如果能就将俄罗斯方块不断地下落,
如果不能就将当前俄罗斯方块嵌入到当前游戏界面,
然后继续判断嵌入的俄罗斯方块能不能达到消除行数的要求,
如果能就消除,
如果不能就不消除,
最后再一次判断目前的游戏状态,
如果游戏状态不是结束,就将当前的俄罗斯方块切换到下一个,重新生成下一个俄罗斯方块,再一次执行这个任务从头开始,
如果游戏状态是结束,游戏状态设置为结束,等待用户按键指示重新开始游戏。
在这里插入图片描述
在这里插入图片描述

D.添加键盘监听

你坚持到这里了吗,我亲爱的朋友?咱们马上就要通过了哦!
在这里我们就是要把咱们的键盘用上了呀,就是要用户按某一个键,俄罗斯方块就这么移动,或者说让游戏界面这么样。这里我们首先是要让我们的GameJframe这个游戏界面实现KeyListener这个接口,去重写里面的按键方法,最后大家一定要记得将咱们的窗口绑定键盘监听哈,千万记得!!!
我的按键设计是
←是俄罗斯方块整体向左移动一格
→是俄罗斯方块整体向右移动一格
↓是俄罗斯方块整体向下移动一格
A是俄罗斯方块逆时针旋转
D是俄罗斯方块顺时针旋转
R是游戏重新开始
C是游戏回复运行状态
P是游戏暂停
空格是俄罗斯方块瞬间下落到最下面
在这里插入图片描述
在这里插入图片描述

三、游戏效果演示

2024-03-20 23-07-10

四、游戏心得

大家在写这个游戏千万不要想到哪就写到哪,也不要着急,先把游戏怎么设计的搞清楚,然后对着设计思路来写。我在写这个游戏的时候,第一遍我是跟着老师的源码从头开始写,第二遍我是只对这老师的设计逻辑重新写了一遍,第三次我就按开始自己的理解写了,并且在老师原有的基础上增加了一些功能和完善逻辑,最后一次没有重新写,就是把自己的游戏思路分享给大家啦。我也是刚刚自学完JavaSE,写完到理解到分享也是用了将近一周的时间。最后我会将老师的资源分享给大家,并且如果有需要我源码的朋友可以加我vx,有什么不理解的也可以在vx上问我,我很乐意与大家一起进步。最最最…后后后,制作十分的不易,如果对你有帮助,可以点赞支持我哈。

五、游戏源码以及游戏出处

有需要我的源码可以上Gitcode上搜索Tetris Game或者有相关的问题可以加我的vx:hsq1878427982,非常乐意帮助大家!

游戏思路来源:哔哩哔哩动画 bilibili.com 博主:动力节点
游戏资源:关键词【JavaSE】超友情分享给你!
链接:https://pan.baidu.com/s/1Z21Te_0AIbe3QM1OkAxZQw
提取码:dljd
B站学习课程链接:https://www.bilibili.com/video/BV1Mb4y1Z74W/?spm_id_from=333.999.0.0
链接失效添加老师微信:javazx01,即可领取完整视频和学习资料哈

如果想转发和使用请加上作者和网址,谢谢!
如果发现文章有问题请指出,谢谢!
后续会继续与大家分享Java学习路上的一些相关内容,如果感兴趣可以关注我哈!
————————————————

俄罗斯方块是一款经典的游戏,Java也是一门适合游戏开发语言。下面是一个简单的俄罗斯方块游戏的Java代码示例: ```java import java.awt.Color; import java.awt.Graphics; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; public class Tetris extends JPanel implements KeyListener { private static final long serialVersionUID = 1L; private final int WIDTH = 10; private final int HEIGHT = 22; private final int BLOCK_SIZE = 30; private int[][] board = new int[HEIGHT][WIDTH]; private Tetromino currentPiece; private Tetromino[] pieces = { new Tetromino(new int[][]{{1, 1, 1, 1}}, this, Color.cyan), new Tetromino(new int[][]{{1, 1, 0}, {0, 1, 1}}, this, Color.orange), new Tetromino(new int[][]{{0, 1, 1}, {1, 1, 0}}, this, Color.blue), new Tetromino(new int[][]{{1, 1, 0}, {1, 1, 0}}, this, Color.yellow), new Tetromino(new int[][]{{1, 0, 0}, {1, 1, 1}}, this, Color.green), new Tetromino(new int[][]{{0, 0, 1}, {1, 1, 1}}, this, Color.pink), new Tetromino(new int[][]{{1, 1}, {1, 1}}, this, Color.red) }; public Tetris() { setPreferredSize(new Dimension(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE)); setBackground(Color.black); addKeyListener(this); newPiece(); } public void paintComponent(Graphics g) { super.paintComponent(g); for (int i = 0; i < HEIGHT; i++) { for (int j = 0; j < WIDTH; j++) { if (board[i][j] != 0) { g.setColor(Color.gray); g.fillRect(j * BLOCK_SIZE, i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); g.setColor(Color.white); g.drawRect(j * BLOCK_SIZE, i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE); } } } currentPiece.draw(g); } public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: currentPiece.move(-1, 0); break; case KeyEvent.VK_RIGHT: currentPiece.move(1, 0); break; case KeyEvent.VK_DOWN: currentPiece.move(0, 1); break; case KeyEvent.VK_UP: currentPiece.rotate(); break; case KeyEvent.VK_SPACE: currentPiece.drop(); break; } repaint(); } public void keyReleased(KeyEvent e) {} public void keyTyped(KeyEvent e) {} public int getBlockSize() { return BLOCK_SIZE; } public int[][] getBoard() { return board; } public Tetromino[] getPieces() { return pieces; } public void newPiece() { Random r = new Random(); currentPiece = pieces[r.nextInt(pieces.length)]; currentPiece.setX(WIDTH / 2 - currentPiece.getPiece()[0].length / 2); currentPiece.setY(0); } public static void main(String[] args) { JFrame frame = new JFrame("Tetris"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); frame.add(new Tetris(), BorderLayout.CENTER); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } } ``` 这个代码示例中,我们使用了Java Swing库进行界面的开发,并且使用了一个Tetromino类来表示俄罗斯方块中的方块。在程序中,我们使用了一个二维数组来表示游戏区域中的方块,并且通过键盘事件来控制方块的移动和旋转。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值