JOURNAL: Space Fleet Combat (now less of a 2D Game Engine)

I decided to go with an ArrayList-based data structure to hold my projectiles for the time beeing, untill i get the BinaryTree structure working the way I want it to.

And, proof that I’m getting somewhere:

http://sphotos.ak.fbcdn.net/hphotos-ak-snc3/hs631.snc3/31653_394869616716_555931716_4682658_905857_n.jpg

yeh, now thats some cinimatic gameplay right there! ;D

Thats a small gunship in the top corner there, and a resource gatherer in the bottom corner.

Cool! Now I want me some 'splosions!

That looks really cool so far, nice work! It always bothered me that there were no 2D game engines available.

Coming up Demonpants!

I’ve re-written my particle engin e code from scratch three times today already. Just haveing massive troubble getting it ti fot in with my component system.

I’ve opted for a seperate particle engine insted.

I have a few problems with it:

  1. scailing my sprite-images
  2. fading in and out images - I have no idea how to do this…

My particle system code as it stands:

[code=Particle Engine]public class ParticleEngine {

int timer = 0;

public ArrayList<ParticleEffect> Effects;

public ParticleEngine()
{
    this.Effects = new ArrayList();
}

public void Update(int deltaTime)
{

    // this stuff here just creates a default particle system every second for testing

    if(timer > 1000)
    {
        this.Effects.add(new ParticleEffect());
        timer = 0;
    }
    else
    {
        timer += deltaTime;
    }
    for(ParticleEffect e: Effects)
    {
        e.Update(deltaTime);
    }
}
public void Render(Graphics2D g)
{
    for(ParticleEffect e:Effects)
    {
        e.Render(g);
    }
}

}



[code=Particle Effect]public class ParticleEffect {

    public ArrayList<Particle> Particles;

    public ParticleEffect()
    {
        this.Particles = new ArrayList();

        setupDemo();
    }

    public void Update(int deltaTime)
    {
        int count = Particles.size();
        for(int i = 0; i < count; i++)
        {
            if(Particles.get(i).EXPIRED)
            {
                this.Particles.remove(i);
                count = this.Particles.size();
            }
            else
            {
                Particles.get(i).Update(deltaTime);
            }
        }
    }
    public void Render(Graphics2D g)
    {
        for(Particle e:Particles)
        {
            e.Render(g);
        }
    }

    private void setupDemo()
    {

        // again, sets up a load of default particles for testing
 
        for(int i = 0; i < 1000; i++)
        {
            this.Particles.add(new Particle());
        }
    }
}

[code=Particle]public class Particle {

public boolean EXPIRED = false;

Vector2D pos;
Vector2D vel;
Vector2D acl;
float rotation;
float scale;

float rotationRait;
float scaleRait;

int life;
int age;

Color color;

Sprite sprite;

public Particle()
{
    //this.sprite = new Sprite();
    //this.sprite.load("artAssets\\effects\\particles\\explosion1.png");
    this.pos = new Vector2D();
    Random rand = new Random();
    this.vel = new Vector2D(rand.nextInt(50)-rand.nextInt(50), rand.nextInt(50)-rand.nextInt(50));
    this.acl = new Vector2D();
    this. life = 1000;
    this.age = 0;

    this.scaleRait = -0.9f;
    this.color = new Color(250,100,0, 250);
}

public void Update(int deltaTime)
{
    if(EXPIRED) return; // and get cleaned out of the list in the next loop.

    if(age > life){ this.EXPIRED = true; return; }
    else
    {
        this.vel = Vector2D.Add(vel, Vector2D.Div(acl, deltaTime));
        this.pos = Vector2D.Add(pos, Vector2D.Div(vel, deltaTime));
        this.rotation += rotationRait/deltaTime;
        this.age += deltaTime;
        
        // the scaling stuff just fails. I think its something to do with how my sprite Render() method 
        // works

        //this.scale += scaleRait/deltaTime;
        
        //if(this.sprite != null)
        //{
        //    this.sprite.SetPos(pos);
        //    this.sprite.SetScale(1+this.scale);
        //}
          

    }


}
public void Render(Graphics2D g)
{
    if(!EXPIRED)
    {
        if(this.sprite != null)
            this.sprite.render(g);

        else
        {
            g.setColor(color);
            g.drawRect((int)this.pos.getX(), (int)this.pos.getY(), 1, 1);
        }
    }
}

}



