Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (120)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  JOURNAL: Space Fleet Combat (now less of a 2D Game Engine)  (Read 5522 times)
0 Members and 1 Guest are viewing this topic.
Offline Dreamcatchermatt

Junior Duke





« Posted 2010-05-12 23:40:43 »

Hi All,

First, if theres a forum that this post would be better placed in, can a mod please move it or direct me where to re-post? Chears Smiley


Ok, as a few of you know from my other posts, I'm currently working on an entity-based game engine over my uni summer break - partly as a lerning exersise, partly becasue i'd like to have a (sellable?) game made before i'm called back to 'real' work, and mostly for the s**ts and giggles.

I'm really bad at motivateing myself, so I figure that if I try to regurly write about the progress I've made, problems I've hit and solutions I've found, it might both motivate me, and also be useful for other beginner Java-game programers.

So: the project so far (Imaginitively titled 'SPACE BATTLES!') ...

My Specifications (somewhat fluid)
  • To make a game, have fun and learn stuff! Yeh!
  • Create a game engine that can then be used for different 2D games with very little prigraming
  • Create development tools for non-programers to design new characters, items, behaviours, etc
  • Use an entity system alowing 'plugable' entity creation from basic components.
  • Have the game network ready, probably with client-server archetecture
  • Use the facebook API as part of the multiplayer (think Farmvile and its ilk.)

What i have so far:

- A basic graphics engine, using java 2d.

- A very basic Entity system. With components for Rendering, Physics (2D), Navigation(W.I.P), and basic character Stats(also W.I.P).
In this system, a space ship would impement all four, a projectile would implement Rendering and Physics, an asteroid would impliment Render, Physics and Stats(HP, Description, Resource Value, etc)

- Other Component ideas: ParticleSystem, ItemGenorator, BehaviourSystem

- A game class that handles all the rendering and updating of Entities stored in a tree datastructure

Unfortunately my desktop pc is offline, so i cant get much in the way of screenshots up (not thet theres much to see anyway.)

As I make progres I'll start adding some code snippets that I think people may find useful or that i could use some help with. Also, once i have something playable, I'll try to get some demos and test-games up.

So, theres the idea Smiley

If anyone has any comments, critique questions or other ideas, I would be happy to hear them.

Matt
Offline Dreamcatchermatt

Junior Duke





« Reply #1 - Posted 2010-05-17 10:35:15 »

Eh, go away exam revision, I want to do some games.

A quick update - the beginnings of my colission detection algorithem for my weapons system class.

I want my game to be able to handle massive hails of torpedoes and cannon shells, and becasue I did not realy want a pre-calculated damage system (say for example, as in EVE Online) but rather a colision based system, I had to have a think about the best way of handeling possibly tens of thousands of colision detections per update loop.

There are two things i have planned for this:
1) store the projectiles in a 2D binary tree structure. Using this I split up the game world into 100X100m (my resolution is 1px per m) cells. THerefor if a ship is within in cells 1020/450 and 1021/450, it will only check for colisions with projectiles stored in these cells.
As a projectile moves across the game world, it is moved through the tree as part of its update system.

2) time-seperate the colission detection. FOr example, if there are 1000 ships in the game world, check colision on only 200 of them per game-loop, balenceing the load.
(another method of doing this is using the 'empty' time when the game loop thread is waiting between frames to do colission detection - or even shifting this to its own thread - although i dont realy understand the pros and cons of that...)

For your reference/amusement/comment: the colision detectioncode I have so far (embarisingly incomplete) ...

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
public class Projectiles {
    BinaryTree<BinaryTree<Projectile>> projectiles;

    public Projectiles()
    {
        this.projectiles = new BinaryTree();
    }

    public void AddProjectile(Vector2D pos, Projectile p)
    {
        // add the projectile p to the tree at index pos
    }

    public void UpdateProjectile(Vector2D pos, Projectile p)
    {
        // move a projectile p to a new index (location pos)
    }

    public Projectile[] GetCollisions(Rectangle r)
    {
        // return an array of projectiles currently within the Rectangle r by comparing
        // their indexes with the rectangles position.

        // (this method will probably be replaced with the method below)

        Projectile[] output = new Projectile[10];

        // magic

        return output;
    }

    private BinaryTree<Projectile> getBetweenIndex(int x1, int y1, int x2, int y2)
    {
        BinaryTree<Projectile> output = new BinaryTree();

        for(int x = x1; x < x2; x++)
        {
            BinaryTreeNode n = projectiles.GetNode(x);
            for(int y = y1; y < y2; y++)
            {            
                output.InsertNode(n.);
            }
        }
    }
}


Welp, back to the flashcards  Tongue
Good luck with all your gaming endevors!
Offline Dreamcatchermatt

Junior Duke





« Reply #2 - Posted 2010-05-18 21:59:24 »

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:



