Not logged inOpenClonk Forum
Up Topic General / Help and Questions / Controls: Convert mouse position to global coordinates
- - By Andriel Date 2012-10-30 21:14
Situation:
I have a PlayerControls.txt in my scenario to reassign the "Q" key. ("Apostrophe" for DVORAK) I want to get the mouse position so I set "SendCursorPos=1" in [ControlDef]. In the script, I access the mouse position like that: cursor_pos[plr][0] (this is x), cursor_pos[plr][1] (this is y). What I want to do, basically:
If I press "Q", I want to know if the mouse is right to my clonk, left to it, above it, below it, or in a corner and then acccelerate it to the opposite direction. (e.g. mouse is to the right of the clonk -> accelerate it to the left) Pretty similar to what the Jar of Winds does, I think. So, is there a way to convert the mouse coordinates (which change according to the screen resolution, I think?) to global coordinates? Or how does the Jar of Winds do it? I had a look at it's script, but there is a lot of sin and cos going on, I don't understand it. (We have not yet learned that at school)
So, can anybody help me?
Reply
Parent - - By Zapper [de] Date 2012-10-30 21:23
There are two coordinate sets: GUI coordinates (change with resolution) and real landscape coordinates.
When you have the landscape coordinates, you could use pretty straight-forward trigonometry:

(let x, y be the global coordinates)
var speed = 100;
var clonk = GetCursor(player);
var angle = Angle(x, y, clonk->GetX(), clonk->GetY()); // the angle pointing from the mouse to the Clonk
var x_speed = Sin(angle, speed);
var y_speed = -Cos(angle, speed);
clonk->SetSpeed(x_speed, y_speed);

(note that I used Sin for the x-coordinate and -Cos for the y-coordinate since the angle starts a little bit off compared to school)

Whether a control sends the landscape or the "real" coordinates can be specified somewhere in PlayerControl.txt - not 100% sure how, though
Parent - - By Clonk-Karl [de] Date 2012-10-30 21:47

> var angle = Angle(x, y, clonk->GetX(), clonk->GetY()); // the angle pointing from the mouse to the Clonk
> var x_speed = Sin(angle, speed);
> var y_speed = -Cos(angle, speed);


You don't even need all that fancy Sin/Cos stuff (trigonometry) here. The intercept theorem and Pythagoras work just as fine:

var x_speed = (x - clonk->GetX()) * speed / Distance(x, y, clonk->GetX(), clonk->GetY());
var y_speed = (y - clonk->GetY()) * speed / Distance(x, y, clonk->GetX(), clonk->GetY());
Reply
Parent - - By Zapper [de] Date 2012-10-30 21:57
But I think my way was more readable :D
Parent - - By Caesar [de] Date 2012-10-30 21:59
As soon as you understand that this is essentially just scaling the wanted speed by the distance on each axis, this one actually is easier. A three-liner would probably be better, though.
Parent - By Zapper [de] Date 2012-10-30 22:02
Not if Andriel wants to get an idea about what the wind-jar does with Sin and Cos :)
Parent - - By Andriel Date 2012-10-30 22:08

>Whether a control sends the landscape or the "real" coordinates


So the "real" coordinates would be GUI coordinates?

>can be specified somewhere in PlayerControl.txt - not 100% sure how, though


Hm, I didn't found something like that.
Documentation quote:

>SendCursorPos - If true then the GUI mouse position at the time of triggering the command will be sent as a separate CON_CursorPos command.


Maybe you mean ControlUse(object, X, Y)? It is used in the Jar of Winds script. (But not documented)
But since this SendCursorPos seems to send just GUI coordinates, is there a way to solve my problem?
If I understand your and ck's examples right, it does a landscape coordinates -> GUI coordinates conversion.
Reply
Parent - - By Zapper [de] Date 2012-10-30 22:35

>So the "real" coordinates would be GUI coordinates?


Oh, no. Sorry. "GUI or the real coordinates". "real" for you would be the landscape/game coordinates

>SendCursorPos - If true then the GUI mouse position at the time of triggering the command will be sent as a separate CON_CursorPos command.


Oh, that might be wrong or old

  [ControlDef]
  Identifier=Use
  GUIName=$CON_Use$
  GUIDesc=$CON_Use_Desc$
  Hold=1
  SendCursorPos=1

  [ControlDef]
  Identifier=GUIClick1
  DefaultDisabled=1
  Hold=1
  CoordinateSpace=Viewport

So I guess the difference is the CoordinateSpace=Viewport line? Try CoordinateSpace=Game (might be default)
Parent - - By Andriel Date 2012-10-30 22:57
Nah, didn't have any affect :(
My [ControlDef] looks like this:

  [ControlDef]
  Identifier=Backpack
  GUIName=Backpack
  GUIDesc=Open/close backpack
  SendCursorPos=1
  CoordinateSpace=Game


But could I maybe use the above formula to convert the clonks position into GUI coordinates and then check where the mouse is?
Reply
Parent - - By Zapper [de] Date 2012-10-30 22:59
The formula is not for converting between game- and GUI-coordinates - it is just to change the speed of a Clonk when you already have the coordinates!

Are you sure your coordinates are GUI coordinates? And what are you doing in the rest of your script?
Parent - By Andriel Date 2012-10-30 23:24

>Are you sure your coordinates are GUI coordinates?


Yes, because I made a testlog which returns the current position of the mouse, when I walk around and don't move the mouse, the coordinates would change if they were global, but they stay the same.

>And what are you doing in the rest of your script?


This is the basic idea:

global func Control2Player(int plr, int ctrl, int x, int y, int strength, bool repeat, bool release)
{
  // cursor pos info - store in player values
  if (ctrl == CON_CursorPos)
  {
    if (!cursor_pos) cursor_pos = CreateArray(plr+1);
    cursor_pos[plr] = [x, y];
    return true; // cursor_pos is an array containing the cursors position at the moment you pressed "Q"
  }
 
 
  // Rucksack command
  if((ctrl == CON_Backpack) && !release) // If you press "Q":
  {
    ActionWhenPressingQ(plr, ctrl, x, y, strength, repeat, release);
  }
  return inherited(plr, ctrl, x, y, strength, repeat, release);
}

global func ActionWhenPressingQ(int plr, int ctrl, int x, int y, int strength, bool repeat, bool release)
{
                SomehowCalculateGlobalCoordinates(cursor_pos[plr][0], cursor_pos[plr][1]); // X and Y input
                CheckWhereMouseIsInRelationToClonkUsingGlobalCoordinates(); // See first post
                if(MouseIsOnTheRightSide()) // In relation to the clonk
                        clonk->PushToTheLeft();
                // and so on...
}


I actually took parts of this from Caedes.
Reply
Up Topic General / Help and Questions / Controls: Convert mouse position to global coordinates

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill