scrolling a large non-tiled world of objects?

was wondering if anyone had tips on implementing large scrolling worlds that have physics on the objects (or not)

some examples:

Bubblehead
http://www.youtube.com/watch?v=A_Tb3vsGZKc#t=0m50s

Pollywog
http://www.youtube.com/watch%3Fv%3DepjxJCT-CgE

Corona seems to perform quite well if you just lay out a lot of objects across a large vertical space and loop through and check if they should be visible if their coordinates are within the viewport… 1000 object sticks around 29-30fps… on the simulator at least,

try my example code from:
http://www.sendspace.com/file/s0cowb

but I’m not doing anything to help performance here eg re-using (pooling) sprites (I’m calling them sprites but they’re just display images rather than spritesheet items)

What I’m wondering though is if you look at something where physics can act on an object, you don’t necessarily want to remove it when it’s off the bottom of the screen, if you’re allowing the user to scroll back down again rather than always going forwards…You’ll need the physical state (position, interaction with other objects etc) to be the same as it was when it went of the screen… maybe these properties need to be stored somewhere before removing it from the off-screen display? Or should i retain the object entirely and just set it’s isVisible=false, rather than re-pool it? If it’s not visible, are physics calculations still performed on it? Or does it just become another data pointer until i enable it’s visibility again? (ie why pool the object, if i’m going to need to store data on its position etc somewhere anyway?)

What I can’t work out is how much of the display optimization Corona does already for offscreen items.

any advice would be appreciated

regards
j

PS as for laying out the levels, i was thinking of using Flash to lay out the whole level and then outputting the coordinates of items with jsfl.

[import]uid: 6645 topic_id: 3854 reply_id: 303854[/import]

What a coincidence! I’m caught in a similar dilemma at this very moment, wondering how to construct my “world” which might (or might not) be alot more complicated than the videos you link to, i.e. more detailed tilemaps versus just large pizza slices, burgers, etc. as shown in the Bubblehead game. Depending on my solution, it could get alot more complex for my own game, and ideally I’d like to construct decently large (but not infinite) worlds with tiles, physics objects, etc.

As you say, performance is the concern. A huge world with objects containing physics bodies or animations could cause a noticeable performance hit. Ansca even mentions that off-screen animations should be forcibly stopped, otherwise Corona continues to process them even though they’re not in the stage/screen bounds.

My initial solution to all of this, very much in the testing stages, is a load/unload routine. I’m hoping to divide the entire world into “chunks” similar to classic games like Ultima 7. For those who didn’t play that game or similar games, the idea is basically that your world is broken up into large chunks, which are like individual tilemaps of 100x100 tiles, for example. Obviously, if you wanted to create a vast role-playing world like Ultima 7 or Zelda: Link to the Past, there’s no way you can place a load of 2000 “chunks” on the engine at once! (i.e. 10000 tiles per chunk, 2000 chunks in the world, 20,000,000 million individual tiles… simply impossible).

So, in my load/unload scenario, each “chunk” (which I plan to make into individual tilemaps) gets loaded OR unloaded as needed, when they are sufficiently off the viewing screen. This solves the issue you mention, wherein if the world moves in different directions (not just left to right), chunks can be RE-loaded if they need to be accessed/viewed again. In my game, chunks will be like mini-tilemaps of 640x640 or something, but in theory a chunk could contain anything, even just 1 large object within that chunk’s dimensions.

At this point, I only have the skeleton framework programmed, but it’s working fine. These “chunks” are referenced in a large array by Column and Row. When a certain column/row (and thus, all its “child” chunks) moves within range of visibility (just slightly off screen) it gets either deleted or it gets displayed. The management of this is handled not by an individual listener on each chunk, but rather by a Runtime listener that monitors the X/Y position of the entire display group, and when coordinates change sufficiently, an entire column or row is handled in a loop.

If this sounds like a possible solution to your dilemma, keep in touch… I’d like to trade some ideas for this as I develop it further. My next step is to build the “display” routine for chunks approaching the camera area. I need to ensure that I can output an entire chunk, with multiple tiles, physics objects, etc. This might or might not work… we’ll see!

