2016-10-10 96 views
-2

現在我正在製作經典遊戲Asteroids。我使用箭頭鍵使船舶移動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; 

} 

} 

Ball類:

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基本類型,但隨後將double添加到它中,並將其存儲回int中。如果您將x和y更改爲雙打,然後在顯示位置之前將它們四捨五入,則不應出現此問題。