the trouble I'm having with my sprite scailing code is that setting the scale for one sprite scales ALL the sprites  :P

This is my Sprite.Render() code:


public int render(Graphics2D g, PhysicsPoint p)
{
this.posX = (int)p.getPosition().getX()+offsetX;
this.posY = (int)p.getPosition().getY()+offsetY;

    // draw the image to the screen.
    // (called during Game.render())
    AffineTransform tf = g.getTransform();


    g.rotate(p.getRotation(),
            p.getPosition().getX()+offsetX,
            p.getPosition().getY()+offsetY);



    // draw the sprite image
    /*g.drawImage(spriteImage,
            (int)p.getPosition().getX()-offsetX,
            (int)p.getPosition().getY()-offsetY,
            null);*/
     g.drawImage(spriteImage,
            posX,
            posY,
            null);


     // debugging stuff...
    //g.setColor(Color.red);
    //g.drawRect(posX, posY, width, height);
    //g.drawRect(
    //        (int)p.getPosition().getX()-2,
    //        (int)p.getPosition().getY()-2, 4, 4);


    g.setTransform(tf);

    return 0;

}


Actualy, that could probably use some cleaning up.. I've not realy looked at it in over a month  :)

If you have any tips or hints as to how I can improve my render method, that would be great. It's prettymuch hacked and slashed together at the moment...


What I want to get together over the next few weeks is a demo game where you can order a fighter/bomber around the game world, have it attack randomly spawning drones, have it return to a supply point for refule/rearm, etc.

This will hopefully let me get behaviour, weapons/projectiles, particles and the mouse point&click/GUI control system working in some basic way.

Emitters would be components that gets its position from its objects. You could attach a smoke emitter to a missile to create a trail effect. All the properties that defines how the particles look would be in the emitter. But all the real work is done in the system. It would have to track all the emitters and update the particle engine.

You know what, I spent about 8 hours streight trying to get that to work …

and kept getting killed by the same error:

somehow, when I try to add a Particle to the ParticleEngine (through the component system - it seems to work outsude that) I get an exaption that i thonk is trying to tell me that my Main class is null ???
which I’m pretty sure is not the case, what with everything working…

I’ve had powercuts on and off all day today, so no progress. Going to make short post/edits incase it goes again.

I’ll edit this post in a while with a stack trace and my particle code. If anyone can shead any light on this I would be much releived!

It was starting to drive me a little bit mad. (er) :wink:

EDIT:

[code=Stack Trace]
run:
DRGame constructor - line 77.
Particle Engine Instanceated - line 98.
Load method begun - line 114.

Exception in thread “main” java.lang.NullPointerException
at SpaceLib.Components.ParticleEmitterComponent.(ParticleEmitterComponent.java:32)
at SpaceLib.Objects.Projectile.(Projectile.java:38)
at SpaceLib.Components.WeaponComponent.initProjectile(WeaponComponent.java:102)
at SpaceLib.Components.WeaponComponent.(WeaponComponent.java:48)
at SpaceLib.Ship.Ship.(Ship.java:42)
at GameLib.DRGame.Load(DRGame.java:130)
at GameLib.DRGame.(DRGame.java:105)
at isogameengine_01.Main.main(Main.java:21)



[code=ParticleEmitterComponent]public class ParticleEmitterComponent extends Component{

    ParticleEffect myEffect;

    public ParticleEmitterComponent(int id, Entity parent)
    {
        super(id, parent);

        this.myEffect = new ParticleEffect();
        
        Main.getGame().GetParticleEngine().AddEffect(myEffect);
    }

    @Override
    public void Update(int deltaTime)
    {
        this.myEffect.Position = this.Parent().GetPhysicsComponent().getPosition();
    }
}

