A simple implement of the Tetris in JAVA

A simple implement of the Tetris in JAVA


OK, This is an implement of the game Tetris by using JAVA.


1. Model

(1) Blocks

As we all know, Tetris has some blocks with different shapes , but how to store this different kinds of the blocks in the computer, or how to express the shapes by data? 

We use arrays. different arrays to show different blocks.

For example, the shape "I" , we can use a two dimensional array 

public class ShapI extends Component {
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>private int[][] components = {
<span style="white-space:pre">			</span>{ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },// state one init 
<span style="white-space:pre">			</span>{ 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 },// state two turn once
<span style="white-space:pre">			</span>{ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
<span style="white-space:pre">			</span>{ 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 }, };
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>public ShapI(){
<span style="white-space:pre">		</span>super.components = components;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public void draw(Graphics g, int x, int y) {
<span style="white-space:pre">		</span>g.fillRect(x, y, 10, 10);
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
}

to show the block, and different state.

The other blocks are same.

(2)The rest blocks on the canvas。

Then,  we still use an array to describe it.

public class ShapAll extends Component {

	private int[][] components = new int[28][30];

	public ShapAll() {
		for (int i = 0; i < 30; i++) {
			components[0][i] = 2;
			components[27][i] = 2;
		}
		for (int i = 0; i < 27; i++) {
			components[i][29] = 2;
		}
	}

	@Override
	public void drawShap(Graphics g) {
		for (int i = 0; i < 28; i++) {
			for (int j = 0; j < 30; j++) {
				if (components[i][j] == 2) {
					g.drawRect(10 * i, 10 * j, 10, 10);
				}
				if (components[i][j] == 1) {
					g.fillRect(10 * i, 10 * j, 10, 10);
				}
			}
		}
	}
<span style="white-space:pre">	</span>// check if there is a block.
	public int getValue(int i, int x, int y) {
		if (components[i % 4 + x / 10][i / 4 + y / 10 + 1] != 0) // down
			return 1;
		if (components[i % 4 + x / 10 + 1][i / 4 + y / 10] != 0) // right
			return 2;
		if (components[i % 4 + x / 10 - 1][i / 4 + y / 10] != 0) // left
			return 3;
		return 0;
	}
<span style="white-space:pre">	</span>// add a new Shape on it (after the shape is down)
	public void addOne(Component comp) {
		for (int i = 0; i < 16; i++) {
			if (comp.getValue(i)) {
				components[i % 4 + comp.getX() / 10][i / 4 + comp.getY() / 10] = 1;
				removeLine();
			}
		}
		for (int i = 0; i < 28; i++) {
			for (int j = 0; j < 30; j++) {
				System.out.print(components[i][j]);
			}
			System.out.println();
		}

		System.out.println();
		removeLine();
	}
<span style="white-space:pre">	</span>// of course remve on
	public void removeLine() {
		int result = 1;
		for (int i = 0; i < 29; i++) {
			for (int j = 1; j < 27; j++) {
				result = result * components[j][i];
			}
			if (result == 1) {
				// 消除后 所有行下移 预留
				
				for(int l=i;l>=1;l--){
					for (int k = 26; k > 0; k--) {
						components[k][l] = components[k][l-1];
					}
				}
				for (int x = 0; x < 28; x++) {
					for (int z= 0; z < 30; z++) {
						System.out.print(components[x][z]);
					}
					System.out.println();
				}
			}
			result = 1;
		}
	}

}

And all the shapes and shapAll are extends from the component.

public class Component {

	protected int x = 130;
	protected int y = 0;
	protected int[][] components = new int[4][16];
	protected int state = 0;

	public void draw(Graphics g, int x, int y) {
		g.fillRect(x, y, 10, 10);
	}

	public void drawShap(Graphics g) {
		for (int i = 0; i < components[0].length; i++) {
			if (components[state][i] == 1) {
				Component comp = new Component();
				comp.draw(g, x + i % 4 * 10, y + i / 4 * 10);
			}
			
		}
	}
	
	public boolean getValue(int i){
		if(components[state][i] != 0)
			return true;
		return false;
	}

	public void turn() {
		state++;
		if (state == 4)
			state = 0;
	}

	public void down() {
		y += 10;
	}

	public void move(int xx, int yy) {
		
		this.x = x + xx;
		this.y = y + yy;
	}

	public int getX(){
		return this.x;
	}
	
	public int getY(){
		return this.y;
	}
	
}


2. Canvas 

Of course we need a canvas to show all the blocks on it.

public class Canvas extends JPanel {
	private static Canvas instance;
	private ArrayList<Component> al_Components;
	private Canvas() {
		this.addKeyListener(new KeyController());
	}


	public static Canvas getInstance() {
		if (instance == null) {
			instance = new Canvas();
		}
		return instance;
	}


	public void setComponents(ArrayList<Component> al_Components){
		this.al_Components = al_Components;
	}
	
	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		for(Component comp: al_Components){
			comp.drawShap(g);
		}
	}
	
}

3. Controllers

We create a KeyController to implements the KeyListener interface to listen the user's action.

and in the KeyController we add a callback interface to response to the user's action.

public class KeyController implements KeyListener {

	private KeyControllCallBack cb;

	public void setContext(KeyControllCallBack cb) {
		this.cb = cb;
	}

	@Override
	public void keyTyped(KeyEvent e) {
		System.out.println(e.getKeyChar());
	}

	@Override
	public void keyPressed(KeyEvent e) {
		switch (e.getKeyCode()) {
		case KeyEvent.VK_SPACE:
			cb.keySpace();
			break;
		case KeyEvent.VK_LEFT:
			cb.keyLeft();
			break;
		case KeyEvent.VK_RIGHT:
			cb.keyRight();
			break;
		case KeyEvent.VK_DOWN:
			cb.keyDown();
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
	}

	public interface KeyControllCallBack {
		public void keySpace();

		public void keyLeft();

		public void keyRight();
		
		public void keyDown();

	}

}

  And the ShapController which implements the Callback interface we mentioned to control the game.

public class ShapController implements KeyControllCallBack {
	private ArrayList<Component> al_component = new ArrayList<Component>();
	private Component comp_Now;
	private ShapAll shapAll;

	private void createNewShap() {
		al_component.remove(comp_Now);
		int i =  (int)(Math.random()*1000)%3;
		switch(i){
		case 0:
			comp_Now = new ShapL();
			break;
		case 1:
			comp_Now = new ShapO();
			break;
		case 2:
			comp_Now = new ShapI();
			break;
		}
		al_component.add(comp_Now);
	}

	

	public ShapController() {
		Canvas.getInstance().setComponents(al_component);
		createNewShap();
		createShapAll();
		Timer timer = new Timer();
		timer.schedule(new TimerTaskGame(), 1000, 1000);
	}

	public void createShapAll() {
		shapAll = new ShapAll();
		al_component.add(shapAll);
	}

	// collision detected
	public int isCollision() {
		int result = 0;
		for (int i = 0; i < 16; i++) {
			if (comp_Now.getValue(i)&& shapAll.getValue(i, comp_Now.getX(), comp_Now.getY())==1){
				result = 1;
			}
			if (comp_Now.getValue(i)&& shapAll.getValue(i, comp_Now.getX(), comp_Now.getY())==2)
				result = 2;
			if (comp_Now.getValue(i)&& shapAll.getValue(i, comp_Now.getX(), comp_Now.getY())==3)
				result = 3;
		}
		return result;
	}

	public void turn() {
		if (isCollision() == 0){
			comp_Now.turn();
		}
	}

	public void down() {
		if (isCollision() != 1) {
			comp_Now.down();
		}else{
			shapAll.addOne(comp_Now);
			createNewShap();
		}
	}

	public void left() {
		if (isCollision() != 3 && isCollision()!=1) {
			comp_Now.move(-10, 0);
		}
	}

	public void right() {
		if (isCollision() != 2 && isCollision()!=1) {
			comp_Now.move(10, 0);
		}
	}

	private class TimerTaskGame extends TimerTask {

		@Override
		public void run() {
			down();
			Canvas.getInstance().repaint();
		}

	}

	@Override
	public void keySpace() {
		turn();
		Canvas.getInstance().repaint();
	}

	@Override
	public void keyLeft() {
		left();
		Canvas.getInstance().repaint();
	}

	@Override
	public void keyRight() {
		right();
		Canvas.getInstance().repaint();
	}

	@Override
	public void keyDown() {
		down();
		Canvas.getInstance().repaint();
	}
}



That's all!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值