带Swing的keyListener和带Swing / keyListener和Thread的游戏级系统

时间:2015-02-20 22:30:48

标签: java multithreading swing keylistener

我是一名新手编写者,大约10年前对C ++有一点经验,现在正在学习java(它已经有4-5个月了)。我有一个小小的合作项目,我已经找到了一些要弄清楚的东西。

以下是代码:

import java.awt.event.*;
import java.awt.*;

import javax.swing.JFrame;

import java.util.Scanner;
import java.util.Random;

public class Game extends JFrame {


    GamePanel panel;
    int[][] grid;
    int size;

    //...and some other variables

    public Game(String title) {

        super(title);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        panel = new GamePanel(grid,size);
        this.add(panel);

        Button button = new Button("WHAT");
        button.setBounds(-100, -100, 70, 70);
        this.add(button);
        button.addKeyListener(new KeyHandler());

    }

    class KeyHandler extends KeyAdapter {

        public void keyPressed(KeyEvent e) {

            int keycode = e.getKeyCode();

            switch(keycode) {

                //arrow keys input and stuff

            }

            if(checkForWin())  //checkForWin() returns a boolean value for win/loss
                //won the game, thus end the thread here

            if(checkForLoss()) // similar stuff as checkForLoss()
                //lost the game, thus end the thread here

            //...update the panel
            panel.repaint();

        }

    }

    public static void main(String [] args) {

        Game me = new Game("GAME");

        me.setVisible(true);

    }

}

这就是整个游戏的样子。

我有疑问:

  1. 我正在使用一个按钮并将其置于负位置以使其不可见并将其用作KeyListener的平均值。有没有其他方法来添加密钥监听器? ex)小组或其他什么?

  2. 我想改变它,以便每个"级别"是一个线程,使其像

    public static void main(String [] args) {
    
        int level = 1;
    
        do {
    
            GameThread gt = new GameThread("Game");
    
            // run() will have the game constructor inside
    
            gt.setLevel(level);
            gt.start();
            gt.join();       //wait until the game "level" is finished
    
            if(won)
                level++;
    
            if(lost)
                level = 1;
    
        } while(!checkIfDonePlaying())
    
    }
    
  3. 有点像这样。我无法让线程继续运行,直到游戏关卡实际完成为止。我该怎么做?

    1. 我想添加一个JLabel来显示框架上的分数。但是当我这样做时,当我重新绘制它时,分数不会更新。我该怎么做?
    2. 提前致谢!

2 个答案:

答案 0 :(得分:1)

一些事情:

  1. 是的,有一种方法可以向面板添加KeyListener,并使用key bindings。例如:

    javax.swing.InputMap im = panel.getInputMap(panel.WHEN_IN_FOCUSED_WINDOW);
    javax.swing.ActionMap am = panel.getActionMap();
    
    im.put(javax.swing.KeyStroke.getKeyStroke("pressed UP"), "up");
    am.put("up", new javax.swing.AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent ev) {
            // handle up arrow key action here
        }
    });
    
  2. Swing是一个事件驱动的环境,因此不应使用do-while循环。相反,使用Swing计时器定期检查您的级别是否已完成。

  3. 由于您未在JLabel上进行任何自定义绘画,因此您不应使用repaint。相反,请使用其setText方法。

答案 1 :(得分:0)

这是第一期的解决方案:

panel.setFocusable(true);
panel.addKeyListener(this);

然后你应该能够做通常的关键监听器方法。一定要实现KeyListener! 解决您的其他问题。 (实际上接受@TNT的建议并使用键绑定,我对听众更舒服,但对于游戏我通常使用lwjgl或slick2d)

2

我觉得运行你的程序级别可能有点低效(可能只是我)我建议在run方法中有一个线程并具有以下内容:

Public void reset(int level)
 {
   //reset all variables based on local variable level...

}

这样称呼:

Reset(++currentLevel)); //use ++ before currentLevel so it adds to it and then resets

如果你想要

,你可以轻松地使用switch case做一些特别的事情
Switch(level){
case 1: //...
}

等等。 (我在移动设备上打字,抱歉怪异的帽子)