Search code examples
cocos2d-iphonesprite

How can I make a sprite that goes off screen and reappears on the opposing side? (100% of sprite always visible)


I have a bit of experience with Cocos2d but it's also been quite a while since I've worked with it. That being said, I don't necessarily need code handed to me - just a pointer towards the right approach I should be taking to achieve my requirements.

My project is a simple block game, where players move blocks by swiping them (the blocks move at the exact speed of the swipe, no acceleration). What I want to achieve, is when the player swipes a block off screen, I want the part of the sprite which is hidden off-screen to appear at another edge of the screen and keep moving until the drag motion has stopped (a bit like the old mobile game, Snake II). When the sprite has completely moved off the screen, it should now be completely visible somewhere on the opposing side of the screen. (so the screen is like an infinite loop which the sprite can move on). For example, the sprite is 40% visible on the left of the screen, and 60% visible on the right of the screen (halved at screen boundary, 0.x). As the sprite moves left, it will become 35% visible on the left, and 65% on the right.

What is the best approach to tackle this? Should I be duplicating the sprite and then moving the new copy onto the screen in an opposing fashion? Or is this somehow possible with one sprite and some kind of mask?

Any help would be greatly appreciated. (I'm not at home now but I can add sample code and images later if my explanation isn't clear)

I'm using the objective-c version of Cocos2d.


Solution

  • I've done this several times before, it's quite simple. Assuming that your sprite can move outside the screen in all directions, you need a total of 4 identical sprites. One sprite is the "master" sprite, ie the one sprite that is always visible when the sprite is not near any screen border. Let's call the other 3 the "slaves".

    Every frame you check whether the master sprite is wholly contained within the screen. A simple CGRectContainsRect test.

    If it's not contained, you make the three slave sprites visible and offset them by screen width, screen height, and screen width & height respectively. Assuming the master sprite is leaving the screen at the lower left corner. If it were leaving at the upper right corner, you would need to subtract screen width/height.

    Now once the master has left the screen entirely, you need to offset its position once and hide the slave sprites once more. For example if the master left the screen to the right, you would have to subtract screen.width from its x position once.

    So basically you just need to determine if master sprite is near any border, then offset the slave sprites according to which quadrant (ie lower left, upper right, etc) the master sprite is on, and then offset the master and disable the slaves once it has left the screen entirely.

    Depending on your needs you may also need to extend collision checks to all four sprites, or you may decide that you want to offset the master sprite not when it left the screen entirely but when its position is no longer within the screen.