剡浩博 2019-08-10 17:59 采纳率: 0%
浏览 475
已采纳

JAVA的线程给Jframe添加键盘监听不同时运行

我想用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) {

        }
    });
}

}

  • 写回答

1条回答 默认 最新

  • 毕小宝 博客专家认证 2019-08-10 21:52
    关注

    监听没有同时运行是不是指监听事件没执行呢?
    这里有一个贪吃蛇的完整游戏的代码,可以参考看看:https://github.com/woodvine/snakegame

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题