小行星球角计算

时间:2016-10-10 18:12:47

标签: java math trigonometry

现在我正在制作经典游戏小行星。我已经让船使用箭头键移动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 个答案:

答案 0 :(得分:2)

我怀疑它有一个舍入错误。您将x和y存储为int基元,然后向其添加双精度数,并将其存储回int中。如果您将x和y更改为双打,然后仅在显示位置之前将它们舍入,则不应该出现此问题