Collision detection for a game viewed from top

Hello,
this is my first post in this forum, so please bear with me :slight_smile:

Situation

  • I’m working on a game viewed from top where ball bounces on individual platforms within defined platform field
  • The goal of each level is to reach the end platform
  • The field is scrolling from top to bottom of the screen
  • There are gaps in the platform field
  • When the ball jumps into the gap the game ends
  • When the ball reaches left/right side of the screen, the platform fields scrolls till its left/right end is reached
  • Mockup for better understanding (yellow platform is the end platform, green one is the one where the ball starts)

Problem

How do I detect that the ball hit some platform when it “hit the ground” (or that it hit the gap)?.

The fact that “hit the ground” event occurred is recognized via specific boolean flag that is set to true when onComplete callback in transition simulating the bounce effect (scaleX, scaleY to 1.x and then back to 1) is executed.

My solution ideas so far

All my ideas are based on the fact that I need to find index into table containing the platform objects. Then, I need to check if there is a platform with such index or if there is a gap, and decide what the correct action is - jump further or fall through.

Calculate platform index from ball coords when hit the ground occurs

My original idea was to calculate the index (into table containing the platform objects) of the platform that was hit from the coordinates of the ball when he hit the ground. This works when the field isn’t scrolling. However, when the field starts to scroll from top to bottom (and possibly also to left/to right), it is hard to calculate the right index.

Brute-force approach

Other option is to go through the whole table of platforms when the “hit the ground” event occurs, and perform some kind of hit test based on coordinates of the platform and ball. However, this doesn’t seem to be an efficient approach to me.

Use physics for pre-selection of possible platforms and hit test only those

I think that the Corona’s physics engine isn’t able to recognize collisions when the ball “falls” on the platform. However, it can register collision when the ball enters/leaves the platform (even when not “on the ground”) via normal collision mechanism and setting the physics bodies to be sensors. In such case, I can store the indexes of platforms which were involved into collision during one “bounce cycle” and then perform the “hit test” operation only on those. In next bounce cycle I create new list of possible “hit test” candidates, etc.

Your opinions

Any ideas for better / more effective solution? [import]uid: 164599 topic_id: 28701 reply_id: 328701[/import]

Nobody? That’s sad - always heard the Corona community was very responsive. [import]uid: 164599 topic_id: 28701 reply_id: 115755[/import]

Sometimes if rather than waiting the customary 24-48 to bump and instead waiting only 11 hours, most of which fell overnight in the US, people might feel you are being rude.

If it is so urgent you need an answer within 12 hours you may want to try premium support; http://www.coronalabs.com/products/support-training/

Otherwise please remember to be patient, lots of people sleep at night and don’t spend all day every day on the forum - the community is actually wonderful here but it helps if you remember common courtesies, like no excessive bumping.

RE your brute-force approach, how many platforms are likely to be on screen at once? This may not be that excessive. [import]uid: 52491 topic_id: 28701 reply_id: 115813[/import]

I didn’t want to be rude by any means. Sorry for my lack of netiquette knowledge.
I know the community is great - I read the other forum questions and the wonderful answers around here.

Ad brute-force approach)
I expect the field to have like 10 platforms per row and let’s say up to 50 rows. This is like up to 500 platforms to test every time the ball “hits the ground” - e.g. once per 800 ms (duration of the transition effect). [import]uid: 164599 topic_id: 28701 reply_id: 115842[/import]

I know, it’s OK - I just wanted to give you a little heads-up :wink:

That is a HUGE number of platforms, are these all going to be on the screen at once, or no? I cannot picture 500 on screen at once. [import]uid: 52491 topic_id: 28701 reply_id: 115886[/import]

No, they won’t be on screen at once.
Maximum amount on the screen in one row is 640 / 128 = 5
Maximum amount of rows is like 960 / 128 = ca 8.

This makes ca 40 platforms. However, I don’t know how I can identify which are those 40 I should iterate through, because every time other platforms can be present on the screen (because of the scrolling and possible left/right movement).

Maybe, I could have a collision detection with “sensor” “boundaries” placed around the screen When platform collides with the boundary when it moves into the screen I copy its index to some table, when it goes of the screen, I remove it from that table. Then, when the ball “hits the ground” I only go through the table with indexes and check only the respective platforms.

Or is there any other better way how to get list of platforms that are worth checking?

[import]uid: 164599 topic_id: 28701 reply_id: 115896[/import]

Just thinking aloud here really, might work, might not…

Build your level so the top-left platform is at 0,0 (or 64, 64 if centered). Have a display group which only contains the objects which should scroll, say cameraGroup. At the start of the level set cameraGroup.x and cameraGroup.y according to which part of the field you want to show.

Put the platform and ‘gap’ images into a 2-dimensional array, setting a flag as to whether it is a platform or gap.

i.e.

[lua]grid[1][1].isPlatform = true
grid[1][2].isPlatform = false[/lua]

To find the grid reference at the point when the ball ‘hits’ the ground:

[lua]local offsetX = ball.x - cameraGroup.x
local offsetY = ball.y - cameraGroup.y

local col = math.round(offsetX/128)
local row = math.round(offsetY/128)[/lua]

i.e. if the ball was in the centre of the screen and the camera hasn’t moved:

[lua]local offsetX = 320 - 0
local offsetY = 480 - 0

local col = math.round(320/128)
local row = math.round(480/128)[/lua]

therefore:

col = 3
row = 4

i.e if the ball on the right-bottom side of the screen and the camera has shifted all the way to the right:

[lua]local offsetX = 507 - (-512)
local offsetY = 612 - (0)

local col = math.round(1019,128)
local row = math.round (612,128)[/lua]
therefore:

col = 8
row = 5 [import]uid: 93133 topic_id: 28701 reply_id: 115902[/import]

@nick_sherman: Firstly, thanks for your suggestion. However, maybe I just don’t understand it, but it seems you thought I had only those 40 platforms. However, I have like up to 500 of those, please have a look at the link to mockup I provided in my original post.

If your proposal takes that into account, yould you maybe provide a brief info how and when would you put the “new platforms” that basically enter the screen from top into the cameraGroup, and how and when to remove those that left the screen in the bottom. [import]uid: 164599 topic_id: 28701 reply_id: 116240[/import]

Yes I had realised that. You would draw your level, i.e. 10 columns, 50 rows, starting from 0,0 and ending at 1280, 6400.

The position of cameraGroup relative to 0,0 then dictates which platforms are on screen.

i.e.

if cameraGroup.x = -256 then you would see columns 3 to 7.

if cameraGroup.y = - 1024 then you would see rows 9 to 16.
[import]uid: 93133 topic_id: 28701 reply_id: 116248[/import]

Regarding drawing and adding the 500 platforms to cameraGroup in advance I have a more general question regarding the common practices of handling such situations in Corona + Lua:

Let’s say I have some level data, in my case setup of where are platforms and where are gaps, in other case it may be definition of a game level from a platformer like Mario (e.g. created in Tiled).

  1. Is it usual to draw the whole level in advance?
  2. I can imagine that all the objects (images, sprites, physics bodies, …) can consume lot of memory. Furthermore the “playing of sprites” and/or collision checking for bodies that are off screen can consume processor power and thus lower performance. Are my worries correct or are there any mechanisms (e.g. I read something about culling) in Corona which prevent wasting “performance” on objects that are off screen?
    [import]uid: 164599 topic_id: 28701 reply_id: 116336[/import]