yeh, now thats some cinimatic gameplay right there!  Grin

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


Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #3 - Posted 2010-05-19 14:15:03 »

Cool! Now I want me some 'splosions!

See my work:
OTC Software
Offline Jacob_

Junior Duke


Projects: 3



« Reply #4 - Posted 2010-05-19 14:44:31 »

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

Junior Duke





« Reply #5 - Posted 2010-05-19 17:31:29 »

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]

[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]

[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);
            }
        }
    }
}[/code]

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

This is my Sprite.Render() code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
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  Smiley

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.
Offline tom
« Reply #6 - Posted 2010-05-19 18:11:29 »

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.

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.

Offline Dreamcatchermatt

Junior Duke





« Reply #7 - Posted 2010-05-22 00:34:28 »

... You could attach a smoke emitter to a missile to create a trail effect ....

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   Huh
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.<init>(ParticleEmitterComponent.java:32)
        at SpaceLib.Objects.Projectile.<init>(Projectile.java:38)
        at SpaceLib.Components.WeaponComponent.initProjectile(WeaponComponent.java:102)
        at SpaceLib.Components.WeaponComponent.<init>(WeaponComponent.java:48)
        at SpaceLib.Ship.Ship.<init>(Ship.java:42)
        at GameLib.DRGame.Load(DRGame.java:130)
        at GameLib.DRGame.<init>(DRGame.java:105)
        at isogameengine_01.Main.main(Main.java:21)
[/code]

[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]

[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]

[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");
    }

}
[/code]

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.
Offline Dreamcatchermatt

Junior Duke





« Reply #8 - Posted 2010-05-24 00:10:01 »

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  Undecided

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
Offline Dreamcatchermatt

Junior Duke





« Reply #9 - Posted 2010-05-26 22:20:46 »

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.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #10 - Posted 2010-06-02 17:53:15 »

Wow, nice work Smiley

Offline Dreamcatchermatt

Junior Duke





« Reply #11 - Posted 2010-07-13 04:33:27 »

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 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! Cheesy

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.
Offline appel

JGO Wizard


Medals: 51
Projects: 4


I always win!


« Reply #12 - Posted 2010-07-13 10:23:47 »

I've been doing similar stuff.

Quote
public class Projectile extends Entity

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




Check out the 4K competition @ www.java4k.com
Check out GAMADU (my own site) @ http://gamadu.com/
Offline Dreamcatchermatt

Junior Duke





« Reply #13 - Posted 2010-07-13 10:37:29 »

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.
Offline Dreamcatchermatt

Junior Duke





« Reply #14 - Posted 2010-07-14 15:22:06 »

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 Update*1 - Queue = one projectile entity - adds it to the world (2).
Entity Update*2 - Queue = one projectile entity - adds it to the world (3).
Entity Update*3 - 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 Update*8 - Queue = two projectile entity - adds it to the world (9).
Entity Update*11 - Queue = two projectile entity - adds it to the world (11).
Entity Update*13 - 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)

Offline Dreamcatchermatt

Junior Duke





« Reply #15 - Posted 2010-07-15 21:49:31 »

Hay all, just a quick update:

As promised, a screen cap of the current game progress


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 Smiley

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.
Offline Dreamcatchermatt

Junior Duke





« Reply #16 - Posted 2010-07-16 07:48:53 »

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!  Grin (I forgot to add the width on one of the endpoints, making it 0. Damn typos.)



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


3) 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.


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;

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
       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.

*[size=8pt]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)[/size]

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. Smiley
  • 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.

[size=8pt]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.[/size]


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
Offline Dreamcatchermatt

Junior Duke





« Reply #17 - Posted 2010-07-24 08:22:13 »

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 Cheesy

At the moment, my classpath looks like this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
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...
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 817
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #18 - Posted 2010-07-24 10:12:17 »

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.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline h3ckboy

JGO Coder


Medals: 5



« Reply #19 - Posted 2010-07-24 10:58:44 »

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 Smiley
Offline Dreamcatchermatt

Junior Duke





« Reply #20 - Posted 2010-07-25 19:33:18 »

1. u learna  whole lot doing it

yeh, that's exactly my reasoning.

Offline Dreamcatchermatt

Junior Duke





« Reply #21 - Posted 2010-08-28 07:26:29 »

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!
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

theagentd (5 views)
2014-10-25 15:46:29

Longarmx (52 views)
2014-10-17 03:59:02

Norakomi (45 views)
2014-10-16 15:22:06

Norakomi (34 views)
2014-10-16 15:20:20

lcass (38 views)
2014-10-15 16:18:58

TehJavaDev (68 views)
2014-10-14 00:39:48

TehJavaDev (68 views)
2014-10-14 00:35:47

TehJavaDev (60 views)
2014-10-14 00:32:37

BurntPizza (73 views)
2014-10-11 23:24:42

BurntPizza (45 views)
2014-10-11 23:10:45
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!