Re: Asteroids fly physics
I'm not sure if I fully understand your question, but I will attempt to answer it by providing some simple motion logic that should work for asteroids. You could use vectors or just floats or some such. I'll use the latter for this example.
Given these fields:
float x, y; // position of the asteroid (x, y)
float speed, heading; // speed is pixels per update, heading is the angle in radians (0 to 2pi)
Every time your game updates, the position should be changed according to the speed and heading, like so:
x += speed * Math.cos(heading);
y += speed * Math.sin(heading);
As for the "original flight behavior," I would start the asteroid at a random position and random direction:
// init
x = Math.random() * WIDTH;
y = Math.random() * HEIGHT;
heading = Math.random() * 2 * Math.PI
speed = ?; //whatever you want to start the speed at
You may want to add some logic so that the initial location isn't overlapping the player at start, and for when the asteroids move beyond the edges of the screen they "wrap around" to the other side, and perhaps some acceleration.
Re: Asteroids fly physics
First of all, thank you, but the asteroids aren't the problem, it's the movement of the player spaceship.
Re: Asteroids fly physics
Ah, sorry about that. The logic for a spaceship moving is pretty much the same as the asteroid, though. It would probably help a lot if you posted a some of your code.
Re: Asteroids fly physics
This is what my code looks like. Currently, I haven't any spaceship or asteroid objects, i just wanted to know, how to let the spaceship fly like in the original game. The other problem is my Timer class.... I don't really know how to program a Timer class,... so... I think my solution is really bad, I hope you can help me.
Start.java
Code:
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Vector2f;
public class Start extends BasicGame {
private final static int WINDOW_WIDTH = 800;
private final static int WINDOW_HEIGHT = 600;
private Image spaceship;
private Vector2f spaceshipPosition;
private Vector2f viewDirection;
private Vector2f currentDirection;
private float speed;
public Start() {
super( "Asteroids" );
}
public static void main( String[] args ) throws SlickException {
AppGameContainer gc = new AppGameContainer( new Start() );
gc.setDisplayMode( WINDOW_WIDTH, WINDOW_HEIGHT, false );
gc.setShowFPS( false );
gc.start();
}
@Override
public void init( GameContainer container ) throws SlickException {
speed = 0.0f;
spaceship = new Image( "res/spaceship.png" );
float startxPosition = WINDOW_WIDTH / 2 - spaceship.getWidth() / 2;
float startyPosition = WINDOW_HEIGHT / 2 - spaceship.getHeight() / 2;
spaceshipPosition = new Vector2f( startxPosition, startyPosition );
viewDirection = new Vector2f();
currentDirection = new Vector2f();
currentDirection.x = (float) ( Math.sin( Math.toRadians( spaceship.getRotation() ) ) * speed );
currentDirection.y = (float) ( Math.cos( Math.toRadians( spaceship.getRotation() ) ) * speed );
}
@Override
public void render( GameContainer container, Graphics g ) throws SlickException {
spaceship.draw( spaceshipPosition.x, spaceshipPosition.y );
}
@Override
public void update( GameContainer container, int delta ) throws SlickException {
viewDirection.x = (float) ( Math.sin( spaceship.getRotation() ) );
viewDirection.y = (float) ( Math.cos( spaceship.getRotation() ) );
Input input = container.getInput();
if ( input.isKeyDown( Input.KEY_UP ) ) {
accelerate();
spaceshipPosition.x += (float) ( Math.sin( Math.toRadians( spaceship.getRotation() ) ) * delta * speed );
spaceshipPosition.y -= (float) ( Math.cos( Math.toRadians( spaceship.getRotation() ) ) * delta * speed );
}
if ( !input.isKeyDown( Input.KEY_UP ) ) {
slowDown();
spaceshipPosition.x += (float) ( Math.sin( Math.toRadians( spaceship.getRotation() ) ) * delta * speed );
spaceshipPosition.y -= (float) ( Math.cos( Math.toRadians( spaceship.getRotation() ) ) * delta * speed );
}
if ( input.isKeyDown( Input.KEY_RIGHT ) ) {
spaceship.rotate( 4.0f );
}
if ( input.isKeyDown( Input.KEY_LEFT ) ) {
spaceship.rotate( -4.0f );
}
}
private void accelerate() {
Timer timer = new Timer( 2000000 );
timer.decreaseTime( 1 );
speed += 0.01f;
if ( speed > 0.3f ) {
speed = 0.5f;
}
}
private void slowDown() {
Timer timer = new Timer( 500000 );
timer.decreaseTime( 0.1f );
speed -= 0.01f;
if ( speed < 0.0f ) {
speed = 0.0f;
}
}
}
Timer.java
Code:
public class Timer {
private float currentTime;
public Timer(float time) {
this.currentTime = time;
}
public void decreaseTime(float timeDelay) {
for(float i = currentTime; currentTime > 0; i--) {
currentTime -= timeDelay;
}
}
}
Re: Asteroids fly physics
I recoded the whole thing and hope, it's better to understand now.
GameObject.java
Code:
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.geom.Vector2f;
public abstract class GameObject {
protected Vector2f currentPosition;
protected Image objectImage;
public GameObject( Image objectImage ) {
this.objectImage = objectImage;
this.objectImage.setCenterOfRotation( this.objectImage.getWidth() / 2, this.objectImage.getHeight() / 2 );
}
public Image getImage() {
return this.objectImage;
}
public void setStartPosition( Vector2f position ) {
this.currentPosition = position;
}
public Vector2f getCurrentPosition() {
return this.currentPosition;
}
public void setCurrentPosition( float x, float y ) {
this.currentPosition.x = x;
this.currentPosition.y = y;
}
public abstract boolean collide( GameObject gameObject );
public abstract void move( Input input, int delta );
}
Spaceship.java
Code:
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
public class Spaceship extends GameObject {
private final float MAX_SPEED = 1.0f;
private float spaceshipSpeed;
private double oldSinRotation, oldCosRotation;
public Spaceship( Image spaceshipImage ) {
super( spaceshipImage );
this.spaceshipSpeed = 0.0f;
}
@Override
public void move( Input input, int delta ) {
if( input.isKeyDown( Input.KEY_UP ) ) {
accelerate();
this.currentPosition.x += (float) ( Math.sin( Math.toRadians( this.objectImage.getRotation() ) ) * delta * this.spaceshipSpeed );
this.currentPosition.y -= (float) ( Math.cos( Math.toRadians( this.objectImage.getRotation() ) ) * delta * this.spaceshipSpeed );
this.changeScreenSide();
this.oldSinRotation = Math.sin( Math.toRadians( this.objectImage.getRotation() ) );
this.oldCosRotation = Math.cos( Math.toRadians( this.objectImage.getRotation() ) );
} else {
this.decelerate();
this.currentPosition.x += (float) ( this.oldSinRotation * delta * this.spaceshipSpeed );
this.currentPosition.y -= (float) ( this.oldCosRotation * delta * this.spaceshipSpeed );
this.changeScreenSide();
}
if( input.isKeyDown( Input.KEY_RIGHT ) ) {
this.objectImage.rotate( 0.4f );
}
if( input.isKeyDown( Input.KEY_LEFT ) ) {
this.objectImage.rotate( -0.4f );
}
}
@Override
public boolean collide( GameObject gameObject ) {
return false;
}
private void changeScreenSide() {
if( this.getCurrentPosition().x < -49.16f ) {
this.setCurrentPosition( 782.19f, this.getCurrentPosition().y );
}
if( this.getCurrentPosition().x > 782.81f ) {
this.setCurrentPosition( -49.18f, this.getCurrentPosition().y );
}
if( this.getCurrentPosition().y < - 45.29f ) {
this.setCurrentPosition( this.getCurrentPosition().x, 584.06f );
}
if( this.getCurrentPosition().y > 584.07f ) {
this.setCurrentPosition( this.getCurrentPosition().x, -45.30f );
}
}
private void accelerate() {
if( this.spaceshipSpeed >= this.MAX_SPEED ) {
this.spaceshipSpeed = this.MAX_SPEED;
}
this.spaceshipSpeed += 0.0009f;
}
private void decelerate() {
if( this.spaceshipSpeed <= 0 ) {
this.spaceshipSpeed = 0;
}
this.spaceshipSpeed -= 0.0009f;
}
}
Game.java
Code:
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Vector2f;
public class Game extends BasicGame {
private final static int GAME_WIDTH = 800;
private final static int GAME_HEIGHT = 600;
private Spaceship spaceship;
public Game( String title ) {
super( title );
}
private static void startGame() throws SlickException {
AppGameContainer game = new AppGameContainer( new Game( "Asteroids" ) );
game.setDisplayMode( Game.GAME_WIDTH, Game.GAME_HEIGHT, false );
game.setShowFPS( false );
game.start();
}
public static void main(String[] args) throws SlickException {
Game.startGame();
}
@Override
public void init( GameContainer container ) throws SlickException {
this.spaceship = new Spaceship( new Image( "res/spaceship.png" ) );
float spaceshipxStartPosition = Game.GAME_WIDTH / 2 - this.spaceship.getImage().getWidth() / 2;
float spaceshipyStartPosition = Game.GAME_HEIGHT / 2 - this.spaceship.getImage().getHeight() / 2;
this.spaceship.setStartPosition( new Vector2f( spaceshipxStartPosition, spaceshipyStartPosition ) );
}
@Override
public void render( GameContainer container, Graphics g ) throws SlickException {
this.spaceship.getImage().draw( this.spaceship.getCurrentPosition().x, this.spaceship.getCurrentPosition().y);
}
@Override
public void update( GameContainer container, int delta ) throws SlickException {
Input input = container.getInput();
this.spaceship.move( input, delta );
}
}
I hope someone can help me with the flying problem