2016-10-10 4 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, чтобы быть двойными, а затем округлите их только перед отображением местоположения, у вас не должно быть этой проблемы.

Смежные вопросы