• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 619
  • Last Modified:

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().playSound("photon.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().playSound("explosion.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().playSound("explosion.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;
    }
}
0
mikedaley
Asked:
mikedaley
  • 6
  • 5
1 Solution
 
TOPIOCommented:
I can tell you my logic but I can't give you the code you just tell me if this sounds logical or not:

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








0
 
TOPIOCommented:
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.
0
 
mikedaleyAuthor Commented:
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
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
mikedaleyAuthor Commented:
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().getHeight() / 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)
0
 
TOPIOCommented:
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
0
 
mikedaleyAuthor Commented:
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)
0
 
mikedaleyAuthor Commented:
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.
0
 
TOPIOCommented:
That is precisely the point I was making about remembering  trig Class:
So let me back track a little bit:
You question was how to move sprites in formation,
I think we have addressed that  in order for a formation to move you have an array with the basic x y coordinates for  every character in the formation.

2. That if you want to  move the formation statically they just follow the "lead" character of the  formation in a fixed ratio (this will give you the "Galaga" formation  where there where two  ships coming down at you, this will also give you the space invaders kind of formation where they're just moving left to right and back and coming down )

3.- If you want to have animation  that is prettier you have to get into  more interesting math functions, in this case you can have all of the members of the formation move together in a more interesting path.

4.- Then if you want to have a beautiful formation  you have to animate every character individually keeping the formation concept as the reference framework where their individual positions are based on the positions of other members of the formation

let me give you and example. Let's say that you want to have an animation where the characters appear from one side then  go up and down whilst moving to the other side of the screen (for this example I'm using only 32 positions as the width of the screen)

For this example the basic coordinates for the movement are in the form of the following:

x      y
1      0
2      1
3      2
4      3
5      4
6      3
7      2
8      1
9      0
10      -1
11      -2
12      -3
13      -4
14      -3
15      -2
16      -1
17      0
18      1
19      2
20      3
21      4
22      3
23      2
24      1
25      0
26      -1
27      -2
28      -3
29      -4
30      -3
31      -2
32      -1

This function already appears in your code where you say that
  //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);

In this case what you need to do is to make sure that the elements in the formation follow in the footsteps of the previous member of the formation as you see fit
so you would probably have a temp array where you store the positions calculated for the "leader"of the formation and then use them for the rest of the members of the formation.

Finally ifyou're having as much fun as I hear you're having  I would recomend
"Sams Teach Yourself Game Programming in 24 Hours " if you're familiar with  C/C++.


0
 
TOPIOCommented:
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).
0
 
mikedaleyAuthor Commented:
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.
0
 
TOPIOCommented:
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.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 6
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now