Brent
[import]uid: 9747 topic_id: 3854 reply_id: 11790[/import]

for tile based worlds, it would be good to discuss this with Graham:
http://developer.anscamobile.com/forum/2010/11/12/introducing-lime-module-import-2d-tilemaps-your-game

maybe you could contribute this to his project (he’s making it modular for this purpose), so having everyone working in a common system would be great - until Ansca tell us they’ve made their own :wink:

For my problem, I think your solution could work but i don’t know if it’s the best approach.

Let’s take these vertical scrollers as an example for now: I thought the best thing to do would have a data table of all my world objects with coordinates, type, properties etc. When an item needs to appear on screen I add (or pool) a display object with those properties. When an item goes off screen I remove that display object (or recycle it), but store it’s state back to my list (eg what Linear Velocity it had, what Angular Velocity etc). Then if i need to add it again (eg if the user goes backwards) I can reapply these forces . But how would that affect items in collision when they went off screen? (Of course it would be simpler if i don’t allow the user to go backwards!)

Also presumably it is best not to have to loop through every object checking every position, as a lot of them won’t even be anywhere near the current viewport. Maybe keep the table indexed on Y position and work outwards through the array (starting a point that is an item within the current viewport) (linked list?) until I find an object that’s outside the viewable Y positions? The problem then is how to optimize reordering the array when item’s Y position changes, in that it’s position swaps vertically with another item so it’s array position needs to change

again thanks for any advice.

j

[import]uid: 6645 topic_id: 3854 reply_id: 11794[/import]

I’d be happy to contribute to Graham’s “Lime” module, once I get my “Chunks” module more refined (ha ha, “Chunks” sounds terrible, maybe if Graham can, or wants to, implement any parts of it into Lime, a fruit name like “Papaya” would be better). Regardless, it needs more work before any of this could happen; as I mentioned, it’s just the base framework right now.

“When an item goes off screen I remove that display object (or recycle it), but store it’s state back to my list (eg what Linear Velocity it had, what Angular Velocity etc).”

This adds alot more complexity to the scenario! At this point, I can only wrap my brain around a somewhat static chunk-scrolling routine… not to say it would be 100% static with zero physical or moving objects in a chunk, but I can’t fully comprehend how to handle “storage” of every object, including moving objects within that chunk, their velocities when they left the screen, etc. For that, I think a different approach would be necessary, and one more complicated.

OR, you just prevent the player from moving backwards. I have decided to re-think some aspects of my game to make it simpler, because I don’t have a team coding away on this every day like most studios would have. I tend to set my ideas higher than my current capabilities, and if I continue to do so, I’ll never get the game completed. :slight_smile:

Brent

[import]uid: 9747 topic_id: 3854 reply_id: 11797[/import]

Strille posted quite a good approach to screen scrolling for Flash http://www.strille.net/tutorials/part1_scrolling.php

if you’ve seen his Sonic Demo, you’ll know this works quite well
http://www.strille.net/works/misc/platform_demo/

I’m going to have a look at this and how it relates to optimizing corona scrolling in certain setups.

although I’m still not sure what to do when physics is involved as presumably i don’t really want to temporarily remove a physical item until it has become static and no longer involved in collisions [import]uid: 6645 topic_id: 3854 reply_id: 12412[/import]

Right now, I’m working on a module/code for world scrolling. This still relies on my concept of “chunks” to display an organized group of items/objects (including physical objects) as they approach the camera area… and then the chunks get removed when they are sufficiently out of view again. Chunks are initially configured, and stored into memory, using external level files: (.txt files that are are parsed and processed). This will allow the user to design multiple levels, keeping only the chunks for that level in game memory.

There will be some definite limitations in the first version. Once the chunks are removed, all objects within will be deleted and removed from memory. I’m not planning on implementing any “save status” features like storing X and Y velocities, rotation, etc. in the first rollout. The chunks could technically be re-displayed, but the chunk contents would be reset to their original settings. In summary, the basic concept is a module to scroll around a world in a set direction (which could vary) but it will not be a full free-form scrolling setup where objects are saved and stored.

