Java俄罗斯方块 ---(一)游戏场景篇

article/2025/11/1 18:19:43

相信俄罗斯方块大家都玩过,在这里就不多介绍规则了,用到的主要框架是Swing。

 

Java俄罗斯方块目录:

  1. Java俄罗斯方块 ---(一)游戏场景篇
  2. Java俄罗斯方块 ---(二)游戏操作与逻辑篇
  3. Java写俄罗斯方块(完整版)

 

以下是要用到的素材:

    1.小方块

                                

    2.游戏背景图

        

    3.GameOver

        

——————————————————————我是分割线—————————————————————

好了,话不多说,我们直接进入正题:

直接上图:

上图展示的是俄罗斯方块里的七种经典方块,每个方块都是由4个小方块组成,序号是为了方块能够变形而特意做的标记。

抽象出对应的数据类型

首先,先创建一个Cell类,用来表示一个小方块,Cell类的主要成员就是这些。

 

  1. row,表示小方块的行号。
  2. col,表示小方块的列号。
  3. image,表示小方块的图片,就是之前素材里的。
  4. left(),right(),drop(),分别表示一个小方块的左移一格,右移一格,下降一格。
public class Cell {private int row;private int col;private BufferedImage image;public Cell() {}public Cell(int row, int col, BufferedImage image) {this.row = row;this.col = col;this.image = image;}/*向左移动*/public void left() {col--;}/*向右移动*/public void right() {col++;}/*向下移动*/public void drop() {row++;}
}

接下来,按照国际惯例(JavaBean规范),我们把这个类补全了,创建全参合无参构造器,属性的get/set方法并重写toString方法。

public class Cell {private int row;private int col;private BufferedImage image;@Overridepublic String toString() {return "(" + row + ", " + col + ")";}public int getRow() {return row;}public void setRow(int row) {this.row = row;}public int getCol() {return col;}public void setCol(int col) {this.col = col;}public BufferedImage getImage() {return image;}public void setImage(BufferedImage image) {this.image = image;}public Cell() {}public Cell(int row, int col, BufferedImage image) {this.row = row;this.col = col;this.image = image;}/*向左移动*/public void left() {col--;}/*向右移动*/public void right() {col++;}/*向下移动*/public void drop() {row++;}
}

之前说过,俄罗斯方块里面有七个经典形状,他们有一些共同特征:

 

  1. 都是由4个小方块组成。
  2. 都能左移,右移,下落。
  3. 变形,因为变形比较麻烦,就不写在父类里了,后面再介绍变形的方法。

那么现在我们就创建一个Tetromino类来作为7个经典形状的父类,并提供相应的成员。

 

  1. Cell数组,用于创建4个小方块。
  2. moveLeft(),moveRight(),softDrop(),分别用于四格方块的左移,右移和软下落,软下落也就是四格方块下落一个,以后会写一个硬下落,让四格方块瞬间落下。
public class Tetromino {protected Cell[] cells=new Cell[4];/*四格方块向左移动*/public void moveLeft() {for(Cell c:cells)c.left();}/*四格方块向右移动*/public void moveRight() {for(Cell c:cells)c.right();}/*四格方块向下移动*/public void softDrop() {for(Cell c:cells)c.drop();}@Overridepublic String toString() {return "[" + Arrays.toString(cells) + "]";}
}

接着,在创建7个不同的形状,根据形状的大致模样,为了方便,这里就用I,J,L,O,S,T,Z来表示了。

形状都要继承Tetromino类,这7个形状类的作用就是为了初始化形状的位置,在初始化位置之前,提一下,游戏的资源,也就是背景,图片等为了加载的效率,一般都创建为静态成员,所以这里用将图片创建为静态的并用静态代码块来调用ImageIO流来读取图片,在主类当中先创建好,方便以后的调用,所以,在初始化形状之前,先创建一个主类,Tetris类,因为这次主要是用JPanel这个框架来完成制作,所以Tetris需要继承JPanel,并通过重写JPanel的方法来完成游戏的制作。

Tetris类,先初始化游戏资源,主要是用BufferedImage和ImageIO流来完成,因为IO流有一个检查型的异常,所以这里需要用try把IO流给圈起来,并用catch来捕获异常。

