As a self-project, I'm trying to make the game 'Asteroids'.
Currently, I'm stuck on trying to figure out how to make it so the lasers fired from my ship appear from the tip of the ship. So far, I've tried experimenting with using the Shape
object's .getBounds2D().getX()
methods, but because getBounds2D()
draws a rectangle around the polygon, the lasers end up appearing from the corner of the imaginary 'box' around my Polygon ship
.
Here's a gif of what I have so far.
Is there a way to 'get' a specific point from a Shape object; where, in this case, that specific point is the tip of the ship.
Main Class:
public class AsteroidGame implements ActionListener, KeyListener{
public static AsteroidGame game;
public Renderer renderer;
public boolean keyDown = false;
public int playerAngle = 0;
public boolean left = false;
public boolean right = false;
public boolean go = false;
public boolean back = false;
public boolean still = true;
public double angle = 0;
public int turnRight = 5;
public int turnLeft = -5;
public Shape transformed;
public ArrayList<Laser> lasers;
public ArrayList<Shape> transformedLasers;
public final int WIDTH = 1400;
public final int HEIGHT = 800;
public Ship ship;
public Rectangle shipHead;
public Shape shipHeadTrans;
public Point headPoint;
public AffineTransform transform = new AffineTransform();
public AffineTransform lasTransform = new AffineTransform();
public AffineTransform headTransform = new AffineTransform();
public AsteroidGame(){
JFrame jframe = new JFrame();
Timer timer = new Timer(20, this);
renderer = new Renderer();
jframe.add(renderer);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setSize(WIDTH, HEIGHT);
jframe.setVisible(true);
jframe.addKeyListener(this);
jframe.setResizable(false);
int xPoints[] = {800, 780, 800, 820};
int yPoints[] = {400, 460, 440, 460};
//(800, 400) is the initial location of the 'tip' of the ship'.
headPoint = new Point(800, 400);
lasers = new ArrayList<Laser>();
transformedLasers = new ArrayList<Shape>();
ship = new Ship(xPoints, yPoints, 4, 0);
transformed = transform.createTransformedShape(ship);
shipHead = new Rectangle(headPoint);
shipHeadTrans = transform.createTransformedShape(shipHead);
//shipHeadTrans.getBounds2D().
timer.start();
}
public void repaint(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(0, 0, WIDTH, HEIGHT);
Graphics2D g2d = (Graphics2D)g;
//drawing the ship
g2d.setColor(Color.WHITE);
g2d.draw(transformed);
//drawing lasers
g2d.setColor(Color.RED);
for (int i = 0; i < transformedLasers.size(); i++){
System.out.println(i);
g2d.draw(transformedLasers.get(i));
}
}
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
/*The for if and else if statements are just to send the ship
* to the other side of the canvas if it ever leaves the screen
*/
if (transformed.getBounds2D().getMinX() > WIDTH){
double tempAng = ship.getAng();
double diff = 90-tempAng;
transform.rotate(Math.toRadians(diff), ship.getCenterX(), ship.getCenterY());
transform.translate(0,WIDTH);
transform.rotate(Math.toRadians(-diff), ship.getCenterX(), ship.getCenterY());
}
else if (transformed.getBounds2D().getX() < 0){
double tempAng = ship.getAng();
double diff = 90-tempAng;
transform.rotate(Math.toRadians(diff), ship.getCenterX(), ship.getCenterY());
transform.translate(0,-WIDTH);
transform.rotate(Math.toRadians(-diff), ship.getCenterX(), ship.getCenterY());
}
else if (transformed.getBounds2D().getY() > HEIGHT){
double tempAng = ship.getAng();
double diff = 180-tempAng;
transform.rotate(Math.toRadians(diff), ship.getCenterX(), ship.getCenterY());
transform.translate(0,HEIGHT);
transform.rotate(Math.toRadians(-diff), ship.getCenterX(), ship.getCenterY());
}
else if (transformed.getBounds2D().getY() < 0){
double tempAng = ship.getAng();
double diff = 180-tempAng;
transform.rotate(Math.toRadians(diff), ship.getCenterX(), ship.getCenterY());
transform.translate(0,-HEIGHT);
transform.rotate(Math.toRadians(-diff), ship.getCenterX(), ship.getCenterY());
}
if (right){
ship.right();
//rotating the ship
transform.rotate(Math.toRadians(turnRight), ship.getCenterX(), ship.getCenterY());
//rotating the 'tip' of the ship.
headTransform.rotate(Math.toRadians(turnRight), ship.getCenterX(), ship.getCenterY());
}
else if (left){
ship.left();
//rotating the ship
transform.rotate(Math.toRadians(turnLeft), ship.getCenterX(), ship.getCenterY());
//rotating the 'tip' of the ship
headTransform.rotate(Math.toRadians(turnLeft), ship.getCenterX(), ship.getCenterY());
}
if (go){
ship.go();
}
else if (back){
ship.reverse();
}
//moving and shaping each individual laser that had been shot
for (int i = 0; i < transformedLasers.size(); i++){
lasers.get(i).move();
lasTransform = new AffineTransform();
lasTransform.rotate(Math.toRadians(lasers.get(i).getAng()), transformed.getBounds2D().getX(), transformed.getBounds2D().getY());
transformedLasers.set(i, lasTransform.createTransformedShape(lasers.get(i)));
}
//moving the ship
ship.move();
//moving the 'tip'
shipHead.y -= ship.getSpeed();
transformed = transform.createTransformedShape(ship);
shipHeadTrans = headTransform.createTransformedShape(shipHead);
renderer.repaint();
}
//defining a new laser
public void fireLaser(){
Laser tempLaser = new Laser((int)transformed.getBounds2D().getX(), (int)transformed.getBounds2D().getY(), 5, 10, ship.getAng());
lasers.add(tempLaser);
lasTransform = new AffineTransform();
lasTransform.rotate(Math.toRadians(ship.getAng()), transformed.getBounds2D().getX(), transformed.getBounds2D().getY());
transformedLasers.add(lasTransform.createTransformedShape(tempLaser));
}
public static void main(String[] args){
game = new AsteroidGame();
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() == KeyEvent.VK_RIGHT){
right = true;
keyDown = true;
}else if (e.getKeyCode() == KeyEvent.VK_LEFT){
left = true;
keyDown = true;
}
else if (e.getKeyCode() == KeyEvent.VK_UP){
go = true;
}
else if (e.getKeyCode() == KeyEvent.VK_DOWN){
back = true;
}
//fire laser
if (e.getKeyCode() == KeyEvent.VK_SPACE){
fireLaser();
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() == KeyEvent.VK_RIGHT){
right = false;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT){
left = false;
}
if (e.getKeyCode() == KeyEvent.VK_UP){
go = false;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN){
back = false;
}
still = true;
keyDown = false;
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
Ship Class (I don't think it's relevant though)
package asteroidGame;
import java.awt.Polygon;
import java.util.Arrays;
public class Ship extends Polygon{
/**
*
*/
private double currSpeed = 0;
private static final long serialVersionUID = 1L;
public double angle;
public int[] midX;
public int[] midY;
public Ship(int[] x, int[] y, int points, double angle){
super(x, y, points);
midX = x;
midY = y;
this.angle= angle;
}
public void right(){
angle += 5;
}
public void left(){
angle -= 5;
}
public void move(){
for (int i = 0; i < super.ypoints.length; i++){
super.ypoints[i] -= currSpeed;
//System.out.println(super.ypoints[i]);
//System.out.println(super.xpoints[i]);
}
//System.out.println(Arrays.toString(super.ypoints));
}
public double getSpeed(){
return currSpeed;
}
public void reverse(){
if (currSpeed > -15) currSpeed -= 0.2;
}
public void go(){
if (currSpeed < 25) currSpeed += 0.5;
}
public int getCenterX(){
return super.xpoints[2];
}
public int getCenterY(){
return super.ypoints[2];
}
public double getAng(){
return angle;
}
public void test(){
for (int x = 0; x < super.ypoints.length; x++){
super.ypoints[x] += 1000;
}
}
/*
public void decrement(){
if(currSpeed == 0){}
else if (currSpeed > 0 && currSpeed < 15){
currSpeed -= 0.05;
}
else if (currSpeed < 0 && currSpeed > -15){
currSpeed += 0.05;
}
System.out.println("losing speed");
}
*/
}
Laser Class (I don't think this is relevant either, but here ya go.)
package asteroidGame;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
public class Laser extends Rectangle{
private double angle;
public Laser(int x, int y , int width, int height, double ang){
super(x, y, width, height);
angle = ang;
Rectangle tst = new Rectangle();
}
public void move(){
super.y -= 35;
}
public double getAng(){
return angle;
}
public boolean intersects (Rectangle2D r){
//if intersects
if (super.intersects(r)){
return true;
}
else{
return false;
}
}
}
I was thinking of maybe turning the the Shape object transformed
back into a Polygon to get the point, but I'm not sure how or if that would work.