俄罗斯方块

先创建一个新的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<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,没有则返回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();

}

}

}

创建七种形状

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 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);

}

}

相关推荐
菜鸟求带飞_5 分钟前
算法打卡:第十一章 图论part01
java·数据结构·算法
浅念同学6 分钟前
算法.图论-建图/拓扑排序及其拓展
算法·图论
是小Y啦22 分钟前
leetcode 106.从中序与后续遍历序列构造二叉树
数据结构·算法·leetcode
liuyang-neu33 分钟前
力扣 42.接雨水
java·算法·leetcode
y_dd40 分钟前
【machine learning-12-多元线性回归】
算法·机器学习·线性回归
m0_6312704040 分钟前
标准c语言(一)
c语言·开发语言·算法
万河归海42840 分钟前
C语言——二分法搜索数组中特定元素并返回下标
c语言·开发语言·数据结构·经验分享·笔记·算法·visualstudio
小周的C语言学习笔记1 小时前
鹏哥C语言36-37---循环/分支语句练习(折半查找算法)
c语言·算法·visual studio
y_dd1 小时前
【machine learning-七-线性回归之成本函数】
算法·回归·线性回归
小魏冬琅1 小时前
K-means 算法的介绍与应用
算法·机器学习·kmeans