摇摆后,我如何使用程序一个游戏?暂停停止? [英] How can I use Program a game after swing.Timer stopped?

查看:150
本文介绍了摇摆后,我如何使用程序一个游戏?暂停停止?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Java中编写一个简单的皮卡丘游戏,而我使用swing.Timer与JProgress Bar,我的代码是这样的:

  public static void TimeBarListener(final View scr){
ActionListener updateProBar = new ActionListener(){
@Override
public void actionPerformed(ActionEvent actionEvent){
int val = scr.timeBar.getValue();
if(val <= 0){
scr.gameOver();
scr.timer = null;
return;
}
scr.timeBar.setValue( - val);
}
};
int t = n * 400;
scr.timer = new Timer(t,updateProBar);
}

这里的src是一个扩展JFrame来显示游戏的类写道,n是一级的皮卡丘件数。它完美地工作,但在添加计时器之后,出现了很多问题:


  1. 我设置变量't'改变水平,但似乎它不起作用(我测试的价值,这是正确的价值,但似乎定时器可以得到它)。时间跑得太快,如果我点击更多的片段,即使我设置更长时间,它没有改变任何东西,速度更快。


  2. 当我第二次点击新游戏时,定时器跑得更快。但是如果我关闭程序然后再次运行,时间恢复正常。


  3. 如果时间用完了,然后再次点击新游戏按钮,显示1秒钟,然后返回到游戏屏幕。有时它有效,但是IndexArrayOutOfBoundsEcception出现。


  4. 我想使用暂停按钮,这意味着计时器必须暂停然后继续运行也是。有没有办法,我可以做吗?


我猜我的问题是基于代码

  if(val <= 0){
scr.gameOver();
scr.timer = null;
return;
}

如果计时器用尽,则会显示游戏屏幕。但我是新来的,我不明白我是如何工作的,所以我无法想到任何解决方案,或者也许不是问题。



希望我会从你们那里得到一些帮助。感谢很多:)

解决方案

你的问题是你不使用正确的架构模式。您应该将业务逻辑与演示文稿分开。此外,您应该在模型中存储变量(如 time_left ),而不是在控制器(即 ActionListener )中。请阅读:模型视图控制器模式。



基本示例





编辑器。 java - 主类

  public class Editor {
public static void main(String [] args) {
Model model = new Model();
View view = new View(model);
new Controller(model,view);
}
}

View.java / p>

  public class View extends JFrame {

private Model model;
私人JButton btn;

public View(Model model){
this.model = model;
this.btn = new JButton(Test);
}

public void addViewControlListener(ActionListener al){
btn.addActionListener(al);
}
}

Controller.java / p>

  public class Controller {
public Controller(Model model,View view){
view.addViewControlListener ViewControlListener(model,view));
}
}

ViewControlListener.java - 实现ActionListener

  public class ViewControlListener实现ActionListener {

private Model model;
私人查看视图;

public ViewControlListener(Model model,View view){
this.model = model;
this.view = view;
}

public void actionPerformed(ActionEvent e){
//更新模型
//刷新视图
}

}

如你所见,我有一个地方( Controller.java )我在哪里创建监听器并将

添加到视图中的组件。您创建了多个相同侦听器的实例并失去控制权。



另外我的 ActionListener ViewControlListener.java )包含模型和视图的实例,因此可以在模型和刷新视图中更新变量。



您的应用程序



现在更多关于你的应用程序。你需要线程(不是真正的动作侦听器),它将减少时间变量和更新视图以显示实际状态(但只有当游戏活动时)。



所以你可以在模型中创建 leftTime isActive 变量与setter和getter:

  private int leftTime; 
private boolean isActive;

public int getLeftTime(){
return leftTime;
}

public void setLeftTime(int leftTime){
this.leftTime = leftTime;
}

public void decLeftTime(){
this.leftTime--;
}

public boolean isActive(){
return isActive;
}

public void setActive(boolean isActive){
this.isActive = isActive;
}

并创建每秒递减时间并重新绘制视图的线程:

  public class Timer extends Thread {

private Model model;
私人查看视图;

public Timer(Model model,View view){
this.model = model;
this.view = view;
}

public void run(){
while(true){//可以更好的
if(model.isActive()){
model.decLeftTime();
view.repaint();
}
try {
sleep(1000);
} catch(InterruptedException e){
e.printStackTrace();
}
}
}
}

然后在Controller中创建并启动该线程:

  public class Controller {
public Controller(Model model,View view){
view.addViewControlListener(new ViewControlListener(model,view));
...
定时器定时器=新的定时器(模型,视图);
timer.start();
}
}

