I’ve never before touched Defold, but I want to make my own version of the recently popular melon game, where you drop different types of fruits in a box and they merge creating bigger fruits. When a fruit touches certain height it’s game over.
I’m using a free github “ball game” as a base for it and I’ve managed to figure out most of the things that I want to change, but I’ve one basic problem.
In the original game you get “game over” when a fruit touches certain height, but in this github project it’s different - when the ball falls outside of the jar and Y<0 then it’s game over.
So how do I even add that “when fruit reaches certain height it’s game over”?
I can’t add “when Y>67 then game over”, because fruit starts dropping from above that height and it causes instant game over.
Can it be done via collision detection? height detection after certain time after dropping fruit passes?
Something like “if object is touching another object AND is also above Y=67 then game over”?
How do I even do that?
Below’s the screenshot of how it looks like, where I’ve added a red line - touching it should cause a game over.
I made a similar game and simply disabled the height check for a couple of seconds to allow time for the ‘ball’ to drop.
That could be the solution! But how do I do that?
The current “game over check” function in the script looks like this:
function update(self, dt)
self.pos = go.get_position()
if self.pos.y < 0 then
msg.post("main:/sound#sound_gate", hash("sound"), {name = "rakka"})
if data.game_state.game ~= "END" then
msg.post(data.C_URL,hash("game_over"))
end
go.delete()
end
if not self.active then
go.delete()
end
end
Something like this might work for you. The init function sets a flag to false, sets a timer for 2 seconds then sets the flag to true. The flag is a condition of doing the position check in the update function.
function init(self)
self.docheck = false
timer.delay(2, false, function() self.docheck = true end)
end
function update(self, dt)
if self.docheck then
self.pos = go.get_position()
if self.pos.y < 0 then
msg.post("main:/sound#sound_gate", hash("sound"), {name = "rakka"})
if data.game_state.game ~= "END" then
msg.post(data.C_URL,hash("game_over"))
end
go.delete()
end
end
if not self.active then
go.delete()
end
end
I’ve tried it, but it caused weird behavior of the balls.
When two the same tier balls touch they should disappear and form a ball one tier bigger.
Sometimes when that happens the new ball appears from below the screen and slides up where it should be. Sometimes it even appears in a completely different place.
I’ve managed to snag a screenshot of it happening (tho you can’t see movement on static picture)
Thank you for trying my sample project.
That ball will be deleted when it makes contact. The timer may malfunction.
Good things may happen if you use trigger object.
And create a judgment script.
-- --------------------------------------------------
-- danger.script
-- [Game over zone]
-- --------------------------------------------------
function on_message(self, message_id, message, sender)
print("check game over trigger")
if message_id == hash("trigger_response") and message.group == hash("default") then
msg.post("/common#game",hash("game_over"))
end
end
Then, rewrite “PLAYING state” and “WAIT state” in game.script.
-- --------------------------------------------------
-- game.script
-- --------------------------------------------------
-- Drop ok ----------------------------------
self.states.PLAYING = (function()
local state = {name = "PLAYING"}
function state.enter(self, sdata)
-- Game over zone trriger enable
msg.post("/danger#collisionobject", hash("enable"))
end
function state.message(self, message_id, message, sender)
-- from danger script
if message_id == hash("game_over") then
-- Game over zone trriger disable
msg.post("/danger#collisionobject", hash("disable"))
msg.post(WINDOWS_URL, hash("hide"))
msg.post(PLAYER_URL, hash("hide"))
-- go to END state
st_pat.transition(self, "END")
-- from player script
elseif message_id == hash("drop") then
-- go to WAITstate
st_pat.transition(self, "WAIT")
end
end
return state
end)()
-- Drop wait ----------------------------------
self.states.WAIT =
(function()
local state = {name = "WAIT"}
function state.enter(self, sdata)
if data.pre_state[self.script_name] == "PLAYING" then
self.wait_time = 0.5
-- Game over zone trriger disable
msg.post("/danger#collisionobject", hash("disable"))
end
end
function state.update(self, dt)
if self.wait_time > 0 then
self.wait_time = self.wait_time - dt
else
msg.post(PLAYER_URL, hash("pull"))
-- go to PLAYING state
st_pat.transition(self, "PLAYING")
end
end
function state.message(self, message_id, message, sender)
-- game over check disable
end
return state
end)()
This game.script will only determine a game over when playing.
Rather than using wait_time, maybe you could using an in_play flag and set this when the height is less than some value.