简体   繁体   English

我在运行基于图块的游戏时经常冻结。 我怎样才能解决这个问题?

[英]A tile-based game frequently freezes when I run it. How can I fix this?

I recently posted this but my question wasn't properly worded, so I'm trying this again. 我最近发布了此消息,但我的问题措词不正确,因此我再次尝试了此问题。 I've been diligently working on a tile-based Java game as a project for my Java class. 作为Java类的项目,我一直在努力开发基于图块的Java游戏。 Everything is going very well so far, but a pretty big problem that I'm having is that when I run my game, it will start frozen about 50% of the time, not reacting to any keys pressed or anything like it should. 到目前为止,一切都进行得很好,但是我遇到的一个很大的问题是,当我运行游戏时,它将在大约50%的时间内冻结,而对按下的任何按键或应有的反应均无反应。 Sometimes it works and sometimes it doesn't. 有时它起作用,有时却不起作用。 It's somewhat similar in structure to this tutorial , but there are obviously a lot of changes and additions that I have made. 它的结构与本教程有些相似,但是显然我做了很多更改和补充。 I have a feeling it is happening in my game panel class, because everything seems to function as intended when the game DOES run correctly, so I'll put post that class. 我感觉这在我的游戏面板课程中正在发生,因为当游戏确实运行正常时,一切似乎都按预期运行,因此我将在该课程后发布。 I also apologize for anything strange or unconventional in my code, I'm still kind of an amateur at coding so if clarification is needed I will supply it. 对于代码中的任何奇怪或非常规的内容,我也深表歉意。我还是一个业余爱好者,因此如果需要澄清,我会提供。

So my main question is does anyone know what the problem is or have any suggestions for how I can remedy the freezing? 所以我的主要问题是,是否有人知道问题出在哪里,或者对如何解决冻结有任何建议? Thanks! 谢谢!

panel.java: panel.java:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class panel extends JPanel implements KeyListener, Runnable
{
    //game variables
    private Thread game;
    private boolean running = false;
    private boolean mapFinished = false;
    player p1;

    //panel variables
    static final int Width = 480;
    static final int Height = 432;
    static final Dimension dim = new Dimension(Width,Height);

    //maps
    map map1;
    map map2;
    map map3;
    map map4;

    enemy e;

    boolean map1Finished;
    boolean map2Finished;
    boolean map3Finished;
    boolean map4Finished;

    //drawing variables
    private BufferedImage image;
    private Graphics g;
    private long time = 6*1000000;
    goal ng;
    private Image winningImage;

    private boolean map2Spawn;
    private boolean map3Spawn;
    private boolean map4Spawn;

    public panel(){
        map1 = new map("tester.txt");
        map2 = new map("tester2.txt");
        map3 = new map("tester3.txt");
        map4 = new map("tester4.txt");
        p1 = new player(map1);
        ng = new goal(map1);
        e = new enemy(map1);
        setPreferredSize(new Dimension(Width,Height));
        setFocusable(true);
        requestFocus();
    }

    public void run(){
        long startTime;
        long elapsedTime;
        long diff;
        long sleepTime;
        long overSleep=0;

        image=new BufferedImage(Width,Height,BufferedImage.TYPE_INT_RGB);
        g=image.getGraphics();
        running = true;

        while (running){
            startTime=System.nanoTime();
            gameUpdate();
            gameRender();
            gameDraw();
            elapsedTime=System.nanoTime();
            diff=elapsedTime-startTime;
            if(diff<time){
                sleepTime=time-diff-overSleep;
                try{
                    game.sleep(sleepTime/1000000);
                }
                catch(Exception e){

                }
            }
            else{
                overSleep=diff-time;
            }
        }
    }

    private void gameUpdate(){
        p1.update();

        if((p1.playerRec.x/48)==(ng.goalRec.x/48) && (p1.playerRec.y/48)==(ng.goalRec.y/48)){
            if(!map1Finished){
                map1Finished=true;
            }
            else if(map1Finished&&!map2Finished){
                map2Finished=true;
            }
            else if(map2Finished&&!map3Finished){
                map3Finished=true;
            }
            else if(map3Finished&&!map4Finished){
                map4Finished=true;
            }

        }

        changeSpawn();
    }

    private void gameRender(){
        g.setColor(Color.WHITE);
        g.fillRect(0,0,Width,Height);
        g.setColor(Color.BLACK);
        if (!map1Finished){
            map1.draw(g);
            p1.draw(g);
        }


        if (map1Finished&&!map2Finished){
            map2.draw(g);
            p1.draw(g);
            winningImage=new ImageIcon("sprites/level1.png").getImage();
            g.drawImage(winningImage,5,5,null);
        }
        if (map2Finished&&!map3Finished){
            map3.draw(g);
            p1.draw(g);
            winningImage=new ImageIcon("sprites/level1.png").getImage();
            g.drawImage(winningImage,5,5,null);
        }
        if (map3Finished&&!map4Finished){
            map4.draw(g);
            p1.draw(g);
            winningImage=new ImageIcon("sprites/level1.png").getImage();
            g.drawImage(winningImage,5,5,null);
        }
        //g.drawString(""+map1.tileMap[1][7], 100, 100);
    }

    public void gameDraw(){
        Graphics g2=this.getGraphics();
        g2.drawImage(image, 0, 0, null);
        g2.dispose();
    }

    public void keyTyped(KeyEvent key) {}

    public void keyPressed(KeyEvent key) {

    int code = key.getKeyCode();    
    if(code == KeyEvent.VK_LEFT) {
            p1.setLeft(true);
    }
    if(code == KeyEvent.VK_RIGHT) {
            p1.setRight(true);
    }
    if(code == KeyEvent.VK_UP) {
            p1.setUp(true);
    }
    if(code == KeyEvent.VK_DOWN) {
            p1.setDown(true);
    }
    }

    public void keyReleased(KeyEvent key) {
    int code = key.getKeyCode();
    if(code == KeyEvent.VK_LEFT) {
        p1.setLeft(false);
    }
    if(code == KeyEvent.VK_RIGHT) {
        p1.setRight(false);
    }
    }

    public void addNotify(){
        super.addNotify();
        if(game==null){
            game=new Thread(this);
            game.start();
        }
        addKeyListener(this);
    }

    public void startGame(){
        if (running == false){
            running = true; 
        }
    }

    public void stopGame(){
        if (running == true)
        {
            running = false; 
        }
    }

    public boolean boolTimer(){
        long now=System.currentTimeMillis();
        long end = now+1*3000;
        long current = System.currentTimeMillis();
        while(current<end){
            current = System.currentTimeMillis();
        }
        return true;
    }

    public void changeSpawn(){
        if(map1Finished==true && map2Spawn==false){
            p1=new player(map2);
            ng=new goal(map2);
            map2Spawn=true;
        }

        else if(map2Finished==true && map3Spawn==false){
            p1=new player(map3);
            ng=new goal(map3);
            map3Spawn=true;
        }
        else if(map3Finished==true && map4Spawn==false){
            p1=new player(map4);
            ng=new goal(map4);
            map4Spawn=true;
        }
    }
}
  1. don't use getGraphics() of a Swing component to do painting. 不要使用Swing组件的getGraphics()进行绘画。 Custom painting is done by overriding the paintComponent() method of the JPanel. 通过重写paintComponent()方法可以完成自定义绘制。

  2. Use a Swing Timer to schedule the animation, not a Thread. 使用Swing Timer来安排动画,而不是线程。

  3. Don't use a KeyListener to listen for KeyEvents. 不要使用KeyListener侦听KeyEvent。 Instead you should be using Key Bindings . 相反,您应该使用Key Bindings

