2016-10-10 11 views
-2

今、私は古典的なゲームの小惑星を作ることに取り組んでいます。矢印キーを使って船を360度動かす。しかし、私はその角度で船からボールを​​撃つことを試みるとき、それらは45度の増分でだけ残す。ボールクラスの私の数学に何か問題があることを意味します:小惑星ボールの角度計算

public Ball(double ballAngle){ 

    angle = ballAngle; 

    xRatio = Math.cos((angle + 90) * 3.14/180); 
    yRatio = Math.sin((angle + 90) * 3.14/180); 

    xChange = xRatio * speed; 
    yChange = yRatio * speed; 

} 

public void update(){ 

    x = (int) Math.round(x + xChange); 
    y = (int) Math.round(y + yChange); 

} 

しかし、私は何が起こっているのか分からないようです。私は値を次の段階で印刷してデバッグしようとしましたが、それでも解決できません。ここに私のコードの残りの部分はあなたがそれを見る必要があります。

メインのゲームクラス:

package Asteroids; 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import java.util.ArrayList; 

@SuppressWarnings("serial") 
public class Asteroids extends JPanel implements KeyListener{ 

public final static int BOX_WIDTH = 600; 
public final static int BOX_HEIGHT = 600; 

public final static int UPDATE_RATE = 300; 

public final static double shipSpeed = 1; 

ArrayList<Ball> balls = new ArrayList<Ball>(); 

int i = 0; 

int ballCount = 0; 

boolean spawn = false; 

Ship ship = new Ship(BOX_WIDTH/2,BOX_HEIGHT/2); 

public Asteroids(){ 

    //Set window size 
    setPreferredSize(new Dimension(BOX_WIDTH,BOX_HEIGHT)); 

    //Start game thread 
    Thread gameThread = new Thread() { 

     public void run(){ 

      while(true){ 

       ship.update(); 

       for (int j=0; j<ballCount; j++){ 

        balls.get(j).update(); 

       } 

       if(spawn){ 

        i++; 

       } 

       if(i % 100 == 0){ 

        balls.add(new Ball(ship.getAngle())); 
        ballCount ++; 

       } 

       repaint(); 

       try {Thread.sleep(1000/UPDATE_RATE);} 
       catch (InterruptedException ex) {} 

      } 
     } 

    }; 

    gameThread.start(); 

} 


@Override 
public void paintComponent(Graphics g) { 

    g.setColor(Color.black); 

    g.fillRect(0, 0, BOX_WIDTH, BOX_HEIGHT); 

    for (int j=0; j<ballCount; j++){ 

     balls.get(j).draw(g); 

    } 

    ship.draw(g); 

} 

public void keyPressed(KeyEvent e){ 

    if(e.getKeyCode() == KeyEvent.VK_LEFT){ 

     ship.setSpeed(-shipSpeed); 

    } 

    if(e.getKeyCode() == KeyEvent.VK_RIGHT){ 

     ship.setSpeed(shipSpeed); 

    } 

    if(e.getKeyCode() == KeyEvent.VK_SPACE){ 

     spawn = true; 

    } 

} 

public void keyReleased(KeyEvent e) { 

    if(e.getKeyCode() == KeyEvent.VK_LEFT){ 

     ship.setSpeed(0); 

    } 

    if(e.getKeyCode() == KeyEvent.VK_RIGHT){ 

     ship.setSpeed(0); 

    } 

    if(e.getKeyCode() == KeyEvent.VK_SPACE){ 

     spawn = false; 

    } 

} 

public void keyTyped(KeyEvent e) {} 

public static void main(String[] args) { 

    javax.swing.SwingUtilities.invokeLater(new Runnable() { 

      public void run() { 

       //Create Frame 
       JFrame frame = new JFrame("ASTEROIDS"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       Asteroids asteroids = new Asteroids(); 
       frame.setContentPane(asteroids); 
       frame.setSize(BOX_WIDTH,BOX_HEIGHT); 
       frame.pack(); 
       frame.addKeyListener(asteroids); 
       frame.setVisible(true); 

      } 

     }); 

} 

public int getBoxHeight(){ 

    return BOX_HEIGHT; 

} 

public int getBoxWidth(){ 

    return BOX_WIDTH; 

} 

} 

船クラス:

package Asteroids; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.util.Random; 

public class Ship { 

Random rng = new Random(); 

int r = rng.nextInt(256); 
int g = rng.nextInt(256); 
int b = rng.nextInt(256); 

Color color = new Color(r,g,b); 

double speed = 0; 

double angle = 0; 

final static int shipLength = 20; 
final static int shipAngle = 40; 

static int x; 
static int y; 

int point1x; 
int point2x; 
int point3x; 

int point1y; 
int point2y; 
int point3y; 

public Ship(int xPos, int yPos){ 

    x = xPos; 
    y = yPos; 

    point1x = x; 
    point2x = (int) Math.round(x - (Math.tan(shipAngle * 6.28/360) * shipLength)); 
    point3x = (int) Math.round(x + (Math.tan(shipAngle * 6.28/360) * shipLength)); 

    point1y = y - shipLength; 
    point2y = y + shipLength; 
    point3y = y + shipLength; 

} 

public void update(){ 

    angle = angle + speed; 

    if(angle < 0){ 

     angle = angle + 360; 

    } 

    else if(angle >= 360){ 

     angle = angle - 360; 

    } 

} 

public void draw(Graphics g) { 

    g.setColor(color); 

    point1x = x - (int) Math.round(Math.sin(angle * 6.28/360) * shipLength); 
    point2x = x + (int) Math.round(Math.sin((angle + shipAngle) * 6.28/360) * shipLength); 
    point3x = x + (int) Math.round(Math.sin((angle - shipAngle) * 6.28/360) * shipLength); 

    point1y = y + (int) Math.round(Math.cos(angle * 6.28/360) * shipLength); 
    point2y = y + (int) Math.round(Math.cos((angle + 180 + shipAngle) * 6.28/360) * shipLength); 
    point3y = y + (int) Math.round(Math.cos((angle - 180 - shipAngle) * 6.28/360) * shipLength); 

    int xpoints[] = {point1x, point2x, point3x}; 
    int ypoints[] = {point1y, point2y, point3y}; 
    int npoints = 3; 

    g.fillPolygon(xpoints, ypoints, npoints); 

} 

public void setSpeed(double s){ 

    speed = s; 

} 

public static int getX(){ 

    return x; 

} 

public static int getY(){ 

    return y; 

} 

public double getAngle(){ 

    return angle; 

} 

} 

ボールクラス:

package Asteroids; 

import java.awt.Color; 
import java.awt.Graphics; 

public class Ball { 

int x = Ship.getX(); 
int y = Ship.getY(); 

double angle; 

double xRatio; 
double yRatio; 

double xChange; 
double yChange; 

final static int speed = 1; 

final static int diameter = 5; 

public Ball(double ballAngle){ 

    angle = ballAngle; 

    xRatio = Math.cos((angle + 90) * 3.14/180); 
    yRatio = Math.sin((angle + 90) * 3.14/180); 

    xChange = xRatio * speed; 
    yChange = yRatio * speed; 

} 

public void update(){ 

    x = (int) Math.round(x + xChange); 
    y = (int) Math.round(y + yChange); 

} 

public void draw(Graphics g) { 

    g.setColor(Color.white); 

    g.fillOval(x - diameter/2, y - diameter/2, diameter, diameter); 

} 

} 
+1

何百行ものコードを読み込む必要がある場合は、誰も手助けしたくありません。関連するコンテンツのみを含めるか、問題を再現する可能な限り小さなコードにプログラムを分割してください。 –

答えて

2

私はその丸め誤差を疑うでしょう。 xとyをintプリミティブとして格納していますが、倍精度を追加してintに戻します。 xとyをdoubleに変更してから位置を表示する前に丸めるだけの場合は、この問題は発生しません。