Implementing a cloning feature for sprites. Good design?

I’ve finished the Space Invaders game that I was working on, works flawlessly. However, I was wondering if there was a more efficient way to draw my aliens. Currently, my draw method for each alien is as follows:

@Override
	public void draw() {
		sheet.texture.bind();
		glBegin(GL_QUADS);
		glTexCoord2f((float) (frameX / sheet.imageWidth),
				(float) (frameY / sheet.imageHeight));
		glVertex2i(x, y);
		glTexCoord2f((float) (frameX + spriteWidth) / sheet.imageWidth,
				(float) (frameY / sheet.imageHeight));
		glVertex2i(x + width, y);
		glTexCoord2f((float) (frameX + spriteWidth) / sheet.imageWidth,
				(float) (frameY + spriteHeight) / sheet.imageHeight);
		glVertex2i(x + width, y + height);
		glTexCoord2f((float) (frameX / sheet.imageWidth),
				(float) (frameY + spriteHeight) / sheet.imageHeight);
		glVertex2i(x, y + height);
		glEnd();
	}

Pretty straightforward. The issue I’m having is that for every alien on which this is called, there are multiple values that remain the same for each one, such as the frame#, the sprite size, etc. This got me thinking: If I were to create 1000 aliens, would there be an easier way to dupe/clone the sprites, than creating each one with it’s own values even though they all reference the same thing?

I was thinking I would create 1 Buffered Sprite if I needed to create multiples, and then instead of creating multiple individual alien objects, the BufferedSprite could have an Array/ArrayList(s) containing all of it’s copies’ position, speed, animation and etc. variables. So I’m wondering if it would be bad to use this design; for example, if I had hundreds of clones, the drawing and updating methods would have to iterate over enormous collections… That is just one of many problems I think I’d encounter with this, but could it save memory since I’m cutting down the amount of unique objects created? I would only use this in cases where I had a sizable number of clones, by the way.

If something is common to every instance of a class, then you could make it static.

I know that… I’m trying to avoid instantiating multiple objects when I’m cloning entities.

Sorry for teaching you to suck eggs then; I was answering the “multiple values that stay the same for each one” bit that you’ve mentioned.

Correct me if I’m wrong, but instead of having 100 alien objects, you want to have ArrayList’s of 100 variables that represent each one? I can’t see any major benefit in doing things this way, and if anything it will just make matters more complicated. I’d still create 100 objects, and have them reference their common properties elsewhere (whether this is static, or some kind of ‘AlienType’ class or something). If the creation (and subsequent GC’ing) of objects is a concern, then you’d be better off thinking about object re-use.

Sorry if I’ve missed the mark; it’s a bit hard when I’m not familiar with your project.

Pretty much, an ArrayList with 100 entries that represent only the unique values for each alien, and then things that remain the same for all of them would be the attributes of the Buffered Sprite.

The idea appeals to me because I was going to try to make game that would have lots of sprites on screen, with the only thing unique about them being their individual Animations and x and y positions (as with the x and y’s of their bounding box). I know it’s complicated but it’s really only a rare-case-use class that would help if I need to clone entities real-time.

If you have a class such as this:



class Sprite {
    int x, y;
    BufferedImage image;
    //other stuff

    Sprite(int posx, int posy, BufferedImage tex) {
        x = posx;
        y = posy;
        image = tex;
    }
}

The coordinates are passed by value (copied, as they are primitives) and are thus stored for each Sprite you create. However, the BufferedImage (to use J2D an an example) is an object reference (a pointer), so only the location of the referenced object is stored for each sprite. The referenced object can be singular, and should be for all Sprites that render the same image.


BufferedImage alienTex = loadImage("alien"); //whatever

// add 1000 alien sprites with random locations
for(int i=0; i<1000; i++) {
    // does create 1000 Sprite objects (as necessary to store all the different locations), but there is only ever one BufferedImage: alienTex
    entities.add(new Sprite((int)(Math.random() * width),(int)(Math.random() * height)), alienTex);
}

...

// draw them

for(Sprite s : entities) {
    g.draw(s.image, s.x, s.y, null); // the same BufferedImage is simply drawn multiple times (assuming all entities are aliens)
}

Maybe you already knew this, but it’s important to know how Objects work in Java (they’re all secretly pointers!), so I figured I’d make sure and post anyway.

TL;DR: don’t use [icode]new[/icode] for non-unique data.

EDIT: also a good rundown on StackOverflow: http://stackoverflow.com/questions/1750106/how-can-i-use-pointers-in-java

I’m pretty sure he isn’t asking about improving client side performance. He probably wants to use buffers of some sort to render his aliens, meaning he has 1 sprite object which he then references through IBO.

There is that, and I do suggest for OP to not use the fixed-function pipeline, but his responses indicate that he is concerned with the OOP-side of the situation. (Also, client side?)
And my point still stands regarding object non-duplication even in an OGL context: OpenGL binds a texture, then blits it multiple times to different coordinates.

But really, at this point it’s all premature optimization:

[quote]works flawlessly
wondering if there was a more efficient way
[/quote]
Dude! Congrats, you made something that works! Now go and write the rest of the game, don’t waste time on things that work fine.

This. Again, this is rare-case scenario stuff that I’d only use if there was an entity that I knew was going to be cloned, but I really would like to know if this solution would be optimal & efficient for cloning because with the way things are set up now, I assume the rendering would get taxing if I needed to have a huge amount of multiples of the same Sprite.

@ Burnt , I use a reference of a Sprite Sheet to load them, that’s not really what I’m concerned about. + thanks, but I’ve already finished the game…

Just wondering if this design is bad or not… :expressionless: