我想用Java写一个俄罗斯方块,其中有一个线程是关于JFrame的键盘监听实现图形的变形,但是监听一直没有同时进行,咋回事。
public class practice1 {
public static void main(String[] args) {
// RegisterInterface Tetris = new RegisterInterface("俄罗斯方块");
SnakeDemo t = new SnakeDemo();
}
}
import java.awt.Canvas;
import java.awt.Container;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
public class SnakeDemo extends JFrame{
private static final long serialVersionUID = 5671798241966272024L;
protected static JFrame game = new JFrame();
protected static Container game1 = game.getContentPane();
private JLabel label1 = new JLabel("分 数:");
private JLabel label2 = new JLabel("所花时间:");
private JLabel label3 = new JLabel("说 明:");
protected static JTextArea explain = new JTextArea("此游戏是一个俄罗斯方块简易版本,实现简单地移动,得分,变形的功能," + "外加上一些显示,计时和音效后。\n"
+ "游戏界面按左右键实现移动,按ESC重新开始,按空格键可以实现暂停和开始,按Shift变形。");
private Font f = new Font("微软雅黑", Font.PLAIN, 15);
protected static boolean a = true;
private boolean b = true;
protected static int x;
protected static int y;
protected static int i,u;
protected static int s2, s3, s4, s5, s6, s7, s8, s1, p = 0;
protected int ran2, l;
private Graphics g1;
Thread e1 = new shift();
public SnakeDemo() {
game.setTitle("俄罗斯方块");
game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.setBounds(400, 10, 700, 800);
game.setResizable(false);
game1.add(label1);
label1.setBounds(500, 260, 85, 20);
label1.setFont(f);
game1.add(label2);
label2.setBounds(500, 290, 85, 20);
label2.setFont(f);
game1.add(label3);
label3.setBounds(500, 320, 85, 20);
label3.setFont(f);
game1.add(explain);
explain.setBounds(500, 350, 160, 200);
explain.setLineWrap(true);
explain.setEditable(false);
explain.setOpaque(false);
explain.setFont(f);
game1.add(new mycanvas());
game.setVisible(true);
game.setFocusable(true);
}
/*
* 在绘制图形时x,y表示的是一个图形左下角的坐标,其中每个小方块的长宽都为20,
* polygon绘制图形其中s(int)表示生成图形的x轴坐标,每个图形的y轴坐标由一个y计算得到
这里提供了最简单的方块的生成与变形,及生成一个横向的可以变形为一个纵向的。
*/
public class mycanvas extends Canvas {
public void paint(Graphics g) {
g1 = (Graphics2D) g;
int max = 7, min = 1;
ran2 = (int) (Math.random() * (max - min) + min);
ran2 = 1;
background(); //绘制背景
//定义线程shift,shift释放则发生变形
if (ran2 == 1) { //如果ran=1则绘制第一种横向方块
i = 0;
s1 = 165;
s2 = 245;
s3 = 245;
s4 = 165;
y = 25;
e1.start(); //调用线程shift
while (a) { //while循环实现图形移动
int x1[] = { s1, s2, s3, s4 };
if (i == 0) { //i=0时为横向状态
int y1[] = { y, y, y - 20, y - 20 };
g1.fillPolygon(x1, y1, 4);
}
if (i == 1) { //i=1时为变形为竖向的状态
int y1[] = { y, y, y - 80, y - 80 };
g1.fillPolygon(x1, y1, 4);
}
movement(); //调用descend方法实现图形下移
background(); //再次绘制背景
}
}
}
}
public void background() { //绘制背景的方法
for (int x2 = 5; x2 <= 405; x2 += 20) {
for (int y2 = 5; y2 <= 705; y2 += 20) {
g1.drawRect(x2, y2, 20, 20);
}
}
}
public void movement() { //图形下移的方法
System.out.println(i);
if (i == 0) { //正常状态下移方法
g1.clearRect(s1, y - 40, 80, 20);
}
if (i == 1) { //变形后下移方法
if (l == 0) {
g1.clearRect(s1 + 20, y - 40, 60, 20);
l = 1;
}
g1.clearRect(s1, y - 100, 20, 20);
}
if (y <= 705)
y += 20;
else
a = false;
}
}
```import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class shift extends Thread {
public void run() {
SnakeDemo.game.addKeyListener(new KeyListener() { // 对Jframe窗体game添加键盘事件监听
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
int code;
code = e.getKeyCode();
switch (code) {
case KeyEvent.VK_SHIFT: // 如果当shift键释放时发生如下变化
if (SnakeDemo.y >= 85) { // 判断图形是否有充足的Y轴变形,如果有则有横向状态变为竖向状态
synchronized (this) {
SnakeDemo.i = 1;
SnakeDemo.s2 = SnakeDemo.s1 + 20;
SnakeDemo.s3 = SnakeDemo.s2;
SnakeDemo.s4 = SnakeDemo.s1;
System.out.println("ghjkbnm,ghjklhjklhjk");
}
}
code = 0;
break;
default:
throw new IllegalArgumentException("Unexpected value: " + code);
}
}
public void keyPressed(KeyEvent e) {
}
});
}
}