Efficient Image & Tile Movement: Masks?

Are there are any performance penalties/benefits in using a mask?


Context: Been reading the forums on efficient tile movement, and still not really sure the best way. Coming from a Flash/Flex background, here’s what I know for moving large tile maps:

  1. You should load the image into a Bitmap, and utilize a double-buffer to scroll, such as BitmapData.copyPixels. The rectangle you supply to copyPixels allows just that small section, say 320x240, to be shown. You aren’t physically moving anything, you’re just copying pixels.

Pro’s: Wicked fast
Con’s: doesn’t support half pixels, and you still have to composite other objects on top

  1. Whether you use a Sprite/MovieClip, or many Bitmaps on top of each other, you utilize the scrollRect. This makes a section of your large displayable area, and moves it merely based on changing the actual rectangle you’d like to view.

So, to move a map left, you’d go:

[as3]scrollRect = mapContainer.scrollRect
scrollRect.x = scrollRect.x - 2
mapContainer.scrollRect = scrollRect[/as3]

Pro’s: Pretty fast, and really easy to handle compositing (many objects in something like a Lua group); basically you aren’t really moving anything.
Con’s: Not as fast as blitting via BitmapData.copyPixels

  1. Mask and Move: You do like #2, but just create a mask, and move the container/group

Pro: Easy
Con: Not as efficient; even though something is masked, it’s drawn by the player/runtime, this includes the iOS export

  1. Dynamic Tile Draw, similar to the other thread and this blog post on creating tile maps in Lua: http://pixels.ph4.se/2010/10/tilemaps-with-corona-part2/

There doesn’t seem to be a way to do #1 in Lua/Corona. There doesn’t seem to be a rectangle display area equivalent to Flash Player’s scrollRect for #2. While #4 is an option, it’s not if you already have the tile maps built and don’t need to create a dynamically created tile area.

…so, I’m curious if #3 is a good or not. In playing with the new build (268), masking a group seems to work (little flaky on the emulator, good on the device).

So again, are there are any performance penalties/benefits in using a mask?

[import]uid: 23693 topic_id: 5718 reply_id: 305718[/import]

there’s also strille’s method
http://www.strille.net/tutorials/part1_scrolling.php

interesting point about the masking performance. what sort of frame rate are you getting and what about when you make your map a lot bigger?

regards
j [import]uid: 6645 topic_id: 5718 reply_id: 19599[/import]

Thanks @jmp909, I actually had horrible performance using that in AS1 back when I didn’t know how to code, nor object pool, so maybe it’d be a lot faster in AS3/Lua. I know reading either yours or someone else’ thread about isVisible isn’t very efficient. I’m curious, do you think it’s better to, in using this technique, to set the object’s isVisible to false, or to simply remove it from the master group, and re-add later if the player walks back?

Regarding frame rate, I have no idea; for Flash/JavaScript, I use Stats; what are y’all using for Corona to determine frame rate?

https://github.com/mrdoob/Hi-ReS-Stats
https://github.com/mrdoob/stats.js

I’ll post sample code later, gotta do real work. [import]uid: 23693 topic_id: 5718 reply_id: 19738[/import]

Alright brudda, here’s the code so you can test yourself. Excuse my n00b code, only been playing with Corona in my spare time for a week, so still learning.

http://jessewarden.com/archives/corona/tile-map.zip

I may try my hand at converting Mr. Doobs’ Stats to Lua tonight to get an easier way to see in-app frame rate.

If you test her out, let me know what you find. [import]uid: 23693 topic_id: 5718 reply_id: 19758[/import]

http://developer.anscamobile.com/code/output-fps-and-texture-memory-usage-your-app

ps jesse, you may have only just started with corona but i’d hardly call you a n00b :wink:
http://www.stevensacks.net/2008/06/30/gaia-site-ribena-by-swamp-at-brahm-uk/

[import]uid: 6645 topic_id: 5718 reply_id: 19802[/import]

Heh, Steven got the names backwards… *ahem*

Thanks for the code link, works great! The mask is interesting, it seems to be using 200k less memory with the mask. Additionally, the startup time is a lot faster (low fps initially, 30 rest of the time). (4.7 without mask, 4.5 with)

*runs on device*

Weird. So, the device (Google Nexus One, Froyo) reports some strange results. Both with/without have about same FPS, and both seem to show 0.00256 megs of ram for textures… :: shrugs ::

*runs on Droid 2*

Not seeing any FPS or ram difference here, ALTHOUGH the masking bugs I’m seeing in the emulator I’m also seeing on the Droid 2.

Anyway, assuming they fix the mask bugs, using a mask seems like the way to go to reduce memory, although, that’s just the emulator and 2 tests talking… [import]uid: 23693 topic_id: 5718 reply_id: 19843[/import]

steven got the names backwards? you’ve lost me. i wrote that article, he just reposted it. i was flagging you as an industry veteran :wink:

anyway… i believe Graham Ranson is talking to Ansca about performance issues as it is vital for Lime. i think any performance gain from masking is an accidental side effect at the moment. (must be something to do with the way OpenGL renders with the mask)

i would hold out on getting efficient tile scrolling for now (other than the gotoAndStop method that reuses tile) if you need to incorporate physics directly. Hopefully this will get better though. Unless you know some effective spatial indexing techniques of course

One of the main problems also is that the physics is tied into the display objects, so you can’t just remove an image from the rendering tree that’s offscreen, if it’s attached to an object in the physics world… have mentioned this here: http://developer.anscamobile.com/forum/2011/01/30/optional-removal-display-object-physics-object-creating-non-visible-physics-shapes

still worth trying out different optimisation techniques though i guess

one thing i would suggest is forcing a small delay before you make your game interactive, to allow it time to render. i think it’s trying to get it running before the texture memory is fully loaded can slow things down. (could do with an “all images loaded” event i guess)

j

[import]uid: 6645 topic_id: 5718 reply_id: 19850[/import]