Performance issues with changing mouse cursor - SOLVED

Started by johanvepa, Thu 22/09/2016 00:03:20

Previous topic - Next topic

johanvepa

I am making a simple tower defense game, and a feature is that the mouse cursor changes with whatever region it is hovering over. The code is this:
Code: ags

function room_RepExec()
{
  if (Region.GetAtRoomXY(mouse.x, mouse.y) == region[1])
  {
    if (mouse.Mode != eModePickup)
    {
      mouse.Mode = eModePickup;
    }    
  }
  if (Region.GetAtRoomXY(mouse.x, mouse.y) == region[3])
  {
    if (mouse.Mode != eModeLookat)
    {
      mouse.Mode = eModeLookat;
    }
  }


This works, but with huge performance issues. The mouse cursor does not always change, it stays in eModePickUp even when hovering over region [3]. After a while it changes, so the code is recognized, but it takes long time for the game to realize. The issue is varying, sometimes it changes more quickly than other times.
Any ideas?

Crimson Wizard

#1
I cannot know if that is the only reason, but first of all, you are calling Region.GetAtRoomXY two or more (if your actual script is longer) times - which means engine performs same region detection all over again for EVERY if your put there.

Instead of doing that, you could call it once and stored result in local variable. Then compare stored result with the array elements, e.g.
Code: ags

Region *r = Region.GetAtRoomXY(mouse.x, mouse.y);

if (r == region[1])
<...>
if (r == region[2])
<...>



Also, the Region pointer returned by Region.GetAtRoomXY already contains ID, so you can do this:
Code: ags

Region *r = Region.GetAtRoomXY(mouse.x, mouse.y);

if (r.ID == 1)
<...>
if (r.ID == 2)
<...>


Note, I do not think you need to check if mouse mode is not the same, because engine might be checking it internally.

Gurok

#2
Two things.

room_RepExec() only gets called when the game isn't doing something that's considered blocking. This includes Wait() commands and commands issued with eBlock. You might be doing something elsewhere that the game is busy with, and that might be why it appears to be unresponsive.

To run your code every game cycle, regardless of whether the game is busy, use repeatedly_execute_always. Don't worry about binding it in the room properties. Just having it inside your room is enough for the game to call it.

Secondly, if you have a scrolling room, there's a difference between mouse coordinates and room coordinates. You'll need to add the position of the viewport to the mouse coordinates to convert them into room coordinates. This might be why the mouse cursor doesn't change when you are clearly hovering over region[3].

Here are CrimsonWizard's suggestions combined with my own:

Code: ags
function repeatedly_execute_always()
{
  Region *r = Region.GetAtRoomXY(GetViewportX() + mouse.x, GetViewportY() + mouse.y);

  if (r.ID == 1)
  {
    mouse.Mode = eModePickup;
  }
  else
    if (r.ID == 3)
    {
      mouse.Mode = eModeLookat;
    }
}


Finally, if things are still sluggish, try calling Mouse.Update() at the beginning of repeatedly_execute_always.
[img]http://7d4iqnx.gif;rWRLUuw.gi

johanvepa

The issue here was the mouse coordinates. I added Space on each side of the room's borders and locked ViewPort, in order to allow for the little monsters to walk in from outside the boundaries of the screen. Didn't think about this changing what coordinates the mouse had.

Also, the room is very simple indeed (game is made on the blank template, too) so I doubt there are any actual performance issues once I apply the necessary changes to mouse coordinates. But good idea with the Region variable, less code to handle.

Thank you both.


Khris

Quote from: Crimson Wizard on Thu 22/09/2016 00:14:28Note, I do not think you need to check if mouse mode is not the same, because engine might be checking it internally.

It might have changed in a recent version, but it used to be quite sensible to check the mouse.Mode because animated cursors didn't work otherwise.

Crimson Wizard

Quote from: Khris on Thu 22/09/2016 12:07:44
Quote from: Crimson Wizard on Thu 22/09/2016 00:14:28Note, I do not think you need to check if mouse mode is not the same, because engine might be checking it internally.

It might have changed in a recent version, but it used to be quite sensible to check the mouse.Mode because animated cursors didn't work otherwise.

Oh... I did not think about that.


SMF spam blocked by CleanTalk