[英]A tile-based game frequently freezes when I run it. How can I fix this?
我最近發布了此消息,但我的問題措詞不正確,因此我再次嘗試了此問題。 作為Java類的項目,我一直在努力開發基於圖塊的Java游戲。 到目前為止,一切都進行得很好,但是我遇到的一個很大的問題是,當我運行游戲時,它將在大約50%的時間內凍結,而對按下的任何按鍵或應有的反應均無反應。 有時它起作用,有時卻不起作用。 它的結構與本教程有些相似,但是顯然我做了很多更改和補充。 我感覺這在我的游戲面板課程中正在發生,因為當游戲確實運行正常時,一切似乎都按預期運行,因此我將在該課程后發布。 對於代碼中的任何奇怪或非常規的內容,我也深表歉意。我還是一個業余愛好者,因此如果需要澄清,我會提供。
所以我的主要問題是,是否有人知道問題出在哪里,或者對如何解決凍結有任何建議? 謝謝!
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;
}
}
}
不要使用Swing組件的getGraphics()進行繪畫。 通過重寫paintComponent()
方法可以完成自定義繪制。
使用Swing Timer
來安排動畫,而不是線程。
不要使用KeyListener偵聽KeyEvent。 相反,您應該使用Key Bindings
。
我建議您先閱讀Swing教程 。 本教程中的各個部分涵蓋了以上幾點。
不要使用requestFocus()。 使用更好的方法是requestFocusInWindow()
。 盡管除非將組件顯示在可見的GUI上,否則這兩種方法都不會起作用,因此將代碼放在構造函數中不會執行任何操作。
靜態最終常數變量應完全大寫,而不僅僅是首字母。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.