2d platform game

hi there,
I’m sharing some code from my project “space weasel” :wink:
first the java web start link: space weasel
then the whole archive, ready to import in eclipse: sweasel2.tgz

context highlighted source: here
not much comments though…

it’s still a work in progress… but i thought it might be of some interest for some ppl willing to
get some working exemple to look at, to build their own games.

hum i don’t know what step i should take to release something under gpl, someone could tell me?
ah, i forgot, graphs are “borrowed” from various games… mainly metroid series.
if i get complains, i’ll remove them quicker than planned and replace them with homebrewd ones :wink:
tnx

Nice game!! Graphics are really arcadey :D, and it’s cool the way you can fly/levitate. I want to get out of work so I can try it out properly.

Keith

thanks for the nice words :slight_smile:

but there’s nothing to do yet…
you can just kill few monsters, walk through few doors and that’s it …
i plan to add all the interesting stuffs in next version…

i have to figure how to make the bullets to not follow you when you go left and right too :wink:
create dying animation for monsters, real size level, figure how to go fullscreen, create a game menu etc etc …

i’m slow though, next version could take 2 months or more :wink:

Are the graphics original? :-o

[quote]Are the graphics original? :-o
[/quote]
no… it’s explained in the first post.
i borrowed them from other games.

there’s some graphics from the nintendo “metroid” series,
and some other found on some public domain ressources on the net…

i plan to change them, but i’m not in a hurry… i’ll create home made graphx little by little…
except if i get lots of complains, i’ll have to remove them immediatly…
but for now they’re used. they’re temporary graphics, just to test the engine …

i don’t plan to sell anything, i don’t plan to deceive anyone. it’s just temporary graphics.
and all my “space weasel” sources are gpl v2 … until gpl v3 is out.

i would appreciate to get some comments about how messy, wrong and redundant the code appears to you folks…
it would help me improve if i could get some advices …
if some ppl have time to have a quick look at the code, please?
can you spot big mistakes ? i surely did lots of them…
i create direct links so it’s easier to see the code… there’s 11 classes:

Game.java
IOLoader.java
Sprite.java
MapHandler.java
MapLoader.java
Keyb.java
Creature.java
PowerUp.java
Player.java
Bullet.java
Grub.java

that’s it…

thanks :slight_smile:

