深圳返利网站建设,手机wap网站建设多少钱,怎么去推广一个网站,wordpress seo优化插件贪吃蛇
一、创建新项目
创建一个新的项目#xff0c;并命名。
创建一个名为images的文件夹用来存放游戏相关图片。
然后再在项目的src文件下创建一个com.xxx.view的包用来存放所有的图形界面类#xff0c;
创建一个com.xxx.controller的包用来存放启动的入口类(控制类) …贪吃蛇
一、创建新项目
创建一个新的项目并命名。
创建一个名为images的文件夹用来存放游戏相关图片。
然后再在项目的src文件下创建一个com.xxx.view的包用来存放所有的图形界面类
创建一个com.xxx.controller的包用来存放启动的入口类(控制类) 二、游戏界面
package com.snake.view;import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;public class SnakeJPanel extends JPanel implements ActionListener{private boolean start;//当前游戏状态private int speed;//速度private boolean exist;//当前是否存在食物private int foodType;//食物种类private int x;//豆子的横坐标private int y;//豆子的纵坐标private ArrayListint[] localList;//蛇public String direction;//方向private String direction2;//引导方向public boolean flag;Random rand new Random();private ImageIcon up;private ImageIcon down;private ImageIcon right;private ImageIcon left;private ImageIcon body;private ImageIcon food;private ImageIcon title;Timer time;private int score;//当前得分情况private int num;//吃到的食物个数// private Image offScreenImage; //图形缓存//图片绘制Overridepublic void paint(Graphics g) {direction direction2;g.setColor(Color.WHITE);g.fillRect(0, 0, 900, 700);//绘制游戏框//标题框
// g.drawRect(25, 30, 800, 75);title.paintIcon(this, g, 25, 10);//内容框g.setColor(Color.black);g.fillRect(25, 75, 850, 600);//绘制食物的坐标位置if(!exist) {//如果当前不存在豆子,随机绘制一个豆子 if(num % 5 0) {foodType 1;}else {foodType 0;}boolean isProduce true;while(isProduce) {isProduce false;x rand.nextInt(33) * 25 25; y rand.nextInt(23) * 25 75; for (int[] arr:localList) {if(x arr[0] y arr[1]) { isProduce true;break; }}} System.out.println(x --- y);}if(eat()) {exist false;}else {exist true;}if(foodType 0) {//绘制食物g.setColor(Color.blue);
// g.fillRect(x, y, 25, 25);g.drawImage(food.getImage(),x, y, 25, 25,null);}else {//绘制食物g.setColor(Color.WHITE);g.fillRect(x, y, 25, 25);
// g.drawImage(food.getImage(),x, y, 25, 25,null);}//绘制头g.setColor(Color.red);
// g.fillRect(localList.get(0)[0], localList.get(0)[1], 25, 25); ImageIcon head null;//判断当前方向if(direction.equals(R)) {head right;}else if(direction.equals(L)) {head left;}else if(direction.equals(U)) {head up;}else if(direction.equals(D)) {head down;}
// g.drawImage(head.getImage(), localList.get(0)[0], localList.get(0)[1], 25, 25,null);head.paintIcon(this, g,localList.get(0)[0], localList.get(0)[1]);//绘制身体g.setColor(Color.white);for (int i 1; i localList.size(); i) {
// g.fillRect(localList.get(i)[0], localList.get(i)[1], 25, 25);
// g.drawImage(body.getImage(), localList.get(i)[0], localList.get(i)[1], 25, 25,null);body.paintIcon(this, g, localList.get(i)[0], localList.get(i)[1]);}
// g.fillRect(localList.get(1)[0], localList.get(1)[1], 25, 25);
// g.fillRect(localList.get(2)[0], localList.get(2)[1], 25, 25);//绘制分数和长度//长度g.setColor(Color.GREEN);g.setFont(new Font(宋体, Font.BOLD, 18));g.drawString(长度: (localList.size() - 1), 25, 30);//分数g.drawString(分数: score, 25, 48);if(!start) {//如果游戏未启动结束移动和重绘g.setColor(Color.white);g.setFont(new Font(宋体, Font.BOLD, 30));g.drawString(暂停/开始(请按任意键开始空格键暂停), 150, 300);time.stop();}else {time.start();}// speed();//移动后进行下一次绘制
// move();//移动
// repaint();//重新绘制 }// //解决闪烁问题
// //如果为JFrame 为重量级 程序不会调用update()方法
// //如果为Frame 为轻量级 重写update()方法 做双缓冲
// //如果为JPanel 不会闪烁
// Override
// public void update(Graphics g)
// {
// System.out.println(update);
// if(offScreenImage null)
// offScreenImage this.createImage(900, 700); //新建一个图像缓存空间,这里图像大小为800*600
// Graphics gImage offScreenImage.getGraphics(); //把它的画笔拿过来,给gImage保存着
// paint(gImage); //将要画的东西画到图像缓存空间去
// g.drawImage(offScreenImage, 0, 0, null); //然后一次性显示出来
// }Overridepublic void actionPerformed(ActionEvent e) { //移动后进行下一次绘制 move();//移动repaint();//重新绘制 }/*** 绘制速度*/
// private void speed() {
// try {//按一定速度进行移动
// Thread.sleep(speed);//控制移动速度
// } catch (InterruptedException e) {
// // TODO 自动生成的 catch 块
// e.printStackTrace();
// }
// }/*** 初始化图片*/private void drawImage() {up new ImageIcon(images/up.png);down new ImageIcon(images/down.png);right new ImageIcon(images/right.png);left new ImageIcon(images/left.png);body new ImageIcon(images/body.png);food new ImageIcon(images/food.png);title new ImageIcon(images/title.jpg);}private boolean eat() {if(localList.get(0)[0] x localList.get(0)[1] y) {//如果当前蛇头吃到了豆子System.out.println(eat);num;if(foodType 0) {score 10;}else {score (rand.nextInt(5) * 10 10);}int last localList.size() - 1;//蛇尾 //在蛇尾后面添加一节身体localList.add(new int[] {localList.get(last)[0],localList.get(last)[1]});return true;}return false;}//移动方法public void move() {//判断是否游戏结束if(isbody()) {System.out.println(game over);start false;//结束游戏移动JOptionPane.showMessageDialog(null,游戏已结束);time.stop();init(); }if(flag localList ! null) {//如果长度不为空且游戏未结束 int last localList.size() - 1;//记录蛇尾for (int i last; i 0; i--) {//从蛇尾开始每节身体移动到前一节身体的位置上localList.set(i,new int[] {localList.get(i - 1)[0],localList.get(i - 1)[1]});}//记录头位置int[] local localList.get(0);//判断当前方向,并进行模拟移动判断是否与边界重合if(direction.equals(R)) {if(local[0] 850) {local[0] 25;}else {local[0] 25;}}else if(direction.equals(L)) {if(local[0] 25) {local[0] 850;}else {local[0] - 25;}}else if(direction.equals(U)) {if(local[1] 75) {local[1] 650;}else {local[1] - 25;}}else if(direction.equals(D)) {if(local[1] 650) {local[1] 75;}else {local[1] 25;}} //更改头的位置localList.set(0, local); } }//判断下一步是否为蛇身private boolean isbody() {// TODO 自动生成的方法存根//记录头位置int x localList.get(0)[0];int y localList.get(0)[1];//判断当前方向,并进行模拟移动判断是否与边界重合if(direction.equals(R)) {x 25;}else if(direction.equals(L)) {x - 25;}else if(direction.equals(U)) {y - 25;}else if(direction.equals(D)) {y 25;} for (int i 1; i localList.size(); i) {if(localList.get(i)[0] x localList.get(i)[1] y) {return true;}}return false;}// //判断下一步是否为边界
// private boolean isborder() {
// // TODO 自动生成的方法存根
// //记录头位置
// // TODO 自动生成的方法存根
// //记录头位置
// int x localList.get(0)[0];
// int y localList.get(0)[1];
//
// //判断当前方向,并进行模拟移动判断是否与边界重合
// if(direction.equals(R)) {
// x 25;
// }else if(direction.equals(L)) {
// x - 25;
// }else if(direction.equals(U)) {
// y - 25;
// }else if(direction.equals(D)) {
// y 25;
// }
//
// if(x 25 || x (33 * 25 25)) {
// return true;//当x坐标超出边界则返回true
// }
// if(y 105 || y (23 * 25 105)) {
// return true;//当y坐标超出边界则返回true
// }
// return false;//蛇头移动后未超出边界返回false
//
// }/*** Create the frame.*/public SnakeJPanel(int speed) {this.speed speed; //初始化速度//初始化游戏面板的基本信息this.setSize(900, 700);this.setLocation(0, 30);this.setFocusable(true);init();//初始化界面drawImage();//绘制图片moveByKey();//给界面添加一个键盘监听}/** 键盘监听* 通过键盘输入上下左右来控制当前蛇头移动的方向* 先判断当前蛇头方向再来改变引导方向* 当进行绘制时再修改蛇的方向* 保证不会因为在短时间内快速变换方向导致蛇头逆向转向*/private void moveByKey() {addKeyListener(new KeyAdapter() {Overridepublic void keyPressed(KeyEvent e) {int key e.getKeyCode();//边界值判断switch(key) {case 65:case 37:{//向左走if(!direction.equals(R)) {direction2 L;}break;} case 87:case 38:{//向上走if(!direction.equals(D)) {direction2 U;} break;} case 68:case 39:{//向右走if(!direction.equals(L)) {direction2 R;}break;}case 83:case 40:{//向下走if(!direction.equals(U)) {direction2 D;} break;}case KeyEvent.VK_SPACE:{//如果当前键盘输入为空格start !start;//调整游戏状态System.out.println(暂停/开始);repaint();//重绘}}//任意键开始if(!start key ! KeyEvent.VK_SPACE) {//如果当前状态为暂停状态且键盘输入不是空格start true;repaint();//重绘} }});}/*** 初始化游戏基本信息*/private void init() {start false;exist true;direction2 U;flag true;localList new ArrayListint[]();localList.add(0,new int[] {75,125});//蛇头localList.add(1,new int[] {75,150});//蛇身1localList.add(2,new int[] {75,175});//蛇身2//创建第一个食物的位置//通过循环保证当前生成的食物不在身体所在的坐标上boolean isProduce true;while(isProduce) {//循环生成食物坐标isProduce false;//结束本次循环x rand.nextInt(33) * 25 25; y rand.nextInt(23) * 25 75; for (int[] arr:localList) {//循环遍历蛇头及蛇身的坐标if(x arr[0] y arr[1]) {//如果食物坐标和蛇的某一节坐标重合isProduce true;//跳转循环状态继续下一次食物生成break; }}//蛇身遍历完成没有重合坐标结束食物坐标生成}time new Timer(speed, this);setLayout(null);score 0;num 0;foodType 0;// repaint();}}
三、构造启动类
package com.snake.controller;import javax.swing.JFrame;
import javax.swing.JOptionPane;import com.snake.view.SnakeJPanel;public class SnakeStart {public static void main(String[] args) {int speed 0;String showInputDialog null;//初始化时间//得到速度while(true) {showInputDialog JOptionPane.showInputDialog(蛇移动速度(1 - 5),3);if(showInputDialog null) {showInputDialog 3;//默认速度break;}if(showInputDialog.length() 1) {continue;}char[] a showInputDialog.toCharArray();if(a[0] 1 a[0] 5) {break;}}speed Integer.parseInt(showInputDialog) * 50;SnakeJPanel snakeJPanel new SnakeJPanel(speed);//创建一个JFrame窗口将游戏面板添加进行窗口中JFrame jFrame new JFrame();//设置窗口的某些属性jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jFrame.setSize(920, 750);jFrame.add(snakeJPanel);jFrame.setLocationRelativeTo(null);jFrame.setVisible(true);}}
四、游戏启动
设置游戏速度 游戏界面 俄罗斯方块
游戏规则
由小方块组成的不同形状的板块陆续从屏幕上方落下来玩家通过调整板块的位置和方向使它们在屏幕底部拼出完整的一条或几条。这些完整的横条会随即消失给新落下来的板块腾出空间与此同时玩家得到分数奖励。没有被消除掉的方块不断堆积起来一旦堆到屏幕顶端玩家便告输游戏结束。
整体代码分为三个模块方格模块七种图形模块俄罗斯方块主模块。
小方块类Cell
package com.zhao.demo.block;import java.awt.image.BufferedImage;
import java.util.Objects;/*** author xiaoZhao* date 2022/5/7* describe* 小方块类* 方法 左移、右移、下落*/
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;}Overridepublic String toString() {return Cell{ row row , col col , image image };}Overridepublic boolean equals(Object o) {if (this o) {return true;}if (!(o instanceof Cell)) {return false;}Cell cell (Cell) o;return getRow() cell.getRow() getCol() cell.getCol() Objects.equals(getImage(), cell.getImage());}Overridepublic int hashCode() {return Objects.hash(getRow(), getCol(), getImage());}//左移动一格public void left(){col--;}//右移动一格public void right(){col;}//下移动一格public void down(){row;}
}四方格图形的父类Tetromino
package com.zhao.demo.block;import com.zhao.demo.shape.*;/*** author xiaoZhao* date 2022/5/11* describe 编写四方格父类*/
public class Tetromino {public Cell[] cells new Cell[4];//旋转的状态protected State[] states;//声明旋转次数protected int count 10000;//左移方法public void moveLeft() {for (Cell cell : cells) {cell.left();}}//右移方法public void moveRight() {for (Cell cell : cells) {cell.right();}}//单元格下落public void moveDrop() {for (Cell cell : cells) {cell.down();}}//编写随机生成四方格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;}//顺时针旋转的方法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() {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);}//四方格旋转状态的内部类protected 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 getCol0() {return col0;}public void setCol0(int col0) {this.col0 col0;}public int getRow1() {return row1;}public void setRow1(int row1) {this.row1 row1;}public int getCol1() {return col1;}public void setCol1(int col1) {this.col1 col1;}public int getRow2() {return row2;}public void setRow2(int row2) {this.row2 row2;}public int getCol2() {return col2;}public void setCol2(int col2) {this.col2 col2;}public int getRow3() {return row3;}public void setRow3(int row3) {this.row3 row3;}public int getCol3() {return col3;}public void setCol3(int col3) {this.col3 col3;}Overridepublic String toString() {return State{ row0 row0 , col0 col0 , row1 row1 , col1 col1 , row2 row2 , col2 col2 , row3 row3 , col3 col3 };}}
}七种图形类I、J、L、O、S、T、Z I
package com.zhao.demo.shape;import com.zhao.demo.App.Tetris;
import com.zhao.demo.block.Cell;
import com.zhao.demo.block.Tetromino;/*** author xiaoZhao* date 2022/5/11* describe*/
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);}}J
package com.zhao.demo.shape;import com.zhao.demo.App.Tetris;
import com.zhao.demo.block.Cell;
import com.zhao.demo.block.Tetromino;/*** author xiaoZhao* date 2022/5/11* describe*/
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);statesnew 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);}
}L
package com.zhao.demo.shape;import com.zhao.demo.App.Tetris;
import com.zhao.demo.block.Cell;
import com.zhao.demo.block.Tetromino;/*** author xiaoZhao* date 2022/5/11* describe*/
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);statesnew 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);}
}O
package com.zhao.demo.shape;import com.zhao.demo.App.Tetris;
import com.zhao.demo.block.Cell;
import com.zhao.demo.block.Tetromino;/*** author xiaoZhao* date 2022/5/11* describe*/
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);//无旋转状态states new State[0];}
}S
package com.zhao.demo.shape;import com.zhao.demo.App.Tetris;
import com.zhao.demo.block.Cell;
import com.zhao.demo.block.Tetromino;/*** author xiaoZhao* date 2022/5/11* describe*/
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);//共有两种旋转状态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);}
}T
package com.zhao.demo.shape;import com.zhao.demo.App.Tetris;
import com.zhao.demo.block.Cell;
import com.zhao.demo.block.Tetromino;/*** author xiaoZhao* date 2022/5/11* describe*/
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);statesnew 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);}
}Z
package com.zhao.demo.shape;import com.zhao.demo.App.Tetris;
import com.zhao.demo.block.Cell;
import com.zhao.demo.block.Tetromino;/*** author xiaoZhao* date 2022/5/11* describe*/
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);}
}俄罗斯方块游戏主类Tetris
package com.zhao.demo.App;import com.zhao.demo.block.Cell;
import com.zhao.demo.block.Tetromino;import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.security.cert.Certificate;/*** author xiaoZhao* date 2022/5/11* describe 俄罗斯方块游戏主类*/
public class Tetris extends JPanel {//正在下落的方块private Tetromino currentOne Tetromino.randomOne();//将要下落的方块private Tetromino nextOne Tetromino.randomOne();//游戏主区域private Cell[][] wall new Cell[18][9];//声明单元格的值private static final int CELL_SIZE 48;//游戏分数池int[] scores_pool {0, 1, 2, 5, 10};//当前游戏的分数private int totalScore 0;//当前消除的行数private int totalLine 0;//游戏三种状态 游戏中、暂停、结束public static final int PLING 0;public static final int STOP 1;public static final int OVER 2;//当前游戏状态值private int game_state;//显示游戏状态String[] show_state {P[pause], C[continue], S[replay]};//载入方块图片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 background;static {try {I ImageIO.read(new File(images/I.png));J ImageIO.read(new File(images/J.png));L ImageIO.read(new File(images/L.png));O ImageIO.read(new File(images/O.png));S ImageIO.read(new File(images/S.png));T ImageIO.read(new File(images/T.png));Z ImageIO.read(new File(images/Z.png));background ImageIO.read(new File(images/background.png));} catch (IOException e) {e.printStackTrace();}}Overridepublic void paint(Graphics g) {g.drawImage(background, 0, 0, null);//平移坐标轴g.translate(22, 15);//绘制游戏主区域paintWall(g);//绘制正在下落的四方格paintCurrentOne(g);//绘制下一个将要下落的四方格paintNextOne(g);//绘制游戏得分paintSource(g);//绘制当前游戏状态paintState(g);}public void start() {game_state PLING;KeyListener l new KeyAdapter() {Overridepublic void keyPressed(KeyEvent e) {int code e.getKeyCode();switch (code) {case KeyEvent.VK_DOWN:sortDropActive();break;case KeyEvent.VK_LEFT:moveleftActive();break;case KeyEvent.VK_RIGHT:moveRightActive();break;case KeyEvent.VK_UP:rotateRightActive();break;case KeyEvent.VK_SPACE:hadnDropActive();break;case KeyEvent.VK_P://判断当前游戏状态if (game_state PLING) {game_state STOP;}break;case KeyEvent.VK_C:if (game_state STOP) {game_state PLING;}break;case KeyEvent.VK_S://重新开始game_state PLING;wall new Cell[18][9];currentOne Tetromino.randomOne();nextOne Tetromino.randomOne();totalScore 0;totalLine 0;break;}}};//将窗口设置为焦点this.addKeyListener(l);this.requestFocus();while (true) {if (game_state PLING) {try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}if (camDrop()) {currentOne.moveDrop();} else {landToWall();destroyLine();if (isGameOver()) {game_state OVER;} else {//游戏没有结束currentOne nextOne;nextOne Tetromino.randomOne();}}}repaint();}}//创建顺时针旋转public void rotateRightActive() {currentOne.rotateRight();if (outOFBounds() || coincide()) {currentOne.rotateLeft();}}//瞬间下落public void hadnDropActive() {while (true) {//判断能否下落if (camDrop()) {currentOne.moveDrop();} else {break;}}//嵌入到墙中landToWall();destroyLine();if (isGameOver()) {game_state OVER;} else {//游戏没有结束currentOne nextOne;nextOne Tetromino.randomOne();}}//按键一次下落一格public void sortDropActive() {if (camDrop()) {//当前四方格下落一格currentOne.moveDrop();} else {landToWall();destroyLine();if (isGameOver()) {game_state OVER;} 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 boolean camDrop() {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 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 isFullLine(int row) {Cell[] cells wall[row];for (Cell cell : cells) {if (cell null) {return false;}}return true;}//判断游戏是否结束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;}private void paintState(Graphics g) {if (game_state PLING) {g.drawString(show_state[PLING], 500, 660);} else if (game_state STOP) {g.drawString(show_state[STOP], 500, 660);} else {g.drawString(show_state[OVER], 500, 660);g.setColor(Color.RED);g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 60));g.drawString(GAME OVER!, 30, 400);}}private void paintSource(Graphics g) {g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 30));g.drawString(分数: totalScore, 500, 250);g.drawString(行数: totalLine, 500, 430);}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, 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, 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, null);}}}}//判断是否出界public boolean outOFBounds() {Cell[] cells currentOne.cells;for (Cell cell : cells) {int col cell.getCol();int row cell.getRow();if (row 0 || row wall.length - 1 || col 0 || col wall[0].length-1) {return true;}}return false;}//按键一次左移一次public void moveleftActive() {currentOne.moveLeft();//判断是否越界或重合if (outOFBounds() || coincide()) {currentOne.moveRight();}}//按键一次右移一次public void moveRightActive() {currentOne.moveRight();//判断是否越界或重合if (outOFBounds() || coincide()) {currentOne.moveLeft();}}//判断是否重合public boolean coincide() {Cell[] cells currentOne.cells;for (Cell cell : cells) {int row cell.getRow();int col cell.getCol();if (wall[row][col] ! null) {return true;}}return false;}public static void main(String[] args) {JFrame jFrame new JFrame(俄罗斯方块);//创建游戏界面Tetris panel new Tetris();jFrame.add(panel);//设置可见jFrame.setVisible(true);//设置窗口大小jFrame.setSize(810, 940);//设置剧中jFrame.setLocationRelativeTo(null);//设置窗口关闭时停止jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//游戏主要开始逻辑panel.start();}
}三、效果展示
游戏开始方快下落右边区域展示即将下落的方块图、分数、消除的行数以及游戏切换的状态。 按下空格键方块瞬间下落 按下P键游戏暂停消除一行分数为1此处由分数池进行控制 按下C键游戏继续。 方块占满游戏结束此时可以按下S键重新开始游戏。