[code=Projectile]public class Projectile extends Entity{

private Entity source;
private double speed;
private int projectileAge;
private int projectileLife;

private Vector2D destination;

public Projectile(Entity source, Vector2D d)
{
    this.source = source;
    this.destination = d;
    this.SetComponent(new PhysicsComponent(0, this));
    this.SetComponent(new RenderableComponent(0, this));
    this.SetComponent(new TrailComponent(0, this));
    this.SetComponent(new ParticleEmitterComponent(0, this));

    initVars();
    Fire();
}

private void initVars()
{
    this.speed = 800;
    this.projectileAge = 0;
    this.projectileLife = 1000;
    this.GetRenderableComponent().GetSprite().load("artAssets\\projectiles\\cannonShell2.png");        
}

public void Fire()
{
    Vector2D go = Vector2D.Sub(this.physicsComponent.getPosition(), destination);
    double theta = go.getAngle();

    this.physicsComponent.setPosition(this.source.GetPhysicsComponent().getPosition());
    this.physicsComponent.setVelocity(Vector2D.fromAngle(this.physicsComponent.getPosition(),
            speed,
            theta));
    //this.physicsComponent.setVelocity(new Vector2D(0,10));
}

private void Detonate()
{
    /*
    if(this.GetParticleComponent() != null)
    {
        this.GetParticleComponent().AddEffect(this.GetPhysicsComponent().getPosition(),
                Main.getEffects().Explosion1);
    }
    else
    {
        this.SetComponent(new ParticleComponent(0, this.parent));
        this.GetParticleComponent().AddEffect(this.GetPhysicsComponent().getPosition(), "Explosion1");
    }
    
     
    this.GetRenderableComponent().GetSprite().load("artAssets\\effects\\particles\\explosion1.png");
     * 
     */
}

private void Expire()
{
    this.Detonate();
}

public void Update(int deltaTime)
{
    /*this.projectileAge += deltaTime;

    if(this.projectileAge > this.projectileLife)
    {
        //this.Expire();
        //this.parent.getChildren().remove(this);
    }
    */
        if(this.physicsComponent != null)
            this.physicsComponent.Update(deltaTime);

        if(this.renderableComponent != null)
            this.renderableComponent.Update(deltaTime);

        if(this.statsComponent != null)
            this.statsComponent.Update(deltaTime);

        if(this.navigatorComponent != null)
            this.navigatorComponent.Update(deltaTime);

        if(this.trailComponent != null)
            this.trailComponent.Update(deltaTime);

        if(this.particleEmitterComponent != null)
            this.particleEmitterComponent.Update(deltaTime);


        if(this.children != null)
        for(Entity e: this.children)
        {
            if(e != null)
                e.Update(deltaTime);
        }
    
}

/*
@Override
public void Render(Graphics2D g)
{
this.GetRenderableComponent().Render(g);
//g.drawRect((int)this.GetPhysicsComponent().getPosition().getX(),
// (int)this.GetPhysicsComponent().getPosition().getX(), 2, 2);
}
*/

}



[code=WeaponsComponent]public class WeaponComponent extends Component{

    int cooldownTime;    // cooldown between bursts (ms)
    int burstTime;       // time between shots (ms)
    int burstCount;      // number of shots to fire per burst
    int timer;           // miliseconds since last state-change.

    boolean firing = false;
    Entity target;

    float acuracyOffset;

    Vector2D offset;

    Projectile projectileTemplate;

    public WeaponComponent(int i, Entity p)
    {
        super(i,p);

        this.cooldownTime = 500;
        this.burstTime = 0;
        this.burstCount = 1;
        this.offset = new Vector2D();
        this.acuracyOffset = 0.05f;

        initProjectile();
    }



    public void SetTarget(Entity e)
    {
        this.target = e;
    }
    public void Fire()
    {
        if(this.target != null)
            firing = true;
    }
    public void CeaseFire()
    {
        firing = false;
    }

    @Override
    public void Update(int deltaTime)
    {
        if(firing)
        {
            //System.out.println("Weapon Timer: " + this.timer);
            if(this.timer < this.cooldownTime)
            {
                timer += deltaTime;
            }
            else if(this.timer >= this.cooldownTime)
            {
                Vector2D V2T = Vector2D.Sub(this.Parent().GetPhysicsComponent().getPosition(),
                    this.target.GetPhysicsComponent().getPosition());

                double D2T = V2T.getLengh();
                double A2T = V2T.getAngle();

                Random rand = new Random();
                double defl = (rand.nextDouble() - rand.nextDouble()) * this.acuracyOffset;

                Projectile x = new Projectile(this.Parent(), Vector2D.fromAngle(
                        this.Parent().GetPhysicsComponent().getPosition(),
                        D2T, A2T+defl));

                Main.getGame().GetWorldProjectiles().AddProjectile(x);

                timer = 0;
            }
        }
    }


    private void initProjectile()
    {
        this.projectileTemplate = new Projectile(this.Parent(), new Vector2D());
        //this.projectileTemplate.GetRenderableComponent().GetSprite().load(
        //        "artAssets\\projectiles\\cannonShell1.png");
    }

}