Basically, I’d add some faster memory-heap-safe-Threads to the code, e.g. your sprite uses an Image as the data-buffer and doesn’t make it softly allocated. I’d add a PhantomReference to it:

   1.  
   2.  import java.awt.Image;
   3.  
   4.  public class Sprite {
   5.  
   6.      //protected Animation anim;
   7.      private Image anim;
            // private PhantomRef
            private Reference phantom;
            // private Ref. Queue
            private ReferenceQueue<? extends Reference> refQueue = new ReferenceQueue<PhantomReference>();
   8.      // position (pixels)
   9.      public float x;
  10.      public float y;
  11.      // velocity (pixels per millisecond)
  12.      private float dx,dy;
  13.      private float lastdx,lastdy;
  14.      public static float zx;
  15.      public static float zy;
  16.      /**
  17.          Creates a new Sprite object with the specified Animation.
  18.      */
  19.      //public Sprite(Animation anim) {
  20.      public Sprite(Image anim) {
  21.          this(anim, new ReferenceQueue<PhantomReference>());
  22.      }
  23.  
            /***/
            public Sprite(Image anim, ReferenceQueue<? extends Reference> refQueue) {
                    this.anim = anim;
                    this.phantom = new PhantomReference(anim, refQueue);
                    this.refQueue = refQueue;
            }

             /***/
             public void finalize() { 
                 anim = null;
                 phantom.clear();
                 super.finalize();
             }
            
  24.      /**
  25.          Updates this Sprite's Animation and its position based
  26.          on the velocity.
  27.      */
  28.     
  29.      public Image update(long elapsedTime) {
  30.          x += dx * elapsedTime;
  31.          y += dy * elapsedTime;   
  32.          zx = x;
  33.          zy = y;
  34.        return anim;// = setX(x);//anim;//. update();
  35.      }
  36.     
  37.      public float getMaxSpeed() {
  38.          return 0.2f;
  39.      }
  40.  
  41.      /*
  42.          Wakes up the creature when the Creature first appears
  43.          on screen. Normally, the creature starts moving left.
  44.      */
  45.     
  46.      public void wakeUp() {
  47.        // if (getState() == STATE_NORMAL && getVelocityX() == 0) {
  48.              setVelocityX(-getMaxSpeed());
  49.        //  }
  50.      }
  51.  
  52.      /**
  53.          Gets this Sprite's current x position.
  54.      */
  55.      public float getX() {
  56.          return x;
  57.      }
  58.  
  59.      /**
  60.          Gets this Sprite's current y position.
  61.      */
  62.      public float getY() {
  63.          return y;
  64.      }
  65.  
  66.      /**
  67.          Sets this Sprite's current x position.
  68.      */
  69.      public void setX(float x) {
  70.          this.x = x;
  71.      }
  72.  
  73.      /**
  74.          Sets this Sprite's current y position.
  75.      */
  76.      public void setY(float y) {
  77.          this.y = y;
  78.      }
  79.  
  80.      /**
  81.          Gets this Sprite's width, based on the size of the
  82.          current image.
  83.      */
  84.      public int getWidth() {
  85.          //return anim.getImage().getWidth(null);
  86.          return anim.getWidth(null);
  87.      }
  88.  
  89.      /**
  90.          Gets this Sprite's height, based on the size of the
  91.          current image.
  92.      */
  93.      public int getHeight() {
  94.        // return anim.getImage().getHeight(null);
  95.          return anim.getHeight(null);
  96.      }
  97.  
  98.      /**
  99.          Gets the horizontal velocity of this Sprite in pixels
 100.          per millisecond.
 101.      */
 102.      public float getVelocityX() {
 103.          return dx;
 104.      }
 105.  
 106.      /**
 107.          Gets the vertical velocity of this Sprite in pixels
 108.          per millisecond.
 109.      */
 110.      public float getVelocityY() {
 111.          return dy;
 112.      }
 113.  
 114.      /**
 115.          Sets the horizontal velocity of this Sprite in pixels
 116.          per millisecond.
 117.      */
 118.      public void setVelocityX(float dx) {
 119.          if (getVelocityX()!=0){
 120.          this.lastdx=this.dx;
 121.          }
 122.          this.dx = dx;
 123.       
 124.      }
 125.      public float getlastdx() {
 126.          return lastdx;
 127.      }
 128.     
 129.  
 130.      /**
 131.          Sets the vertical velocity of this Sprite in pixels
 132.          per millisecond.
 133.      */
 134.      public void setVelocityY(float dy) {
 135.          this.lastdy=this.dy;
 136.          this.dy = dy;
 137.      }
 138.     
 139.      public float getlastdy() {
 140.          return lastdy;
 141.      }
 142.  
 143.      /**
 144.          Gets this Sprite's current image.
 145.      */
 146.      public Image getImage() {
 147.          //return anim.getImage();       
 148.          return anim;
 149.      }
 150.  
 151.      /**
 152.          Clones this Sprite. Does not clone position or velocity
 153.          info.
 154.      */
 155.     
 156.      public Object clone() {
 157.          return new Sprite(anim);
 158.      }
 159.     
 160.  }

That’s my point.
You may try this code and test it. That might be faster with larger amount of sprites. Notice the finalize meth that explicitly clears the buffer. It also may be linked with other Sprites for animation throughout a common ReferenceQueue given as contructor arg. ::slight_smile: ::slight_smile: ::slight_smile:

thanks for the advice :slight_smile:
i tryed to do it, i added the 3 imports (ReferenceQueue, Reference, and PhantomReference)
but i got some error with super.finalize();
it said something about throwable exception iirc …
i’ll try again tommorow, see if i can make this working… i’ve never heard of theses classes before, and i have no idea what’s their purposes and how i can use em… i’ll browse a bit more through java 6 api-docs
…i appreciate the help anyway :slight_smile:

hi there, i got it working like this:


import java.awt.Image;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.PhantomReference;
import java.io.IOException;

public class Sprite {

    private Image anim;
     private Reference phantom;
     private ReferenceQueue<? extends Reference> refQueue = new ReferenceQueue<PhantomReference>();
    public float x;
    public float y;
    private float dx,dy;
    private float lastdx,lastdy;
    public static float zx;
    public static float zy;

    public Sprite(Image anim) {
        this(anim, new ReferenceQueue<PhantomReference>());
    }

     public Sprite(Image anim, ReferenceQueue<? extends Reference> refQueue) {
             this.anim = anim;
             this.phantom = new PhantomReference(anim, refQueue);
             this.refQueue = refQueue;
     }

      public void finalize() throws IOException {  
          anim = null;
          phantom.clear();   
          	try {
        	  	    super.finalize();
        	  	}
        	  	catch(Throwable e){
        	  	    throw new IOException(e.getMessage());
        	  	}   
      	}
   
