Need help with merge mechanics

hi there, I’m looking into your engine and I have a few questions, I hope for your help.

in my game fruits fall from above, i want that if two same fruits collide then they will turn into the next fruit

here I create fruits on click

local camera = require "orthographic.camera"
local fruit_list = {"apple", "pear", "orange", "grape", "strawberry", "blueberry"}

function spawnFruit()
	local random_index = math.random(1, #fruit_list)
	local fruit = fruit_list[random_index]
	return fruit
end

function init(self)
	msg.post(".", "acquire_input_focus")
	self.pos = vmath.vector3()
end

function on_input(self, action_id, action)
	if action_id == hash("touch") and action.pressed then
		local pos = vmath.vector3(action.x, action.y, 0)
		local camera_id = hash("/camera")
		self.pos = camera.screen_to_world(camera_id, pos)
		local item_id = factory.create("#factory", self.pos)

		local url = msg.url(item_id)
		url.fragment = "sprite"

		local random_fruit = spawnFruit()
		sprite.play_flipbook(url, random_fruit)

		msg.post(item_id, "created")
	end
end

and here I’m trying to push fruits, but I can’t

function on_message(self, message_id, message, sender)
	if message_id == hash("collision_response") then
		if message.other_id == hash("/walls") then
			return
		else
			local url = msg.url(message.other_id)
			url.fragment = "sprite"
			local sprite_name = go.get(url, "animation")
			print(sprite_name)
			if sprite_name then
				local fruit_list = {"apple", "pear", "orange", "grape", "strawberry", "blueberry"}
				local index = 1
				for i, fruit in ipairs(fruit_list) do
					if fruit == sprite_name then
						index = i
						break
					end
				end

				local next_index = (index % #fruit_list) + 1
				local next_fruit = fruit_list[next_index]

				sprite.play_flipbook(url, hash(next_fruit))
				-- factory.create("/cubeFactory#factory", vmath.vector3(0, 0, 0), nil, {sprite = next_fruit})
			else
				return
			end
			-- sprite.play_flipbook(url, hash("grape"))
		end
	end
end

I came from Unity and there I could understand in different ways what object I encountered, how to do this in Defold?
For example, I want to understand that a pear collided with a pear, which means that they then stack and turn into an orange.

How can I tell if one sprite has collided with another and their sprites are equal? how to destroy colliding objects and spawn a sprite with a higher grade in their place?


here is a screenshot from the game

You could use one physics group per fruit and let each fruit only collide with the walls and its own kind. You achieve this by setting the group and mask fields of each collection object. You can check which group you collide with by checking message.other_group.

The other option is to do what you are doing in your code and check which sprite animation you have and compare it to the list of all fruits. BUT I think you have a bug in your code, the go.get(url, "animation") will return a hash, not a string, which means that you should store hashed strings in your fruit_list.

By the way, here’s a similar game made in Defold. I’m sure @schlista can give you advice as well.

Here’s my game. Kabocha Game by Kabocha Games (itch.io)

One issue I did hit was too many collision groups. I was able to work around by renaming a few Like making all my boundary collision objects the same name. This was a rookie mistake I initially made, but you do need to know i think it’s 16 max groups.

thank you very much for the advice, then I have the following question: if I now have one instance of a fruit, and change the sprite through code, should I get away from this logic and make each fruit a separate object with its own sprite and spawn it somehow (I I still haven’t figured out how to spawn a random object from the list of objects) a random object from the entire pool of fruits?

this is exactly what I’m doing, I chose this project to practice and study defold, please tell me how best to do it: one object, that is, now I’m just changing the sprite of the spawned object, but I understand that I need to make a collection with each sprite, thus I will have, for example, 8 collections or game objects and they will already have groups and masks installed, right? so far I still don’t understand how to spawn an object from a list of other objects

I created a new object when they combined. Using a factory. I didn’t need a collection factory. I used one factory for each vegetable type.

But I did have issues when spawning them because sometimes they’d spawn inside of another object (whether it was the wall/floor of the shopping bag or another veggie). So I had to spawn it at a very small size then grow it over several update cycles. The user doesn’t notice it but it prevents a ton of fused objects.

Maybe changing the sprite could work, but then the collisionobject attached to it would need to be changed as well to match the new sprite unless all objects are the same size.

BTW: this was a great first project for me in defold. I learned alot.

1 Like

how did you compare that the colliding vegetables are of the same type? what check did you do? I thought of one general script and hanging it on all objects, but I don’t know how to make this script universal

You should look into script properties:

Thank you!
I think the knowledge that I received here is enough for me, the topic can be closed.

I think it could be too much trouble relying on the physics collisions system.
Instead I would make all fruit exactly the same regarding their physics setup and check their collision manually in a script by using a simple double for loop. That way not only I can have a list of all the colliding fruit of the same value but I can also control their effective radius and increase it a little for a more forgiving and therefore more fun gameplay.
After the loop I can sort the resulting list (prioritise lower fruit), find chains, limit merging fruit count (say one merge in 0.1s) and do all sorts of stuff that would be hard to do using the regular physics collision events.

2 Likes

thank you!

1 Like

I relied on the Box 2D collisions and it ended up being an issue after as the merging of fruits slowed down when the basket got nearly full. And some other issues. So I concur…If I were to do it over I’d make it differently. Or at least find a way to make the collsions respond quicker.

1 Like