I’m afraid that its all rather hacked together and got really messed up yesterday as I was trying random crap to try fix it. I think I need to have a good clean-up of the code I have before going any further.

I’d hoped to havfe some demo pics of the latest build of my particle system by now, but I just hit some weird problems, and have lost my flow :-\

What I had working today sofar:

  • The particle system now works.
  • The Entity/Component system now plays nicely with the particle system (mostly, still a few weird buggs). Demoed this with the Projectile entity - smoke trails and launch/muzzle ‘puff’.
  • The particle system now loads all the particles from a CSV file, alowing easy (in a very nerdy excell way) adding, removeing and editing particles in the system.
  • 9 basic particle types including smoke, fire, point-particle/sparks and little floating wreckage peices.

What I want to get done next:

  • Similar CSV data for ParticleEmitters
  • Similar CSV data for some of the basic Entities such as Ships, Projectiles, etc.
  • Maybe some sort of Swing/Winforms content editor if I have time.

Next major addition:
Will be a complete re-do of the navigation and entity behavior component, including loading behaviors from a file, some very basic scripting of behaviours, etc.
Some sort of ‘Formation’ component that allows an Entity to dictate points reletive to it that other Entitys can lock their position too - alowing docking and flight formations.

Behaviours that I need for the fighter demo:

  • Move To Point.
  • Strafe Attack Target
  • Flee
  • Join Entity Formation (for say docking, refuling, etc)
  • Match Target Speed
  • Orbit Target

I’ve decided that I’m going to try to move my graphics to JOGL, as I dont think that I can get the results I wanted using just Graphics2D.

I’m a bit dubious, as it seems like a whole new level of complexity for me to deal with, but hay, it’s all fun.

Will update when I have more to show.

Wow, nice work :slight_smile:

Allright!
So I totally dropped the ball on this project as I got sucked into another project for ‘work’. I’ve dropped the ball on THAT project now, so I’m now back on the game with fresh eyes.

I’ve finished porting it to Slick2D, integrated the Slick ParticleSystem classes into my Entity-Component system and made some very basic GUI and interface bits work (RMB to drag the camera around, LMB to test-fire different projectiles.)

Using the ideas in this tutorial I now have an asset loading system that reads my art, sound and particle effect assets from an XML resource file. Many thanks to Spiegel for a great tutorial and also starting me on my first steps to mastering my phobia of XML - I’ve even started geting an Entity loader class togetehr to store entities in XML.

I’ve spent this morning working on a EntitySystem class that handles updating and rendering of all the entities in the game ‘world’. In effect, this class is the game’s playing board, and makes sure everything updates in a more efficient way.

One of the big problems that I have over come with my original game class is that EVERY entity updated and rendered EVERY frame. This limited me to a few thousand Entities total, and with the integration of the Slick particle effects, was whipping the hell out of my poor, aged workstation :stuck_out_tongue:

To get around this, the EntitySystem stores every entity in the game in a 3D array. The keys for these arrays come from the world position of the entity, with X and Y divided by 500 (dimension Z gives me more than one entity in each 2D index).

This effectively splits the game world into cells 500*500 pixels across, each with an array of Entities that are within that cell.

What I then did was modified my Update and Render loop methods to only U/R the cells that will appear on the screen (technically the 6*6 grid centered on my camera focus), ignoring any empty cells and cells that fall outside of the viewable area.

This alone on my Render time is saving over 150-200ms in a world with 100,000 entities all moving around, bringing me a little closer to my 1M+ entity goal.

Hell yeh! :smiley:

Right, so what I’m working on now is a better method for updating entities that are NOT on the viewable area.

Just to get something working I implemented a timed method, so every X milliseconds, EVERYTHING is updated. This worked ok, but in 100K+ worlds, it means about a 200-300ms pause every second or so - not cool.

Back to pen and paper, I’m currently working on a method of updating a single off-screen row of cells every loop (actually, it would be practical to do 10 or so, or it would take 5000 game loops to update my 5000*5000 test world).

My problem is keeping track of when each cell was last updated. I’m thinking that I have another huge 2D array of long last update times and working it out that way, but that seems really cumbersome…

It may be the way to go if i cant think if anything prettier though.

Matt

EDIT: Ok I think a better solution is to create a Cell class that contains the Entity[] of contents and a few helper methods to get the deltaTime and an lastUpdatedTime for that cell.

Going to have a play around with different off-screen update loops and see what works best.

I’ve been doing similar stuff.

[quote]public class Projectile extends Entity
[/quote]
Stop right there. Why on planet earth would you do such a thing? The whole point with using component based system is so you don’t have inheritance hierarchies like that. In fact, some “experts” claim that the Entity class should really just be an id and not contain anything (not even components).

Some reading:
http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
Game Gems 6 - Game Object Component System article

Yeh, that’s something i’ve had from ages ago.

I’m slowly replacing the inheritance code with better entity based code as I go.

I’m not sure how useful an Entity class with just an ID would be… What I have at the moment is a class with a collection of components and an update and render method that goes through the collection updating and rendering where needed.

I’m working at getting all the rendering stuff cared out by the Renderable component, but its slow going at the moment.

Ugh, I’ve just had one of those FFFFFUUUUUUUUUUUU moments…

For the last few days worth of game time, i’ve been trying to figure out this weird deltaTime problem, where things seem to be rendering at uneven speeds.

Today i set up the profiling tools on Netbeans and ran the game by them - exponential rise in memory usage and instanced objects over time. This was my first pointer.

Next, i spent a few hours getting my own game-specific profiling and debug tool made that interfaces with the entity system. From this i learn that every time a gun is fired, i get a HUGE increment in Update/Render methods per loop. This was my second pointer.

Next, i litraly rip apart all my update/render loop code, to try to see if i have any errant loops in there. No dice.

So i give up in a huff. Go to make a fresh pot of coffe and literally the moment my hand touched the kettle, i realsied the one place i had not thought to check.

Ok, so to make things simpler with Entity addition/removal in the system, i have a LinkedList queues of entities to be created and deleted. At the end of each Update loop either add the queued entities from the add queue to my Entity system, or remove the expired ones (this is every 50 game loops, as its a bit overkill to do a clean-up every loop.)

By now you’ve probably guessed that the one thing i hadn’t thought to check is whether i was emptying the FFFFUUUU… queue each time I added it’s contents to the system…

Yep:
Gun fired - Queue = one projectile entity - adds it to the world.
Entity Update1 - Queue = one projectile entity - adds it to the world (2).
Entity Update
2 - Queue = one projectile entity - adds it to the world (3).
Entity Update3 - Queue = one projectile entity - adds it to the world (4).
Entity Update
4 - Queue = one projectile entity - adds it to the world (5).
Gun fired - Queue = two projectile entitys - adds it to the world (7).
Entity Update8 - Queue = two projectile entity - adds it to the world (9).
Entity Update
11 - Queue = two projectile entity - adds it to the world (11).
Entity Update13 - Queue = two projectile entity - adds it to the world (13).
Entity Update
15 - Queue = two projectile entity - adds it to the world (15).

etc…

well, its working now.

I’ll get a screen shot up in a bit.

Next: Collision detection and Damage! (you know the game bit of the game)

Hay all, just a quick update:

As promised, a screen cap of the current game progress

http://sphotos.ak.fbcdn.net/hphotos-ak-snc4/hs194.snc4/38059_411722081716_555931716_5149035_8373472_n.jpg

Here we have three ships, all loaded from XML, set to attack one another. The one on the right is armed with particle beams, the ones on the left are firing basic rocket-type things. Currently tracking projectiles is broken for some reason. the way I’m going about this is:

Projectile Acceleration = (Target Position - My Position).NormaliseVector() * projectileMaxAcl

this just seems to lead my projectiles off in random directions like a drink fly though … I’ll be the first to admit that my geometry sicks. If anyone can suggest a better Vector2D and Physics class available it would be cool :slight_smile:

Also, I still have not got rotation on my sprites sorted. It seems rather a simple thing to do, I know, but yeh … i’ll do it tomorrow

Matt

PS: I’m also looking for someone who has some experience with Iso-tile based games (think Fallout 1/2) to work with on an applet (probably Facebook based) game idea that I have had floating around for some time. If anyone’s interested, feel free to PM me for more info.

Edit:
I’ve just had a browse through the documentation for Phys2D ans the library looks like it does everything I need and more. I’m going to spend a few hours integrating Phys2D into a copy of my current game code to see how much of an improvement it makes.

Also, as this project has slowly evolved away from a full game engine and more into a game, I’ve re-named the thread accordingly.

UPDATE: Procedural object creation.

Ok, not really a tutorial, more of a walk-through of the process I’m experimenting with to create procedurally generated content - in this case, everyone’s favorite retro adversary, Asteroids!

I’ll be updating throughout the day as I’m working on this, so feel free to leave comments and suggestions.

I started by writing down on paper the general idea of what I wanted to do. The basic steps I’m going to follow are;

  • Start with a seed number (long) that will be the random number generator seed.
  • Around my center point (0,0), start creating new radial co-ordinate points every 11.25 degrees with Random(seed+loop#) radie.
  • this gives me 32 points. Next create beziaer curves using 4 points at a time, going around.
  • For each curve, get 20 points along its edge and add them to my asteroids Polygon

Next I threw a few sketchy classes together and ran a few renders to see what the results were;

  1. Giant Space Hippy Daises of DOOM! ;D (I forgot to add the width on one of the endpoints, making it 0. Damn typos.)

http://sphotos.ak.fbcdn.net/hphotos-ak-ash2/hs017.ash2/34235_411839461716_555931716_5151115_1783637_n.jpg

  1. I fixed the width thing, now they’re looking a bit more like rocks. (or marshmallows)

http://sphotos.ak.fbcdn.net/hphotos-ak-ash2/hs017.ash2/34235_411839466716_555931716_5151116_1409856_n.jpg

  1. I wanted a bit more variance in the shape and size, so next i used the my random numbers to pick the minimum and maximum radius of each point. (before they were 100 and 500). I forgot to get a screen cap of that, but there was not a huge difference.
    What I have changed here is instead of using consecutive seeds (1,2,3,4,etc) I’m using multiples of 1000. So going right to left, we see the first 10,000 generations of asteroid.

http://sphotos.ak.fbcdn.net/hphotos-ak-snc4/hs017.snc4/34235_411839471716_555931716_5151117_6794960_n.jpg

Ok, more like it. Note that the first one is still very similar to the original 10. This is because they seem to gradually evolve over time. I’ll see if i can get a video of it later.

Actually, they are a little too jagged, so I’m going to experiment a little more.

Will update when I have something.

UPDATE 2:
Whell that was easier to do that I expected…

As you can see, its a bit ropey, and for some reason, goes WAYYYY smaller than the 100px minimum size. (radii are set to be between 100-1000px … hmm)

Also, does anyone know if its possible to embed youtube vids?

Update 3:

After some tinkering and a break to let my poor aged GPU have a nap on a few occasions I got this code producing nice looking asteroid shapes;


       public static Asteroid MakeAsteroid(long seed)
        {
            Asteroid asteroid = new Asteroid();

            Vector2f[] line = new Vector2f[32];

            float minWidth = 100;//RandomDice.SEED_ROLL_BETWEEN(100, 200, seed);
            float maxWidth = 200;//RandomDice.SEED_ROLL_BETWEEN(minWidth, minWidth*2, seed+1);
            float width;

            float theta = (float)Math.toRadians(40d);

            width = RandomDice.SEED_ROLL_BETWEEN(minWidth, maxWidth, seed);
            Vector2f[] points = new Vector2f[9];
            

            for(int i = 0; i < 9; i++)
            {
                width = RandomDice.SEED_ROLL_BETWEEN(minWidth, maxWidth, seed+i);
                points[i] = Vector2f.fromAngle(i*theta, width);
            }

            Path path = new Path(points[0].getX(), points[0].getY());

            path.curveTo(
                        points[2].getX(), points[2].getY(),
                        points[1].getX(), points[1].getY(),
                        points[1].getX(), points[1].getY(),
                        4);
            path.curveTo(
                        points[4].getX(), points[4].getY(),
                        points[3].getX(), points[3].getY(),
                        points[3].getX(), points[3].getY(),
                        4);
            path.curveTo(
                        points[6].getX(), points[6].getY(),
                        points[5].getX(), points[5].getY(),
                        points[5].getX(), points[5].getY(),
                        4);
            path.curveTo(
                        points[8].getX(), points[8].getY(),
                        points[7].getX(), points[7].getY(),
                        points[7].getX(), points[7].getY(),
                        4);

            asteroid.outline = path;
            return asteroid;
        }

I recorded a quick vid showing the variety of sizes that come out of the generator (again, incrementing the seed by 1000 for each asteroid.)

One think I’ve noticed right off the bat is that rendering primitives like this seems a lot more intensive* than rendering images. In previous tests with image asteroids i can have 10,000+ all moving around no problem but with these, things start chugging at about 300.

*By ‘intensive’ I mean my GPU keeps crashing, which literally shorts out my PC causing a hard shutdown. I’m open to the idea that this may be more of a hardware problem than anything I’m doing… I think that I might be one of the few people who still owns a GeForce MX440. (some retro right there for ya)

I’m going to look into ways of getting the performance up to scratch. Firstly, the only time there’s ever going to be a load of these things rendering is when the camera is zoomed way out, so I’m going to modify the factory method to provide 4 different shapes to render, ranging from a 100+ point high-detail path to a single point dot, depending on the camera zoom.

Next I’m going to get an asteroid-field builder factory type thing so that I can split up the playing field into sections that I can dynamically load (from local cache or server) on the fly as the player moves in and out of range. (one game play dynamic I’ve been thinking of to hide this is a player can only see what his ship’s sensors can see - so the same way that we know that there’s moons around Saturn, we only know what they look like when we have a probe up close.)

My TODO List Next:

  • I cant remember what its called but that level of detail thingy. :slight_smile:
  • Procedurally generate a 1000*1000km asteroid field.
  • Make a level reader to load these on the fly from an XML file.

Update 4:

I put a LOD variance on, but have not integrated it properly yet.

I got fed up with coding, and hit Photo shop to make myself some maps. Below is the asteroid density for (sorta) our solar system.

If you’re nerdy and you know it; Ring in the center is the Main Belt, the three blobs around that are the Trojan, Greek and Hildas(sp?) fields (in Jupiter Lagrange points). Out beyond that is the main mass of Kupiter belt objects and beyond that is the little knows Artistic Licence belt.

http://sphotos.ak.fbcdn.net/hphotos-ak-ash2/hs102.ash2/38433_411970351716_555931716_5154243_5907069_n.jpg

The idea is that I can use this to generate the asteroid density procedurally in a game world that actually is 80AU from Sun to edge - LOADS of scope for MMORPGR action!

Going to call it a day now and get back to it in the morning, hopefully with the zone-loading map rather than trying to do it all at once. (even a 50*50 pixel (on the map image) ended up with 40K asteroids, lol).

Have a good evening if you’ve been following along,
Matt

No great experiments today, just going back to updating my empty template game to use SLick2D’s StateBasedGame, with a short animated introduction state and sound.

After some discussion on the forums and some reading around, I’m re-writing my content loading code to use the ClassLoader class, and storing all my content in the classpath.

My overall goal for today is to consolidate everything I have into something reusable. Until now I have been copy-pasting bits from other projects here and there as I need them. This has lead to the obvious problem of having 30 copies of the same class on my HDD, one of which is the RIGHT one :smiley:

At the moment, my classpath looks like this:


TemplateSlickGame (used to create a new game project in NetBeans)
  assets
    art                          (for storing images)
      sound              (for storing sounds & music)
      effects              (currently only for storing particle effects)

  slickgametemplate
    Main (main class for the app)
    SlickGame (extends StateBasedGame)
    RBGWIntroState (extends GameState to show a splash screen)


rbgwLib (code library common to all my games)
  content
    ResourceManager          (loads and indexes art, music, particle effects, etc)
    IResourceLoader          (an interface for loading resources)
      loaders
        ImageLoader        (loads images)
        SoundLoader        (loads sounds/music)
        FontLoader        (loads Slick Font types)
        ParticleLoader        (loads particle systems)
        AnimationLoader        (loads Slick Animations)
                
  TODO: Move the rest of my crappy-hacked code into this library :)


Probably not allot of scope for screen shots today…

Good to see you’re transforming your code from an engine into a game. ‘Eating your own dog food’ is very important. Besides that, there are so many 2D engines written by people with at least a decade of (game) programming experience, that you’d be hard pressed to match their engine quality. So while you’re writing your engine it’s better to write it for yourself, and once you’ve written a bunch of games with it, consider to put it in the public domain.

yeah, I agree with riven, an engine wont be greatly appreciated by the public because there are probably better ones. but it is nice for u for 2 reasons

  1. u learna whole lot doing it
  2. whenever u need a new feature, u know exactly how to fit it in, not having to ask the developer and wait a few days (or even weeks) for that feature, which is a real roadblock in your development.

btw, game looks REALLY good :slight_smile:

yeh, that’s exactly my reasoning.

Hay all,

Just to let you know me and the project are still alive. The project is on hold for a few weeks while I take a break and work on some research stuff.

This is usualy how I roll, so expect another gaming binge in a while!