    public Image update(long elapsedTime) {
        x += dx * elapsedTime;
        y += dy * elapsedTime;   
        zx = x;
        zy = y;
      return anim;
    }
   
    public float getMaxSpeed() {
        return 0.2f;
    }

    public void wakeUp() {
    }

    public float getX() {
        return x;
    }

    public float getY() {
        return y;
    }

    public void setX(float x) {
        this.x = x;
    }


    public void setY(float y) {
        this.y = y;
    }

    public int getWidth() {
        return anim.getWidth(null);
    }

    public int getHeight() {
        return anim.getHeight(null);
    }

    public float getVelocityX() {
        return dx;
    }

    public float getVelocityY() {
        return dy;
    }

    public void setVelocityX(float dx) {
        if (getVelocityX()!=0){
        this.lastdx=this.dx;
        }
        this.dx = dx;
     
    }
    public float getlastdx() {
        return lastdx;
    }   

    public void setVelocityY(float dy) {
        this.lastdy=this.dy;
        this.dy = dy;
    }
   
    public float getlastdy() {
        return lastdy;
    }

    public Image getImage() {
        return anim;
    }
   
    public Object clone() {
        return new Sprite(anim);
    }   
}


is this the way you were speaking about ?
So basicaly what it does is, help the objects to be better garbage collected?
performance wise, it roughly the same as before… maybe when i’ll add more entities, i’ll see the benefit of such methods?

tnx

that’s alright! Then I add those referenced Sprites to an Animation containing a managed refQueue with basically the minimal alg for storing the Sprites on cache. Say you store the refQueue in a variable of Animation then keep the sprites in a Map whose keys are ordered in the way the Sprites are fetched by your Timers.
This is less easy to impl but is required to avoid HeapMemory Errors. You might post questions about that. I’ll be ready to answer. :smiley:

it’s too complex for me, i don’t understand it all …
right now i’m trying to create something else …a small gui (swing) with a JComboBox to where to choose weither to run the game fullscreen or windowed mode.
i did it, but then i lost control over the key listeners it seems…
when the game start wether in window or fullscreen mode, i have no reponse upon key presses anymore.
no matter what i do i wasn’t able to get back control of the keys yet .

it seems your additions help when there’s lots of sprites… i need to investigate more… but it will take me lot of time i’m affraid …
yet i’m glad you taught me how to do it… i’m using your modification… but i’ll need more time to understand them…

since it’s a bit tricky to me, i delay studying it by working on some other parts… like the screenmode selection gui or other stuffs.

thanks for your help

right just a tip about the keyListeners: they loose indeed all focus on window when switching from one to another or the bug is something similar to that. The solution is to implement the KeyEventDispatcher and to add it to the KeyboardEventDispatcher. This is AWT toolkit. :wink:

Aaah… i’ve been trying to understand this for few days now :wink:
so it’s probably a bug ? thanks for telling me… i wasn’t able to understand why i couldn’t get back my keylistener after switching back from the mini-swing gui to my game jframe…
i was thinking to forget about the swing -screen selector gui- and doing in from inside the game… like it’s done on most of the real games out there…
an option screen from inside the game. but then maybe i would have encountered the same problem again :wink:
thanks for the hint, i’ll definately try that this weekend.

btw, i was wondering, do you know a good java irc channel ?
i tryed #java on freenode… but there’s lot of ppl, not much help, and not much game related dev…
would be nice if javaGaming.org had a irc channel somewhere…

tnx

I’m not an expert in game dev, but a game loop seems to be a bit wired: you are sleeping unpredictably: sometimes after two updates, sometimes after three or five, etc. Anyway - game runs smoothly and that’s the point.

Thanks for code.

thanks for the info :slight_smile:

by any chance could you suggest something to correct this weird gameLoop ?
i’m not good programmer at all… this is only my 3rd project … and it’s a patchwork of tutorials i’ve followed on the net.
mainly kevglass and pianeta tutorials.

so if you could show me how i could correct his weird behavior (i didn’t even noticed it was doing such weird stuffs :wink:
any help would be more than welcome

thanks :slight_smile:

a more “up to date” version: archive here
and java web start: click me

now it have an option screen… the logo "space weasel sucks :wink:

the keys are: ESC to open or leave the option screen (btw fullscreen option doesn’t work yet.)
Return key to select something in the option screen.
arrow key to move
space key to fire

that’s it i guess

BUG: Walk through door while holding fire :wink: