0
$\begingroup$

I recently ran into an issue when applying forces to an object. I was working with this question. I am trying to add forces to my character as certain keys are pressed. Here are the keys and their direction of force:

W = forward

S = backward

A = leftward

D = rightward

As I hit any of the keys, a force is added to its direction. However, a problem arises with diagonal movements as a different technique would be needed to define direction. I am having trouble with defining diagonal directions. For instance, (10, 10, 0) would add the force 10 on x and y. This will not work. I need to add 10 to a new direction; this direction will be the diagonal consisting of the two directions combined. I will add the force to this direction. I am puzzled on how I would define such a direction with the (x, y, z) format. How could I define a diagonal direction?

$\endgroup$

2 Answers 2

1
$\begingroup$

As I hit any of the keys, a force is added to its direction.

This makes them separate. But you say you want them combined.

So combine them. Don't apply them immediately, but gather them together, then apply a vector with the length you want.

The easiest way is to just add together the different impulses, normalize the resulting vector, scale it to the desired size, and apply the scaled result to the object.

Example:

from mathutils import Vector

combined_force = Vector()
vector_length = 10.0

if is_forward_key_pressed:
  combined_force += Vector((1.0, 0.0, 0.0))

if is_backward_key_pressed:
  combined_force += Vector((-1.0, 0.0, 0.0))

if is_left_key_pressed:
  combined_force += Vector((0.0, -1.0, 0.0))

if is_right_key_pressed:
  combined_force += Vector((0.0, 1.0, 0.0))

combined_force.normalize()
combined_force *= vector_length

game_object.applyForce(combined_force)

This calculation would occur at most once each frame, instead of repeating it for each key pressed.

A more complex way would be to track the direction as Euler angles, Quaternions, or Matrices, and calculating a final vector from those.

$\endgroup$
5
  • $\begingroup$ The original poster seems to have found the answer on a linked question on the right hand panel. View this blender.stackexchange.com/questions/42739/… $\endgroup$
    – hawkenfox
    Commented Jan 1, 2016 at 15:28
  • $\begingroup$ @hawkenfox That's from 3 weeks ago. $\endgroup$ Commented Jan 1, 2016 at 15:49
  • $\begingroup$ If this question is a repeat, then someone else will merge these, as I don't see how it should look like. But the fact that this question appeared after 3 weeks, indicates that some kind of problem still exists. Maybe this simplified version will teach something to the poster. $\endgroup$ Commented Jan 1, 2016 at 16:14
  • $\begingroup$ Well , good call. $\endgroup$
    – hawkenfox
    Commented Jan 1, 2016 at 17:28
  • $\begingroup$ Oh! I didn't understand something. Thank you for the answer! :) Greatly appreciate it. Cleared up something I didn't do correctly. $\endgroup$
    – blackhole
    Commented Jan 4, 2016 at 0:44
0
$\begingroup$
import bge

def main():
cont = bge.logic.getCurrentController()
cubeObj = cont.owner


# Create event listeners that check for
# keyboard buttons pressed events.
keybrd = bge.logic.keyboard

wKey = bge.logic.KX_INPUT_ACTIVE == keybrd.events[bge.events.WKEY]
sKey = bge.logic.KX_INPUT_ACTIVE == keybrd.events[bge.events.SKEY]
aKey = bge.logic.KX_INPUT_ACTIVE == keybrd.events[bge.events.AKEY]
dKey = bge.logic.KX_INPUT_ACTIVE == keybrd.events[bge.events.DKEY]
spaceKey = bge.logic.KX_INPUT_ACTIVE == keybrd.events[bge.events.SPACEKEY]    

wKey_r = bge.logic.KX_INPUT_JUST_RELEASED == keybrd.events[bge.events.WKEY]
sKey_r = bge.logic.KX_INPUT_JUST_RELEASED == keybrd.events[bge.events.SKEY]

# Create speed variables for quick changes
# over multiple lines, later if required.
movSpd = 0.025
# rotSpd = 0.05
jump = 25
drift = 75

# Actions instructions when keys are pressed.
if wKey:
    cubeObj.applyMovement((0, movSpd, 0), True)
elif sKey:
    cubeObj.applyMovement((0, -movSpd, 0), True)

if wKey_r:
    cubeObj.applyForce((0, drift, 0), True)
if sKey_r:
    cubeObj.applyForce((0, -drift, 0), True)

if aKey:
    cubeObj.applyMovement((-movSpd, 0, 0), True)
if dKey:
    cubeObj.applyMovement((movSpd, 0, 0), True) 
if spaceKey:
    cubeObj.applyForce((0, 0, jump), True)

main()

Is this what you are looking for? Let me know.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .