shell脚本制作俄罗斯方块游戏
- 格式:doc
- 大小:57.00 KB
- 文档页数:11
俄罗斯方块最简单代码俄罗斯方块游戏一直是老少皆宜的休闲游戏之一,它不仅富有挑战性,而且还能让人们在消磨时间的同时,放松身心,享受游戏的快乐。
在这篇文章中,我们将介绍俄罗斯方块最简单的代码,在这里让大家一窥游戏编程的神秘面纱。
1. 游戏规则俄罗斯方块的游戏规则非常简单,玩家需要通过移动俄罗斯方块的形状,让它们在屏幕底部的平台上堆叠起来。
当一整行方块被填满时,该行将被清除并给玩家带来积分。
如果游戏区域被方块堆满,则游戏结束。
2. 编写代码俄罗斯方块的代码可以使用各种编程语言实现,本文将使用简单易用的Python进行演示。
代码实现需要安装Python的pygame模块,因此您需要先安装它。
以下是代码实现的主要部分:```pythonimport pygame, sysdef run_game():pygame.init()game_width, game_height = 300, 600screen = pygame.display.set_mode((game_width,game_height))pygame.display.set_caption("Tetris")while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()screen.fill((0, 0, 0))# 在这里添加游戏逻辑pygame.display.update()run_game()```以上代码展示了一个空白屏幕,并在屏幕标题中添加了“Tetris”游戏标题。
接下来,我们需要添加游戏逻辑。
3. 添加游戏逻辑在上方的主循环中,我们可以添加游戏逻辑。
为了使游戏逻辑尽可能简单,我们将使用一个简单的方块模型来代表俄罗斯方块。
```pythonclass Block:def __init__(self, color, width, height):self.color = colorself.width = widthself.height = heightdef draw(self, x, y, screen):pygame.draw.rect(screen, self.color, (x, y,self.width, self.height))```以上代码定义了一个Block类,其中包含方块的颜色、宽度和高度信息,并实现了一个draw()方法,用于在屏幕上绘制方块。
简单俄罗斯方块程序代码俄罗斯方块是一款非常经典的游戏,它需要玩家通过操作方块来消除行,随着游戏的深入,难度越来越大。
我们可以用Python语言来编写俄罗斯方块程序,它可以让我们体验到这个经典游戏的乐趣。
首先,我们需要导入相关的模块:```pythonimport pygameimport random```其中,pygame模块可以让我们创建图形化界面,random模块可以用于生成随机数,方便我们随机生成方块。
接下来,我们需要定义一些常量和变量:```python# 定义常量WIDTH = 480HEIGHT = 640CELL_SIZE = 30# 定义变量board = [[0] * 10 for i in range(20)]score = 0ticks = 0fall_speed = 60next_block = random.randint(0, 6)block_pos = (0, 3)current_block = None```这里定义了几个常量:游戏窗口的宽度和高度,单元格的大小。
同时,我们还需要一个二维数组board来表示游戏画面上的格子状态,score来表示当前得分,ticks表示已经落下的方块数量,fall_speed表示方块下落的速度,next_block表示下一个方块的类型,block_pos表示当前方块的位置,current_block则表示当前正在下落的方块。
接下来,我们需要定义一些函数来实现游戏的各种功能。
首先是绘制游戏画面的函数:```pythondef draw_game():screen.fill((0, 0, 0))# 绘制已经落下的方块for i in range(20):for j in range(10):if board[i][j] != 0:pygame.draw.rect(screen, (255, 255, 255),(j * CELL_SIZE, i * CELL_SIZE, CELL_SIZE, CELL_SIZE))# 绘制正在下落的方块if current_block:for i in range(4):for j in range(4):if current_block[i][j] != 0:pygame.draw.rect(screen, (255, 255, 255),((block_pos[1] + j) * CELL_SIZE, (block_pos[0] + i) * CELL_SIZE, CELL_SIZE, CELL_SIZE))# 绘制下一个方块draw_next_block()# 绘制得分font = pygame.font.SysFont('SimHei', 20)text = font.render('得分:%d' % score, True, (255, 255, 255))screen.blit(text, (10, 10))pygame.display.flip()```这个函数会首先清空画面,然后遍历board数组,绘制已经落下的方块。
//不多说,直接可以拷贝下面的东西,就可以运行。
package day04;import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.applet.*;import ng.String.*;import ng.*;import java.io.*;public class ERSBlock extends JPanel implements ActionListener,KeyListener//应该是继承JPanel{static Button but[] = new Button[6];static Button noStop = new Button("取消暂停"); static Label scoreLab = new Label("分数:");static Label infoLab = new Label("提示:");static Label speedLab = new Label("级数:");static Label scoreTex = new Label("0");static Label infoTex = new Label(" ");static Label speedTex = new Label("1");static JFrame jf = new JFrame();static MyTimer timer;static ImageIcon icon=new ImageIcon("resource/Block.jpg");static JMenuBar mb = new JMenuBar();static JMenu menu0 = new JMenu("游戏 ");static JMenu menu1 = new JMenu("帮助 ");static JMenuItem mi0 = new JMenuItem("新游戏"); static JMenuItem mi1 = new JMenuItem("退出");static JMenuItem mi1_0 = new JMenuItem("关于"); static JDialog dlg_1;static JTextArea dlg_1_text = new JTextArea(); static int startSign= 0;//游戏开始标志 0 未开始 1 开始 2 暂停static String butLab[] = {"开始游戏","重新开始","降低级数","提高级数","游戏暂停","退出游戏"};static int game_body[][] = new int[19][10];static int game_sign_x[] = new int[4];//用于记录4个方格的水平位置static int game_sign_y[] = new int[4];//用于记录4个方格的垂直位置static boolean downSign = false;//是否落下static int blockNumber = 1;//砖块的编号static int gameScore = 0;//游戏分数static int speedMark = 1;public static void main(String args[]) {ERSBlock myBlock = new ERSBlock();mb.add(menu0);mb.add(menu1);menu0.add(mi0);menu0.add(mi1);menu1.add(mi1_0);jf.setJMenuBar(mb);myBlock.init();jf.add(myBlock);jf.setSize(565,501);jf.setResizable(false);jf.setTitle("俄罗斯方块");jf.setIconImage(icon.getImage());jf.setLocation(200,100);jf.show();timer = new MyTimer(myBlock); //启动线程timer.setDaemon(true);timer.start();timer.suspend();}public void init(){setLayout(null);for(int i = 0;i < 6;i++){but[i] = new Button(butLab[i]);add(but[i]);but[i].addActionListener(this);but[i].addKeyListener(this);but[i].setBounds(360,(240 + 30 * i),160,25); }add(scoreLab);add(scoreTex);add(speedLab);add(speedTex);add(infoLab);add(infoTex);add(scoreLab);scoreLab.setBounds(320,15,30,20); scoreTex.setBounds(360,15,160,20); scoreTex.setBackground(Color.white); speedLab.setBounds(320,45,30,20); speedTex.setBounds(360,45,160,20); speedTex.setBackground(Color.white);but[1].setEnabled(false);but[4].setEnabled(false);infoLab.setBounds(320,75,30,20); infoTex.setBounds(360,75,160,20); infoTex.setBackground(Color.white); noStop.setBounds(360,360,160,25); noStop.addActionListener(this); noStop.addKeyListener(this);mi0.addActionListener(this);mi1.addActionListener(this);mi1_0.addActionListener(this);num_csh_game();rand_block();}public void actionPerformed(ActionEvent e){if(e.getSource() == but[0])//开始游戏{startSign = 1;infoTex.setText("游戏已经开始!");but[0].setEnabled(false);but[1].setEnabled(true);but[4].setEnabled(true);timer.resume();}if(e.getSource() == but[1]||e.getSource() == mi0)//重新开始游戏{startSign = 0;gameScore = 0;timer.suspend();num_csh_restart();repaint();rand_block();scoreTex.setText("0");infoTex.setText("新游戏!");but[0].setEnabled(true);but[1].setEnabled(false);but[4].setEnabled(false);}if(e.getSource() == but[2])//降低级数 {infoTex.setText("降低级数!"); speedMark--;if(speedMark <= 1){speedMark = 1;infoTex.setText("已经是最低级数!"); }speedTex.setText(speedMark + ""); }if(e.getSource() == but[3])//提高级数 {infoTex.setText("提高级数!");speedMark++;if(speedMark >= 9){speedMark = 9;infoTex.setText("已经是最高级数!"); }speedTex.setText(speedMark + ""); }if(e.getSource() == but[4])//游戏暂停 {this.add(noStop);this.remove(but[4]);infoTex.setText("游戏暂停!"); timer.suspend();}if(e.getSource() == noStop)//取消暂停 {this.remove(noStop);this.add(but[4]);infoTex.setText("继续游戏!"); timer.resume();}if(e.getSource() == but[5]||e.getSource() == mi1)//退出游戏{jf.dispose();}if(e.getSource() == mi1_0)//退出游戏{dlg_1 = new JDialog(jf,"关于");try{FileInputStream io = new FileInputStream("resource/guanyu.txt");//得到路径byte a[] = new byte[io.available()];io.read(a);io.close();String str = new String(a);dlg_1_text.setText(str);}catch(Exception g){}dlg_1_text.setEditable(false);dlg_1.add(dlg_1_text);dlg_1.pack();dlg_1.setResizable(false);dlg_1.setSize(200, 120);dlg_1.setLocation(400, 240);dlg_1.show();}}public void rand_block()//随机产生砖块{int num;num = (int)(Math.random() * 6) + 1;//产生0~6之间的随机数blockNumber = num;switch(blockNumber){case 1: block1(); blockNumber = 1; break;case 2: block2(); blockNumber = 2; break;case 3: block3(); blockNumber = 3; break;case 4: block4(); blockNumber = 4; break;case 5: block5(); blockNumber = 5; break;case 6: block6(); blockNumber = 6; break;case 7: block7(); blockNumber = 7; break;}}public void change_body(int blockNumber)//改变砖块状态{dingwei();if(blockNumber == 1&&downSign == false)//变换长条2种情况{if(game_sign_y[0] == game_sign_y[1]&&game_sign_y[3] <= 16)//说明长条是横着的{if(game_body[game_sign_y[0] - 1][game_sign_x[0] + 1] != 2&&game_body[game_sign_y[3] + 2][game_sign_x[3] - 2] != 2){num_csh_game();game_body[game_sign_y[0] - 1][game_sign_x[0] + 1] = 1;game_body[game_sign_y[1]][game_sign_x[1]] = 1;game_body[game_sign_y[2] + 1][game_sign_x[2] - 1] = 1;game_body[game_sign_y[3] + 2][game_sign_x[3] - 2] = 1;infoTex.setText("游戏进行中!");repaint();}}if(game_sign_x[0] == game_sign_x[1]&&game_sign_x[0] >= 1&&game_sign_x[3] <= 7)//说明长条是竖着的{if(game_body[game_sign_y[0] +1][game_sign_x[0]-1] != 2&&game_body[game_sign_y[3] -2][game_sign_x[3] + 2] != 2){num_csh_game();game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] = 1;game_body[game_sign_y[1]][game_sign_x[1]]=1;game_body[game_sign_y[2] - 1][game_sign_x[2] + 1] = 1;game_body[game_sign_y[3] - 2][game_sign_x[3] + 2] = 1;infoTex.setText("游戏进行中!");repaint();}}}if(blockNumber == 3&&downSign == false)//变换转弯1有4种情况{if(game_sign_x[0] == game_sign_x[1]&&game_sign_x[0] == game_sign_x[2]&&game_sign_y[2] == game_sign_y[3]&&game_sign_x[0] >= 1){if(game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] != 2&&game_body[game_sign_y[2] - 1][game_sign_x[2] + 1] != 2&&game_body[game_sign_y[3] - 2][game_sign_x[3]] != 2){num_csh_game();game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] = 1;game_body[game_sign_y[1]][game_sign_x[1]] = 1;= 1;game_body[game_sign_y[3] - 2][game_sign_x[3]] = 1;infoTex.setText("游戏进行中!");repaint();}}if(game_sign_y[1] == game_sign_y[2]&&game_sign_y[2] == game_sign_y[3]&&game_sign_x[0] == game_sign_x[3]&&game_sign_y[1] <= 17){if(game_body[game_sign_y[0]][game_sign_x[0] - 2] != 2&&game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] - 1] != 2){num_csh_game();game_body[game_sign_y[0]][game_sign_x[0] - 2] = 1;game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] = 1;game_body[game_sign_y[2]][game_sign_x[2]] = 1;= 1;infoTex.setText("游戏进行中!");repaint();}}if(game_sign_x[1] == game_sign_x[2]&&game_sign_x[1] == game_sign_x[3]&&game_sign_y[0] == game_sign_y[1]&&game_sign_x[3] <= 8){if(game_body[game_sign_y[0] + 2][game_sign_x[0]] != 2&&game_body[game_sign_y[1] + 1][game_sign_x[1] - 1] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] != 2){num_csh_game();game_body[game_sign_y[0] + 2][game_sign_x[0]] = 1;game_body[game_sign_y[1] + 1][game_sign_x[1] - 1] = 1;game_body[game_sign_y[2]][game_sign_x[2]] = 1;game_body[game_sign_y[3] - 1][game_sign_x[3] + 1]= 1;infoTex.setText("游戏进行中!");repaint();}}if(game_sign_y[0] == game_sign_y[1]&&game_sign_y[1] == game_sign_y[2]&&game_sign_x[0] == game_sign_x[3]) {if(game_body[game_sign_y[0] + 1][game_sign_x[0] + 1] != 2&&game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] != 2&&game_body[game_sign_y[3]][game_sign_x[3] + 2] != 2){num_csh_game();game_body[game_sign_y[0] + 1][game_sign_x[0] + 1] = 1;game_body[game_sign_y[1]][game_sign_x[1]] = 1;game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] = 1;game_body[game_sign_y[3]][game_sign_x[3] + 2] = 1;infoTex.setText("游戏进行中!");repaint();}}}if(blockNumber == 4&&downSign == false)//变换转弯2有4种情况{if(game_sign_x[0] == game_sign_x[1]&&game_sign_x[0] == game_sign_x[3]&&game_sign_y[1] == game_sign_y[2]&&game_sign_x[3] <= 7){if(game_body[game_sign_y[0] + 2][game_sign_x[0]] != 2&&game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] != 2&&game_body[game_sign_y[3]][game_sign_x[3] + 2] != 2){num_csh_game();game_body[game_sign_y[0] + 2][game_sign_x[0]] = 1;game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] = 1;game_body[game_sign_y[2]][game_sign_x[2]] = 1;game_body[game_sign_y[3]][game_sign_x[3] + 2] = 1;infoTex.setText("游戏进行中!");repaint();}}if(game_sign_y[1] == game_sign_y[2]&&game_sign_y[1] == game_sign_y[3]&&game_sign_x[0] == game_sign_x[2]) {if(game_body[game_sign_y[1]][game_sign_x[1] + 2] != 2&&game_body[game_sign_y[2] - 1][game_sign_x[2] + 1] != 2&&game_body[game_sign_y[3] - 2][game_sign_x[3]] != 2){num_csh_game();game_body[game_sign_y[0]][game_sign_x[0]] = 1;game_body[game_sign_y[1]][game_sign_x[1] + 2] = 1;game_body[game_sign_y[2] - 1][game_sign_x[2] + 1] = 1;game_body[game_sign_y[3] - 2][game_sign_x[3]] = 1;infoTex.setText("游戏进行中!");repaint();}}if(game_sign_x[0] == game_sign_x[2]&&game_sign_x[0] == game_sign_x[3]&&game_sign_y[1] == game_sign_y[2]&&game_sign_x[0] >= 2){if(game_body[game_sign_y[0]][game_sign_x[0] - 2] != 2&&game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] != 2&&game_body[game_sign_y[3] - 2][game_sign_x[3]] != 2){num_csh_game();game_body[game_sign_y[0]][game_sign_x[0] - 2] = 1;game_body[game_sign_y[1]][game_sign_x[1]] = 1;game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] = 1;game_body[game_sign_y[3] - 2][game_sign_x[3]] = 1;infoTex.setText("游戏进行中!");repaint();}}if(game_sign_y[0] == game_sign_y[1]&&game_sign_y[0] == game_sign_y[2]&&game_sign_x[1] == game_sign_x[3]&&game_sign_y[0] <= 16){if(game_body[game_sign_y[0] + 2][game_sign_x[0]] != 2&&game_body[game_sign_y[1] + 1][game_sign_x[1] - 1] != 2&&game_body[game_sign_y[2]][game_sign_x[2] - 2] != 2){num_csh_game();game_body[game_sign_y[0] + 2][game_sign_x[0]] = 1;game_body[game_sign_y[1] + 1][game_sign_x[1] - 1] = 1;game_body[game_sign_y[2]][game_sign_x[2] - 2] = 1;game_body[game_sign_y[3]][game_sign_x[3]] = 1;infoTex.setText("游戏进行中!");repaint();}}}if(blockNumber == 5&&downSign == false)//变换转弯3有4种情况{if(game_sign_x[0] == game_sign_x[2]&&game_sign_x[2] == game_sign_x[3]&&game_sign_y[0] == game_sign_y[1]&&game_sign_x[1] >= 2){if(game_body[game_sign_y[0] + 1][game_sign_x[0] -1] != 2&&game_body[game_sign_y[1]][game_sign_x[1] -2] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] != 2){num_csh_game();game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] = 1;game_body[game_sign_y[1]][game_sign_x[1] - 2] = 1;game_body[game_sign_y[2]][game_sign_x[2]] = 1;game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] = 1;infoTex.setText("游戏进行中!");repaint();}}if(game_sign_y[1] == game_sign_y[2]&&game_sign_y[2] == game_sign_y[3]&&game_sign_x[0] == game_sign_x[1]&&game_sign_y[0] <= 16){if(game_body[game_sign_y[0] + 2][game_sign_x[0]] != 2&&game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] - 1] != 2){num_csh_game();game_body[game_sign_y[0] + 2][game_sign_x[0]] = 1;game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] = 1;game_body[game_sign_y[2]][game_sign_x[2]] = 1;game_body[game_sign_y[3] - 1][game_sign_x[3] - 1] = 1;infoTex.setText("游戏进行中!");repaint();}}if(game_sign_x[0] == game_sign_x[1]&&game_sign_x[1] == game_sign_x[3]&&game_sign_y[2] == game_sign_y[3]) {if(game_body[game_sign_y[0] + 1][game_sign_x[0] -1] != 2&&game_body[game_sign_y[2]][game_sign_x[2] +2] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] != 2){num_csh_game();game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] = 1;game_body[game_sign_y[1]][game_sign_x[1]] = 1;game_body[game_sign_y[2]][game_sign_x[2] + 2] = 1;game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] = 1;infoTex.setText("游戏进行中!");repaint();}}if(game_sign_y[0] == game_sign_y[1]&&game_sign_y[1] == game_sign_y[2]&&game_sign_x[2] == game_sign_x[3]){if(game_body[game_sign_y[0] + 1][game_sign_x[0] + 1] != 2&&game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] != 2&&game_body[game_sign_y[3] - 2][game_sign_x[3]] != 2){num_csh_game();game_body[game_sign_y[0] + 1][game_sign_x[0] + 1] = 1;game_body[game_sign_y[1]][game_sign_x[1]] = 1;game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] = 1;game_body[game_sign_y[3] - 2][game_sign_x[3]] = 1;infoTex.setText("游戏进行中!");repaint();}}}if(blockNumber == 6&&downSign == false)//变换两层砖块1的2种情况{if(game_sign_x[0] == game_sign_x[2]&&game_sign_x[0] >= 2){if(game_body[game_sign_y[0]][game_sign_x[0] - 2] != 2&&game_body[game_sign_y[2] - 1][game_sign_x[2] -1 ] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] != 2){num_csh_game();game_body[game_sign_y[0]][game_sign_x[0] - 2] = 1;game_body[game_sign_y[1]][game_sign_x[1]] = 1;game_body[game_sign_y[2] - 1][game_sign_x[2] - 1] = 1;game_body[game_sign_y[3] - 1][game_sign_x[3] + 1] = 1;infoTex.setText("游戏进行中!");repaint();}}if(game_sign_y[0] == game_sign_y[1]&&game_sign_y[3] <= 17){if(game_body[game_sign_y[0]][game_sign_x[0] + 2] != 2&&game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] != 2&&game_body[game_sign_y[3] + 1][game_sign_x[3] - 1] != 2){num_csh_game();game_body[game_sign_y[0]][game_sign_x[0] + 2] = 1;game_body[game_sign_y[1] + 1][game_sign_x[1] + 1] = 1;game_body[game_sign_y[2]][game_sign_x[2]] = 1;game_body[game_sign_y[3] + 1][game_sign_x[3] - 1] = 1;infoTex.setText("游戏进行中!");repaint();}}}if(blockNumber == 7&&downSign == false)//变换两层砖块2的2种情况{if(game_sign_x[0] == game_sign_x[1]&&game_sign_x[0] <= 16){if(game_body[game_sign_y[0]][game_sign_x[0] + 2] != 2&&game_body[game_sign_y[1] - 1][game_sign_x[1] + 1] != 2&&game_body[game_sign_y[3] - 1][game_sign_x[3] - 1] != 2){num_csh_game();game_body[game_sign_y[0]][game_sign_x[0] + 2] = 1;game_body[game_sign_y[1] - 1][game_sign_x[1] + 1] = 1;game_body[game_sign_y[2]][game_sign_x[2]] = 1;game_body[game_sign_y[3] - 1][game_sign_x[3] - 1] = 1;infoTex.setText("游戏进行中!");repaint();}}if(game_sign_y[0] == game_sign_y[1]&&game_sign_y[2] <= 17)if(game_body[game_sign_y[0] + 1][game_sign_x[0] -1] != 2&&game_body[game_sign_y[1]][game_sign_x[1] -2] != 2&&game_body[game_sign_y[2] + 1][game_sign_x[2] + 1] != 2){num_csh_game();game_body[game_sign_y[0] + 1][game_sign_x[0] - 1] = 1;game_body[game_sign_y[1]][game_sign_x[1] - 2] = 1;game_body[game_sign_y[2] + 1][game_sign_x[2] + 1] = 1;game_body[game_sign_y[3]][game_sign_x[3]] = 1;infoTex.setText("游戏进行中!");repaint();}}}}public void num_csh_game()//数组清零for(int i = 0;i < 19;i++){for(int j = 0;j < 10;j++){if(game_body[i][j] == 2){game_body[i][j] = 2;}else{game_body[i][j] = 0;}}}}public void num_csh_restart()//重新开始时数组清零 {for(int i = 0;i < 19;i++){for(int j = 0;j < 10;j++)game_body[i][j] = 0;}}}public void keyTyped(KeyEvent e){}public void keyPressed(KeyEvent e){if(e.getKeyCode() == KeyEvent.VK_DOWN&&startSign == 1)//处理下键{this.down();}if(e.getKeyCode() == KeyEvent.VK_LEFT&&startSign == 1)//处理左键{this.left();}if(e.getKeyCode() == KeyEvent.VK_RIGHT&&startSign== 1)//处理右键{this.right();}if(e.getKeyCode() == KeyEvent.VK_UP&&startSign== 1)//处理上键转换{this.change_body(blockNumber);}if(startSign == 0){infoTex.setText("游戏未开始或已结束!");}}public void keyReleased(KeyEvent e){}public void paint(Graphics g){g.setColor(Color.black);g.fill3DRect(0,0,300,450,true);for(int i = 0;i < 19;i++){for(int j = 0;j < 10;j++){if(game_body[i][j] == 1){g.setColor(Color.blue);g.fill3DRect(30*j,30*(i-4),30,30,true); }if(game_body[i][j] == 2){g.setColor(Color.magenta);g.fill3DRect(30*j,30*(i-4),30,30,true); }}}}public void left()//向左移动{int sign = 0;dingwei();for(int k = 0;k < 4;k++){if(game_sign_x[k] == 0||game_body[game_sign_y[k]][game_sign_x[k] - 1] == 2){sign = 1;}}if(sign == 0&&downSign == false){num_csh_game();for(int k = 0;k < 4;k++){game_body[game_sign_y[k]][game_sign_x[k] - 1] = 1; }infoTex.setText("向左移动!");repaint();}}public void right()//向右移动{int sign = 0;dingwei();for(int k = 0;k < 4;k++){if(game_sign_x[k] == 9||game_body[game_sign_y[k]][game_sign_x[k] + 1] == 2){sign = 1;}}if(sign == 0&&downSign == false){num_csh_game();for(int k = 0;k < 4;k++){game_body[game_sign_y[k]][game_sign_x[k] + 1] = 1; }infoTex.setText("向右移动!");repaint();}}public void down()//下落{int sign = 0;dingwei();for(int k = 0;k < 4;k++){if(game_sign_y[k] == 18||game_body[game_sign_y[k] + 1][game_sign_x[k]] == 2){sign = 1;downSign = true;changeColor();cancelDW();getScore();if(game_over() == false){rand_block();repaint();}}}if(sign == 0){num_csh_game();for(int k = 0;k < 4;k++){game_body[game_sign_y[k] + 1][game_sign_x[k]] = 1;}infoTex.setText("游戏进行中!");repaint();}}public boolean game_over()//判断游戏是否结束{int sign=0;for(int i = 0;i < 10;i++){if(game_body[4][i] == 2){sign = 1;}}if(sign == 1){infoTex.setText("游戏结束!");changeColor();repaint();startSign = 0;timer.suspend();return true;}elsereturn false;}public void getScore()//满行消除方法{for(int i = 0;i < 19;i++){int sign = 0;for(int j = 0;j < 10;j++){if(game_body[i][j] == 2){sign++;}}if(sign == 10){gameScore += 100;scoreTex.setText(gameScore+"");infoTex.setText("恭喜得分!");for(int j = i;j >= 1;j--){for(int k = 0;k < 10;k++){game_body[j][k] = game_body[j - 1][k];}}}}}public void changeColor()//给已经落下的块换色{downSign = false;for(int k = 0;k < 4;k++){game_body[game_sign_y[k]][game_sign_x[k]] = 2; }}public void dingwei()//确定其位置{int k = 0;cancelDW();for(int i = 0;i < 19;i++){for(int j = 0;j < 10;j++){if(game_body[i][j] == 1){game_sign_x[k] = j;game_sign_y[k] = i;k++;}}}}public void cancelDW()//将定位数组初始化{for(int k = 0;k < 4;k++){game_sign_x[k] = 0;game_sign_y[k] = 0;}}public void block1()//长条{game_body[0][4] = 1;game_body[1][4] = 1;game_body[2][4] = 1;game_body[3][4] = 1;}public void block2()//正方形{game_body[3][4] = 1;game_body[3][5] = 1;game_body[2][5] = 1;}public void block3()//3加1(下) {game_body[1][4] = 1;game_body[2][4] = 1;game_body[3][4] = 1;game_body[3][5] = 1;}public void block4()//3加1(中) {game_body[1][4] = 1;game_body[2][4] = 1;game_body[3][4] = 1;game_body[2][5] = 1;}public void block5()//3加1(上) {game_body[1][4] = 1;game_body[2][4] = 1;game_body[1][5] = 1;}public void block6()//转折1 {game_body[1][5] = 1;game_body[2][5] = 1;game_body[2][4] = 1;game_body[3][4] = 1;}public void block7()//转折2 {game_body[1][4] = 1;game_body[2][4] = 1;game_body[2][5] = 1;game_body[3][5] = 1;}}//定时线程class MyTimer extends Thread {ERSBlock myBlock;public MyTimer(ERSBlock myBlock){this.myBlock = myBlock;}public void run(){while(myBlock.startSign == 1){try{sleep((10-myBlock.speedMark + 1)*100);myBlock.down();}catch(InterruptedException e){}}}}。
python实现简单俄罗斯⽅块游戏本⽂实例为⼤家分享了python实现简单俄罗斯⽅块游戏的具体代码,供⼤家参考,具体内容如下import pygame,sys,random,timeall_block = [[[0,0],[0,-1],[0,1],[0,2]],[[0,0],[0,1],[1,1],[1,0]],[[0,0],[0,-1],[-1,0],[-1,1]],[[0,0],[0,1],[-1,-1],[-1,0]],[[0,0],[0,1],[1,0],[0,-1]],[[0,0],[1,0],[-1,0],[1,-1]],[[0,0],[1,0],[-1,0],[1,1]]]background = [[0 for column in range(0,10)] for row in range(0,22)]background[0] = [1 for column in range(0,10)]select_block = list(random.choice(all_block))block_initial_position = [21,5]times = 0score = [0]gameover = []press = Falsepygame.init()screen = pygame.display.set_mode((250,500))title = pygame.display.set_caption("俄罗斯⽅块")#下落、位置、数组检测、得分、屏幕信息def block_move_down():y_drop=block_initial_position[0]x_move=block_initial_position[1]y_drop-=1for row,column in select_block:row+=y_dropcolumn+=x_moveif background[row][column]==1:breakelse:block_initial_position.clear()block_initial_position.extend([y_drop,x_move])returny_drop,x_move=block_initial_positionfor row,column in select_block:background[y_drop+row][x_move+column]=1complete_row=[]for row in range(1,21):if 0 not in background[row]:complete_row.append(row)complete_row.sort(reverse=True)for row in complete_row:background.pop(row)background.append([0 for column in range(0,10)])score[0]+=len(complete_row)pygame.display.set_caption(str(score[0])+'分')select_block.clear()select_block.extend(list(random.choice(all_block)))block_initial_position.clear()block_initial_position.extend([20,5])y_drop,x_move=block_initial_positionfor row,column in select_block:row+=y_dropcolumn+=x_moveif background[row][column]:gameover.append(1)#⽅块设置、变化、背景改变def new_draw():y_drop,x_move=block_initial_positionfor row,column in select_block:row+=y_dropcolumn+=x_movepygame.draw.rect(screen,(255,165,0),(column*25,500-row*25,23,23))for row in range(0,20):for column in range(0,10):bottom_block=background[row][column]if bottom_block:pygame.draw.rect(screen,(0,0,255),(column*25,500-row*25,23,23)) #⽅块的移动,防⽌出界,碰撞def move_left_right(n):y_drop,x_move=block_initial_positionx_move+=nfor row,column in select_block:row+=y_dropcolumn+=x_moveif column<0 or column>9 or background[row][column]:breakelse:block_initial_position.clear()block_initial_position.extend([y_drop,x_move])#旋转,位置都进⾏变化def rotate():y_drop,x_move=block_initial_positionrotating_position=[(-column,row)for row,column in select_block]for row,column in rotating_position:row+=y_dropcolumn+=x_moveif column<0 or column>9 or background[row][column]:breakelse:select_block.clear()select_block.extend(rotating_position)while True:screen.fill((255,255,255))for event in pygame.event.get():if event.type==pygame.QUIT:sys.exit()elif event.type==pygame.KEYDOWN and event.key==pygame.K_LEFT: move_left_right(-1)elif event.type==pygame.KEYDOWN and event.key==pygame.K_RIGHT: move_left_right(1)elif event.type==pygame.KEYDOWN and event.key==pygame.K_UP:rotate()elif event.type==pygame.KEYDOWN and event.key==pygame.K_DOWN: press=Trueelif event.type==pygame.KEYUP and event.key==pygame.K_DOWN:press=Falseif press:times+=10if times>=50:block_move_down()times=0else:times+=1if gameover:sys.exit()new_draw()pygame.time.Clock().tick(200)pygame.display.flip()效果:以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
俄罗斯方块游戏编程俄罗斯方块是一款非常经典且富有挑战性的游戏,它起源于俄罗斯,现已风靡全球。
这款游戏的编程实现涉及到许多关键的算法和技术,下面将为大家介绍一下俄罗斯方块游戏的编程过程。
一、游戏的整体结构俄罗斯方块游戏的编程可以分为前端和后端两个部分。
前端是指游戏的界面和用户交互逻辑,后端则负责游戏的核心算法和各种游戏逻辑的实现。
在前端部分,需要实现游戏界面的绘制和刷新,包括游戏区域的绘制、方块的绘制和下落效果、得分的实时更新等。
同时,还需要监听玩家的键盘操作,控制方块的移动、旋转和下落。
前端的编程通常使用图形库或者游戏引擎进行实现,比如常用的Python图形库Pygame。
在后端部分,核心算法是方块的下落和碰撞检测。
方块的下落是整个游戏的核心,需要考虑到方块的速度、位置和边界等因素。
碰撞检测是指判断方块是否与其他方块或者游戏区域的边界发生碰撞,如果发生碰撞,则需要停止方块的下落,并进行相关的处理,比如消除已满的行、生成新方块等。
此外,游戏还需要实现游戏开始、暂停、结束等功能,以及相应的状态管理和逻辑判断。
二、方块的表示和操作在俄罗斯方块游戏的编程中,方块是整个游戏的基本组成单元。
方块通常使用二维数组来表示,数组中的每个元素代表方块的一个单元格。
通过对方块数组的操作,可以实现方块的移动、旋转等效果。
方块的移动可以通过改变方块数组中元素的位置来实现。
比如向左移动方块,只需要将方块数组中每个元素的列索引减一;向右移动方块,则将列索引加一。
类似地,对于方块的旋转,可以通过改变方块数组中元素的行列索引来实现。
需要注意的是,在改变方块的位置和形状时,要进行边界检测,以防止方块超出游戏区域或者与其他方块发生重叠。
三、碰撞检测和处理在俄罗斯方块游戏中,碰撞检测是一个非常关键的环节。
碰撞检测的主要目的是判断当前的方块是否与其他方块或者游戏区域的边界发生碰撞,从而决定方块是否需要停止下落,并进行相应的处理。
对于方块与其他方块的碰撞检测,可以通过比较方块数组和游戏区域数组中相应位置的元素来实现。
python实现简单的俄罗斯⽅块本⽂实例为⼤家分享了python实现简单的俄罗斯⽅块的具体代码,供⼤家参考,具体内容如下1. 案例介绍俄罗斯⽅块是由 4 个⼩⽅块组成不同形状的板块,随机从屏幕上⽅落下,按⽅向键调整板块的位置和⽅向,在底部拼出完整的⼀⾏或⼏⾏。
这些完整的横条会消失,给新落下来的板块腾出空间,并获得分数奖励。
没有被消除掉的⽅块不断堆积,⼀旦堆到顶端,便告输,游戏结束。
本例难度为⾼级,适合具有 Python 进阶和 Pygame 编程技巧的⽤户学习。
2. 设计要点边框――由 15*25 个空格组成,⽅块就落在这⾥⾯。
盒⼦――组成⽅块的其中⼩⽅块,是组成⽅块的基本单元。
⽅块――从边框顶掉下的东西,游戏者可以翻转和改变位置。
每个⽅块由 4 个盒⼦组成。
形状――不同类型的⽅块。
这⾥形状的名字被叫做 T, S, Z ,J, L, I , O。
如下图所⽰:模版――⽤⼀个列表存放形状被翻转后的所有可能样式。
全部存放在变量⾥,变量名字如 S or J。
着陆――当⼀个⽅块到达边框的底部或接触到在其他的盒⼦话,就说这个⽅块着陆了。
那样的话,另⼀个⽅块就会开始下落。
3. ⽰例效果4. ⽰例源码import pygameimport randomimport ospygame.init()GRID_WIDTH = 20GRID_NUM_WIDTH = 15GRID_NUM_HEIGHT = 25WIDTH, HEIGHT = GRID_WIDTH * GRID_NUM_WIDTH, GRID_WIDTH * GRID_NUM_HEIGHTSIDE_WIDTH = 200SCREEN_WIDTH = WIDTH + SIDE_WIDTHWHITE = (0xff, 0xff, 0xff)BLACK = (0, 0, 0)LINE_COLOR = (0x33, 0x33, 0x33)CUBE_COLORS = [(0xcc, 0x99, 0x99), (0xff, 0xff, 0x99), (0x66, 0x66, 0x99),(0x99, 0x00, 0x66), (0xff, 0xcc, 0x00), (0xcc, 0x00, 0x33),(0xff, 0x00, 0x33), (0x00, 0x66, 0x99), (0xff, 0xff, 0x33),(0x99, 0x00, 0x33), (0xcc, 0xff, 0x66), (0xff, 0x99, 0x00)]screen = pygame.display.set_mode((SCREEN_WIDTH, HEIGHT))pygame.display.set_caption("俄罗斯⽅块")clock = pygame.time.Clock()FPS = 30score = 0level = 1screen_color_matrix = [[None] * GRID_NUM_WIDTH for i in range(GRID_NUM_HEIGHT)]# 设置游戏的根⽬录为当前⽂件夹base_folder = os.path.dirname(__file__)def show_text(surf, text, size, x, y, color=WHITE):font_name = os.path.join(base_folder, 'font/font.ttc')font = pygame.font.Font(font_name, size)text_surface = font.render(text, True, color)text_rect = text_surface.get_rect()text_rect.midtop = (x, y)surf.blit(text_surface, text_rect)class CubeShape(object):SHAPES = ['I', 'J', 'L', 'O', 'S', 'T', 'Z']I = [[(0, -1), (0, 0), (0, 1), (0, 2)],[(-1, 0), (0, 0), (1, 0), (2, 0)]]J = [[(-2, 0), (-1, 0), (0, 0), (0, -1)],[(-1, 0), (0, 0), (0, 1), (0, 2)],[(0, 1), (0, 0), (1, 0), (2, 0)],[(0, -2), (0, -1), (0, 0), (1, 0)]]L = [[(-2, 0), (-1, 0), (0, 0), (0, 1)],[(1, 0), (0, 0), (0, 1), (0, 2)],[(0, -1), (0, 0), (1, 0), (2, 0)],[(0, -2), (0, -1), (0, 0), (-1, 0)]]O = [[(0, 0), (0, 1), (1, 0), (1, 1)]]S = [[(-1, 0), (0, 0), (0, 1), (1, 1)],[(1, -1), (1, 0), (0, 0), (0, 1)]]T = [[(0, -1), (0, 0), (0, 1), (-1, 0)],[(-1, 0), (0, 0), (1, 0), (0, 1)],[(0, -1), (0, 0), (0, 1), (1, 0)],[(-1, 0), (0, 0), (1, 0), (0, -1)]]Z = [[(0, -1), (0, 0), (1, 0), (1, 1)],[(-1, 0), (0, 0), (0, -1), (1, -1)]]SHAPES_WITH_DIR = {'I': I, 'J': J, 'L': L, 'O': O, 'S': S, 'T': T, 'Z': Z}def __init__(self):self.shape = self.SHAPES[random.randint(0, len(self.SHAPES) - 1)]# ⾻牌所在的⾏列self.center = (2, GRID_NUM_WIDTH // 2)self.dir = random.randint(0, len(self.SHAPES_WITH_DIR[self.shape]) - 1) self.color = CUBE_COLORS[random.randint(0, len(CUBE_COLORS) - 1)] def get_all_gridpos(self, center=None):curr_shape = self.SHAPES_WITH_DIR[self.shape][self.dir]if center is None:center = [self.center[0], self.center[1]]return [(cube[0] + center[0], cube[1] + center[1])for cube in curr_shape]def conflict(self, center):for cube in self.get_all_gridpos(center):# 超出屏幕之外,说明不合法if cube[0] < 0 or cube[1] < 0 or cube[0] >= GRID_NUM_HEIGHT or \ cube[1] >= GRID_NUM_WIDTH:return True# 不为None,说明之前已经有⼩⽅块存在了,也不合法if screen_color_matrix[cube[0]][cube[1]] is not None:return Truereturn Falsedef rotate(self):new_dir = self.dir + 1new_dir %= len(self.SHAPES_WITH_DIR[self.shape])old_dir = self.dirself.dir = new_dirif self.conflict(self.center):self.dir = old_dirreturn Falsedef down(self):# import pdb; pdb.set_trace()center = (self.center[0] + 1, self.center[1])if self.conflict(center):return Falseself.center = centerreturn Truedef left(self):center = (self.center[0], self.center[1] - 1)if self.conflict(center):return Falseself.center = centerreturn Truedef right(self):center = (self.center[0], self.center[1] + 1)if self.conflict(center):return Falseself.center = centerreturn Truedef draw(self):for cube in self.get_all_gridpos():pygame.draw.rect(screen, self.color,(cube[1] * GRID_WIDTH, cube[0] * GRID_WIDTH,GRID_WIDTH, GRID_WIDTH))pygame.draw.rect(screen, WHITE,(cube[1] * GRID_WIDTH, cube[0] * GRID_WIDTH,GRID_WIDTH, GRID_WIDTH),1)def draw_grids():for i in range(GRID_NUM_WIDTH):pygame.draw.line(screen, LINE_COLOR,(i * GRID_WIDTH, 0), (i * GRID_WIDTH, HEIGHT))for i in range(GRID_NUM_HEIGHT):pygame.draw.line(screen, LINE_COLOR,(0, i * GRID_WIDTH), (WIDTH, i * GRID_WIDTH))pygame.draw.line(screen, WHITE,(GRID_WIDTH * GRID_NUM_WIDTH, 0),(GRID_WIDTH * GRID_NUM_WIDTH, GRID_WIDTH * GRID_NUM_HEIGHT)) def draw_matrix():for i, row in zip(range(GRID_NUM_HEIGHT), screen_color_matrix):for j, color in zip(range(GRID_NUM_WIDTH), row):if color is not None:pygame.draw.rect(screen, color,(j * GRID_WIDTH, i * GRID_WIDTH,GRID_WIDTH, GRID_WIDTH))pygame.draw.rect(screen, WHITE,(j * GRID_WIDTH, i * GRID_WIDTH,GRID_WIDTH, GRID_WIDTH), 2)def draw_score():show_text(screen, u'得分:{}'.format(score), 20, WIDTH + SIDE_WIDTH // 2, 100)def remove_full_line():global screen_color_matrixglobal scoreglobal levelnew_matrix = [[None] * GRID_NUM_WIDTH for i in range(GRID_NUM_HEIGHT)]index = GRID_NUM_HEIGHT - 1n_full_line = 0for i in range(GRID_NUM_HEIGHT - 1, -1, -1):is_full = Truefor j in range(GRID_NUM_WIDTH):if screen_color_matrix[i][j] is None:is_full = Falsecontinueif not is_full:new_matrix[index] = screen_color_matrix[i]index -= 1else:n_full_line += 1score += n_full_linelevel = score // 20 + 1screen_color_matrix = new_matrixdef show_welcome(screen):show_text(screen, u'俄罗斯⽅块', 30, WIDTH / 2, HEIGHT / 2)show_text(screen, u'按任意键开始游戏', 20, WIDTH / 2, HEIGHT / 2 + 50)running = Truegameover = Truecounter = 0live_cube = Nonewhile running:clock.tick(FPS)for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseelif event.type == pygame.KEYDOWN:if gameover:gameover = Falselive_cube = CubeShape()breakif event.key == pygame.K_LEFT:live_cube.left()elif event.key == pygame.K_RIGHT:live_cube.right()elif event.key == pygame.K_DOWN:live_cube.down()elif event.key == pygame.K_UP:live_cube.rotate()elif event.key == pygame.K_SPACE:while live_cube.down() == True:passremove_full_line()# level 是为了⽅便游戏的难度,level 越⾼ FPS // level 的值越⼩# 这样屏幕刷新的就越快,难度就越⼤if gameover is False and counter % (FPS // level) == 0:# down 表⽰下移⾻牌,返回False表⽰下移不成功,可能超过了屏幕或者和之前固定的# ⼩⽅块冲突了if live_cube.down() == False:for cube in live_cube.get_all_gridpos():screen_color_matrix[cube[0]][cube[1]] = live_cube.colorlive_cube = CubeShape()if live_cube.conflict(live_cube.center):gameover = Truescore = 0live_cube = Nonescreen_color_matrix = [[None] * GRID_NUM_WIDTH for i in range(GRID_NUM_HEIGHT)] # 消除满⾏remove_full_line()counter += 1# 更新屏幕screen.fill(BLACK)draw_grids()draw_matrix()draw_score()if live_cube is not None:live_cube.draw()if gameover:show_welcome(screen)pygame.display.update()以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
#!/bin/bash#颜色定义cRed=1cGreen=2cYellow=3cBlue=4cFuchsia=5cCyan=6cWhite=7colorTable=($cRed $cGreen $cYellow $cBlue $cFuchsia $cCyan $cWhite)#位置和大小iLeft=3iTop=2((iTrayLeft = iLeft + 2))((iTrayTop = iTop + 1))((iTrayWidth = 10))((iTrayHeight = 15))#颜色设置cBorder=$cGreencScore=$cFuchsiacScoreV alue=$cCyan#控制信号#改游戏使用两个进程,一个用于接收输入,一个用于游戏流程和显示界面; #当前者接收到上下左右等按键时,通过向后者发送signal的方式通知后者。
sigRotate=25sigLeft=26sigRight=27sigDown=28sigAllDown=29sigExit=30#七种不同的方块的定义#通过旋转,每种方块的显示的样式可能有几种box0=(0 0 0 1 1 0 1 1)box1=(0 2 1 2 2 2 3 2 1 0 1 1 1 2 1 3)box2=(0 0 0 1 1 1 1 2 0 1 1 0 1 1 2 0)box3=(0 1 0 2 1 0 1 1 0 0 1 0 1 1 2 1)box4=(0 1 0 2 1 1 2 1 1 0 1 1 1 2 2 2 0 1 1 1 2 0 2 1 0 0 1 0 1 1 1 2)box5=(0 1 1 1 2 1 2 2 1 0 1 1 1 2 2 0 0 0 0 1 1 1 2 1 0 2 1 0 1 1 1 2)box6=(0 1 1 1 1 2 2 1 1 0 1 1 1 2 2 1 0 1 1 0 1 1 2 1 0 1 1 0 1 1 1 2)#所有其中方块的定义都放到box变量中box=(${box0[@]} ${box1[@]} ${box2[@]} ${box3[@]} ${box4[@]} ${box5[@]} ${box6[@]})#各种方块旋转后可能的样式数目countBox=(1 2 2 2 4 4 4)#各种方块再box数组中的偏移offsetBox=(0 1 3 5 7 11 15)#每提高一个速度级需要积累的分数iScoreEachLevel=50 #be greater than 7#运行时数据sig=0 #接收到的signaliScore=0 #总分iLevel=0 #速度级boxNew=() #新下落的方块的位置定义cBoxNew=0 #新下落的方块的颜色iBoxNewType=0 #新下落的方块的种类iBoxNewRotate=0 #新下落的方块的旋转角度boxCur=() #当前方块的位置定义cBoxCur=0 #当前方块的颜色iBoxCurType=0 #当前方块的种类iBoxCurRotate=0 #当前方块的旋转角度boxCurX=-1 #当前方块的x坐标位置boxCurY=-1 #当前方块的y坐标位置iMap=() #背景方块图表#初始化所有背景方块为-1, 表示没有方块for ((i = 0; i < iTrayHeight * iTrayWidth; i++)); do iMap[$i]=-1; done#接收输入的进程的主函数function RunAsKeyReceiver(){local pidDisplayer key aKey sig cESC sTTYpidDisplayer=$1aKey=(0 0 0)cESC=`echo -ne "\33"`cSpace=`echo -ne "\40"`#保存终端属性。
前言:喵~你们相信按键精灵除了能做游戏辅助脚本外,还能做一个游戏玩玩吗?这是真的吗?小猫告诉你,是真的,编程是无所不能的,只要你敢想,就能实现!!!游戏下载地址:喵~用按键精灵做的<俄罗斯方块>游戏~[更新至1.11.0701]技术:1.多线程2.窗口句柄工具:按键精灵8361的窗口插件mp9999ddd的多线程互斥锁插件俄罗斯方块百度感谢以上两位高人提供的插件喵。
游戏背景图片:思路:要写一个游戏,必须要对游戏有一定的了解,而不是简简单单的知道怎么玩。
现在小猫要写的是俄罗斯方块,那么小猫需要知道以下几个数据:“游戏的边框长短,各个方块的具体形状,每次变形后的形状,得分的算法,游戏的规则。
”那怎么获得这些数据呢?对,活用百度谷歌,具体内容看上面的俄罗斯方块百科,已经写的很清楚了,游戏是10x20大小的,方块有S、Z、L、J、I、O、T这7种形状,得分的大致算法。
OK,游戏的一些大致数据已经收集好了,现在要利用这些数据了。
小猫刚开始的时候,是想用91的写屏插件,通过清屏和写屏两种功能完成游戏的,后来才发现,这个思路的代码和算法太复杂,于是果断放弃,转为使用361的窗口插件,通过创建一个游戏背景区域和多个方块(按钮),然后使用移动窗口和关闭窗口实现方块的移动和消除,而判断方法则是采用判断上下左右句柄得到。
正文:首先,我们要创建一个游戏区域,游戏原本是边框10x20,方块1x1的,我们将其放大30倍,即变为边框300x600,方块30x30,我们还要计算好游戏区域的左上角坐标,在这里,小猫电脑分辨率是1280x800的,小猫为了游戏区域在屏幕中间,故设置游戏区域的左上角坐标为489,99。
接着,大家注意找下361窗口插件中的“CreateCustomRgn 创建不规则区域”功能,简单的说,这个就是放置一张图片大小的窗口,只不过他会将指定颜色挖空。
在这里,我们使用上面那张300x600的背景图片,创建这个游戏区域即可。
#!/bin/bash# Tetris Game# 10.21.2003 xhchen<[email]xhchen@[/email]>#APP declarationAPP_NAME="${0##*[\\/]}"APP_VERSION="1.0"#颜色定义cRed=1cGreen=2cYellow=3cBlue=4cFuchsia=5cCyan=6cWhite=7colorTable=($cRed $cGreen $cYellow $cBlue $cFuchsia $cCyan $cWhite)#位置和大小iLeft=3iTop=2((iTrayLeft = iLeft + 2))((iTrayTop = iTop + 1))((iTrayWidth = 10))((iTrayHeight = 15))#颜色设置cBorder=$cGreencScore=$cFuchsiacScoreValue=$cCyan#控制信号#改游戏使用两个进程,一个用于接收输入,一个用于游戏流程和显示界面;#当前者接收到上下左右等按键时,通过向后者发送signal的方式通知后者。
sigRotate=25sigLeft=26sigRight=27sigDown=28sigAllDown=29sigExit=30#七中不同的方块的定义#通过旋转,每种方块的显示的样式可能有几种box0=(0 0 0 1 1 0 1 1)box1=(0 2 1 2 2 2 3 2 1 0 1 1 1 2 1 3)box2=(0 0 0 1 1 1 1 2 0 1 1 0 1 1 2 0)box3=(0 1 0 2 1 0 1 1 0 0 1 0 1 1 2 1)box4=(0 1 0 2 1 1 2 1 1 0 1 1 1 2 2 2 0 1 1 1 2 0 2 1 0 0 1 0 1 1 1 2) box5=(0 1 1 1 2 1 2 2 1 0 1 1 1 2 2 0 0 0 0 1 1 1 2 1 0 2 1 0 1 1 1 2) box6=(0 1 1 1 1 2 2 1 1 0 1 1 1 2 2 1 0 1 1 0 1 1 2 1 0 1 1 0 1 1 1 2) #所有其中方块的定义都放到box变量中box=(${box0[@]} ${box1[@]} ${box2[@]} ${box3[@]} ${box4[@]} ${box5[@]} ${box6[@]})#各种方块旋转后可能的样式数目countBox=(1 2 2 2 4 4 4)#各种方块再box数组中的偏移offsetBox=(0 1 3 5 7 11 15)#每提高一个速度级需要积累的分数iScoreEachLevel=50 #be greater than 7#运行时数据sig=0 #接收到的signaliScore=0 #总分iLevel=0 #速度级boxNew=() #新下落的方块的位置定义cBoxNew=0 #新下落的方块的颜色iBoxNewType=0 #新下落的方块的种类iBoxNewRotate=0 #新下落的方块的旋转角度boxCur=() #当前方块的位置定义cBoxCur=0 #当前方块的颜色iBoxCurType=0 #当前方块的种类iBoxCurRotate=0 #当前方块的旋转角度boxCurX=-1 #当前方块的x坐标位置boxCurY=-1 #当前方块的y坐标位置iMap=() #背景方块图表#初始化所有背景方块为-1, 表示没有方块for ((i = 0; i < iTrayHeight * iTrayWidth; i++)); do iMap[$i]=-1; done#接收输入的进程的主函数function RunAsKeyReceiver(){local pidDisplayer key aKey sig cESC sTTYpidDisplayer=$1aKey=(0 0 0)cESC=`echo -ne "\033"`cSpace=`echo -ne "\040"`#保存终端属性。
在read -s读取终端键时,终端的属性会被暂时改变。
#如果在read -s时程序被不幸杀掉,可能会导致终端混乱,#需要在程序退出时恢复终端属性。
sTTY=`stty -g`#捕捉退出信号trap "MyExit;" INT TERMtrap "MyExitNoSub;" $sigExit#隐藏光标echo -ne "\033[?25l"while :do#读取输入。
注-s不回显,-n读到一个字符立即返回read -s -n 1 keyaKey[0]=${aKey[1]}aKey[1]=${aKey[2]}aKey[2]=$keysig=0#判断输入了何种键if [[ $key == $cESC && ${aKey[1]} == $cESC ]]then#ESC键MyExitelif [[ ${aKey[0]} == $cESC && ${aKey[1]} == "[" ]]thenif [[ $key == "A" ]]; then sig=$sigRotate #<向上键> elif [[ $key == "B" ]]; then sig=$sigDown #<向下键>elif [[ $key == "D" ]]; then sig=$sigLeft #<向左键> elif [[ $key == "C" ]]; then sig=$sigRight #<向右键>fielif [[ $key == "W" || $key == "w" ]]; then sig=$sigRotate #W, welif [[ $key == "S" || $key == "s" ]]; then sig=$sigDown #S, selif [[ $key == "A" || $key == "a" ]]; then sig=$sigLeft #A, aelif [[ $key == "D" || $key == "d" ]]; then sig=$sigRight #D, delif [[ "[$key]" == "[]" ]]; then sig=$sigAllDown #空格键 elif [[ $key == "Q" || $key == "q" ]] #Q, q thenMyExitfiif [[ $sig != 0 ]]then#向另一进程发送消息kill -$sig $pidDisplayerfidone}#退出前的恢复function MyExitNoSub(){local y#恢复终端属性stty $sTTY((y = iTop + iTrayHeight + 4))#显示光标echo -e "\033[?25h\033[${y};0H"exit}function MyExit(){#通知显示进程需要退出kill -$sigExit $pidDisplayerMyExitNoSub}#处理显示和游戏流程的主函数function RunAsDisplayer(){local sigThisInitDraw#挂载各种信号的处理函数trap "sig=$sigRotate;" $sigRotatetrap "sig=$sigLeft;" $sigLefttrap "sig=$sigRight;" $sigRighttrap "sig=$sigDown;" $sigDowntrap "sig=$sigAllDown;" $sigAllDowntrap "ShowExit;" $sigExitwhile :do#根据当前的速度级iLevel不同,设定相应的循环的次数for ((i = 0; i < 21 - iLevel; i++))dosleep 0.02sigThis=$sigsig=0#根据sig变量判断是否接受到相应的信号if ((sigThis == sigRotate)); then BoxRotate; #旋转 elif ((sigThis == sigLeft)); then BoxLeft; #左移一列elif ((sigThis == sigRight)); then BoxRight; #右移一列elif ((sigThis == sigDown)); then BoxDown; #下落一行elif ((sigThis == sigAllDown)); then BoxAllDown; #下落到底fidone#kill -$sigDown $$BoxDown #下落一行done}#BoxMove(y, x), 测试是否可以把移动中的方块移到(x, y)的位置, 返回0则可以, 1不可以function BoxMove(){local j i x y xTest yTestyTest=$1xTest=$2for ((j = 0; j < 8; j += 2))do((i = j + 1))((y = ${boxCur[$j]} + yTest))((x = ${boxCur[$i]} + xTest))if (( y < 0 || y >= iTrayHeight || x < 0 || x >= iTrayWidth)) then#撞到墙壁了return 1fiif ((${iMap[y * iTrayWidth + x]} != -1 ))then#撞到其他已经存在的方块了return 1fidonereturn 0;}#将当前移动中的方块放到背景方块中去,#并计算新的分数和速度级。
(即一次方块落到底部)function Box2Map(){local j i x y xp yp line#将当前移动中的方块放到背景方块中去for ((j = 0; j < 8; j += 2))do((y = ${boxCur[$j]} + boxCurY))((x = ${boxCur[$i]} + boxCurX))((i = y * iTrayWidth + x))iMap[$i]=$cBoxCurdone#消去可被消去的行line=0for ((j = 0; j < iTrayWidth * iTrayHeight; j += iTrayWidth)) dofor ((i = j + iTrayWidth - 1; i >= j; i--))doif ((${iMap[$i]} == -1)); then break; fidoneif ((i >= j)); then continue; fi((line++))for ((i = j - 1; i >= 0; i--))do((x = i + iTrayWidth))iMap[$x]=${iMap[$i]}donefor ((i = 0; i < iTrayWidth; i++))doiMap[$i]=-1donedoneif ((line == 0)); then return; fi#根据消去的行数line计算分数和速度级((x = iLeft + iTrayWidth * 2 + 7))((y = iTop + 11))((iScore += line * 2 - 1))#显示新的分数echo -ne"\033[1m\033[3${cScoreValue}m\033[${y};${x}H${iScore} "if ((iScore % iScoreEachLevel < line * 2 - 1))thenif ((iLevel < 20))then((iLevel++))((y = iTop + 14))#显示新的速度级echo -ne"\033[3${cScoreValue}m\033[${y};${x}H${iLevel} "fifiecho -ne "\033[0m"#重新显示背景方块for ((y = 0; y < iTrayHeight; y++))do((yp = y + iTrayTop + 1))((xp = iTrayLeft + 1))((i = y * iTrayWidth))echo -ne "\033[${yp};${xp}H"for ((x = 0; x < iTrayWidth; x++))do((j = i + x))if ((${iMap[$j]} == -1))echo -ne " "elseecho -ne"\033[1m\033[7m\033[3${iMap[$j]}m\033[4${iMap[$j]}m[]\033[0m"fidonedone}#下落一行function BoxDown(){local y s((y = boxCurY + 1)) #新的y坐标if BoxMove $y $boxCurX #测试是否可以下落一行thens="`DrawCurBox 0`" #将旧的方块抹去((boxCurY = y))s="$s`DrawCurBox 1`" #显示新的下落后方块echo -ne $selse#走到这儿, 如果不能下落了Box2Map #将当前移动中的方块贴到背景方块中 RandomBox #产生新的方块fi}#左移一列function BoxLeft(){local x s((x = boxCurX - 1))if BoxMove $boxCurY $xthens=`DrawCurBox 0`((boxCurX = x))s=$s`DrawCurBox 1`echo -ne $sfi}#右移一列function BoxRight(){local x s((x = boxCurX + 1))if BoxMove $boxCurY $xthens=`DrawCurBox 0`((boxCurX = x))s=$s`DrawCurBox 1`echo -ne $sfi}#下落到底function BoxAllDown(){local k j i x y iDown siDown=$iTrayHeight#计算一共需要下落多少行for ((j = 0; j < 8; j += 2))do((i = j + 1))((y = ${boxCur[$j]} + boxCurY))((x = ${boxCur[$i]} + boxCurX))for ((k = y + 1; k < iTrayHeight; k++))do((i = k * iTrayWidth + x))if (( ${iMap[$i]} != -1)); then break; fidone((k -= y + 1))if (( $iDown > $k )); then iDown=$k; fidones=`DrawCurBox 0` #将旧的方块抹去((boxCurY += iDown))s=$s`DrawCurBox 1` #显示新的下落后的方块echo -ne $sBox2Map #将当前移动中的方块贴到背景方块中RandomBox #产生新的方块}#旋转方块function BoxRotate(){local iCount iTestRotate boxTest j i siCount=${countBox[$iBoxCurType]} #当前的方块经旋转可以产生的样式的数目#计算旋转后的新的样式((iTestRotate = iBoxCurRotate + 1))if ((iTestRotate >= iCount))then((iTestRotate = 0))fi#更新到新的样式, 保存老的样式(但不显示)for ((j = 0, i = (${offsetBox[$iBoxCurType]} + $iTestRotate) * 8; j < 8; j++, i++))doboxTest[$j]=${boxCur[$j]}boxCur[$j]=${box[$i]}doneif BoxMove $boxCurY $boxCurX #测试旋转后是否有空间放的下then#抹去旧的方块for ((j = 0; j < 8; j++))doboxCur[$j]=${boxTest[$j]}dones=`DrawCurBox 0`#画上新的方块for ((j = 0, i = (${offsetBox[$iBoxCurType]} + $iTestRotate) * 8; j < 8; j++, i++))doboxCur[$j]=${box[$i]}dones=$s`DrawCurBox 1`echo -ne $siBoxCurRotate=$iTestRotateelse#不能旋转,还是继续使用老的样式for ((j = 0; j < 8; j++))doboxCur[$j]=${boxTest[$j]}donefi}#DrawCurBox(bDraw), 绘制当前移动中的方块, bDraw为1, 画上, bDraw为0, 抹去方块。