Mouse detection during battle

I’m new to rpg maker mv and I’m wondering how I can create a little clicker minigame during combat. When casting a skill, I want to have a little minigame where the player have to quickly click circles that would show up in random positions on the screen and base on how well they did, the skill would get a damage buff or fail to cast

You’ll mainly be working with the TouchInput.isTriggered() function and
TouchInput.x and TouchInput.y to evaluate where or what the player clicked.

I would do this in a common event. I’m assuming you’re going to use Show/Move Picture commands for your circles. You’ll basically make a Conditional Branch that evaluates if the player has clicked or touched the screen and if that falls within the image’s hitbox.
The hitbox detections is easier done than explained.

Skill Setup

First, you’ll make a skill that calls a common event as an effect. Besides targeting an enemy, it doesn’t actually do anything. The Common Event will Show/Move your Circles and handle the detection, I’ll come back to that.
You’ll end the common event with the [Force Action] command, using the skill that does the actually animation and damage formula to the enemy.
The thing with [Force Action] in MV is that you can select “Last Target”, but the editor doesn’t provide a “Last Subject” in the drop down list. Maybe that’s not a problem if it’s a Harold Only skill, you just make Harold the subject. But if it’s a skill that any of the actors can use it’s easier to use the Force Action command via a script call and input the active battler as the subject.

//Force Action
this._params = [1, BattleManager._subject._actorId, 12, -2]; 
this.command339();

This is just an example script block that you’d use.
The parameters above translate to something like
[is an Actor, Active Subject Id, Skill ID, Last Target]
If you copy and paste it then all you need to change is the Skill ID number where I was using “12”.

Hit Detection

In the skill’s common event, you’re going to show/move your pictures around however you want. And run a conditional branch in a loop or as a secondary common event to detect the mouse clicks.

This is easier done than explained.
MZ would make this slightly easier than MV, because it has a clickable sprite class, but even those are still just rectangular hitboxes using the image’s frame. Since you’re using Circles, you’ll want to ignore the Alpha (transparent) pixels too, ideally. Luckily, MV has a getAlphaPixel() function we can utilize.

I put together this function pictureMouseover() for you. I started to explain how it works; but to keep this short, all you need to do is copy it in above your condition branch.
I had to make the format compact because MV’s Script box has limited vertical space :confused:

pictureMouseOver = function(picId) {
var pic = SceneManager._scene._spriteset._pictureContainer.children[picId - 1];
if (!pic || !pic.bitmap || !pic.bitmap.isReady()) return false;
var x = TouchInput.x, y = TouchInput.y, node = pic;
while (node) { x -= node.x; y -= node.y; node = node.parent; }
var bx = Math.floor(x / pic.scale.x + pic.bitmap.width * pic.anchor.x);
var by = Math.floor(y / pic.scale.y + pic.bitmap.height * pic.anchor.y);
if (bx < 0 || by < 0 || bx >= pic.bitmap.width || by >= pic.bitmap.height) return false;
return pic.bitmap.getAlphaPixel(bx, by) > 0;
};

Then use the function in your conditional branch like:
TouchInput.isTriggered() && pictureMouseOver(1)
This is evaluating true or false. If the player is touching/clicking something AND it’s over picture “1”. Meeting those conditions, it does whatever you want it to do.

The common event doesn’t look like much. Although I was just using a static picture. When you click on the picture, It plays a chime, erases the picture, and forces the action.

I have the Conditional Branch Script in a loop until the picture is clicked.
But for a timed event, you could break the loop with a switch from a secondary common event that manages your Circles.

2 Likes

holy crap you are goated. Thank you so much for your help ! I’ll try these out and write a response for you shortly after


I tested it on some bats. The picture did show up but I think I might be missing something with the click detection. Clicking it didn’t seem to work

The first thing that comes to mind is that you might be using a plugin that changes the order of the picture container’s children. Some plugins add images for lighting, weather, and fog effects. So picture “1” might not actually be the first picture in the container index.
There could be somekind of offset. You might have to change pictureMouseOver(1) to a different Picture ID number.

you’re right the plugins did change the picture container order. I turned them all off and then tried again and 1 worked. But now that begs the question of how do i even know the id of the picture im using. should i just bruteforce it and test from 1 to 100?

I doubt the offset would be more than 10.
What you could do is Run a test battle. Press F12 to open the Developer Tools console.
Type (copy&paste) in: SceneManager._scene._spriteset._pictureContainer
You’ll get a nested view of the children objects. By default there should only be 100 picture containers. If it show something like 109, that means the other plugins probably added a few more in front of everything. So the index for picture 1 wouldn’t be index 0, [picId - 1], but something like [picId - 1 + 9], which you can correct in the first line of the pictureMouseOver function.
var pic = SceneManager._scene._spriteset._pictureContainer.children[picId - 1 + 9]

Does that make sense?

Edit: replacing
SceneManager._scene._spriteset._pictureContainer.children[picId - 1]
with
SceneManager._scene._spriteset._pictureContainer.children.find(sprite => sprite._pictureId === picId)
Might also work, so you don’t have to fix this again if you decide to drop or pick up a plugin


I did this and at first it said “undefined”. I tried to test it out a bit more by just using the skill while having the console out and it returned this. The plugins gets in the way apparently

edit : additionally, turning off the plugins and the command works normally. I found out that SRD_CameraCore is the reason why the command return undefined

Looks like the pictureMouseOver() function is missing a few lines at the end. That might have happened when you edited that first line. Since MV’s script command box has limited vertical lines, you got to be careful not to push stuff off.

I added back the missing lines and now there’s no errors. But there’s still the issue of the image being unresponsive to clicks when I have the plugins. I hope this is not too much to ask, but if possible, may I contact you through discord ?