I suggest you start by reading the Swing tutorial . 我建议您先阅读Swing教程 There are sections in the tutorial that cover the above points. 本教程中的各个部分涵盖了以上几点。

  1. Don't use requestFocus(). 不要使用requestFocus()。 The better method to use is requestFocusInWindow() . 使用更好的方法是requestFocusInWindow() Although neither method will work unless the component is displayed on a visible GUI, so placing the code in the constructor doesn't do anything. 尽管除非将组件显示在可见的GUI上,否则这两种方法都不会起作用,因此将代码放在构造函数中不会执行任何操作。

  2. static final constant variables should be completely upper cased, not just the first letter. 静态最终常数变量应完全大写,而不仅仅是首字母。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在基于图块的游戏中更新照明 - Updating lighting in a tile-based game 基于图块的游戏上的重复图块 - Duplicated tiles on tile-based game 基于二维平铺的游戏:每个平铺作为一个对象是不切实际的? - 2-Dimensional Tile-Based Game: Each tile as an object impractical? 用于基于图块的游戏的Java 2D游戏引擎 - Java 2D Game engine for tile-based Game 资源加载到ArrayList中,用于基于图块的游戏。 (JAVA) - Resource loading into ArrayList for tile-based game. (Java) 我第一次尝试制作一个简单的基于图块的Java游戏 - My first time trying to make a simple tile-based java game 基于图块的碰撞; 拐角碰撞问题 - Tile-based collision; Corner collision problems 当我尝试关闭程序时。 如何解决这个无限循环? - Looping program when I try to close it. How do I fix this infinite loop? NullPointerException被抛出,但我不知道如何解决它。 - A NullPointerException is being thrown but I can't figure out how to fix it. 使用浏览器视图打开IntelliJ的Scenebuilder时。 我无法运行/调试应用程序,因为BrowserContext已锁定 - When opening IntelliJ's Scenebuilder with a browserview in it. I can't run/debug the app because the BrowserContext is locked
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM