mikedaley
asked on
Move sprites in formation
Hi ya
I am writing a retro computer game for my kids. Its based on a top down scrolling shoot em up like Xenon 2 back in the early-mid 80's (showing my age there).
I have all the basics of the game working such a player movement, different aliens, firing, score etc. etc.
At the moment thought, my alien sprites are moving in a random manner i.e. they move at a set angle and velocity until they hit the edge of the screen and then pick a new angle and speed.
I'm hoping someone has some ideas on how I can get my sprites to move in patterns or loops, like in the old shoot-em-ups like Xenon 2.
I'm not sure I'm making much sense, but I hope this triggers something and someone has some ideas on how I could implement such movement for the sprites. I have pasted below the class which controls an enemy sprite (actor) within the game. The act() method is called during each cycle of the main game loop to update what the sprite is doing.
Any and all help appreciated.
Thanks
/*
* Alien.java
*
* Created on Sep 17, 2007, 8:08:22 PM
*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.daleyuk.alieninvaders. actors;
import com.daleyuk.alieninvaders. *;
/**
* Extends the base Actor class and defines a monster in the game
* @author mikedaley
*/
public class Alien extends Actor {
/**
* At present the monsters only move from left to right, so we have an x axis velocity variable
*/
protected int velocity;
protected boolean isDead;
protected double angle;
protected static final double FIRING_FREQUENCY = 0.04;
/**
* We define the stage on which the monster will belong and set up the two frames of animation plus the framespeed
* More details on the base Actor class are found in Actor.java
* @param stage Stage
*/
public Alien(Stage stage) {
super(stage);
this.stage = stage;
setSpriteName(new String[] {"newalien2.gif"});
setFrameSpeed(2);
isDead = false;
angle = Math.random() * 360;
}
/**
* This overrides the base Actor method for act. It telles the monster to move from left to right with a velocity of
* vX. This velocity is defined when the monster is defined and each instance of monster can have its own speed.
* I need to work on this to provide a much more interesting movement for the monsters.
*/
@Override
public void act() {
super.act();
//Calculate the x and Y based on the current velocity and angle of the alien
x += velocity * Math.cos(angle);
y += velocity * Math.sin(angle);
//If the monster is about to leave the viewable screen, pick a random anlge
//so that it changes direction
if (x <= 0 || x >= stage.WIDTH || y <= 0 || y >= stage.PLAY_HEIGHT - getHeight()) {
angle = (Math.random() * 359) + 1;
velocity = (int) (Math.random()*10-4) + 1;
if (velocity <= 0) {
velocity = 1;
}
}
if (x >= stage.getPlayer().getX() - 10 && x <= stage.getPlayer().getX() + 10 && stage.getPlayer().getY() >= y && Math.random() < FIRING_FREQUENCY) {
fire();
}
}
/**
* This method is called on a random frequency. When is is called it creates a new instance of the laser
* actor and places it on the stage from the location of the alien firing and centred to the middle of the
* alien sprite. It also plays the sound of the laser firing.
* */
public void fire() {
Laser m = new Laser(stage);
m.setX(x + getWidth() / 2);
m.setY(y + getHeight());
stage.addActor(m);
stage.getSoundCache().play Sound("pho ton.wav");
}
/**
* If the alien collides with a bullet, shield, multilaster or player then mark for removal, place an explosion sprite on screen
* and add to the players score
*/
@Override
public void collision(Actor a) {
if (a instanceof Bullet || a instanceof MultiLaser || a instanceof Shield) {
remove(); //Remove the aliean from the stage
Explosion e = new Explosion(stage, this.getX() - a.getWidth() / 2, this.getY() - a.getHeight() / 2);
stage.addActor(e); //Add the explosion to the stage
stage.getSoundCache().play Sound("exp losion.wav "); //Play the explosion sound effect
spawn(); //Spawn a new alien
}
if (a == stage.getPlayer()) {
remove(); //Remove the aliean from the stage
Explosion e = new Explosion(stage, this.getX() - a.getWidth() / 2, this.getY() - a.getHeight() / 2);
stage.addActor(e); //Add the explosion to the stage
stage.getSoundCache().play Sound("exp losion.wav "); //Play the explosion sound effect
spawn(); //Spawn a new alien
}
}
/**
* Basic method to place an alien on the stage. Used when an alien is killed for example
* */
public void spawn() {
Alien m = new Alien(stage);
m.setX((int) (Math.random() * Stage.WIDTH - m.getWidth()));
m.setY((int) (Math.random() * Stage.PLAY_HEIGHT / 2));
m.setVelocity((int) (Math.random()*10-4) + 1);
if (velocity <= 0) {
velocity = 1;
}
stage.addActor(m);
}
/**
* Getters and setters
* @return int Velocity
*/
public int getVelocity() {
return velocity;
}
public void setVelocity(int velocity) {
if (velocity != 0) {
this.velocity = velocity;
} else {
this.velocity = 0;
}
}
public double getAngle() {
return this.angle;
}
}
I am writing a retro computer game for my kids. Its based on a top down scrolling shoot em up like Xenon 2 back in the early-mid 80's (showing my age there).
I have all the basics of the game working such a player movement, different aliens, firing, score etc. etc.
At the moment thought, my alien sprites are moving in a random manner i.e. they move at a set angle and velocity until they hit the edge of the screen and then pick a new angle and speed.
I'm hoping someone has some ideas on how I can get my sprites to move in patterns or loops, like in the old shoot-em-ups like Xenon 2.
I'm not sure I'm making much sense, but I hope this triggers something and someone has some ideas on how I could implement such movement for the sprites. I have pasted below the class which controls an enemy sprite (actor) within the game. The act() method is called during each cycle of the main game loop to update what the sprite is doing.
Any and all help appreciated.
Thanks
/*
* Alien.java
*
* Created on Sep 17, 2007, 8:08:22 PM
*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.daleyuk.alieninvaders.
import com.daleyuk.alieninvaders.
/**
* Extends the base Actor class and defines a monster in the game
* @author mikedaley
*/
public class Alien extends Actor {
/**
* At present the monsters only move from left to right, so we have an x axis velocity variable
*/
protected int velocity;
protected boolean isDead;
protected double angle;
protected static final double FIRING_FREQUENCY = 0.04;
/**
* We define the stage on which the monster will belong and set up the two frames of animation plus the framespeed
* More details on the base Actor class are found in Actor.java
* @param stage Stage
*/
public Alien(Stage stage) {
super(stage);
this.stage = stage;
setSpriteName(new String[] {"newalien2.gif"});
setFrameSpeed(2);
isDead = false;
angle = Math.random() * 360;
}
/**
* This overrides the base Actor method for act. It telles the monster to move from left to right with a velocity of
* vX. This velocity is defined when the monster is defined and each instance of monster can have its own speed.
* I need to work on this to provide a much more interesting movement for the monsters.
*/
@Override
public void act() {
super.act();
//Calculate the x and Y based on the current velocity and angle of the alien
x += velocity * Math.cos(angle);
y += velocity * Math.sin(angle);
//If the monster is about to leave the viewable screen, pick a random anlge
//so that it changes direction
if (x <= 0 || x >= stage.WIDTH || y <= 0 || y >= stage.PLAY_HEIGHT - getHeight()) {
angle = (Math.random() * 359) + 1;
velocity = (int) (Math.random()*10-4) + 1;
if (velocity <= 0) {
velocity = 1;
}
}
if (x >= stage.getPlayer().getX() - 10 && x <= stage.getPlayer().getX() + 10 && stage.getPlayer().getY() >= y && Math.random() < FIRING_FREQUENCY) {
fire();
}
}
/**
* This method is called on a random frequency. When is is called it creates a new instance of the laser
* actor and places it on the stage from the location of the alien firing and centred to the middle of the
* alien sprite. It also plays the sound of the laser firing.
* */
public void fire() {
Laser m = new Laser(stage);
m.setX(x + getWidth() / 2);
m.setY(y + getHeight());
stage.addActor(m);
stage.getSoundCache().play
}
/**
* If the alien collides with a bullet, shield, multilaster or player then mark for removal, place an explosion sprite on screen
* and add to the players score
*/
@Override
public void collision(Actor a) {
if (a instanceof Bullet || a instanceof MultiLaser || a instanceof Shield) {
remove(); //Remove the aliean from the stage
Explosion e = new Explosion(stage, this.getX() - a.getWidth() / 2, this.getY() - a.getHeight() / 2);
stage.addActor(e); //Add the explosion to the stage
stage.getSoundCache().play
spawn(); //Spawn a new alien
}
if (a == stage.getPlayer()) {
remove(); //Remove the aliean from the stage
Explosion e = new Explosion(stage, this.getX() - a.getWidth() / 2, this.getY() - a.getHeight() / 2);
stage.addActor(e); //Add the explosion to the stage
stage.getSoundCache().play
spawn(); //Spawn a new alien
}
}
/**
* Basic method to place an alien on the stage. Used when an alien is killed for example
* */
public void spawn() {
Alien m = new Alien(stage);
m.setX((int) (Math.random() * Stage.WIDTH - m.getWidth()));
m.setY((int) (Math.random() * Stage.PLAY_HEIGHT / 2));
m.setVelocity((int) (Math.random()*10-4) + 1);
if (velocity <= 0) {
velocity = 1;
}
stage.addActor(m);
}
/**
* Getters and setters
* @return int Velocity
*/
public int getVelocity() {
return velocity;
}
public void setVelocity(int velocity) {
if (velocity != 0) {
this.velocity = velocity;
} else {
this.velocity = 0;
}
}
public double getAngle() {
return this.angle;
}
}
The beatuy of this concept is that you can make your formations and movements as complicated as you like just taking care of one little dude, as I mentioned you can make your formations as interesting as you like and the concept is the same.
One thing i forogot to mention is that for every formation you can keep 4 variables
minx, miny, maxX, maxY that should help you in reducing the complexity of the wall collision detection,
if you remeber your trigonometry clases you can even make them do spirals and such.
One thing i forogot to mention is that for every formation you can keep 4 variables
minx, miny, maxX, maxY that should help you in reducing the complexity of the wall collision detection,
if you remeber your trigonometry clases you can even make them do spirals and such.
ASKER
Hi TOPIO
Thanks for the quick response. No problem with not having any code. At the moment I'd be happy with just a design of how this could work or any algorithm people may have which I could use to make the sprites moved around the screen following each other. I think I get what you are saying about placing the formation of the bad guys into an array, and then only checking the position of the bad guy closest to the screen edge and then deciding to do something. This would then ripple up through the rest of the sprites in the array.
I'll put pencil to paper and see if I can map this out a little more based on how my game engine works and get back to you. I think the idea of putting a formation into an array is a good start and has got my mind going.
If you have any good ideas on some maths I could use to move the lead sprite around the screen in some kind of spiral or pattern etc, that would be great too.....not that I'm asking for much :o)
I'll think it through and post back
Thanks
Thanks for the quick response. No problem with not having any code. At the moment I'd be happy with just a design of how this could work or any algorithm people may have which I could use to make the sprites moved around the screen following each other. I think I get what you are saying about placing the formation of the bad guys into an array, and then only checking the position of the bad guy closest to the screen edge and then deciding to do something. This would then ripple up through the rest of the sprites in the array.
I'll put pencil to paper and see if I can map this out a little more based on how my game engine works and get back to you. I think the idea of putting a formation into an array is a good start and has got my mind going.
If you have any good ideas on some maths I could use to move the lead sprite around the screen in some kind of spiral or pattern etc, that would be great too.....not that I'm asking for much :o)
I'll think it through and post back
Thanks
ASKER
Ah trig.....it's at times like these I wish I had listened more closely to those lessons :o)
I've got some basic trig going already. I have a powerup which drops down the screen. If the player ship hits that, he gets 4 sprites which rotate around the player ship acting like a shield i.e. if they hit a bad guy, the bad guy bits it and that shield element goes as well.
The act() method for each shield sprite is below
/**
* Move the spinner actor around the player location
*/
@Override
public void act() {
super.act();
double nx;
double ny;
nx = stage.getPlayer().getX() + stage.getPlayer().getWidth () / 2 - 7 + Math.cos(angle * PI / 180) * distance;
ny = stage.getPlayer().getY() + stage.getPlayer().getHeigh t() / 2 - 6 + Math.sin(angle * PI / 180) * distance;
x = (int) nx;
y = (int) ny;
angle += speed;
if (angle > 360) {
angle = 0;
}
}
That is about as complex as my trig gets at the moment. But I'm thinking I could use the basics of that to move the point around which the sprite is rotating and get some kind of spiral effect......
Any comments on that welcome. Coding this game is becoming very addictive now :o)
I've got some basic trig going already. I have a powerup which drops down the screen. If the player ship hits that, he gets 4 sprites which rotate around the player ship acting like a shield i.e. if they hit a bad guy, the bad guy bits it and that shield element goes as well.
The act() method for each shield sprite is below
/**
* Move the spinner actor around the player location
*/
@Override
public void act() {
super.act();
double nx;
double ny;
nx = stage.getPlayer().getX() + stage.getPlayer().getWidth
ny = stage.getPlayer().getY() + stage.getPlayer().getHeigh
x = (int) nx;
y = (int) ny;
angle += speed;
if (angle > 360) {
angle = 0;
}
}
That is about as complex as my trig gets at the moment. But I'm thinking I could use the basics of that to move the point around which the sprite is rotating and get some kind of spiral effect......
Any comments on that welcome. Coding this game is becoming very addictive now :o)
You have the concept right, the next best thing for us to do is to look at old math books :)
The next things I would suggets is
1.- Make sure that you can move the formation together and
2.- Try moving aliens within the formation.
You can even recycle you code to use the circling around the player to circle around a big alien ship
with escrots at the end of the level.
You cna also create different levels with differente complexity in the movement in each level
The next things I would suggets is
1.- Make sure that you can move the formation together and
2.- Try moving aliens within the formation.
You can even recycle you code to use the circling around the player to circle around a big alien ship
with escrots at the end of the level.
You cna also create different levels with differente complexity in the movement in each level
ASKER
Thanks TOPIO
I've started to get some ideas down on paper so I'll get those coded up and see how its looking. I'll post back when I've had a play :o)
I like the idea of the end of level boss as well :o)
I've started to get some ideas down on paper so I'll get those coded up and see how its looking. I'll post back when I've had a play :o)
I like the idea of the end of level boss as well :o)
ASKER
Hi TOPIO
I've been playing with the ideas and also looking around for other possibilities. The problem I encountered was that even with a lead sprite, to make it move in interesting ways I need some good maths or LOTS of pre defined points.
In looking around, it looks like games programmers use something called Splines. This allows you to have two points and then calculate a path or vector between them. If you have a Bezier Spline then you can travel between the two points in a curve. Its all a little heavy but I'm seeing if I can take something like that and use it.
I've been playing with the ideas and also looking around for other possibilities. The problem I encountered was that even with a lead sprite, to make it move in interesting ways I need some good maths or LOTS of pre defined points.
In looking around, it looks like games programmers use something called Splines. This allows you to have two points and then calculate a path or vector between them. If you have a Bezier Spline then you can travel between the two points in a curve. Its all a little heavy but I'm seeing if I can take something like that and use it.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
And I did check out splines and it seems like the way to go
i would suggest starting with a sin() function as the results as the one above are easy
to get and the math required is not that difficult to achieve programmatically (as I saw that you're already using sin() and cos() functions).
i would suggest starting with a sin() function as the results as the one above are easy
to get and the math required is not that difficult to achieve programmatically (as I saw that you're already using sin() and cos() functions).
ASKER
Thanks TOPIO. You've provided good info and spent time helping me out on this one. I've given you the points as you certainly have given me some good info and things to try. I'm going to have a play with your suggestions above and I'll let you know how I get on.
I'll also check out the book you mentioned as well.
Thanks again for all your time and help.
I'll also check out the book you mentioned as well.
Thanks again for all your time and help.
You can post anything interesting that you found in there because In about 1 year I will be also need to provide information for a very active toddler.
first you create a formation a formation is an array that contains the coordinates of up to n aliens (lets say 3 in this example.
So for any Formation you have 3 aliens a1, a2 and a3, where you would have the coordinates for x and y defined as integers as you already have.
The change is that in your edge collision detection routine you have to check for the impact of only the alien closest to that side of the screen
lets use a simple space invaders formation where they move side by side (after this we can go into the galaga type formation i think you're looking for)
for this example lets say that you have a screen 100 pix wide and every alien is 1 pix wide
the space invaders formation algorithm goes like this:
Starting from the top left corner going back and fort and descending every time you hit a wall
but in order to move in formation they all detect the collision depending on the alien closest to the wall.
so our formation is A1 - A2 - A3 (aliens)
at the begining the coordinates of
a1 are a1.x=0 and a1.y =0 ,
for a2 a2.x=a1.x+(width of alien) + (width of space in formation) and a2.y =0,
for alien 3 the coordinates are
a3.x=a2.x+(width of alien) + (width of space in formation) and a2.y =0,
So you move them by increasing only a1.x the calculation routine takes care of the rest
Movement routine
Movement Direction has two variables (x) and (y)
so MD.x=1 md.y=0
every cycle then
a1.x=a1.x+md.x
a1.y=a1.y+md.y
UNTIL
the highest living alien in this case a3 if it has not been killed hits the edge of the screen
in this case
if a3.x= 100 then a1.x=a1.x-1 a1.y=a1.y+1 and md.x=-1 md.y=0
(you cange the direction of movement, since we're in space invaders they descend one level and start moving backwards)
tell me what you think