06主要是定义了一些按键事件,继承了KeyAdapter类,KeyEvent中的getKeyCode()方法可以监测按下了什么按键。
对于触碰左侧、右侧的事件,主要通过x的取值来进行判断。对于持续按下“Down”键,通过Thread的sleep()参数来控制。
TetrisClient类:
import java.awt.*;
import java.awt.event.*;
public class TetrisClient extends Frame{
//声明变量,窗口出现的位置
int x = 300;
int y = 100;
//游戏窗体宽高
public static final int WIDTH = 400;
public static final int HEIGHT = 480;
//修正值
public static final int CORRECT_X = 110;
public static final int CORRECT_Y = 50;
//游戏区域大小
public static final int GAME_WIDTH = 200;
public static final int GAME_HEIGHTH = 400;
Shape s = new Shape(CORRECT_X + 60, CORRECT_Y + 60, 3);
public void lancher() {
//出现位置
this.setLocation(x,y);
//大小
this.setSize(WIDTH, HEIGHT);
//设置标题
this.setTitle("Tetris Game");
//不可调节大小
this.setResizable(false);
//布局属性
this.setLayout(null);
//设置游戏背景颜色
this.setBackground(new Color(255, 239, 213));
//添加窗口关闭事件
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//启动一个刷新线程
new Thread(new paintThread()).start();
//可见性
this.setVisible(true);
//添加按键监控
this.addKeyListener(new keyMonitor());
}
@Override
public void paint(Graphics g) {
Color c = g.getColor();
g.drawRect(CORRECT_X, CORRECT_Y, GAME_WIDTH, GAME_HEIGHTH);
g.setColor(c);
//关于Shape的测试
s.draw(g);
s.changeStatus();
if(!s.stopped) {
s.drop();
}
}
public static void main(String[] args) {
new TetrisClient().lancher();
}
//刷新类(内部类)-线程
public class paintThread implements Runnable{
@Override
public void run() {
while(true) {
repaint();
//刷新间隔
try {
//“下”键按下加速
if(!s.speedUp) {
Thread.sleep(300);
}
Thread.sleep(20);
} catch (InterruptedException e) {
e.getStackTrace();
}
}
}
}
//按键事件的内部类
private class keyMonitor extends KeyAdapter{
@Override
public void keyPressed(KeyEvent e) {
s.keyPressed(e);
}
@Override
public void keyReleased(KeyEvent e) {
s.keyReleased(e);
}
}
}
Unit类:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
public class Unit {
//出现的位置
private int x,y;
//大小
public static final int SIZE = 20;
//下落步长
public static final int SPEED = 20;
//停止状态
public boolean stopped = false;
//Shape颜色
private Color color = Color.BLACK;
//构造函数
public Unit() {
}
public Unit(int x,int y) {
this.x = x;
this.y = y;
}
public Unit(int x,int y,Color color) {
this(x,y);
this.color = color;
}
//画出自己的方法
public void draw(Graphics g) {
//Color c = g.getColor();
//g.setColor(Color.BLUE);
Graphics2D g2 = (Graphics2D)g;
g2.setStroke(new BasicStroke(3.0f));
g.drawRect(x, y, SIZE - 5, SIZE - 5);
g.fillRect(x + 2, y + 2, SIZE - 10, SIZE - 10);
}
public void drop() {
y += SPEED;
}
//检测当前状态
public void changeStatus() {
if(y + SIZE >= TetrisClient.CORRECT_Y + TetrisClient.GAME_HEIGHTH) {
stopped = true;
}
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void moveLeft() {
x -= SIZE;
}
public void moveRight() {
x += SIZE;
}
public boolean hitLeft() {
if(x <= TetrisClient.CORRECT_X)
return true;
return false;
}
public boolean hitRight() {
if(x >= TetrisClient.CORRECT_X + TetrisClient.GAME_WIDTH - Unit.SIZE)
return true;
return false;
}
}
Shape类:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Shape {
int x,y;
//类型
int type;
//是否按下“下”
boolean speedUp = false;
//是否停止
public boolean stopped = false;
//图像颜色
private Color color = null;
//颜色数组
public static Color[] ColorArr = {
//new Color(255, 250, 205),
new Color(230, 230, 250),
new Color(238, 210, 238),
new Color(106, 90, 205),
new Color(192, 255, 62),
new Color(162, 205, 90),
new Color(255, 246, 143),
new Color(255, 165, 0)
};
//随机类对象
Random r = new Random();
int colorIndex = r.nextInt(ColorArr.length);
//类型的图
int[][][] data= {
{//0. 一字型
{0,0,0,0},
{0,0,0,0},
{2,2,2,2},
{0,0,0,0}
},
{//1. 田字型
{0,0,0,0},
{0,2,2,0},
{0,2,2,0},
{0,0,0,0}
},
{//2. L字型
{0,0,0,0},
{0,2,0,0},
{0,2,0,0},
{0,2,2,0}
},
{//3. 反L字型
{0,0,0,0},
{0,2,0,0},
{0,2,0,0},
{2,2,0,0}
},
{//4. Z字型
{0,0,0,0},
{2,2,0,0},
{0,2,2,0},
{0,0,0,0}
},
{//5. 反Z字型
{0,0,0,0},
{0,0,2,2},
{0,2,2,0},
{0,0,0,0}
},
{//6. 品字型
{0,0,0,0},
{0,2,0,0},
{2,2,2,0},
{0,0,0,0}
},
};
//能够装Unit的容器
List units = new ArrayList();
//构造方法
public Shape(int x,int y,int type) {
this.x = x;
this.y = y;
this.type = type;
//使用随机颜色
this.color = ColorArr[colorIndex];
//实例化4个unit对象
for(int i = 0;i < 4;++i) {
units.add(new Unit());
}
createByType();
}
private void createByType() {
int count = 0;
for(int i = 0;i < data[type].length;++i) {
for(int j = 0;j < data[type][i].length;++j) {
if(data[type][i][j] == 2) {
units.get(count).setX(x + j * Unit.SIZE);
units.get(count).setY(y + i * Unit.SIZE);
count++;
}
}
}
}
//画图
public void draw(Graphics g) {
g.setColor(color);
for(int i = 0;i < units.size();++i) {
units.get(i).draw(g);
}
}
//下落方法
public void drop() {
y += Unit.SPEED;
for(int i = 0;i < units.size();++i) {
units.get(i).drop();
}
}
//检测是否停止
public void changeStatus() {
//如果判断每一个unit,有任意一个停止,则修改停止状态
for(int i = 0;i < units.size();++i) {
Unit u = units.get(i);
u.changeStatus();
if(u.stopped) {
stopped = true;
return;
}
}
}
//按键事件
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch(key) {
case KeyEvent.VK_LEFT:
if(!hitLeft())
moveLeft();
break;
case KeyEvent.VK_RIGHT:
if(!hitRight())
moveRight();
break;
case KeyEvent.VK_DOWN:
speedUp = true;
}
}
private void moveRight() {
x -= Unit.SIZE;
for(int i = 0;i < units.size();++i) {
units.get(i).moveRight();
}
}
private void moveLeft() {
x += Unit.SIZE;
for(int i = 0;i < units.size();++i) {
units.get(i).moveLeft();
}
}
//判断是否触碰左侧
public boolean hitLeft() {
boolean b = false;
for(int i = 0;i < units.size();++i) {
if(units.get(i).hitLeft()) {
b = true;
break;
}
}
return b;
}
//判断是否触碰右侧
public boolean hitRight() {
boolean b = false;
for(int i = 0;i < units.size();++i) {
if(units.get(i).hitRight()) {
b = true;
break;
}
}
return b;
}
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_DOWN) {
speedUp = false;
}
}
}