Game over when object reaches set height

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.

2 Likes

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
1 Like

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.

1 Like