在视图中,您将添加一些显示剩余时间的组件



PS不要忘记在游戏开始时设置 leftTime


I'm writing a simple pikachu game in Java, and I use swing.Timer with JProgress Bar, my code is like this:

public static void TimeBarListener(final View scr){
    ActionListener updateProBar = new ActionListener() {
        @Override
            public void actionPerformed(ActionEvent actionEvent) {
            int val = scr.timeBar.getValue();
            if (val <= 0) {
                scr.gameOver();
                scr.timer = null;
                return;
            }
            scr.timeBar.setValue(--val);
        }
    };
    int t = n*400;
    scr.timer = new Timer(t, updateProBar);
}

The "src" here is a class which extends JFrame to display the game I wrote, and 'n' is the number of pikachu pieces on a level. It works perfectly but after I add "timer", there are lots of problems occured:

  1. I set the variable 't' change by level, but seems like it doesn't work ( I test the value, it was the right value but seems like 'timer' could'n get it). The time ran out too fast, faster if I click more on the pieces, and even if I set it longer it didn't change anything.

  2. When I clicked "New Game" the second times, timer ran out even faster. But if I close the programs and then run again, the time return normal.

  3. If the time ran out and then I click the "New Game" button again, It appears for 1 second then return to the "Game Over screen". Sometimes it works, but "IndexArrayOutOfBounds" Ecception appears.

  4. I want to use the "Pause" button, which means that timer must pause and then continue to run, too. Is there anyway that I can do it?

I guess my problems are based on the code

            if (val <= 0) {
                scr.gameOver();
                scr.timer = null;
                return;
            }

which makes the Game Over screen appears if the timer run out. But I'm new to this and I cant understand how I works, so I can't think of any solutions myself, or maybe it's not the problem.

Hope that I'll get some helps from you guys. Thanks a lot :)

解决方案

Your problem is that you don't use correct architecture pattern. You should separate your business logic from your presentation. Also you should store variables (like time_left) in model, not in the controller (i.e. ActionListener). Please read about: Model View Controller pattern. It's a basic pattern and it'll solve most of yours problems.

Basic Example

Editor.java - main class

public class Editor {
    public static void main(String[] args) {
        Model model = new Model();
        View view = new View(model);
        new Controller(model, view);
    }
}

View.java

public class View extends JFrame {

    private Model model;
    private JButton btn;

    public View(Model model) {
        this.model = model;
        this.btn = new JButton("Test");
    }

    public void addViewControlListener(ActionListener al){
        btn.addActionListener(al);
    }
}

Controller.java

public class Controller {
    public Controller(Model model, View view) {
        view.addViewControlListener(new ViewControlListener(model, view));
    }
}

ViewControlListener.java - implements ActionListener

public class ViewControlListener implements ActionListener {

    private Model model;
    private View view;

    public ViewControlListener(Model model, View view){
        this.model = model;
        this.view = view;
    }

    public void actionPerformed(ActionEvent e) {
        //update model
        //refresh view
    }

}

As you can see I have the one place (Controller.java) where I create listeners and add
these to components in view. You created multiple instances of the same listeners and lost control.

Also my ActionListener (ViewControlListener.java) holds instances of model and view, so it can update variables in model and refresh view.

Your application

And now something more about your application. You need thread (not realy action listener) that would decrement time variable and update view to show actual state (but only when game is active).

So you could create in model leftTime and isActive variables with setters and getters:

private int leftTime;
private boolean isActive;

public int getLeftTime() {
    return leftTime;
}

public void setLeftTime(int leftTime) {
    this.leftTime = leftTime;
}

public void decLeftTime() {
    this.leftTime--;
}

public boolean isActive() {
    return isActive;
}

public void setActive(boolean isActive) {
    this.isActive = isActive;
}

And create thread that decrement time every second and repaint the view:

public class Timer extends Thread {

    private Model model;
    private View view;

    public Timer(Model model, View view) {
        this.model = model;
        this.view = view;
    }

    public void run() {
        while(true) { //could be better
            if(model.isActive()) {
                model.decLeftTime();
                view.repaint();
            }
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Then create and start that thread in Controller:

public class Controller {
    public Controller(Model model, View view) {
        view.addViewControlListener(new ViewControlListener(model, view));
        ...
        Timer timer = new Timer(model, view);
        timer.start();
    }
}

In view you would add some component that shows left time from model and that's it.

PS do not forget set leftTime on game start.

这篇关于摇摆后,我如何使用程序一个游戏?暂停停止?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