Long term, however, I’d want to accomplish the above. Additionally, I’d like to create a sort of GUI module that lets the user design the chunks visually, dragging items into the chunk area, and hopefully even drawing polygonal multi-body physics shapes around objects to dictate their physical bounds. This last feature is probably long long term, due to the complexity of designing a GUI editor and having it render all of that info to a text file for later use.

Anyway, back to work on this! I’m making progress but it’s a fair ways off still.

Brent
[import]uid: 9747 topic_id: 3854 reply_id: 12414[/import]

that’ll keep the ex-GameSalad users happy! (and me) :slight_smile:

j.
[import]uid: 6645 topic_id: 3854 reply_id: 12417[/import]

also i was wondering how well corona’s engine performs if you keep a large Box2D world running, but remove the graphic parts of physics bodies (probably just with isVisible=false) for offscreen items and also allow sleeping, until they need to be redrawn again.

i kind of did this in my scroll test with a couple of thousand objects, which i posted on the forum, although i think the post might have disappeared. but i didnt optimize the checks to see what items should be visible. really i shouldnt even be testing items that are more than 2 or 3 screens away in any direction. was wondering if i should use a linked list to determine this or if there’s an optimal way to sort an array on a specific value (say an item’s .y position) and then only look at items within an N-distance of my current y pos.

[import]uid: 6645 topic_id: 3854 reply_id: 12418[/import]

obviously i need to read up on this

http://www.gotoandplay.it/_articles/2005/07/patterns.php?PHPSESSID=cfd1f33d0c627e6cfe96bc80971d6861#spatialindex

SPATIAL INDEX

Intent

Speed searches by position in a Model Database.

Motivation

Almost all games need to search a Model Database quickly by location or region.

A few examples of spatial searches:

* the renderer (see View Pattern) needs to cull objects which can not be seen;
* a trigger (see Trigger) needs to determine if the player has passed over it;
* the UI needs to determine what object was clicked on by the mouse;
* the physics needs to detect collisions;
* a time bomb needs to determine what to damage.

Implementation

There are many implementations of spatial indices, each optimized for the particular kind of game. Without excellent implementations of these indices, whole categories of games could not exist.

Some common examples:

* Binary Space Partition Trees;

* X and Y Hashes with threaded collision resolution;

* Portals which link isolated spatial indices.

Indices must remain synchronized with the associated Model Database. It is common to see the spatial index implemented within the framework of a Model Database.

[import]uid: 6645 topic_id: 3854 reply_id: 12912[/import]

Did you send me a feature request on this? how is p4mance?

c. [import]uid: 24 topic_id: 3854 reply_id: 13927[/import]

not on the physics… but check this thread
http://developer.anscamobile.com/forum/2010/12/11/another-scrolling-performance-test

thanks
j [import]uid: 6645 topic_id: 3854 reply_id: 13931[/import]

I’m a little late to this one, but I’ve just posted a cut-down, self contained (single file with no external dependencies) demo of side scrolling with physics at the code exchange. [import]uid: 3953 topic_id: 3854 reply_id: 15798[/import]

great thanks. will check it out

do you think you could summarize what you’re doing to optimize visual performance and also does it slow down when you make your world bigger?

thanks
j [import]uid: 6645 topic_id: 3854 reply_id: 15864[/import]

hi, the cart just falls through the ground with that example [import]uid: 6645 topic_id: 3854 reply_id: 15880[/import]

Thanks for the feedback. Damn, big oversight on my part. It’s not self contained as I claimed. In addition to the supplied main.lua, you need these 2 additional files, as it’s a landscape mode demo, and requires 60fps:

build.settings

settings =  
{  
 orientation =  
 {  
 default = "landscapeRight",  
 },   
  
 iphone =  
 {  
 plist =  
 {   
 UIStatusBarHidden = true,  
 UIApplicationExitsOnSuspend = true,   
 },  
 },  
  
}  

config.lua

  
application =  
{  
 content =  
 {  
 width = 320,  
 height = 480,  
 scale = "letterbox",  
 fps = 60,   
 },   
}  
  

[import]uid: 3953 topic_id: 3854 reply_id: 15883[/import]