小游戏 俄罗斯方块

来源:互联网 发布:w7无法安装软件 编辑:程序博客网 时间:2024/05/17 03:21

这个是简单俄罗斯方块的java实现


                     

代码:

package cn.hncu.tetris;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.Calendar;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.Timer;public class Tetris extends JFrame{private MyPanel gamePanel;public Tetris() {super("dragon版 俄罗斯方块");setSize(200, 275);setLocationRelativeTo(this);setDefaultCloseOperation(EXIT_ON_CLOSE);setResizable(false);//设置大小不可变gamePanel=new MyPanel();getContentPane().add(gamePanel);addKeyListener(gamePanel.getListener());setVisible(true);}public static void main(String[] args) {new Tetris();}}class MyPanel extends JPanel{private int map[][]=new int[13][23];//游戏框架,实际为21行,10列(2列一行的边框),行列各预留一行防止越界/* * 三维数组表示产生的方块形状, * 第一维表示种类 type * 第二维表示变形 turnState * 第三维表示方块矩阵(4行,4列的矩阵代表一个方块。) * shaps[type][turnState][i]i==>[i/4][i%4] */private int shaps[][][]={/* * { * {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, * {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, * {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, * {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} * } */// I (※把版本1中的横条从第1行换到第2行){ { 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, 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 } },// Z 第3行: shapes[2][2][]{ { 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 } } };private int type;private int turnState;private int x;//当前块的位置:列private int y;//当前块的位置:行private Timer timer;private int delay;private int score;private TimerListener listener;public TimerListener getListener() {return listener;}public MyPanel() {newGames();//初始化,map[][]nextBlock();//出现随机的方块}private void newGames() {for(int i=0;i<12;i++){for(int j=0;j<22;j++){if(i==0 || i==11 ||j==21){map[i][j]=3;//游戏框架}else{map[i][j]=0;}}}//因为这个listener要加到框架上,所以可以定义为成员变量,用实例调listener=new TimerListener();delay=1000;score = 0;timer=new Timer(delay, listener);timer.start();}private void nextBlock() {type=(int) (Calendar.getInstance().getTime().getTime()%7);turnState=(int) (Calendar.getInstance().getTime().getTime()%4);x=4;y=0;//初始出现位置(4,0)//在随机出现方块之后需要 马上 进行判断是否会相撞if(crash(x, y, type, turnState)==0){timer.stop();int op = JOptionPane.showConfirmDialog(this, "Game Over~ 是否在来一局");if(op==JOptionPane.YES_OPTION){newGames();}else if(op==JOptionPane.NO_OPTION){System.exit(0);}}}class TimerListener extends KeyAdapter implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {down();//使方块下落}@Overridepublic void keyPressed(KeyEvent e) {switch(e.getKeyCode()){case KeyEvent.VK_DOWN :down();break;case KeyEvent.VK_UP :turn();break;case KeyEvent.VK_LEFT :left();break;case KeyEvent.VK_RIGHT :right();}}}private void down() {//y++;如果下落的这个位置:越界,或者与其他已经在落下的方块碰撞时,不能再落if(crash(x,y+1,type,turnState)==0){//如果相撞,或者越界,则把这个方块加入到map中add(x,y,type,turnState);//然后在随机出现一个方块nextBlock();}else{y++;}repaint();}private void right() {if(x<8){if(crash(x+1, y, type, turnState)==1){x++;repaint();}}}private void left() {if(x>=0){if(crash(x-1, y, type, turnState)==1){x--;repaint();}}}private void turn() {if(crash(x, y, type, (turnState+1)%4)==1){//如果下一个要变化的形状,不会相撞则可以变化turnState=(turnState+1)%4;repaint();}}private int crash(int x, int y, int type, int turnState) {for(int i=0;i<4;i++){//表示行for(int j=0;j<4;j++){//表示列if( (map[x+1+j][y+i] & shaps[type][turnState][i*4+j] ) == 1){//当shapes为1 map为1或者3 时,表示相撞、或者越界(超过下边框)return 0;}}}return 1;}private void add(int x, int y, int type, int turnState) {for(int i=0;i<4;i++){//行号for(int j=0;j<4;j++){//列号if(shaps[type][turnState][i*4+j]==1){map[x+1+j][y+i]=1;}}}//每次添加一个,判断一下是否可以消除一行。tryDelLine();}private void tryDelLine() {for(int i=0;i<21;i++){boolean boo=true;for(int j=0;j<11;j++){if(map[j][i]!=1 && map[j][i]!=3){//只有当一行都不是方块,或者框架的时候才是能消除的boo=false;}}if(boo){//如果能消除,则需要把这一行以上的每一行都往下移动一行for(int j=i;j>0;j--){for(int k=0;k<11;k++){map[k][j]=map[k][j-1];}}if(delay>200){delay=delay-100;}score+=10;}}}@Overridepublic void paint(Graphics g) {super.paint(g);//画出框架==>相当于初始化map[][] for(int i=0;i<12;i++){for(int j=0;j<22;j++){if(map[i][j]==3){g.setColor(Color.red);g.drawRect(i*10, j*10, 10, 10);}if(map[i][j]==1){g.setColor(Color.red);g.fillRect(i*10, j*10, 10, 10);g.setColor(Color.yellow);g.drawRect(i*10, j*10, 10, 10);}}}//画出当前出现的方块//下面这样写就写死了。//int type=3;int turnSate=2;int x=4;int y=5;for(int i=0;i<16;i++){if(shaps[type][turnState][i]==1){g.fillRect((x+1+i%4)*10, (y+i/4)*10, 10, 10);}}g.setColor(Color.black);g.setFont(new Font("aa", Font.BOLD, 15));g.drawString("Socre:"+score, 125, 20);g.drawString("当前速度:"+delay/1000+"秒每行", 125, 50);g.drawString(delay*1.0/1000+"秒每行", 125, 80);}}