2011-12-22 2 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

「Timer」を設定するときに、より高いms値を使用しようとしましたか?通常、タイミングは15ms程度以下では正確ではありません。 – cgull

+0

また、マルチスレッドの問題もあります: 'dx'はキーイベントのSwingイベントディスパッチスレッド(EDT)で変更されますが、' Player.move() 'のタイマースレッドでも使用されます。 'dx'の値はタイマースレッドでは最新ではないかもしれません。しかし、キャラクターは動くが正しいスピードでは動かないので、あなたの主な問題はおそらく上記のタイマーの不正確さのようなものかもしれません。 'AtomicInteger dx'を使うと、同期の問題が解決されます。 – toto2

+1

それは本当にタイミングの問題でした。私がより高い価値を設定すると、問題は消えます。どうもありがとうございました! –

答えて

1

タイマーはリアルタイム保証がありません。したがって、移動が最後に呼び出されてからの時間差を計算し、移動した量で乗算する必要があります。私はそれを大きくするために別のconstを追加するので、数字が小さくなります。実際には、actionPerformed(または別のプロセスメソッド)の時間デルタを取得し、すべてのプロセスまたは移動メソッドに渡して、すべてが同じ時間デルタを使用して移動するようにしてください。

関連する問題