Mouse pointer over a hotspot

Hello.

After many frustrating days of trial and error and several deinstallations and reinstallations of Defold, I decided to do one last try before giving up at all.

I’m trying to create a point-and-click adventure. In my opinion this type of game is just a background image with one or more hotspots. If the player clicks on a hotspot, one or more actions will be executed (e.g. walk to a given position, say something, take an object and put it into the inventory).

I was able to create the following collection:

As you can see there are two hotspots (which are game objects with a collision component). Then there is the pointer game object (which has also a collision component). The hotspots and the pointer have a Type of Trigger.

The pointer has the following script. If the pointer and a hotspot collide, the label beside the pointer shows the description of the hotspot.

The problem is now that this is not efficient at all. In a real point-and-click adventure there could be hundreds of hotspots. I shouldn’t use hundreds of if-else statements just to show the description of a hotspot. And don’t forget the problem that I am not able to handle the click on a hotspot at this time. I just don’t know how to do that.

Another problem is that the real game would have dozens of scenes. I think it would be a good idea to use a collection for every scene (scene 1 = scene1.collection, scene 17 = scene17.collection, …). Then I could add the hotspots for every scene as game objects with a collision component.

But does all of that really work with the pointer script above?

I just feel really overwhelmed.

Thanks in advance for your help.

5 Likes

You just need a table. Use the hashed IDs as the keys, and either just the label text, or (more useful), a table with whatever data you want to associate with the hotspot.

Something like this (untested):

local hotSpotDatas = {
	[hash("/hotspotExit")] = { label = "Exit" },
	[hash("/hotspotComputer")] = { label = "Computer" },
}

function on_message(self, message_id, message, sender)
	if message_id == hash("trigger_response") then
		if message.enter then
			local hotSpotData = hotSpotDatas[message.other_id]
			if hotSpotData then
				local label_text = hotSpotData.label
				label.set_text("/pointer#label", label_text)
			end
		else
			label.set_text("/pointer#label", "")
		end
	end
end

All you need for clicking on things, is to know what you clicked on (and if you clicked on anything). You’re already doing the collision detection, so you just need to save some information (store it in a ‘self’ property) about what the cursor is currently colliding with. Then, in your on_input function, if it’s a click, check the info you saved, and if the cursor is colliding with something, do something with it.

The short anwser: Yes, it’ll be fine.
The long answer: I wouldn’t worry about this at the moment. Just take it one step at a time. Do things the quickest, dirtiest, easiest way you can think of first, and if you run into problems, then you fix it. No use speculating about problems that you have no information about.

4 Likes

It is possible for one person to make a point and click game. In fact, of all the possible games, I’d say it’s a great one to get started with. It will be fairly simple to learn how to point, display information, click, put items into an inventory, etc… It’s much simpler than other games and it’s a great project for a first-timer.

With that said… yes, making video games sometimes involves putting the names of hundreds of different variables into a list. Sorry!! I really, really, hope you don’t give up and keep working on your project. Best of luck!

Learning about lists and how to use them with ipairs is very very important. Because it means you avoid a lot of manual repetition. Here’s a simple example that I am just working on now with a list of GUI nodes.

function init(self)
	msg.post(".", "acquire_input_focus")
	self.nodes = {"A","B","C","AB","BC","AC","Fstop","Bstop","B1","B2","B3","B4","F1","F2","F3","F4"}
end


function on_input(self, action_id, action)
	if self.on then
		for k,v in ipairs(self.nodes) do
			if gui.pick_node(gui.get_node(v), action.x, action.y) and action.pressed then
				gui.animate(gui.get_node(v), "color", vmath.vector4(1,1,1,1), 1, 0.1)
				msg.post("controller#script", v, {"pressed"})
			else
				gui.set_color(gui.get_node(v), vmath.vector4(0,0,0,0.5))
			end
		end
	end
end
2 Likes

There’s some good threads on this topic! Marco Giorgini is experienced in creating point and click adventures in Defold.

Here he shares the source of one of his jam games:

Here he talks a bit about his workflow:

Marco has made more point and click jam games so I encourage you to browse his post history.

2 Likes

Please, don’t give up, this would be a pity! Your background looks so beautiful.

2 Likes

Your tips were quite helpful. I’m now able to click on a hotspot and the engine returns not only the id of the hotspot but also it prints a custom text on the console.

And you’re absolutely right about doing things the quickest, dirtiest, easiest way at first. If it works, it works.

4 Likes

Thanks to you, too, for your helpful tips.

1 Like

I’ve found Marcos point-and-click adventure before and downloaded the Defold project. But I have to confess that his project is far beyond my capabilities. I understand very little how he has done it. Maybe after several years. :wink:

2 Likes

It’s not mine. It’s from a game called Deponia. I just needed a placeholder.

:grinning_face_with_smiling_eyes: I thought it looked vaguely familiar.

Brilliant. Looking forward to your game, point and clicks are so cool!