俄罗斯方块Java编写精髓
- 格式:ppt
- 大小:1.23 MB
- 文档页数:36
俄罗斯方块游戏一、课题内容和要求课题内容:俄罗斯方块游戏(Tetris)是一款经典单机游戏,早期常见于各个平台。
设计一个俄罗斯方块,玩家根据下落的不同方块形状,通过上、下、左、右四个键实现对方块的左右移动、旋转、下落等控制。
游戏中,一共有7种不同的方块形状、每种方块以1/7的概率随机出现,一旦方块到达顶部,游戏结束。
当某一个行布满方块时,改行消除。
基本要求:通过图形界面实现俄罗斯方块游戏;能以图形显示游戏运行的过程;实现相应四个键游戏玩家的控制;记录消除的行数。
扩展要求:在上述功能要求的基础上,为了提高成绩,可以添加一些额外的功能;变量、方法命名符合规范;注释详细:每个变量都要求有注释说明用途;函数有注释说明功能,对参数、返回值也要以注释的形式说明用途;关键的语句段要求有注释解释;程序的层次清晰,可读性强。
系统功能要求:(1)界面设定玩家可以在界面左侧的游戏区中堆积方块,游戏区上面有“游戏”“帮助”两个选项,界面右侧为游戏得分,玩家在游戏过程中随时可以查看游戏得分。
(2)游戏控制不同的随机图形会从区域上方缓慢落下,通过键盘的左、右、下键可以控制方块以一格为单位左右移动,长按实现快速移动;上键能以90度为单位旋转每一方块;区域中横向格子方块填满,则该行会自动消除并为玩家的得分;当固定的方块推到区域最上方,则游戏结束。
二、需求分析1.需求分析图-1 俄罗斯方块游戏需求分析2.任务及实现方式(1)绘制游戏区域通过绘制地图方块、已经固定的方块和运动中的方块来实现(2)实现键盘对方块的实时控制添加键盘监听者和方块位置移动的函数(3)记录消除行数添加记分函数和Graphics类的drawString函数实现(4)游戏结束添加判断游戏结束函数并给出提示3.预期效果(1)实现俄罗斯方块游戏的动态显示(2)实现键盘对方块各种操作(3)实现消行、记分(4)游戏能够正确结束三、概要设计1.主要功能流程图说明:游戏流程较为复杂,流程图粗略显示部分流程图-2 主要功能流程图2.主要类及类之间的关系的UML图图-3 Class Tetris图-4 Class Tetrisblok图-5 RelationShip 四、源程序代码import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import javax.swing.*;import javax.swing.Timer;public class Tetris extends JFrame {public Tetris() {Tetrisblok a = new Tetrisblok();addKeyListener(a);add(a);}public static void main(String[] args) {Tetris frame = new Tetris();//菜单条JMenuBar menu = new JMenuBar();//添加菜单条frame.setJMenuBar(menu);//菜单JMenu game = new JMenu("游戏");//菜单项JMenuItem newgame = game.add("新游戏");JMenuItem pause = game.add("暂停");JMenuItem goon = game.add("继续");JMenuItem exit = game.add("退出");//菜单JMenu help = new JMenu("帮助");JMenuItem about = help.add("关于");//添加菜单至菜单条menu.add(game);menu.add(help);//对窗口设置//居中frame.setLocationRelativeTo(null);//关闭程序frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//大小frame.setSize(220, 275);//标题frame.setTitle("俄罗斯方块");//可见性frame.setVisible(true);//不可更改大小frame.setResizable(false);}}// 创建俄罗斯方块类class Tetrisblok extends JPanel implements KeyListener {// blockType 代表方块类型// turnState代表方块状态private int blockType;private int turnState;private int score = 0;private int x;private int y;private int i = 0;int j = 0;int flag = 0;// 定义已经放下的方块x=0-11,y=0-21;int[][] map = new int[13][23];// 7种方块类型,每一个方块有4种旋转状态,使用16位数字表示一种旋转状态private final int shapes[][][] = new int[][][] {// i{ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },{ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },{ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },{ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 } },// s{ { 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },{ 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },{ 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },{ 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 } }, // z{ { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },{ 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },{ 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },{ 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 } }, // j{ { 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },{ 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },{ 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },{ 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // o{ { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },{ 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },{ 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },{ 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // l{ { 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },{ 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },{ 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },{ 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // t{ { 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },{ 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },{ 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },{ 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 } } };// 生成新方块的方法public void newblock() {blockType = (int) (Math.random() * 1000) % 7;turnState = (int) (Math.random() * 1000) % 4;x = 4;y = 0;if (gameover(x, y) == 1) {newmap();drawwall();score = 0;JOptionPane.showMessageDialog(null, "GAME OVER");}}// 初始化地图public void newmap() {for (i = 0; i < 12; i++) {for (j = 0; j < 22; j++) {map[i][j] = 0;}}}// 画围墙public void drawwall() {for (i = 0; i < 12; i++) {map[i][21] = 2;}for (j = 0; j < 22; j++) {map[11][j] = 2;map[0][j] = 2;}}// 初始化构造方法Tetrisblok() {newblock();newmap();drawwall();Timer timer = new Timer(1000, new TimerListener());timer.start();}// 旋转的方法public void turn() {int tempturnState = turnState;turnState = (turnState + 1) % 4;if (blow(x, y, blockType, turnState) == 1) {}if (blow(x, y, blockType, turnState) == 0) {turnState = tempturnState;}repaint();}// 左移的方法public void left() {if (blow(x - 1, y, blockType, turnState) == 1) {x = x - 1;};repaint();}// 右移的方法public void right() {if (blow(x + 1, y, blockType, turnState) == 1) {x = x + 1;};repaint();}// 下落的方法public void down() {if (blow(x, y + 1, blockType, turnState) == 1) {y = y + 1;delline();};if (blow(x, y + 1, blockType, turnState) == 0) {add(x, y, blockType, turnState);newblock();delline();};repaint();}// 是否合法的方法(是否碰到墙壁或者其他方块)public int blow(int x, int y, int blockType, int turnState) {for (int a = 0; a < 4; a++) {for (int b = 0; b < 4; b++) {if (((shapes[blockType][turnState][a * 4 + b] == 1) && (map[x+ b + 1][y + a] == 1))|| ((shapes[blockType][turnState][a * 4 + b] == 1) && (map[x+ b + 1][y + a] == 2))) {return 0;}}return 1;}// 消行的方法public void delline() {int c = 0;for (int b = 0; b < 22; b++) {for (int a = 0; a < 12; a++) {if (map[a][b] == 1) {c = c + 1;if (c == 10) {score += 10;for (int d = b; d > 0; d--) {for (int e = 0; e < 11; e++) {map[e][d] = map[e][d - 1];}}}}}c = 0;}}// 判断你挂的方法public int gameover(int x, int y) {if (blow(x, y, blockType, turnState) == 0) {return 1;}return 0;}// 把当前添加mappublic void add(int x, int y, int blockType, int turnState) {int j = 0;for (int a = 0; a < 4; a++) {for (int b = 0; b < 4; b++) {if (map[x + b + 1][y + a] == 0) {map[x + b + 1][y + a] = shapes[blockType][turnState][j];;j++;}}}// 画方块的的方法public void paintComponent(Graphics g) {super.paintComponent(g);// 画当前方块for (j = 0; j < 16; j++) {if (shapes[blockType][turnState][j] == 1) {g.fillRect((j % 4 + x + 1) * 10, (j / 4 + y) * 10, 10, 10);}}// 画已经固定的方块for (j = 0; j < 22; j++) {for (i = 0; i < 12; i++) {if (map[i][j] == 1) {g.fillRect(i * 10, j * 10, 10, 10);}if (map[i][j] == 2) {g.drawRect(i * 10, j * 10, 10, 10);}}}g.drawString("行数=" + score/10, 125, 10);g.drawString("*——*", 125, 50);g.drawString("加油", 125, 70);g.drawString("*——*", 125, 90);}// 键盘监听public void keyPressed(KeyEvent e) {switch (e.getKeyCode()) {case KeyEvent.VK_DOWN:down();break;case KeyEvent.VK_UP:turn();break;case KeyEvent.VK_RIGHT:right();break;case KeyEvent.VK_LEFT:left();break;}}// 无用public void keyReleased(KeyEvent e) {}// 无用public void keyTyped(KeyEvent e) {}// 定时器监听class TimerListener implements ActionListener {public void actionPerformed(ActionEvent e) {repaint();if (blow(x, y + 1, blockType, turnState) == 1) {y = y + 1;delline();};if (blow(x, y + 1, blockType, turnState) == 0) {if (flag == 1) {add(x, y, blockType, turnState);delline();newblock();flag = 0;}flag = 1;};}}}五、测试数据及其分析结果(1)游戏进行中图-6 游戏进行中(2)游戏消行图-7 游戏消行(3)游戏结束图-8 游戏结束(4)自然进行状态图-9 自然下落六、调试中出现的问题(1)方块移动超出了边界为程序添加判断移动是否合法函数(2)如何绘制方块查询资料了解到可以使用Graphics类的方法绘制(3)运行过程中,虽无报错,但在控制台闪烁“Exception in thread ‘AWT-EventQueue-0’ng.Error:Unresolved compilation :The type Tetrisblok must implement the inherited abstract method KeyListener.keyReleased(KeyEvent)”查询资料后添加public void keyReleased(KeyEvent e) 函数和public void keyTyped(KeyEvent e)解决七、课程设计总结对于我们来讲,此次程序设计课程是一个挑战,同时也是一个超越自我的过程。
Java实现俄罗斯⽅块游戏简单版本⽂实例为⼤家分享了Java实现俄罗斯⽅块游戏的具体代码,供⼤家参考,具体内容如下游戏页⾯效果如下:俄罗斯⽅块游戏本⾝的逻辑:俄罗斯⽅块游戏的逻辑是⽐较简单的。
它就类似于堆砌房⼦⼀样,各种各样的⽅地形状是不同的。
但是,俄罗斯⽅块游戏的界⾯被等均的分为若⼲⾏和若⼲列,因此⽅块的本质就是占⽤了多少个单元。
⾸先来考虑⼀下数据的问题。
对于界⾯来说,需要⼀个⼆维的 int 型数组,它保存着那些地⽅应该有着⾊,哪些没有;然后是⽅块本⾝,尽管它们的形状不统⼀,但是它们可以⽤⼀个4X4⽐例的⽅块所包围,因此⽤16个字节就可以把⼀个⽅块的信息保存者,注意:其实⽅块的数据也可以⽤int 数组表⽰,但是涉及到效率问题,⽤位操作⽐⽤普通的算术运算要快⼀点。
接下来思考⼀下动作具体有下⾯⼏点:(1)⽅块的诞⽣。
它的诞⽣是需要⽤随机原理的,另外,它如何初始化的被放置在游戏界⾯的顶部?(2)⽅块是需要⾃动的往下掉的,它在掉的过程中,还需要判断它是否与周围的环境是否发⽣了冲突,能不能继续往下。
(3)⽅块本⾝还可以变形,变形以后的⽅块具有不同的数据,判断的⽅式⼜会不⼀样。
(4)当⽤户⼀直按住s键的时候,⽅块还需要持续往下掉。
然后就是过程,玩家主要操作的地⽅有以下⼏个⽅⾯:(1)左右操作。
需要监听KeyEvent,让⽅块左右移动,直到碰到边界。
(2)变形操作。
也要监听KeyEvent,让⽅块⾃动的变形。
(3)下降操作。
也要监听KeyEvent,让⽅块快速的下降。
⾄于游戏的结束,只有⼀种情况,那就是诞⽣的⽅块出世就与其他⽅块冲突了。
源程序代码如下:注释详细package tetris;import java.awt.BorderLayout;import java.awt.Color;import java.awt.GridLayout;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JTextArea;import javax.swing.JTextField;public class Main extends JFrame implements KeyListener {private JTextArea[][] grids;// 把整个界⾯变为⼀个⽂本区域,整个游戏在⾥⾯进⾏private int data[][]; // 对于每个格⼦的数据,1代表有⽅块,0代表为空⽩区private int[] allRect; // 所有的⽅块类型,⽤16个字节来存储,俄罗斯⽅块图形都是在4*4格⼦⾥private int rect; // 当前游戏下落的⽅块类型;private int x, y; // 当前⽅块的坐标位置,x代表⾏,y代表列private int score = 0; // 记录当前游戏得分情况,每消⼀层得10分private JLabel label; // 显⽰分数的标签private JLabel label1;// 显⽰游戏是否结束private boolean running; // ⽤于判断游戏是否结束/*⽆参构造函数*/public Main() {grids = new JTextArea[26][12];//设置游戏区域⾏和列data = new int[26][12];//开辟data数组空间与游戏区域⾏和列⼀致allRect = new int[] { 0x00cc, 0x8888, 0x000f, 0x0c44, 0x002e, 0x088c, 0x00e8, 0x0c88, 0x00e2, 0x044c, 0x008e,0x08c4, 0x006c, 0x04c8, 0x00c6, 0x08c8, 0x004e, 0x04c4, 0x00e4 };//19种⽅块形状,如0x00cc就是 0000 表⽰⼀个2*2的正⽅形⽅块//0000//1100//1100label = new JLabel("score: 0"); //此标签存放得分情况,初始化为0分label1 = new JLabel("开始游戏"); //此标签为提⽰游戏状态:开始还是结束running = false; //为标志变量,false为游戏结束,true为游戏正在进⾏init(); // 游戏界⾯初始化}/*游戏界⾯初始化函数*/public void init() {JPanel center = new JPanel(); //此⾯板为游戏核⼼区域JPanel right = new JPanel(); //此⾯板为游戏说明区域center.setLayout(new GridLayout(26, 12, 1, 1)); //给游戏核⼼区域划分⾏、列共26⾏,12列for (int i = 0; i < grids.length; i++) {//初始化⾯板for (int j = 0; j < grids[i].length; j++) {grids[i][j] = new JTextArea(20, 20);grids[i][j].setBackground(Color.WHITE);grids[i][j].addKeyListener(this);// 添加键盘监听事件//初始化游戏边界if (j == 0 || j == grids[i].length - 1 || i == grids.length - 1) {grids[i][j].setBackground(Color.PINK);data[i][j] = 1;}grids[i][j].setEditable(false);// ⽂本区域不可编辑center.add(grids[i][j]); //把⽂本区域添加到主⾯板上}}//初始化游戏说明⾯板right.setLayout(new GridLayout(4, 1));right.add(new JLabel(" a : left d : right"));right.add(new JLabel(" s : down w : change"));right.add(label);label1.setForeground(Color.RED);// 设置标签内容为红⾊字体right.add(label1);//把主⾯板和说明⾯板添加到窗体中this.setLayout(new BorderLayout());this.add(center, BorderLayout.CENTER);this.add(right, BorderLayout.EAST);running = true; //初始化running状态为true,表⽰程序运⾏即游戏开始this.setSize(600, 850);// 设置窗体⼤⼩this.setVisible(true);// 窗体可见this.setLocationRelativeTo(null);// 设置窗体居中this.setResizable(false);// 窗体⼤⼩不可改变this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 释放窗体}/*主函数*/public static void main(String[] args) {Main m = new Main(); //创建Main对象,主要⽤于初始化数据m.go();// 开始游戏}/*开始游戏*/public void go() {// 开始游戏while (true) {//游戏开始直到游戏失败才结束,否则⼀直执⾏if (running == false) {//如果游戏失败break;}ranRect();// 绘制下落⽅格形状start();// 开始游戏}label1.setText("游戏结束!");//则游戏结束}/*绘制下落⽅格形状*/public void ranRect() {rect = allRect[(int) (Math.random() * 19)];// 随机⽣成⽅块类型(共7种,19个形状)}/*游戏开始函数*/public void start() {x = 0;y = 5; //初始化下落⽅块的位置for (int i = 0; i < 26; i++) {//共26层,⼀层⼀层下落try {Thread.sleep(1000);//每层延时1秒if (canFall(x, y) == false) {// 如果不可以掉落saveData(x, y);//把此⽅块区域data[][]标志为1,表⽰有数据for (int k = x; k < x + 4; k++) {//循环遍历4层,看是否有哪⼀层都有⽅块的情况,以便消除那⼀⾏⽅格和统计得分 int sum = 0;for (int j = 1; j <= 10; j++) {if (data[k][j] == 1) {sum++;}}if (sum == 10) {//如果k层都有⽅块,则消除k层⽅块removeRow(k);}}for (int j = 1; j <= 10; j++) {//游戏最上⾯的4层不能有⽅块,否则游戏失败 if (data[3][j] == 1) {running = false;break;}}break;}// 如果可以掉落x++;// 层加⼀fall(x, y);// 掉下来⼀层} catch (InterruptedException e) {e.printStackTrace();}}}/*判断正下落的⽅块是否可以下落*/public boolean canFall(int m, int n) {int temp = 0x8000;//表⽰1000 0000 0000 0000for (int i = 0; i < 4; i++) {//循环遍历16个⽅格(4*4)for (int j = 0; j < 4; j++) {if ((temp & rect) != 0) {// 此处有⽅块时if (data[m + 1][n] == 1)// 如果下⼀个地⽅有⽅块,则直接返回falsereturn false;}n++;//列加⼀temp >>= 1;}m++;// 下⼀⾏n = n - 4;// 回到⾸列}return true;//可以掉落返回true}/*把不可下降的⽅块的对应的data存储为1,表⽰此坐标有⽅块*/public void saveData(int m, int n) {int temp = 0x8000;//表⽰1000 0000 0000 0000for (int i = 0; i < 4; i++) {//循环遍历16个⽅格(4*4)for (int j = 0; j < 4; j++) {if ((temp & rect) != 0) {// 此处有⽅块时data[m][n] = 1;//data数组存放为1}n++;//下⼀列temp >>= 1;}m++;// 下⼀⾏n = n - 4;// 回到⾸列}}/*移除row⾏所有⽅块,以上的依次往下降*/public void removeRow(int row) {for (int i = row; i >= 1; i--) {for (int j = 1; j <= 10; j++) {data[i][j] = data[i - 1][j];//}}reflesh();// 刷新移除row⾏⽅块后的游戏主⾯板区域score += 10;// 分数加10;label.setText("score: " + score);//显⽰得分}/* 刷新移除row⾏⽅块后的游戏主⾯板区域*/public void reflesh() {for (int i = 1; i < 25; i++) {for (int j = 1; j < 11; j++) {if (data[i][j] == 1) {//有⽅块的地⽅把⽅块设置为绿⾊grids[i][j].setBackground(Color.GREEN);} else {//⽆⽅块的地⽅把⽅块设置为⽩⾊grids[i][j].setBackground(Color.WHITE);}}}}/*⽅块掉落⼀层*/public void fall(int m, int n) {if (m > 0)// ⽅块下落⼀层时clear(m - 1, n);// 清除上⼀层有颜⾊的⽅块draw(m, n);// 重新绘制⽅块图像}/*清除⽅块掉落之前有颜⾊的地⽅*/public void clear(int m, int n) {int temp = 0x8000;//表⽰1000 0000 0000 0000for (int i = 0; i < 4; i++) {//循环遍历16个⽅格(4*4)for (int j = 0; j < 4; j++) {if ((temp & rect) != 0) {// 此处有⽅块时grids[m][n].setBackground(Color.WHITE);//清除颜⾊,变为⽩⾊ }n++;//下⼀列temp >>= 1;}m++;//下⼀⾏n = n - 4;//回到⾸列}}/*绘制掉落后⽅块图像*/public void draw(int m, int n) {int temp = 0x8000;//表⽰1000 0000 0000 0000for (int i = 0; i < 4; i++) {//循环遍历16个⽅格(4*4)for (int j = 0; j < 4; j++) {if ((temp & rect) != 0) {// 此处有⽅块时grids[m][n].setBackground(Color.GREEN);//有⽅块的地⽅变为绿⾊ }n++;//下⼀列temp >>= 1;}m++;//下⼀⾏n = n - 4;//回到⾸列}}@Overridepublic void keyPressed(KeyEvent e) {}@Overridepublic void keyReleased(KeyEvent e) {}@Overridepublic void keyTyped(KeyEvent e) {if (e.getKeyChar() == 'a') {// ⽅格进⾏左移if (running == false) {return;}if (y <= 1)//碰到左边墙壁时return;int temp = 0x8000;//表⽰1000 0000 0000 0000for (int i = x; i < x + 4; i++) {//循环遍历16个⽅格(4*4)for (int j = y; j < y + 4; j++) {if ((rect & temp) != 0) {// 此处有⽅块时if (data[i][j - 1] == 1) {//如果左移⼀格有⽅块时return;}}temp >>= 1;}}clear(x, y);//可以进⾏左移操作时,清除左移前⽅块颜⾊y--;draw(x, y);//然后重新绘制左移后⽅块的图像}if (e.getKeyChar() == 'd') {//⽅块进⾏右移操作if (running == false) {return;}int temp = 0x8000;int m = x, n = y;int num = 7;for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {if ((temp & rect) != 0) {if (n > num) {num = n;}}temp >>= 1;n++;}m++;n = n - 4;}if (num >= 10) {return;}temp = 0x8000;for (int i = x; i < x + 4; i++) {for (int j = y; j < y + 4; j++) {if ((rect & temp) != 0) {if (data[i][j + 1] == 1) {return;}}temp >>= 1;}}clear(x, y);//可以进⾏右移操作时,清除右移前⽅块颜⾊y++;draw(x, y);//然后重新绘制右移后⽅块的图像}if (e.getKeyChar() == 's') {//⽅块进⾏下移操作if (running == false) {return;}if (canFall(x, y) == false) {saveData(x, y);return;}clear(x, y);//可以进⾏下移操作时,清除下移前⽅块颜⾊x++;draw(x, y);//然后重新绘制下移后⽅块的图像}if (e.getKeyChar() == 'w') {//改变⽅块形状if (running == false) {return;}int i = 0;for (i = 0; i < allRect.length; i++) {//循环遍历19个⽅块形状if (allRect[i] == rect)//找到下落的⽅块对应的形状,然后进⾏形状改变 break;}if (i == 0)//为正⽅形⽅块⽆需形状改变,为⽅块图形种类1return;clear(x, y);if (i == 1 || i == 2) {//为⽅块图形种类2rect = allRect[i == 1 ? 2 : 1];if (y > 7)y = 7;}if (i >= 3 && i <= 6) {//为⽅块图形种类3rect = allRect[i + 1 > 6 ? 3 : i + 1];}if (i >= 7 && i <= 10) {//为⽅块图形种类4rect = allRect[i + 1 > 10 ? 7 : i + 1];}if (i == 11 || i == 12) {//为⽅块图形种类5rect = allRect[i == 11 ? 12 : 11];}if (i == 13 || i == 14) {//为⽅块图形种类6rect = allRect[i == 13 ? 14 : 13];}if (i >= 15 && i <= 18) {//为⽅块图形种类7rect = allRect[i + 1 > 18 ? 15 : i + 1];}draw(x, y);}}}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
浅析Java 语言在俄罗斯方块游戏中的实现作者:王立友来源:《发明与创新(职业教育)》 2019年第7期王立友(淮南联合大学,安徽淮南232001)摘要:《俄罗斯方块》作为一款益智类小游戏,一度风靡全球。
游戏操作简单灵活,趣味性强。
本文阐述了利用Java语言实现俄罗斯方块游戏的整个流程。
通过对游戏过程的分析,阐述《俄罗斯方块》实现过程中的架构设计和技术难点。
关键词:俄罗斯方块游戏;Java俄罗斯方块名字的来由源自于希腊语,含义为4,因为游戏中所有方块的设计均为四个方块的组合。
俄罗斯方块游戏是一款经久不衰的益智类小游戏[1],游戏规则简单明了,趣味性强。
对于 Java 编程爱好者而言,是一个不错的训练项目,难度适中,在游戏的开发设计过程中,不仅可以检验Java编程知识的综合运用,提升开发技能,同时还可以激发开发者的学习兴趣。
一、俄罗斯方块游戏总体设计(一)游戏功能模块系统构成游戏主要包括3个功能模块:方块控制功能、方块预览功能、游戏积分统计功能[2]。
1.方块控制功能:主要通过条件判断,来实现方块在下落的过程中向左移动、向右移动、方块旋转、方块触边、方块触块、方块触底及满行消除功能。
2.方块预览功能:当游戏界面出现一个游戏方块时,游戏方块预览区域中将随机生成下一个游戏方块,便于游戏玩家判断方块堆叠的走势,更好地布局方块的具体下落位置。
3.游戏积分统计功能:每消除一行得100分,如果一次消除两行则可以得100+200即300分,以此类推,当游戏分数累积到一定程度,系统游戏难度会增加,共有5个难度等级,难度系数1级最简单,5级最难。
当游戏失败时,记录当前分数与历史最高分相比较,如果超过历史最高分,则将当前分数记作历史最高分,并返回游戏初始界面。
(二)游戏运行流程游戏开始时,在控制面板顶部随机生成方块,方块自由下落,判断下落中是否到达顶部,如果到达顶部则表示游戏结束,否则判断是否到底或者是否碰到障碍物,如果没有碰到障碍物,方块继续下落,如果碰到障碍物,则停止下落,判断是否有满行,满行就消除并累加分数。
一、程序功能介绍本程序实现了俄罗斯方块游戏的基本功能,游戏中玩家可以做的操作有:1.中间一个方块不变其他三个以90度为单位向右旋转方每一格块,此程序会判断方块有没有空间让他实现旋转,即判断是否越界,若越界则不可以实现旋转。
2.以格子为单位左右移动方块,下方向让方块加速落下,空格键则急速下落。
3.方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的随机图形会出现在区域上方开始落下。
4.当区域中某一列横向格子全部由方块填满,则该列会自动消除并成为玩家的得分。
同时删除的列数越多,得分指数上升。
5.当固定的方块堆到区域最上方,则游戏结束。
(此功能尚未实现)6.此程序还不完善,开始,暂停,重来,结束都没有实现,有待改进。
二、课程设计过程1、总体概述:设计一个简单的游戏,能够将Java的面向对象程序思想应用到课程设计中,用到Java 中常用的组件以及相应的布局方式。
完成设计、编程、测试等过程,给出设计思路、设计说明书、主要的代码的说明、源代码以及可运行的游戏程序。
2、各个子类的定义:1.定义俄罗斯方块类,通过可视化界面设定一个游戏界面窗口,用一个10*20表示游戏区域。
public class TetrisGame extends JPanelJFrame jf=new JFrame("俄罗斯方块");jf.setSize(540,600);jf.setVisible(true);public static final int ROWS=20;public static final int COLS=10;2.定义7种俄罗斯方块的基本类型,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。
先定义四方格主类:public class Tetromino;再定义它的7个子类:S、Z、L、J、I、O、Tprivate static class S extends Tetromino;private static class Z extends Tetromino;private static class L extends Tetromino;private static class J extends Tetromino;private static class I extends Tetromino;private static class O extends Tetromino;private static class T extends Tetromino;3.通过switch语句,随机输出方块到游戏区域顶部。
基于Java的俄罗斯⽅块的设计和实现毕业论⽂本科⽣毕业论⽂(设计)基于Java的俄罗斯⽅块的设计与实现姓名学号专业指导教师2013年5⽉30⽇摘要俄罗斯⽅块作为⼀款风靡全球的多样化终端游戏,经久不衰。
俄罗斯⽅块简单的基本游戏规则是旋转、移动,游戏⾃动随机输出7种形状的⽅块,经旋转后可形成28种形状,⽅块堆叠在⼀起,排列成完整的⼀⾏或多⾏消除得分,积分达到⼀定程度会⾃动提升级别。
该游戏上⼿简单、⽼少皆宜、家喻户晓。
本论⽂在详尽分析传统俄罗斯实现的基本原理、基本规则基础上,更深⼀步地研究俄罗斯⽅块的创新模式,在经典模式基础上开发出等级可变的模式,以及进⼀步开发出颜⾊可变的模式,如随意改变界⾯的背景⾊、前景⾊等,本⽂对以上功能给出了实现流程、详尽描述、和部分源代码。
论⽂阐述了该游戏的历史、开发此游戏的意义和环境并根据软件⼯程的相关知识,进⾏系统的需求分析、概要设计、详细设计与实现、调试运⾏进⾏描述。
此设计是在Microsoft Windows XP系统下,以Java为开发语⾔,在MyEclipse开发平台上进⾏游戏的设计与实现。
关键词:游戏;俄罗斯⽅块;错误!未找到引⽤源。
软件⼯程;MyEclipse错误!未找到引⽤源。
AbstractTetris is a popular global diversification of terminal enduring game.Simple basic rules of the game is rotating, moving, automatic random output of 7 kinds of shape square game. It forms 28 kinds of shape, after rotating cube stacked together, forming complete one or more lines to eliminate score. Its level automatically rises with the score. The game is easy for young and old, has become a household name.This paper not only give the detailed analysis of the traditional Tetris which based on the basic principle and simple rules but also develop the color variable model, such as random change the background color and foreground color and so on. Further more, in this paper, the above functions are given the implementation process, the detailed description, and some source code.The paper expounds the history of the game, develops the meaning of the game and the environment of design. According to the relevant knowledge of software engineering, the author reports the demand analysis, outline design, detailed design, planning and execution of the test. This design is under Microsoft Windows XP system, based on Java development language, the MyEclipse development platforms to carry on the design and implementation of the game.Key Words: Game, Tetris, Software engineering, MyEclipse⽬录1 引⾔ (1)2 系统的需求分析 (2)2.1系统需求 (2)2.2接⼝控制 (3)3 系统的概要设计 (4)3.1软件运⾏和开发⼯具 (4)3.2系统功能设计 (4)3.2.1 ⼿⼯处理业务的基本流程 (4)3.2.2 基本流程的功能模块 (5)4 系统的详细设计与实现 (8)4.1游戏主界⾯显⽰模块 (8)4.2画布、⽅块显⽰模块 (9)4.2.1 背景画布模块设计 (10)4.2.2 预览⽅块模块设计 (11)4.2.3 ⽅块移动、旋转设计 (14)4.3控制⾯板模块 (18)4.3.1 菜单栏模块设计 (18)4.3.2 控制⾯板按钮设计 (20)5 系统的调试运⾏ (21)5.1测试的意义及注意事项 (21)5.2游戏代码、算法的测试 (21)5.3游戏界⾯菜单选项的功能测试 (22)5.4按键事件的功能测试 (24)5.5⽅块堆砌与消⾏测试 (25)5.6测试结果分析 (26)6 结论 (27)参考⽂献 (28)致谢 (29)1 引⾔俄罗斯⽅块的影响已⽏庸置疑, 当今世界的电脑、⼿机到处都有俄罗斯⽅块的踪迹,同时它更是每个游戏平台的必备游戏,相关的复制品不胜枚举。
俄罗斯方块java代码俄罗斯方块是最经典的休闲益智游戏之一,现在很多人都不玩了,这里就来写一篇俄罗斯方块的Java代码。
首先,需要说明的是,Java代码中有两个类,一个是主类(Tetris.java),一个是方块类(Block.java)。
主类包含的功能是:显示游戏画面、游戏的主逻辑、处理键盘事件、以及控制游戏暂停、游戏结束等;方块类包含的功能是:初始化方块颜色、坐标、方向等,旋转方块。
那么我们来分析一下主类(Tetris.java)的代码。
首先是一些变量的定义:游戏区域的宽度和高度static final int Width = 10;static final int Height = 22;方块的颜色static Color blocksColor[] = {new Color(255, 255, 255), new Color(204, 102, 102),new Color(102, 204, 102), new Color(102, 102, 204),new Color(204, 204, 102), new Color(204, 102, 204),new Color(102, 204, 204), new Color(218, 170, 0) };游戏区域static int[][] wall = new int[Width][Height];当前方块static Block curBlock;下一个方块static Block nextBlock;游戏是否结束static boolean isOver;线程static MyThread t;接下来是一些初始化操作:初始化主窗体public Tetris() {initFrame();initUI();initGame();}初始化游戏界面private void initUI() {设置游戏面板和游戏区域pnlGame = new JPanel();pnlGame.setPreferredSize(new Dimension(blockSize * Width, blockSize * Height));pnlGame.setBorder(BorderFactory.createLineBorder(Color.gray));gameArea = new GameArea();pnlGame.add(gameArea);设置下一个方块显示面板和下一个方块区域pnlNextBlock = new JPanel();pnlNextBlock.setPreferredSize(new Dimension(blockSize * 4, blockSize * 4));pnlNextBlock.setBorder(BorderFactory.createTitledBorder("Next Block"));nextBlockArea = new BlockArea();pnlNextBlock.add(nextBlockArea);将游戏界面和下一个方块界面加入主窗体frmMain.getContentPane().add(pnlGame, BorderLayout.WEST);frmMain.getContentPane().add(pnlNextBlock, BorderLayout.EAST);显示窗体frmMain.pack();frmMain.setVisible(true);}初始化游戏private void initGame() {初始化积分、速度score = 0;speed = 1;初始化游戏区域for (int i = 0; i < Width; i++) {for (int j = 0; j < Height; j++) {wall[i][j] = 0;}}旋转T型方块,初始朝向为横向curBlock = new Block(1, 0);生成下一块方块nextBlock = new Block(0, 0);}我们可以看到,主类(Tetris.java)包含以下方法:1. initFrame()方法,用来初始化主窗体。
一、作品题目《趣味俄罗斯》二、实现功能1.键盘控制方块运动2.方块显示和隐藏3.碰撞检测4.分数的统计三、程序创新点及特点(突然自己的创新)1.色彩温和的搭配2.简单易懂的操作步骤3. 用了很多定义构造函数来节约代码四、设计思路(自己设计的过程)1.第一步就是认清自己需要做什么2.先定义方块的图形,和出现的方式(随机生成)3.设计游戏所会触发的所有事件(触碰边界,底部相同消除,按键盘↑→←→键产生的效果等)五、程序结构(文件名,方法等各部分完成什么功能)//创建图形的形状var over=false,shapes=("0,1,1,1,2,1,3,1; 1,0,1,1,1,2,2,2; 2,0,2,1,2,2,1,2; 0,1,1,1,1,2,2,2; 1,2,2,2,2,1,3,1;1,1,2,1,1,2,2,2;0,2,1,2,1,1,2,2").split(";");//创建图形的组合和属性function create(tag,css){var elm=document.createElement(tag);elm.className = css;document.body.appendChild(elm);return elm;}//定义下落的图形的事件function Tetris(appear, t, x, y){appear=appear?appear:"appear";//用div来创建一些小方块this.divs =[create("div",appear),create("div",appear),create("div",appear), create("div",appear)];this.reset = function(){//图形下落的初始位置this.x = typeof x != 'undefined'?x:4;this.y = typeof y != 'undefined'?y:1;//随机生成下落的图形this.shape =t?t:shapes[Math.floor(Math.random()*(shapes.length-0.00001) )].split(",");//this.show();if(this.field&&this.field.check(this.shape,this.x,this.y,'v')=='D'){over=true;this.field.fixShape(this.shape,this.x,this.y);alert('游戏结束,你得到:' +document.buzzy.txtScore.value + '分');}}//定义由方块组成的图形this.show = function(){for(var i in this.divs){this.divs[i].style.left =(this.shape[i*2]*1+this.x)*20+'px';this.divs[i].style.top =(this.shape[i*2+1]*1+this.y)*20+'px';}}this.field=null;//键盘方向键←→触发的事件this.hMove = function(step){var r = this.field.check(this.shape,this.x--step,this.y,'h');if(r!='N'&&r==0){this.x-=-step;this.show();}}//键盘方向键↓触发的事件this.vMove = function(){if(this.field.check(this.shape,this.x,this.y--1,'v')=='N'){this.y+=1;this.show();}else{this.field.fixShape(this.shape,this.x,this.y);this.field.findFull();this.reset();}}//键盘方向键↑触发的事件this.rotate = function(){var s=this.shape;varnewShape=[3-s[1],s[0],3-s[3],s[2],3-s[5],s[4],3-s[7],s[6]];var r =this.field.check(newShape,this.x,this.y,'h');if(r=='D')return;if(r==0){this.shape=newShape;this.show();}elseif(this.field.check(newShape,this.x-r,this.y,'h')==0){this.x-=r;this.shape=newShape;this.show();}};this.reset();}//背景的属性function Field(w,h){//底层12个方块可以占满this.width = w?w:12;//总高度为20个方块this.height = h?h:20;//背景的大小this.show = function(){var content = create("div","content")content.style.width=this.width*20+'px';content.style.height=372+'px';}//消除相同的底层的事件this.findFull = function(){for(var l=0;l<this.height;l++){var s=0;for(var i=0;i<this.width;i++){s+=this[l*this.width+i]?1:0;}//如果底层的相同,则消除,且分数增加1if(s==this.width){document.buzzy.txtScore.value = eval(document.buzzy.txtScore.value) + 1;this.removeLine(l);}}}//左右移动的事件this.removeLine = function(line){for(var i=0;i<this.width;i++){document.body.removeChild(this[line*this.width+i]);}for(var l=line;l>0;l--){for(i=0;i<this.width;i++){this[l*this.width- -i]=this[(l-1)*this.width- -i];if(this[l*this.width- -i])this[l*this.width- -i].style.top = l*20+'px';}}} //检查图形是否已经到边界this.check = function(shape, x, y, disappear){var r1=0,r2='N';for(var i=0;i<8;i+=2){if(shape[i]- -x < 0 && shape[i]- -x <r1){r1 = shape[i]- -x;}else if(shape[i]- -x>=this.width && shape[i]- -x>r1){r1 = shape[i]- -x;}if(shape[i+1]- -y>=this.height || this[shape[i]- -x- -(shape[i+1]- -y)*this.width]){r2='D';}}if(disappear=='h'&&r2=='N')return r1>0?r1-this.width- -1:r1;elsereturn r2;}//定义已经不能动的图形的事件this.fixShape = function(shape,x,y){var disappear=new Tetris("disappear",shape,x,y);disappear.show();for(var i=0;i<8;i+=2){this[shape[i]- -x- -(shape[i+1]--y)*this.width]=disappear.divs[i/2];}}}var content = new Field();content.show();var s = new Tetris();s.field = content;s.show();//方块下落速度0.5秒一个单位window.setInterval("if(!over)s.vMove();",500);//键盘触发事件document.onkeydown = function(e){e = window.event ? window.event : e;switch(e.keyCode){case 38: //按键盘↑s.rotate();break;case 40: //按键盘↓s.vMove();break;case 37: //按键盘←s.hMove(-1);break;case 39: //按键盘→s.hMove(1);break;}}六、运行方法和效果图(如果是网站指出首页名)。