public class Tetris extends JPanel{
//载入方块图片public static  BufferedImage T;public static  BufferedImage I;public static  BufferedImage O;public static  BufferedImage J;public static  BufferedImage L;public static  BufferedImage S;public static  BufferedImage Z;public static  BufferedImage background;public static  BufferedImage gameover;static {try {/** getResource(String url)* url:加载图片的路径* 相对位置是同包下*/T = ImageIO.read(Tetris.class.getResource("T.png"));I = ImageIO.read(Tetris.class.getResource("I.png"));O = ImageIO.read(Tetris.class.getResource("O.png"));J = ImageIO.read(Tetris.class.getResource("J.png"));L = ImageIO.read(Tetris.class.getResource("L.png"));S = ImageIO.read(Tetris.class.getResource("S.png"));Z = ImageIO.read(Tetris.class.getResource("Z.png"));background = ImageIO.read(Tetris.class.getResource("tetris.png"));gameover = ImageIO.read(Tetris.class.getResource("game-over.png"));} catch (Exception e) {e.printStackTrace();}}
}

接下来,在用对应的形状类来初始化形状。

public class I extends Tetromino{/** 提供构造器进行初始化* I型的四格方块的位置*/public I() {cells[0]=new Cell(0,4,Tetris.I);cells[1]=new Cell(0,3,Tetris.I);cells[2]=new Cell(0,5,Tetris.I);cells[3]=new Cell(0,6,Tetris.I);}
}

剩下的几个形状也类似,只需要根据前面的形状坐标来修改即可,图片随意,创建好形状之后,需要生成一个四格方块,所以回到Tetromino类,为了方便以后调用,写一个随机生成方块的静态方法。

一共有7个形状,这里用(int)Math.random()*7来表示7个不同的形状,因为形状都是继承与父类,在这里直接向上转型就可以了。

         /*随机生成一个四格方块*/public static Tetromino randomOne() {Tetromino t = null;int num=(int)(Math.random()*7);switch (num) {case 0:t=new T();break;case 1:t=new O();break;case 2:t=new I();break;case 3:t=new J();break;case 4:t=new L();break;case 5:t=new S();break;case 6:t=new Z();break;}return t;}

都创建好了以后,回到主类Tetris类当中,在游戏当中,有以下这些对象,我们把他们抽象成相应的成员:

 

  1. currentOne,描述正在下落的方块。
  2. nextOne,描述将要下落的方块。
  3. wall,游戏的主区域。
  4. 这里需要提一下,生成方块的方法,我们放到父类Tetromino当中,为了方便调用,我们把生成方块的方法创建为静态方法。
        /*属性:正在下落的四格方块*/private Tetromino currentOne = Tetromino.randomOne();/*属性:将要下落的四格方块*/private Tetromino nextOne = Tetromino.randomOne();/*属性:墙,20行 10列的 表格  宽度为26*/private Cell[][] wall=new Cell[20][10];

接下来,在Tetris中创建一个main方法,在main方法中创建游戏场景,窗口的尺寸为了和游戏场景相符,用535*595的大小。

public static void main(String[] args) {//1:创建一个窗口对象JFrame frame=new JFrame("玩玩俄罗斯方块");//2:设置为可见frame.setVisible(true);//3:设置窗口的尺寸frame.setSize(535, 595);//4:设置窗口居中frame.setLocationRelativeTo(null);//5:设置窗口关闭,即程序中止frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}

运行效果图

 

一. 绘制游戏背景

现在,我们有了游戏的窗口,接下来要做的就是绘制游戏场景,向main方法中添加以下两行代码,为了避免一些不必要的麻烦,建议把这两行代码加到 JFrame frame=new JFrame("玩玩俄罗斯方块"); 这行代码下面。

//创建游戏界面,即画板(面板)
Tetris panel = new Tetris();
//将面板嵌入窗口
frame.add(panel);

接下来,让我们来绘制游戏吧,重写JPanel当中的paint方法(paint方法用来描述游戏的所有场景和元素),绘制游戏背景,在这里用JPanel框架绘制主要用到以下方法。

 

  1. drawImage(image,x,y,null),用于绘制图片。
  2. drawRect(x,y,width,height),用于绘制图形。
  3. drawString(str,x,y),用于绘制字符串。
  4. 以上三个方法都需要通过画笔Graphics来调用,参数的含义就不多说了。
public void paint(Graphics g) {//绘制背景/** g:画笔* g.drawImage(image,x,y,null)* image:绘制的图片* x:开始绘制的横坐标* y:开始绘制的纵坐标*/g.drawImage(background, 0,0, null);}
运行效果

游戏背景我们绘制出来了,接下来继续绘制其他游戏元素。

1.paintWall,绘制游戏主区域,编写以下方法,在paint方法中调用,绘制之前,讲一下JPanel的绘制,在绘制图形时,是从上往下,从左到右绘制的:

 

  1. CELL_SIZE,是一个常量,用来描述一个单元格的宽度,这个在游戏当中是26,不用纠结这个数字,只是为了和游戏区域相符(为了好看),直接在Tetris类当中创建这个常量即可。
  2. 之前说过,游戏主区域是一个20行10列的二维数组,所以这里用双层for循环来绘制每个小方块,从而形成游戏主区域。
  3. 在绘制时需要判断小方格也就是wall[i][j]是否有小方块,这是因为当方块不能再下落时,需要嵌入到墙中,也就是绘制一张小方块的图片,并把四格方块的坐标赋给wall。
/*小方格宽度*/
private static final int CELL_SIZE=26;
public void paintWall(Graphics a) {//外层循环控制行数for(int i=0;i<20;i++){//内层循环控制列数for(int j=0;j<10;j++){int x = j*CELL_SIZE;int y = i*CELL_SIZE;Cell cell=wall[i][j];/** 判断所在单元格是否有方块,*     有方块的话,获取方块的图片,绘制成图片嵌入墙中。*     没有方块的话,绘制一个矩形作为墙的一部分。*/if(cell==null)//判断所在单元格是否无方块{a.drawRect(x, y, CELL_SIZE, CELL_SIZE);}else{a.drawImage(cell.getImage(),x,y,null);}}}}

写好了以后,运行看看效果。

会发现墙的位置和预期想的位置不一样,这就是之前有提过,从上至下,从左至右的绘制规则,并且,游戏的主区域在游戏背景当中并不是从左上角开始的,稍微有点偏移,现在,就把这一点点偏移量加到paint方法当中去。

在paint中添加以下代码,以下代码的作用就是平移坐标轴,横坐标和纵坐标的偏移量大概是15:

                //平移坐标轴g.translate(15, 15);

然后,我们在绘制其他游戏元素,想要绘制什么东西,就封装好一个绘制的方法,然后在paint方法中调用即可。

二. 绘制正在下落的方块

首先,取得随机生成的四格方块,赋给Cell数组,遍历Cell数组,取得每个小方格的行号、列号乘以宽度,将每个小方格作为图片画到游戏主区域当中。

    1.说一下为什么要乘以宽度,之前说过JPanel的绘制规则,并且创建的游戏主区域,也就是墙Wall是一个由26*26的正方形组成的20*10*正方形的大矩形,绘制下落的四格方块,就是绘制4个小方格到主区域当中,并且小方格的宽度就是正方形的宽度,所以,需要根据小方格的坐标来乘以宽度最后绘制出四格方块的形状。

        /*绘制正在下落的四格方块* 取出数组的元素* 绘制元素的图片* 横坐标x* 纵坐标y */public void paintCurrentOne(Graphics g){Cell[] cells = currentOne.cells;for(Cell c:cells){int x = c.getCol()*CELL_SIZE;int y = c.getRow()*CELL_SIZE;g.drawImage(c.getImage(),x,y,null);}}

三. 绘制下一个将要下落的四格方块

原理和绘制正在下落的方块一样,主要是所在游戏场景位置不同,需要加上偏移量。

public void paintNextOne(Graphics g) {//获取nextOne对象的四个元素Cell[] cells = nextOne.cells;for(Cell c:cells) {//获取每一个元素的行号和列号int row = c.getRow();int col = c.getCol();//横坐标int x = col*CELL_SIZE+260;//纵坐标int y = row*CELL_SIZE+26;g.drawImage(c.getImage(),x,y,null);}}

四. 绘制游戏得分

首先,需要创建以下常量用于存储游戏分数。

 

  1. scores_pool,游戏分数池,根据一次消除的行数数量不同,得分也不同,消一行得1分,消两行得2分,消三行得5分,最多消四行,得10分。
  2. totalScore,当前获得的游戏分数。
  3. totalLine,当前已消除的行数。
        /*统计分数*/int[] scores_pool = {0,1,2,5,10};private int totalScore = 0;private int totalLine = 0;

用paintScore方法来绘制游戏得分:

 

  1. g.setFont是设置字符串的格式,字体、大小等。
  2. g.drawString之前说过是用来绘制字符串的。
public void paintScore(Graphics g) {g.setFont(new Font(Font.SANS_SERIF, Font.ITALIC, 30));g.drawString("SCORES:"+totalScore, 285, 160);g.drawString("LINES:"+totalLine, 285, 215);}

运行效果

 

五. 绘制游戏状态

接下来,来绘制游戏状态,游戏分为三个状态,游戏中,暂停,游戏结束,用常量来充当游戏状态,并定义一个变量来存储当前游戏状态。

        /*定义三个常量:充当游戏的状态*/public static final int PLAYING = 0;public static final int PAUSE = 1;public static final int GAMEOVER = 2;/*定义一个属性,存储游戏的当前状态*/private int game_state;

    1. paintState,用来绘制游戏的当前状态,在绘制之前,创建一个字符串数组,用来显示游戏状态。即当游戏运行时,显示按P暂停,游戏暂停时,显示按C继续,游戏结束时,显示按S重新开始。

        String[] show_state = {"P[pause]","C[continue]","S[replay]"};
public void paintState(Graphics g) {if(game_state == GAMEOVER) {g.drawImage(gameover, 0, 0, null);g.drawString(show_state[GAMEOVER], 285, 265);}else if (game_state == PLAYING) {g.drawString(show_state[PLAYING], 285, 265);}else if (game_state == PAUSE) {g.drawString(show_state[PAUSE], 285, 265);}		}
运行效果

查看后续教程,Java俄罗斯方块 ---(二)游戏操作与逻辑篇

 


http://chatgpt.dhexx.cn/article/j0V8H9kJ.shtml

相关文章

java实现俄罗斯方块项目

导读:俄罗斯方块项目,基本功能包括:游戏主界面显示模块、方块及数据显示模块、方块移动控制模块、游戏界面颜色控制模块、游戏进度、等级控制模块等。本项目结构如下: (1)游戏主界面显示模块: 显示游戏和帮助两个菜单; 游戏使用功能键盘,得分 等级; (2)画布…

用JAVA写一个俄罗斯方块游戏tetrisGame

开拔 文章目录 开发环境前言一、先看一下游戏运行时的画面二、代码部分1.项目结构以及主程序入口以及下载路径下载路径代码1. Cell.java2. I.java3. J.java4. L.java5. O.java6. S.java7. T.java8. Tetris.java9. Tetromino.java10. Z.java 总结 开发环境 开发工具&#xff1a…

Java ——简易俄罗斯方块

一、将对象抽象为类 首先考虑俄罗斯方块游戏中含有哪些具体的对象&#xff0c;对象中含有哪些具体属性和方法&#xff0c;然后用代码来实现。 建立如下类&#xff1a; Cell类&#xff1a;代表最小的方格单位&#xff0c;构成7种图形的最基本图形。 含有row&#xff08;行号&…

【Java】俄罗斯方块小游戏(附源码)

俄罗斯方块小游戏 一、最终效果二、功能需求二、程序实现 一、最终效果 二、功能需求 1、 在二维平面里面用各种随机产生的方块堆积木&#xff0c;每满一行消去一行&#xff0c;当达到顶部时&#xff0c;游戏结束。 2、 通过方向键来控制方块转动&#xff0c;左移&#xff0c;…

Java实现俄罗斯方块附源码

Java实现俄罗斯方块 软件的开发过程&#xff1a; 1&#xff09; 搞清需求&#xff0c;就是软件的功能描述 俄罗斯方块的基本规则&#xff1a; 1、一个用于摆放小型正方形的平面虚拟场地&#xff0c;其标准大小&#xff1a; 行宽为10&#xff0c;列高为20&#xff0c;以每个小…

JAVA 实现《俄罗斯方块》游戏|CSDN创作打卡

前言 俄罗斯方块是一个最初由阿列克谢帕吉特诺夫在苏联设计和编程的益智类视频游戏。 《俄罗斯方块》的基本规则是移动、旋转和摆放游戏自动输出的各种方块&#xff0c;使之排列成完整的一行或多行并且消除得分。 用java语言实现&#xff0c;采用了swing技术进行了界面化处理…

Java游戏开发——俄罗斯方块

游戏介绍 俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机的游戏&#xff0c;它曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事。这款游戏最初是由苏联的游戏制作人Alex Pajitnov制作的&#xff0c;它看似简单但却变化无穷&#xff0c;游戏过程中仅需要玩家将不…

Java写俄罗斯方块,了解一下

Java俄罗斯方块目录&#xff1a; Java俄罗斯方块 ---&#xff08;一&#xff09;游戏场景篇Java俄罗斯方块 ---&#xff08;二&#xff09;游戏操作与逻辑篇Java写俄罗斯方块&#xff08;完整版&#xff09; 简要分析&#xff1a; 俄罗斯方块的规则在这里就不细说了&#xf…

Java游戏开发 —— 俄罗斯方块

引言&#xff1a; 俄罗斯方块的代码实现很简单&#xff0c;很有意思&#xff01; 思路&#xff1a; 1、创建主窗口&#xff0c;加载菜单及游戏面板。 2、在游戏面板中初始化各种参数&#xff0c;并建立各种功能组件。 3、利用paint()函数开始画方块。 4、游戏结束&#xff0c;…

Java俄罗斯方块,老程序员花了一个周末,连接中学年代!

Java俄罗斯方块&#xff0c;老程序员花了一个周末&#xff0c;连接中学年代&#xff01; 热门专栏推荐 【1】Java小游戏&#xff08;俄罗斯方块、飞机大战、植物大战僵尸等&#xff09; 【2】JavaWeb项目实战&#xff08;图书管理、在线考试、宿舍管理等&#xff09; 【3】Jav…

软件设计实战:基于Java的俄罗斯方块游戏【完整版】

个人简介 &#x1f468;&#x1f3fb;‍&#x1f4bb;个人主页&#xff1a;陈橘又青 &#x1f3c3;&#x1f3fb;‍♂️博客记录心情&#xff0c;代码编写人生。 &#x1f31f;如果文章对你有用&#xff0c;麻烦关注点赞收藏走一波&#xff0c;感谢支持&#xff01; &#x1f3…

Java实现游戏开发《俄罗斯方块》

一、用Java实现俄罗斯方块游戏&#xff1a; 1、效果图&#xff0c;如下图所示&#xff1a; 7种形态的第一种形态, 如下所示&#xff1a;分布是 &#xff1a;|、S、Z、J、O、L、T; 0 1 0 0 0 1 1 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 1 0 0 1 0 0 1 1 0 0 0 1 1 0 0 1 0 0 1…

俄罗斯方块游戏的设计与实现(Java+Swing+Eclipse)

目录 基于Java的俄罗斯方块游戏的设计与实现 I 摘 要 I Based on the design and implementation of Java game Tetris II Abstract II 1 绪论 1 1.1程序开发背景及意义 1 1.2开发技术概述 2 1.3俄罗斯方块游戏的研究现状 2 1.3.1 国内外研究现状 2 1.3.2 文献综述 3 2相关技术…

【Java小游戏】俄罗斯方块

文章目录 规则准备工作编写小方块类编写四方格父类创建7种不同的形状编写俄罗斯方块主类初始化7种形状 随机生成四方格创建游戏场景绘制游戏绘制游戏背景绘制游戏主区域绘制正在下落的四方格绘制下一个下落的四方格绘制游戏得分绘制游戏状态 编写游戏逻辑判断方块是否出界判断方…

Java实现俄罗斯方块小游戏。(附完整源代码)

大家好&#xff0c;我是百思不得小赵。 创作时间&#xff1a;2022 年 5 月 12 日 博客主页&#xff1a; &#x1f50d;点此进入博客主页 —— 新时代的农民工 &#x1f64a; —— 换一种思维逻辑去看待这个世界 &#x1f440; 今天是加入CSDN的第1167天。觉得有帮助麻烦&#x…

Java实现俄罗斯方块游戏(简单版)

游戏页面效果如下&#xff1a; 俄罗斯方块游戏本身的逻辑&#xff1a; 俄罗斯方块游戏的逻辑是比较简单的。它就类似于堆砌房子一样&#xff0c;各种各样的方地形状是不同的。但是&#xff0c;俄罗斯方块游戏的界面被等均的分为若干行和若干列&#xff0c;因此方块的本质就是占…

vs2019功能介绍_MFC界面库BCGControlBar v30.0新功能详解:支持VS 2019

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v30.0正式发布&#xff01;新版本添加了对Visual Studio 2019的支持等。接下来几篇文章将对这个版本的新功能一一进行介绍&#xff0c;让您对BCG这个控件有一个全新的认…

MFC界面库BCGControlBar v32.0 - 网格、报表控件升级

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v32.0正式发布&#xff01;新版本支持Windows 11、增强功能区简化模式、改进控件外观等&#xff0c;以及其他新功能和改进。需要最新版的可以点击这里【BCG下载】 BCGC…

MFC扩展库BCGControlBar :网格和报告控件

BCGControlBar ("Business Components Gallery ControlBar")是MFC扩展库&#xff0c;使您可以创建具有完全自定义选项&#xff08;功能区、可自定义工具栏、菜单等&#xff09;以及一组专业设计的丰富Microsoft Office和Microsoft Visual Studio的应用程序 GUI控件&a…

MFC界面库之BCGControlers使用

觉得默认的MFC实在是太丑了,想要用一下扩展的界面库.网上查了些资料.不过在这里我还是小结一下使用的过程吧! 1.当然是安装文件了,在上一步不用多勾选,直接按照默认的就可以了...但是要注意一定要以管理员身份运行BCGCBProBuildWizard.exe否则没有办法通过...... 2.配置lib文件…