小游戏 俄罗斯方块

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


小游戏 俄罗斯方块_第1张图片                     小游戏 俄罗斯方块_第2张图片

代码:

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{
		@Override
		public void actionPerformed(ActionEvent e) {
			down();	//使方块下落
		}

		@Override
		public 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;
			}
		}
	}

	@Override
	public 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);
	}
}


你可能感兴趣的:(小游戏)