Any views on the best/correct/easiest way to implement this type of behaviour?
[import]uid: 8353 topic_id: 3255 reply_id: 303255[/import]
Probably have each cherry listen for a collision event with the ‘PacMan’ character and have the cherry remove itself upon the collision.
alternatively the cherry could be a sprite that is played once the collision happens and it animates away and removes itself once animation finished.
Look in the API for collision handling. [import]uid: 5354 topic_id: 3255 reply_id: 9669[/import]
Might be more efficient to listen for the collision on the PacMan character rather than on each cherry though [import]uid: 10464 topic_id: 3255 reply_id: 9677[/import]
Maybe…
Ive found the collision listeners to be very efficient and ive been using hundreds of them so depends on the type of app probably and how its going to be coded.
My idea would to have a cherry constructor class where each cherry had a listener, the attached function ( for removing itself ) and anything else necessary ( like updating the score ) all contained within the cherry object. This way each cherry would just be independent of anything else going on and they all sort of take care of themselves.
I tend to find that trying to attach too much functionality to one object, like the pac man, can mean that his code can get quite complicated and keeping things separate and simple can help in debugging and designing the game.
For this I would have ( a simple breakdown )
- main.lua - for initialising the game, getting up groups
- pacman.lua - loads, draws and moves the character
- cherry.lua - loads, draws, defines and controls the cherrys
- levels.lua - for loading new levels, clearing old ones away
- score.lua - for loading, saving and tracking scores
this way…
myCherry = cherry.newCherry( x , y ) would place a new cherry. In the cherry lua it would have an overall function for loading and placing a new cherry and a bunch of local functions cherry would call, like removing a cherry if its eaten etc… This would be called from the levels.lua when its building a new level from a table of positions for cherrys and walls.
if cherry is eaten then the cherry calls myCherry.removeMe, remove me would obviously remove that cherry from the game, clear memory etc… but in there it would also call score.increaseScore( 10 ) adding 10 to the score.
Now as score is its own module, it has a local variable for tracking the score and increaseScore( 10 ) would increase this local number by 10. I would have a listener look at that variable and if it changes I would then fire an animation (also in score.lua) which would animate the score increasing on the users screen.
So nice and tidy code with each module taking care of 1 part of the game. Why do this, its clean, easy to debug, easy to alter / replace / update a part of the code without worrying about other parts.
To extend this, even a little bit, cherrys could become bombs (like bomberman) with you activating it timers on collision. This would be simple if the game is built as described above as I would just need to extend cherry.lua to add the countdown listener and explosion graphic. I would also extend the pacman.lua with a death function at that point, like pacman.dieNow or something like that. A cherry now has a wider listener what detects if pacman is in the explosion area and if it was it would call ( or tell ) pacman.dieNow. [import]uid: 5354 topic_id: 3255 reply_id: 9685[/import]
Thanks Matthew for a great answer.
I’m totally with you on the single responsibility principle and that’s how I’ve structured my code (even though I often have to fight against Lua to enfoce good coding principles but hey).
One more question: if the cherry and the pacman (in this discussion) were both physics bodies then how would I stop the cherry from knocking pacman off course?
I’ve tried tweaking density, bounce, etc but I can’t get the 2 to collide without having some sort of effect (which I don’t want on this occassion). Should I not be using physics bodies - but then how can I detect the “collision”…
[import]uid: 8353 topic_id: 3255 reply_id: 9687[/import]
I know what you mean about lua / coding principles but if you dont have anything in main expect for setup and everything else is modular then they can all see each other. Thats what I tend to do with one global mastergroup containing the local groups setup by each required lua. Anything locally is done to the local group and its contents and as the modules can see each other they can talk easily when needed.
So like I said, score is local to score.lua and no other part of the game needs know the score or to change it. Those parts of the game that do want the score can call score.returnScore or score.updateScore etc… It helps keep things local but logical.
To answer your other question, the API explains it better than I could
physics.addBody( rect, { isSensor = true } )
http://developer.anscamobile.com/content/game-edition-physics-bodies
“Any body (or element of a multi-element body) can be turned into a “sensor”. Sensors do not physically interact with other bodies, but produce collision events when other bodies pass through them. For example, the pockets on a pool table might be implemented as sensors.” [import]uid: 5354 topic_id: 3255 reply_id: 9688[/import]
Thanks again for the pointer, that’s exactly what I need. This is a good example of the learning curve of Corona: sometimes you end up looking for a needle in a haystack without knowing whether there’s a needle in there. Good job guys like you help us noobs out.
BTW, main.lua for me has 4 lines of code and I keep looking at them and thinking “hmm…”
:o) [import]uid: 8353 topic_id: 3255 reply_id: 9689[/import]
for me the less in main the better, it is processed before the app officially starts ( in my mind at least ) and from there you can move to different loops for splash screens, menus, ingame etc…
In php I tend to have everything included at the start of the code and the page is generated from there, same with the main.lua file, I really just use it to require any modules, setup a global master group and remove the display bar at the top of the screen.
Im trying to describe a few ideas on how to start with Corona to a few GS users here http://developer.anscamobile.com/forum/2010/10/13/ex-gs-users-switching-corona?page=5 [import]uid: 5354 topic_id: 3255 reply_id: 9691[/import]
why even use physics at all? store your game board in a 2-dimensional array, then when pacman enters a certain row column check the type of object at [lua]board[column][row][/lua] and act accordingly
[import]uid: 6645 topic_id: 3255 reply_id: 12127[/import]
I have an issue that kind of relates to this. When I create objects that collide with a particular object, I find that I get a memory leak. Any thoughts on what I am doing wrong with the removal?
My code:
[code]
local physics = require(“physics”)
physics.start()
physics.setGravity( 0, 0 )
local score = 0
local x = 50
scoreTextfield = display.newText( " " … score, 200, 105, nil, 14 )
scoreTextfield:setTextColor( 255, 255, 255, 255 )
scoreTextfield.text = " " … score
collectgarbage(“collect”)
score = "System Memory : " … collectgarbage(“count”)
scoreTextfield.text = " " … score
local bar = display.newRect( 0, 350, 350, 20 )
bar:setFillColor ( 255, 255, 255 )
physics.addBody( bar, “static”, { density=2.9, friction=0.0, bounce = 0 } )
local function randomBall ()
if x < 3000 then
local randomPos = math.random
local imageBall = display.newRect( randomPos(300), -20, 30, 30 )
imageBall:setFillColor ( 255, 255, 255 )
physics.addBody( imageBall, { density=2.9, friction=0.0, bounce = 0 } )
imageBall:setLinearVelocity( 0, 600 )
imageBall:addEventListener( “collision”, imageBall )
local function onLocalCollision( obj, event )
if ( obj.x ) then
if ( obj.y > 315) then
obj:removeSelf()
end
end
end
imageBall.collision = onLocalCollision
end
end
y = 10
local timerBall = timer.performWithDelay( x, randomBall, y )
local function memCheck ()
collectgarbage(“collect”)
score = "System Memory : " … collectgarbage(“count”)
scoreTextfield.text = " " … score
end
local timerCheck = timer.performWithDelay( 3000, memCheck, 1 )
[/code] [import]uid: 10903 topic_id: 3255 reply_id: 12197[/import]