I'm making an asteroids kind of game, and I want to create knockback between ships. I tried doing this by calculating the angle between the two ships, then sending them both off with vectors in that angle (though one of the angles is negative so it goes the other way). For some reason, the ships teleport to the left and right edge (I made a wall to stop ships from leaving there) and never at an angle.
Below is my very unfinished ship. This is the one I'm controlling.
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
/**
* Write a description of class Enemy here.
*
* @author (your name)
* @version (a version number or a date)
*/
public class MyShip extends SmoothMover
{
private int gunReloadTime;
private int reloadDelayCount;
private int gold;
private int energy;
private int health;
private boolean knockback;
private int knockbackWait;
public int weapon;
public int shipLevel;
public MyShip()
{
gunReloadTime = 8;
reloadDelayCount = 8;
weapon =1;
shipLevel=1;
health = 10;
knockback = false;
knockbackWait = 0;
}
/**
* Act - do whatever the Enemy wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act()
{
knockback = false;
checkKeys();
reloadDelayCount++;
move();
checkCollision();
}
private void checkKeys()
{
if (Greenfoot.isKeyDown("space"))
{
fire();
}
if (knockback ==false)
{
if (Greenfoot.isKeyDown("left"))
{
this.addForce(new Vector(180, .6));
if (movement.getTheX()<-10)
{
movement.setX(-10);
}
if (movement.getTheX()>-2.5&&movement.getTheX()<2.5)
{
movement.setX(-2.5);
}
}
if (Greenfoot.isKeyDown("right"))
{
this.addForce(new Vector(0, .6));
if (movement.getTheX()>10)
{
movement.setX(10);
}
if (movement.getTheX()<2.5&&movement.getTheX()>-2.5)
{
movement.setX(4);
}
}
if (Greenfoot.isKeyDown("up"))
{
this.addForce(new Vector(270, .6));
if (movement.getTheY()<-10)
{
movement.setY(-10);
}
if (movement.getTheY()>-2.5&&movement.getTheY()<2.5)
{
movement.setY(-2.5);
}
}
if (Greenfoot.isKeyDown("down"))
{
this.addForce(new Vector(90, .6));
if (movement.getTheY()>10)
{
movement.setY(10);
}
if (movement.getTheY()<2.5&&movement.getTheY()>-2.5)
{
movement.setY(2.5);
}
}
}
if (movement.getTheX()>0.5)
{
movement.setX(movement.getTheX()-.2);
}
if (movement.getTheX()>0 &&movement.getTheX()<0.5)
{
movement.setX(movement.getTheX()-0.1);
if(movement.getTheX()<0)
{
movement.setX(0);
}
}
if (movement.getTheX()<-0.5)
{
movement.setX(movement.getTheX()+.2);
}
if (movement.getTheX()<0 &&movement.getTheX()>-0.5)
{
movement.setX(movement.getTheX()+0.1);
if(movement.getTheX()>0)
{
movement.setX(0);
}
}
if (movement.getTheY()>0.5)
{
movement.setY(movement.getTheY()-.2);
}
if (movement.getTheY()>0 &&movement.getTheY()<0.5)
{
movement.setY(movement.getTheY()-.1);
if(movement.getTheY()<0)
{
movement.setY(0);
}
}
if (movement.getTheY()<-0.5)
{
movement.setY(movement.getTheY()+.2);
}
if (movement.getTheY()<0 &&movement.getTheY()>-0.5)
{
movement.setY(movement.getTheY()+.1);
if(movement.getTheY()>0)
{
movement.setY(0);
}
}
if(exactX >= getWorld().getWidth()&&movement.getTheX()>0) {
exactX = getWorld().getWidth();
movement.setX(0);
}
if(exactX < 0&&movement.getTheX()<0) {
exactX = 0;
movement.setX(0);
}
if(exactY >= getWorld().getHeight()&&movement.getTheY()>0) {
exactY = getWorld().getHeight();
movement.setY(0);
}
if(exactY < 0&&movement.getTheY()<0) {
exactY = 0;
movement.setY(0);
}
knockbackWait--;
}
public void checkCollision()//here is most of the stuff
{
Enemy thing = (Enemy)getOneIntersectingObject(Enemy.class);
if (thing != null){
knockback = true;
double x = getX()-thing.getX();
double y = getY()-thing.getY();
double degrees = Math.atan(y/x);
if (x>0)
{
degrees = Math.PI-degrees;
}
else
{
degrees = -degrees;
}
if (knockbackWait<=0&&knockback ==true)
{
knockback = false;
zdegrees = 360-degrees*180/Math.PI;
System.out.println(degrees);
System.out.println("Force added at " + degrees);
this.addForce(new Vector(-degrees, 1.5));//if I replace -degrees with ANY angle it will work as intended. degrees also works as intended, I tested it and it always prints correctly. In addition, when I use a constant it goes the correct speed instead of teleporting.
knockbackWait = 100;//ignore knockbackWait and knockback, they are both failed attempts to fix the code
// thing.collide(degrees);
}
}
}
public void fire()
{
if (reloadDelayCount >= gunReloadTime)
{
if (shipLevel ==1)
{
if (weapon ==1)
{
DefaultLaser laser = new DefaultLaser (new Vector(270, 7.5), 270);
getWorld().addObject (laser, getX()-40, getY()+3);
laser.move();
laser =new DefaultLaser (new Vector(270, 7.5), 270);
getWorld().addObject (laser, getX()+40, getY()+3);
laser.move();
reloadDelayCount = 0;
}
}
}
}
public void hit(int change)
{
health = health - change;
if (health<=0)
{
death();
}
}
public void death()
{
getWorld().removeObject(this);
}
}