I have a character that I want to move around a hexagonal grid. I need the character to rotate exactly 60 degrees either left or right depending on which way the mouse is moved. I’ve tried a few things that sort of do what I want to do, but it involves a lot of empties and separate objects. It’s gotten complicated, and it still doesn’t work 100%.
Is there a simple way to do this? And also possibly have a threshold the motion needs to overcome in order to trigger the left or right rotation?
I can probably handle the rotation myself, my problem is just being able to separate mouse left vs mouse right.
First calculate the x-motion then evaluate the results and activate the according actuators all in one frame. Be aware the mouse.determineMouseXMotion needs to be triggered first.
First calculate the x-motion. At the next frame the property sensors will evaluate the result and trigger the according actuators. Due to the timing it means the motion will take effect one frame later.
C) Custom code
You can use the above code to perform whatever custom code you want. Either you manipulate the function determineMouseXMotion() or (recommended )you create and setup a new function similar to isLeftMotion()
def onLeftDoSomething():
if allSensorsPositive() and getMouseXMotion()<0:
doSomeThing()
How the code works:
determineMouseXMotion():
grabs the current mouse position
grabs the last mouse position
stores the current mouse position (to be used next time)
calculates the x-motion (positional difference between last and current mouse position)
determineMotion():
stores the calculated x-motion in property “xmotion” which can be checked at the next frame
is???Motion():
checks the sensors to act like an AND controller
checks if the property “xmotion” is below, above or equal to 0
activates all connected actuators dependent on the evaluation result.
Remarks:
Be aware determineMouseXMotion() should be called ONCE per frame ONLY! Otherwise some results will be 0.
import bge
cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
player = scene.objects["Player"]
mouse = bge.logic.mouse
xdiff = mouse.position[0] - 0.5 #mouse.position = (0.5,0.5) = tuple, values from 0 to 1
ydiff = mouse.position[1] - 0.5
deadzone = 0.001*player.get("deadzone",1.0) #a property in player called "deadzone"
rad = 57.295779513082320876798154814105 # = 180 / ( 2 * pi)
diffx = False
diffy = False
def signum(x):if x > 0:
[INDENT=2]return 1[/INDENT]
elif x == 0:
[INDENT=2]return 0
[/INDENT]
return -1 #dont need an else statement because "return" stops the function
mousepos = []
if abs(xdiff) > deadzone:rotval = signum(xdiff)*60/rad
player.applyRotation((0,0,rotval),False)
if abs(ydiff) > deadzone:#you dont need they y value i think, but it would be bad if you could move the mouse up
diffy = True
#now reset mouse position
if diffx and diffy:
mouse.position = (.5,.5)
elif diffx:
mouse.position = (.5,mouse.position[1])
elif diffy:
mouse.position = (mouse.position[0],.5)
#the round brackets are neccessary because mouse.position must be a tuple
I’m using Monster’s setup right now because it was easy for me to understand and add actuators.
I’ve almost gotten the result I want with animation actions, but I can’t get the clockwise rotation for turning right to work properly. It seems like the 60 degree rotation is being added first and then rotating back. I’ve already reset the rotation at frame 15 to 0 degrees. What else can I do to avoid this? I would prefer to use animations for the rotation so I can add quirks to the characters motion later on.
Added a location action for exacting the distance and used a frame property to make the player unable to move when the action is not on the first or last frame.
How could I reset the mouse position to the center of the screen without the script thinking it is mouse motion? The mouse sometimes gets stuck to one side of the screen when moving the character.
The script I offered to you does not manipulate the mouse cursors’s position. This is good for mouse input like menus and so on (where you see the mouse cursor). I call that “absolute mouse”.
The other scripts reset the mouse position to the middle of the screen. This is good when acting like a joystick. This is often used on FPV. I call it “relative mouse”.
To get a “relative mouse x motion” the a different architecture is needed.
You do not need the internal storage as by resetting the mouse cursor you already know the “last position” as it is reset.
You can determine the motion just once per frame (rather than once per object). Due to the mouse position manipulation any subsequent motion calculation will result 0.
I suggest to have a single object that determines the motion (both vertical and horizontal) ->MouseMotionCalculator. mouse.determineMotion should run first (enable the priority flag at the controller). The resulting motion will be stored at the script. This way any other object can get it from there.
Motion-dependent objects can call mouse.isLeftMotion, mouse.isRightMotion, mouse.isNoMotion as before -> DirectActivation.
The other option needs a small change. Replace mouse.determineMotion with mouse.motionToProperties.
you could just add this to the end of the script you are using now (dont need the “import bge” because thats probably at the start of the script anyway), or connect this to an always sensor