我目前,为了好玩,制作一个乒乓球游戏,但我目前卡住试图通过w键按下我的布尔“上升”的值到真实状态。我的渲染类中有布尔值,以及int x和int y,并且设置为false。在这个类中,我绘制一个正方形,其中x为int x,y为int y。在另一个类(Framemake.java)中,我有一个设置为我的Jframe的键监听器。在这堂课中,我有keylistener听w键按下和释放。这就是我的问题出现的地方:如果按下W键,我希望它将upup更改为true,如果已释放,我希望它更改为false;这工作正常,但问题是我的渲染类我已经设置了一个计时器,然后在图形方法中启动(不确定正确的名称)。在我设置的定时器动作中:如果上升是真的,我希望它打印出“up up is true-render”。这就是问题 - 即使由于按下了w键而向上移动,打印也不会打印到屏幕上。 (感谢您阅读本文,我需要您完全了解最新情况 - 即使它可能会或可能不会非常明显)。
这是代码: Starter.java
public class Starter {
public static void main(String[] args) {
Frame frame = new Frame();
frame.Start();
}
}
这是Frame.java
public class Frame implements Runnable {
Framemake r = new Framemake();
public void Start(){
new Thread(this).start();//
}
public void run() {
try {
r.framemade();
}
catch (Exception e) { //
e.printStackTrace();
}
}
}
这是Render.java的一部分,因为我在这篇文章中遇到了麻烦
public class Render extends JPanel implements ActionListener {
boolean goingup = false;
boolean goingdown = false;
int x = 0; //starting pos of x .
int y = 150;//starting pos of y
Timer tm = new Timer(7, this); //The timer is created
public void paintComponent(Graphics g) {
Framemake frames = new Framemake();
super.paintComponent(g);
tm.start();
g.setColor(Color.GREEN);
g.fillRect(x, y, 20, 150);
g.dispose();
}
public void actionPerformed(ActionEvent e){ //timer
if(goingup){
System.out.println("Going up is true- render");
x++;//for example...
repaint();
}
}
这是Framemake.java
public class Framemake implements KeyListener {
int WIDTH = 500;
int HEIGHT = 500;
Render c = new Render();
public void framemade() {
System.out.println("Frame starting");
//Frame is created here
Render render = new Render();
JFrame frame = new JFrame();
frame.setSize(WIDTH, HEIGHT);
frame.setVisible(true);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setTitle("Animation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Window w = frame;
w.addKeyListener(this);
frame.add(render); //displays all graphics from render to the screen
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_W) {
System.out.println("Going up");
c.goingup = true;
}
if (keyCode == KeyEvent.VK_S) {
System.out.println("Going down");
c.goingdown = true;
}
}
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_W) {
System.out.println("Up terminated");
c.goingup = false;
}
if (keyCode == KeyEvent.VK_S) {
System.out.println("Down terminated");
c.goingdown = false;
}
}
public void keyTyped(KeyEvent e) {}
}
我希望这里的问题很明确(如果我的代码发布错误,很抱歉),我们非常感谢您的帮助。
答案 0 :(得分:2)
问题是,在您的班级Framemake
中,您没有将Render c
添加到frame
。您正在创建局部变量render
。
要解决此问题,只需删除
的声明即可Render render = new Render();
并将c
添加到frame
:
frame.add(c); // Instead of 'frame.add(render)'
摘要:您的方法framemade()
应如下所示:
public void framemade()
{
System.out.println("Frame starting");
//Frame is created here
JFrame frame = new JFrame();
frame.setSize(WIDTH, HEIGHT);
frame.setVisible(true);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setTitle("Animation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Window w = frame;
w.addKeyListener(this);
frame.add(c); // Change this line
}
修改强>
答案 1 :(得分:0)
我想,你的计时器根本不会发射。您应该只启动一次,而不是paintComponent
方法。因为默认情况下它会每7毫秒触发一次。
还要添加一行以查看actionPerformed
方法是否实际触发:
public void actionPerformed(ActionEvent e){ //timer
System.out.println("Timer: actionPerformed");
if(goingup){
System.out.println("Going up is true- render");
x++;//for example...
repaint();
}
}
为什么要在g.dispose();
方法中拨打paintComponent
?每次重绘都会调用此方法。这很可能也会导致问题。
答案 2 :(得分:0)
你应该能够通过简单地添加这样的方法来实现这一点,然后调用它: Public void setgoingup(boolean b){ this.goingup = b; }
Ps:我很累,并没有阅读所有代码 - 对不起,如果我错过了任何事情。
答案 3 :(得分:0)
您需要使用observer(或通知程序)模式。
一个非常简单(天真)的例子: 创建一个将扮演observable角色的类,并且 具有观察者角色的接口及其实现 类。 将列表保存到观察者实例的可观察类,以便在需要时通知
(注意:未经测试的代码):
public interface Observer{
public void notify();
}
public class Observable{
public List<Observer> _observers;
public Observable(){
_observers = new List<Observer>();
}
public void registerObserver(Observer obs){
_observers.add(obs)
}
public void unregisterObserver(Observer obs){
_observers.remove(obs);
}
public void notifyObservers{
for(Observer obs : _observers) {
obs.notify();
}
}
}
public class SpecificObserver implements Observer{
//Properties, Ctors etc
public void notify(){
//Do stuff when notified here
}
}
and in your program:
public static void main(string[] args){
Observable observable = new Observable();
SpecificObserver specificObserver = new SpecificObserver();
//More init code here
observable.registerObserver(specificObserver);
//Etc...
//read input
string str = YourClass.GetInput();
while(!str.Equals("EndString"))
{
if(str.Equals("SpecificInput"))
{
observable.notifyObservers();
}
str = YourClass.GetInput();
}
}
当然,您可以根据需要对其进行修改(为Notify
方法添加参数,将循环运行到另一个检查所需条件的线程而不是输入等)