Jump to content
  • Advertisement
Sign in to follow this  
jbrennan

How to design Entities which can wrap around the map?

This topic is 2647 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been thinking about "Mario Bros." lately (the old arcade game where you're in a sewer) and how when the player goes off screen (it's fixed-camera) to the left, he pops out on the right and vice versa. I've been considering how that would be implemented.

Now, if the character went fully offscreen before popping out the other, then that would be really simple, you'd just need to manually adjust and "jump" them back to the other side. But the trouble comes because the player can be half off to the left and half wrapped-around to the right. How is this done?

The best guess I can come up with is each Entity actually has 2 identical sprites/images associated with them, with one usually hidden and the other usually visible. When the wrap-around is in progress (ie half on each side of the screen), then both images of the entity are simultaneously visible, offset by the proper amounts on either side. And then when the entity fully pops out the other side, then the other image is made hidden.

Is that how it's done or is there a better way? I'm of course only talking about a 2D game.

Share this post


Link to post
Share on other sites
Advertisement
I recently had to implement this for an asteroids clone that I made to test out the 2d sprite functionality in my latest renderer. I originally thought, oh, just draw 2, one at x and one at x+screenwidth. It turns out in my case, there can be up to four copies drawn: in asteroids you wrap in both dimensions, so anything in the corner of the screen is 'quartered' into all 4.

The logic was pretty simple. I had screen coordinates [0,0] bottom left to (1,1) top right. Sprites are drawn specifying their bottom left point. So a sprite drawn at (0,0) is perfectly in the bottom left corner, and a sprite at (1,0) is completely off the right side of the screen. A sprite at (1-sprite.width,0) is in the bottom right corner, and at (1-sprite.width, 1-sprite.height) is perfectly in the top right corner.

The drawing code looks like this:



//main object
sprite_draw(entity.sprite, entity.x, entity.y);

//if exceeding right side of screen, draw one off the left

if (entity.x + entity.sprite.width > 1.0)
sprite_draw(entity.sprite, entity.x-1, entity.y);

//if exceed top of screen, draw one on bottom
if (entity.y + entity.sprite.height > 1.0)
sprite_draw(entity.sprite, entity.x, entity.y-1);

//if exceeding both, draw one off the bottom left
if ((entity.y + entity.sprite.height > 1.0) && (entity.x + entity.sprite.width > 1.0))
sprite_draw(entity.sprite, entity.x-1, entity.y-1);




Note, the above is from memory, as my code to do this is at home. If there's an error, I'll be sure to correct it when I look back at the real code!

Also, if you're rending with GL or another reasonable API, you don't really even have to do the tests; I tried always drawing 4 copies of the sprite, and it works fine. I suppose its a performance hit, but the graphics API should clip away anything off the screen anyway. Its slightly faster if you clip it yourself like I did above, but not strictly necessary.

Share this post


Link to post
Share on other sites
Perfect! Worked perfectly. Makes sense, not really sure why it hadn't dawned on me already, haha. Thanks again.

Share this post


Link to post
Share on other sites
I also had to think about this for an asteroids game. You not only have to copy the drawable part, but also consider a few other things, for example collision detection (you don't want the character to be visible on both sides, but hittable only on one).

As I was experimenting with a "component system", this resulted in one entity having several copies of various components, but I am not sure this is the best way to go. Maybe at the point you are, it would be easier to just duplicate the collision checks, the same way you do for the drawing method.

Share this post


Link to post
Share on other sites
For my asteroids clone (written some years ago), I wrote a function called "int getPositions(vector2 *array)" that filled the array with up to 4 vector2 instances, and returned the "count" as the return value.

This would be used for drawing and collision. The internal logic of that function was similar to DracoLacertae's draw example. I used a similar tecnique of having 0,0 the centre of the screen and having the screen dimensions + or - 1 in all directions. To wrap a sprite, I had to add or subtract 2 from its position's x/y components.

Share this post


Link to post
Share on other sites

I also had to think about this for an asteroids game. You not only have to copy the drawable part, but also consider a few other things, for example collision detection (you don't want the character to be visible on both sides, but hittable only on one).


Hmm, great point and something I hadn't considered. I'll have to fix this in my code. Thanks for the heads-up!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!