俄罗斯方块

一.准备工作

先创建一个新的Java项目命名为“俄罗斯方块”。再在该项目中创建一个文件夹命名为”images”,并将所需的图片素材拖入该文件夹。

二.代码呈现 

编写小方块类:

import java.awt.image.BufferedImage;/*** 描述:小方块类* 属性:行,列以及单元格的图片* 方法: 左移一格,右移一格,下移一格*/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 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 void left() {col--;}//右移public void right() {col++;}//下移public void soft() {row++;}
}

编写四方格父类:

/*** 描述:四方格父类* 属性:Cell[]数组用于创建4个小方块* 方法:左移一格,右移一格,下移一格,变形*/public class Tetromino {protected Cell[] cells = new Cell[4];//左移public void moveLeft() {for (Cell cell : cells) {cell.left();}}//右移public void moveRight() {for (Cell cell : cells) {cell.right();}}//下移public void sftDrop() {for (Cell cell : cells) {cell.drop();}}//随机生成四方格public static Tetromino randomOne() {int num = (int)(Math.random() * 7);Tetromino tetromino = null;switch (num) {case 0 :tetromino = new I();break;case 1 :tetromino = new J();break;case 2 :tetromino = new L();break;case 3 :tetromino = new O();break;case 4 :tetromino = new S();break;case 5 :tetromino = new T();break;case 6 :tetromino = new Z();break;}return tetromino;}//编写旋转状态protected State[] states;//声明旋转次数protected int count = 10000;/**描述:四方格旋转状态的内部类* 属性:记录四方格的相对位置*/class State {int row0,col0,row1,col1,row2,col2,row3,col3;public State(){}public State(int row0, int col0, int row1, int col1, int row2, int col2, int row3, int col3) {this.row0 = row0;this.col0 = col0;this.row1 = row1;this.col1 = col1;this.row2 = row2;this.col2 = col2;this.row3 = row3;this.col3 = col3;}public int getRow0() {return row0;}public void setRow0(int row0) {this.row0 = row0;}public int getRow1() {return row1;}public void setRow1(int row1) {this.row1 = row1;}public int getRow2() {return row2;}public void setRow2(int row2) {this.row2 = row2;}public int getRow3() {return row3;}public void setRow3(int row3) {this.row3 = row3;}public int getCol0() {return col0;}public void setCol0(int col0) {this.col0 = col0;}public int getCol1() {return col1;}public void setCol1(int col1) {this.col1 = col1;}public int getCol2() {return col2;}public void setCol2(int col2) {this.col2 = col2;}public int getCol3() {return col3;}public void setCol3(int col3) {this.col3 = col3;}}//编写顺时针旋转四方格方法public void rotateRight() {if (states.length == 0) {return;}//旋转次数加1count++;//获取当前状态State s = states[count % states.length];Cell cell = cells[0];int row = cell.getRow();int col = cell.getCol();//变形cells[1].setRow(row + s.row1);cells[1].setCol(col + s.col1);cells[2].setRow(row + s.row2);cells[2].setCol(col + s.col2);cells[3].setRow(row + s.row3);cells[3].setCol(col + s.col3);}//逆时针旋转四方格方法public void rotateLeft() {//旋转次数加1count--;//获取当前状态State s = states[count % states.length];Cell cell = cells[0];int row = cell.getRow();int col = cell.getCol();//变形cells[1].setRow(row + s.row1);cells[1].setCol(col + s.col1);cells[2].setRow(row + s.row2);cells[2].setCol(col + s.col2);cells[3].setRow(row + s.row3);cells[3].setCol(col + s.col3);}//顺时针旋转public void rotateRightAction() {Tetromino currentOne = null;currentOne.rotateRight();//判断是否越界或者重合,否则恢复原来的状态if (outOfBounds() || coincide()) {currentOne.rotateLeft();}}private boolean coincide() {// TODO Auto-generated method stubreturn false;}private boolean outOfBounds() {// TODO Auto-generated method stubreturn false;}//判断游戏是否结束,结束返回true,继续返回falsepublic boolean isGameOver() {Cell[] cells = nextOne.cells;for (Cell cell : cells) {int row = cell.getRow();int col = cell.getCol();if (wall[row][col] != null) {return true;}}return false;}//判断当前行是否满,满返回true,没有满返回falsepublic boolean isFullLine(int row) {Cell[] cells = wall[row];for (Cell cell : cells) {if (cell == null) {return false;}}return true;}//创建销行方法public void  destroyLine() {//统计当前形参行数int line = 0;Cell[] cells = currentOne.cells;for (Cell cell : cells) {int row = cell.getRow();//判断当前行是否满if (isFullLine(row)) {line++;//将消除行以上的方块下落到对应行数for (int i = row; i > 0; i--) {System.arraycopy(wall[i - 1],0,wall[i],0,wall[0].length);}//重新创造第一行wall[0] = new Cell[9];}}//更新分数totalScore += scores_pool[line];//更新消除行数totalLine += line;}//判断四方格能否下落public boolean canDrop() {Cell[] cells = currentOne.cells;for (Cell cell : cells) {int row = cell.getRow();int col = cell.getCol();//判断能否全部到达底部if (row == wall.length - 1) {return false;} else if(wall[row + 1][col] != null) { //判断该位置是否有方块return false;}}return true;}//按键一次四方格下落一个public void sortDropAction() {//判断能否下落if (canDrop()) {//当前四方格下落一格currentOne.softDrop();} else {//把四方格嵌入墙中landToWall();//判断能否销行destroyLine();//判断游戏是否结束if (isGameOver()) {game_state = GAMEOVER;} else {//继续生成四方格currentOne = nextOne;nextOne = Tetromino.randomOne();}}}//把四方格嵌入墙中private void landToWall() {Cell[] cells = currentOne.cells;for (Cell cell : cells) {int row = cell.getRow();int col = cell.getCol();wall[row][col] = cell;}}//瞬间下落public void handDropAction() {while (canDrop()) {currentOne.softDrop();}//把四方格嵌入墙中landToWall();//判断能否销行destroyLine();//判断游戏是否结束if (isGameOver()) {game_state = GAMEOVER;} else {//继续生成四方格currentOne = nextOne;nextOne = Tetromino.randomOne();}}public void start() {game_state = PLAYING;KeyListener listener = new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {int code = e.getKeyCode();switch (code) {case KeyEvent.VK_DOWN: //↓sortDropAction(); //下落一格break;case KeyEvent.VK_LEFT://←moveLeftAction(); //左移一格break;case KeyEvent.VK_RIGHT: //→moveRightAction(); //右移一格break;case KeyEvent.VK_UP://↑rotateRightAction();//顺时针旋转break;case KeyEvent.VK_SPACE://空格handDropAction();//瞬间下落break;case KeyEvent.VK_P: //p//判断游戏是否在运行,没有才能暂停if (game_state == PLAYING) {game_state = PAUSE;}break;case KeyEvent.VK_C://游戏暂停后,才能继续if (game_state == PAUSE) {game_state = PLAYING;}break;case KeyEvent.VK_R://重新开始游戏,把游戏状态变为正在游戏game_state = PLAYING;//界面清空wall = new Cell[ROW][COL];currentOne = Tetromino.randomOne();nextOne = Tetromino.randomOne();//数据清空totalLine = 0;totalScore = 0;break;}}};//把俄罗斯方块窗口设置为焦点this.addKeyListener(listener);this.requestFocus();while(true){//判断,当前游戏状态在游戏中时,每隔0.5秒下落if(game_state == PLAYING){try {Thread.sleep(700);} catch (InterruptedException e) {e.printStackTrace();}//判断能否下落if(canDrop()){currentOne.softDrop();}else{//嵌入到墙中landToWall();//判断能否消行destroyLine();//判断游戏是否结束if(isGameOver()){game_state = GAMEOVER;}else{currentOne = nextOne;nextOne = Tetromino.randomOne();}}}//重新绘制repaint();}}}

编写俄罗斯方块主类:

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;//俄罗斯方块主类
public class Tetris extends JPanel {static int ROW=18;static int COL=9;//声明正在下落的方块private Tetromino currentOne = Tetromino.randomOne();//声明将要下落的方块private Tetromino nextOne = Tetromino.randomOne();//声明游戏主区域private Cell[][] wall = new Cell[ROW][COL];//声明单元格像素为48像素private static final int CELL_SIZE=48;//游戏分数池int[] scores_pool = {0, 1, 2, 5, 10};//游戏总分private int totalScore = 0;//游戏消除总行数private int totalLine = 0;//游戏的状态:游戏中,游戏暂停,游戏结束private static final int PLAYING=0;private static final int PAUSE=1;private static final int GAMEOVER=2;//声明变量来存放当前游戏状态private int game_state;//数组显示当前游戏状态String[] show_state= {"P[暂停]","C[继续]","R[重开]"};//静态载入图片public static BufferedImage I;public static BufferedImage J;public static BufferedImage L;public static BufferedImage O;public static BufferedImage S;public static BufferedImage T;public static BufferedImage Z;public static BufferedImage backImage;static {try {I = ImageIO.read(new File(pathname:"images/I.png"));J = ImageIO.read(new File(pathname:"images/J.png"));L = ImageIO.read(new File(pathname:"images/L.png"));O = ImageIO.read(new File(pathname:"images/O.png"));S = ImageIO.read(new File(pathname:"images/S.png"));T = ImageIO.read(new File(pathname:"images/T.png"));Z = ImageIO.read(new File(pathname:"images/Z.png"));backImage=ImageIO.read(new File(pathname:"images/background.png"));} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {//创建窗口对象JFrame frame = new JFrame(title:"俄罗斯方块");//创建游戏窗口(即面板)Tetris panel = new Tetris();//把面板嵌入到窗口中frame.add(panel);//设置可见frame.setVisible(true);//设置窗口尺寸frame.setSize(width:810,height:940);//设置窗口居中frame.setLocationRelativeTo(null);//设置窗口关闭时程序中止frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//游戏逻辑封装在方法中panel.start();}@Overridepublic void paint(Graphics g) {g.drawImage(backImage,x:0,y:0,observer:null);//平移坐标轴g.translate(x:22, y:15);//绘制游戏主区域paintWall(g);//绘制正在下落的四方格paintCurrentOne(g);//绘制下一个下落的四方格paintNextOne(g);//绘制游戏得分paintScore(g);//绘制游戏当前状态paintState(g);}//绘制游戏当前状态private void paintState(Graphics g) {if(game_state==PLAYING) {g.drawString(show_state[0],x:500,y:660);}else if(game_state==PAUSE) {g.drawString(show_state[1],x:500,y:660);}else if(game_state==GAMEOVER) {g.drawString(show_state[2],x:500,y:660);g.setColor(Color.red);g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,size:60));g.drawString(str:"GAMEOVER!",x:30,y:400);}}private void paintNextOne(Graphics g) {Cell[] cells=nextOne.cells;for(Cell cell:cells) {int x=cell.getCol()*CELL_SIZE+370;int y=cell.getRow()*CELL_SIZE+25;g.drawImage(cell.getImage(),x,y,observer:null);}}private void paintCurrentOne(Graphics g) {Cell[] cells=currentOne.cells;for(Cell cell:cells) {int x=cell.getCol()*CELL_SIZE;int y=cell.getRow()*CELL_SIZE;g.drawImage(cell.getImage(),x,y,observer:null);}}private void paintWall(Graphics g) {for(int i=0;i<wall.length;i++) {for(int j=0;j<wall[i].length;j++) {int x=j*CELL_SIZE;int y=i*CELL_SIZE;Cell cell=wall[i][j];//判断当前单元格是否有小方格,如果无则绘制矩形,否则将小方块嵌到墙中if(cell==null) {g.drawRect(x,y,CELL_SIZE,CELL_SIZE);}else {g.drawImage(cell.getImage(), x, y, observer.null);}}}}//判断方块是否出界,出界返回true,没有则返回falsepublic boolean outOfBounds() {Cell[] cells = currentOne.cells;for (Cell cell : cells) {int col = cell.getCol();int row = cell.getRow();if (col < 0 || col > COL - 1 || row < 0 || row > ROW - 1) {return true;}}return false;}//判断方块是否重合,重合返回true,没有返回falsepublic boolean coincide() {Cell[] cells = currentOne.cells;for (Cell cell : cells) {int col = cell.getCol();int row = cell.getRow();if (wall[row][col] != null) {return true;}}return false;}//按键←触发左移public void moveLeftAction() {currentOne.moveLeft();//判断是否越界或者重合,如果是则右移恢复原来的状态,不是则左移if (outOfBounds() || coincide()) {currentOne.moveRight();}}//按键→触发右移public void moveRightAction() {currentOne.moveRight();//判断是否越界或者重合,如果是则左移恢复原来的状态,不是则右移if (outOfBounds() || coincide()) {currentOne.moveLeft();}}}

分别创建并初始化7种形状:

public class I extends Tetromino{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);//两种状态states = new State[2];//相对坐标states[0] = new State(0,0,0,-1,0,1,0,2);states[1] = new State(0,0,-1,0,1,0,2,0);}
}
public class J extends Tetromino{public J() {cells[0] = new Cell(0,4,Tetris.J);cells[1] = new Cell(0,3,Tetris.J);cells[2] = new Cell(0,5,Tetris.J);cells[3] = new Cell(1,5,Tetris.J);//4种状态states = new State[4];states[0] = new State(0,0,0,1,0,1,1,1);states[1] = new State(0,0,-1,0,1,0,1,-1);states[2] = new State(0,0,0,1,0,-1,-1,-1);states[3] = new State(0,0,1,0,-1,0,-1,1);}
}
public class L extends Tetromino{public L() {cells[0] = new Cell(0,4,Tetris.L);cells[1] = new Cell(0,3,Tetris.L);cells[2] = new Cell(0,5,Tetris.L);cells[3] = new Cell(1,3,Tetris.L);//4种状态states = new State[4];//初始化states[0] = new State(0,0,0,-1,0,1,1,-1);states[1] = new State(0,0,-1,0,1,0,-1,-1);states[2] = new State(0,0,0,1,0,-1,-1,1);states[3] = new State(0,0,1,0,-1,0,1,1);}
}
public class O extends Tetromino{public O() {cells[0] = new Cell(0,4,Tetris.O);cells[1] = new Cell(0,5,Tetris.O);cells[2] = new Cell(1,4,Tetris.O);cells[3] = new Cell(1,5,Tetris.O);//0种状态states = new State[0];}
}
public class S extends Tetromino{public S() {cells[0] = new Cell(0,4,Tetris.S);cells[1] = new Cell(0,5,Tetris.S);cells[2] = new Cell(1,3,Tetris.S);cells[3] = new Cell(1,4,Tetris.S);//2种状态states = new State[2];//初始化相对位置states[0] = new State(0,0,0,1,1,-1,1,0);states[1] = new State(0,0,1,0,-1,-1,0,-1);}
}
public class T extends Tetromino{public T() {cells[0] = new Cell(0,4,Tetris.T);cells[1] = new Cell(0,3,Tetris.T);cells[2] = new Cell(0,5,Tetris.T);cells[3] = new Cell(1,4,Tetris.T);//4种状态states = new State[4];//初始化相对坐标states[0] = new State(0,0,0,-1,0,1,1,0);states[1] = new State(0,0,-1,0,1,0,0,-1);states[2] = new State(0,0,0,1,0,-1,-1,0);states[3] = new State(0,0,1,0,-1,0,0,1);}
}
public class Z extends Tetromino{public Z() {cells[0] = new Cell(1,4,Tetris.Z);cells[1] = new Cell(0,3,Tetris.Z);cells[2] = new Cell(0,4,Tetris.Z);cells[3] = new Cell(1,5,Tetris.Z);//两种状态states = new State[2];//初始化相对位置states[0] = new State(0,0,-1,-1,-1,0,0,1);states[1] = new State(0,0,-1,1,0,1,1,0);}
}

三.结果呈现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/180305.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Google 向中国开发者开放数百份 TensorFlow 资源

Google 的机器学习框架 TensorFlow 自 2015 年开源后&#xff0c;已然成为 AI 领域最受欢迎的框架。 据统计&#xff0c;在广受欢迎的 Python 编程语言在线软件知识库 PyPi 上&#xff0c;TensorFlow 的下载次数已超过 90 万&#xff0c;其中有 15% 来自中国。谷歌官方博客也表…

你是想被ChatGPT改变,还是改变软件开发的未来?丨IDCF

人工智能技术的发展&#xff0c;正在深刻地改变着我们的生活和工作方式。在软件工程领域&#xff0c;ChatGPT作为一种新兴的人工智能技术&#xff0c;正在逐渐地被应用到软件开发的各个环节中。那么&#xff0c;ChatGPT对每个人的影响是什么呢&#xff1f; 一、对软件开发人员…

从零搭建微服务架构:Spring Boot与Nacos完美整合

&#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 从零搭建微服务架构&#xff1a;Spring Boot与Nacos完美整合 前言第一&#xff1a;服务注册与发现第二&#xff1a;配置中心第三&#xff1a;报错问题解决第四&#xff1a;什…

自己搭设开源密码管理工具 bitwarden

简介 Bitwarden是一款自由且开源的密码管理服务&#xff0c;用户可在加密的保管库中存储敏感信息&#xff08;例如网站登录凭据&#xff09;。Bitwarden平台提供有多种客户端应用程序&#xff0c;包括网页用户界面、桌面应用&#xff0c;浏览器扩展、移动应用以及命令行界面。[…

247:vue+openlayers 根据坐标显示多边形(3857投影),计算出最大幅宽

第247个 点击查看专栏目录 本示例是演示如何在vue+openlayers项目中根据坐标显示多边形(3857投影),计算出最大幅宽。这里先通过Polygon来显示出多边形,利用getExtent() 获取3857坐标下的最大最小x,y值,通过ransformExtent转换坐标为4326, 通过turf的turf.distance和计算…

5、鸿蒙项目远程调试

一、注册华为账号&#xff0c; 如果是华为手机&#xff0c;并注册了账号可能跳过此步骤&#xff0c;如果使用邮箱注册&#xff0c;此邮箱一定是要正确的邮箱&#xff0c;此处需要使用邮箱获取验证码 注册地址&#xff1a;‎ 1、进入注册页面&#xff0c;输入手机号等信息后点…

系列二、类装载器ClassLoader

一、能干嘛 1.1、方法区 存放类的描述信息的地方。 1.2、JVM中的类装载器 1.3、获取ClassLoader的方式 /*** Author : 一叶浮萍归大海* Date: 2023/11/16 0:08* Description: 获取类的加载器的方式*/ public class ClassLoaderMainApp {public static void main(String[] arg…

Android 10.0 framework层设置后台运行app进程最大数功能实现

1. 前言 在10.0的定制开发中,在系统中,对于后台运行的app过多的时候,会比较耗内存,导致系统运行有可能会卡顿,所以在系统优化的 过程中,会限制后台app进程运行的数量,来保证系统流畅不影响体验,所以需要分析下系统中关于限制app进程的相关源码来实现 功能 2.framewo…

VIVADO+FPGA调试记录

vivadoFPGA调试记录 vitis编译vivado导出的硬件平台&#xff0c;提示xxxx.h file cant find vitis编译vivado导出的硬件平台&#xff0c;提示’xxxx.h file cant find’ 此硬件平台中&#xff0c;包含有AXI接口类型的ip。在vitis编译硬件平台时&#xff0c;经常会报错&#xf…

贪吃蛇小游戏

一. 准备工作 首先获取贪吃蛇小游戏所需要的头部、身体、食物以及贪吃蛇标题等图片。、 然后&#xff0c;创建贪吃蛇游戏的Java项目命名为snake_game&#xff0c;并在这个项目里创建一个文件夹命名为images&#xff0c;将图片素材导入文件夹。 再在src文件下创建两个包&#…

JavaWeb-HTML

​ 一、什么是HTML HTML是hypertext markup language&#xff08;超文本标记语言&#xff09;的缩写。HTML文件本质上是文本文件&#xff0c;普通的文本文件只能显示字符&#xff0c;而HTML文件可以在浏览器上显示更丰富的信息&#xff08;如图片等&#xff09;。 超文本&am…

python链表_递归求和_递归求最大小值

创建一个单链表&#xff1a; class LinkNode: #设置属性def __init__(self,data None):self.data dataself.next None class LinkList: #设置头结点def __init__(self):self.head LinkNode()self.head.next Nonedef CreateListR(self,a): …