2011-12-22 71 views
0

我最近用java編寫了我的第一個簡單的側面滾動遊戲,但是我遇到了一些滯後,我不知道爲什麼。當我側身移動我的角色時,它似乎正在改變速度,大部分時間很快,但有時會放慢速度。它讓遊戲的感覺很奇怪。我希望有人能指出我朝着正確的方向,我會後我下面的類:在Java簡單的側面滾動遊戲中的滯後

主類:

public class MainGame { 

    public static void main(String[] args) { 
     Frame frame = new Frame(); 
    } 

} 

框架類:

import javax.swing.JFrame; 


public class Frame extends JFrame{ 

    public Frame(){ 
     add(new Board()); 
     setTitle("2-D Test Game"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setSize(800,325); 
     this.setResizable(false); 
     setLocationRelativeTo(null); 
     setVisible(true); 
    } 

} 

板類:

import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Image; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import javax.swing.*; 


public class Board extends JPanel implements ActionListener{ 


    private Player p; 
    private Timer timer; 
    private Image background; 

    public Board(){ 
     super(); 
     p = new Player(); 
     addKeyListener(new ActionListener()); 
     setFocusable(true); 
     ImageIcon i = new ImageIcon("C:/test.png"); 
     background = i.getImage(); 
     timer = new Timer(5,this); 
     timer.start(); 
    } 

    public void actionPerformed(ActionEvent arg0) { 
     p.move(); 
     repaint(); 
    } 

    public void paint(Graphics g){ 
     super.paint(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.drawImage(background,p.nx,0,null); 
     g2d.drawImage(p.getImage(), 350, p.getY(), null); 
    } 

    private class ActionListener extends KeyAdapter{ 
     public void keyReleased(KeyEvent e){ 
      p.keyReleased(e); 
     } 

     public void keyPressed(KeyEvent e){ 
      p.keyPressed(e); 
     } 
    } 

} 

玩家等級:

import java.awt.Image; 
import java.awt.event.KeyEvent; 
import javax.swing.*; 


public class Player { 

    private Image img; 
    int x,y,dx,dy,nx; 
    long time; 
    private final int SPEED = 2; 
    private final int GRAV = 1; 
    boolean left,right,isJumping; 

    public Player(){ 
     ImageIcon i = new ImageIcon("C:/plager.png"); 
     img = i.getImage(); 
     x = 350; 
     y = 160; 
     dx = 0; 
     dy = 0; 
     nx = 0; 
     left = false; 
     right = false; 
     isJumping = false; 
    } 

    public void move(){ 
     x += dx; 
     nx = (nx-dx); 
    } 


    public int getX(){ 
     return x; 
    } 

    public int getY(){ 
     return y; 
    } 

    public Image getImage(){ 
     return img; 
    } 

     public void keyReleased(KeyEvent e) { 
      int code = e.getKeyCode(); 
      if(code == KeyEvent.VK_LEFT){ 
       left = false; 
       if(right){ 
        dx = SPEED; 
       }else{ 
        dx = 0; 
       } 
      }else if(code == KeyEvent.VK_RIGHT){ 
       right = false; 
       if(left){ 
        dx = -SPEED; 
       }else{ 
        dx = 0; 
       } 
      } 
     } 

     public void keyPressed(KeyEvent e) { 
      int code = e.getKeyCode(); 
      if(code == KeyEvent.VK_LEFT){ 
       left = true; 
       dx = -SPEED; 
      }else if(code == KeyEvent.VK_RIGHT){ 
       right = true; 
       dx = SPEED; 
      } 
     } 

} 
+2

您是否在嘗試使用較高的ms值設置「Timer」?通常計時不準確到不到15ms左右。 – cgull 2011-12-22 19:09:45

+0

您還有一些多線程潛在的複雜性:在關鍵事件上,'dx'在Swing事件分派線程(EDT)上發生了變化,但它也在'Player.move()'的計時器線程中使用。計時器線程中'dx'的值可能不是最新的。但是,由於角色確實移動了,但速度並不正確,所以您的主要問題可能是其他問題,例如上面提到的定時器不準確性。使用'AtomicInteger dx'可以解決同步問題。 – toto2 2011-12-22 19:30:48

+1

這確實是一個時間問題,當我設定一個更高的價值時,問題就消失了。非常感謝你! – 2011-12-22 19:39:20

回答

1

計時器沒有實時保證。所以,你應該計算上一次移動的時間差,並乘以移動的數量。它會使數字更小,所以我會添加另一個const使其更大。實際上,在actionPerformed(或其他處理方法)中獲取時間增量並將其傳遞給所有進程或移動方法會更好,因此所有內容都使用相同的時間增量進行移動。