先创建一个新的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;
- }
- //旋转次数加1
- count++;
- //获取当前状态
- 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() {
- //旋转次数加1
- count--;
- //获取当前状态
- 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 stub
- return false;
- }
- private boolean outOfBounds() {
- // TODO Auto-generated method stub
- return false;
- }
- //判断游戏是否结束,结束返回true,继续返回false
- public 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,没有满返回false
- public 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() {
- @Override
- public 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();
- }
- @Override
- public 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
- for(int j=0;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,没有则返回false
- public 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,没有返回false
- public 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);
- }
- }
三.结果呈现
-
相关阅读:
【stm32】大一上学期笔记复制
22年建模经验交流
spark on hive
微信小程序如何在切换页面后原页面状态不变
【踩坑系列】uniapp之h5 跨域的问题
IIS通过ARR实现负载均衡
【JavaScript】运算符与表达式、控制语句、常用API
【Ansible自动化运维工具 1】Ansible常用模块详解(附各模块应用实例和Ansible环境安装部署)
Mysql应用日志时间与系统时间相差八小时
【数学】旋转后仍为函数图像问题
-
原文地址:https://blog.csdn.net/m0_73900459/article/details/134483257