1
$\begingroup$

I would like to know if it's possible to access the jump speed via python to set different values for it. (.game.jump_speed / GameObjectSettings.jump_speed).

Is there a python script sample somewhere?

Here is a practical example to illustrate this question:

Let's say you have two types of platforms: Red and Blue. When one collides with the red platform this event triggers a jump force of 10.00 (ten). When one collides with the blue platform this event triggers a jump force of 20.00 (twenty).

pic

enter image description here

There is a .blend for prototyping here (google drive, saved in Blender version 2.78c): https://drive.google.com/file/d/0Byr4NYScNOlRMkkwWGx5VG5ETEk/view?usp=sharing (Controls: WASD to move the character).

enter image description here

Physics pannel:

enter image description here

$\endgroup$
3
+50
$\begingroup$

Current api (2.78c) GameObjectSettings.jump_speed

GameObjectSettings is part of bpy which only work inside of blender and only in Blender, this means that your game using bpy and bge only will work inside Blender because bpy will not work in standalone and you dont want that if you are making a game but if you are makin sortsof simulation and you will be using always blender then you can use bge and bpy.

You can access jump_speed:

from bpy import data

data.objects["Cube"].game.jump_speed = 50
print(data.objects["Cube"].game.jump_speed)

As soon as you run the script 50 will be the value for jump force in physics property panel:

enter image description here

here you can found some (old) good bge python tutorials

If you want in game dinamically change the jump speed you can use the next script portion was extracted from one of the tutorials, thanks to Goran Milovanovic

script

from bge import logic
from mathutils import Vector
import math

class MoveWSAD:
    """
    Goran's 2.6x FPS base-frame

    2011 - Goran Milovanvic - nilunder.com

    """
    def __init__(self, cont, own):
        self.cont = cont
        self.body = own
        self.sen_key_w = self.cont.sensors["W"]
        self.sen_key_s = self.cont.sensors["S"]
        self.sen_key_a = self.cont.sensors["A"]
        self.sen_key_d = self.cont.sensors["D"]
        self.sen_key_space = self.cont.sensors["space"]
        self.sen_col_onground = self.cont.sensors["onground"]
        self.speed_ground = 4
        self.speed_jump = self.speed_ground * 0.8
        self.main = self._inAir

    def _getMoveVec(self):
        forward_back = self.sen_key_w.positive - self.sen_key_s.positive
        left_right = self.sen_key_d.positive - self.sen_key_a.positive
        velocity = Vector((left_right, forward_back, 0))
        return velocity

    def _onGround(self):
        vec_velocity = self._getMoveVec()
        vec_velocity.magnitude = self.speed_ground
        if self.sen_key_space.positive:
            vec_velocity.z = self.speed_jump
        self.body.setLinearVelocity(vec_velocity, 1)
        if not self.sen_col_onground.positive:
            self.main = self._inAir

    def _inAir(self):
        if self.sen_col_onground.positive:
            self.main = self._onGround

"""Strapicarus 2017"""                
class Player:       
    def __init__(self, cont, body):       
        self.body = body
        self.move_wsad = MoveWSAD(cont, body)
        self.main = self.walking

    def walking(self):
        if self.move_wsad.sen_key_space.positive:
             self.change_speed(1)
        self.move_wsad.main()


    def change_speed(self, speed):
        if self.move_wsad.speed_jump < 20:
            self.move_wsad.speed_jump += speed
        else:
            self.move_wsad.speed_jump = self.move_wsad.speed_ground * 0.8
        return

def main(cont):
    if not 'init' in cont.owner.getPropertyNames():
        cont.owner['player'] = Player(cont, cont.owner)
        cont.owner['init'] = True
    cont.owner['player'].main()

main(logic.getCurrentController())

LogicBricks

enter image description here

Physics panel

enter image description here

EDIT ADDED

Well a just download your blend and you put the right blend this time (i forgot to mention that before answer), and i test ¿if i change the loc z in motion actuator the character will jump higher? and YES it works.

So you just need increase the loc z value to set the jump speed for that motion actuator:

enter image description here

And if you want a python way here is to:

jump.py

from bge import logic

def main(cont):
    jumpact = cont.actuators['jumpSpeed']
    colsen = cont.sensors['Blue']
    if not 'init' in cont.owner.getPropertyNames():
        cont.owner['init'] = True
        cont.owner['_onair'] = False
        cont.owner['jumpSpeed'] = 0.0
        print('init...')
        return   

    if not cont.owner['_onair'] and colsen.positive:
        if  cont.owner['jumpSpeed'] < 10.0:
            cont.owner['jumpSpeed'] += 1 
            jumpact.dLoc = (0,0,cont.owner['jumpSpeed'])
            print('adding jump speed')
            print(jumpact.dLoc.z)
        else:
            cont.owner['jumpSpeed'] = 0.0
        cont.activate(jumpact)
        cont.owner['_onair'] = True
        return
    else:
        cont.deactivate(jumpact)
        cont.owner['_onair'] = False
        return
#    print(dir(jumpact))
#    print(jumpact.force)
#    print(jumpact.linV)
#    print(jumpact.torque)
#    print(jumpact.dLoc) #FOUND IT ! xD

main(logic.getCurrentController())

Logic editor

enter image description here

Blend file

$\endgroup$
  • $\begingroup$ Dear Strapicarus, Thank you very much for your reply. But in my case I need a solution that works inside the Blender Game Engine (real time update) and with the "charachter" physics type. I also don't need other movements other than jump. The bounty prize is yours because of the effort. But I still consider this question without solution ;) Greetings! Ortiz $\endgroup$ – chicOrtiz Jul 3 '17 at 17:39
  • $\begingroup$ I think i found a solution check it in the edit. $\endgroup$ – Strapicarus Jul 3 '17 at 20:22
  • $\begingroup$ Hi Strapicarus! I tested your file in Blender 2.78c, but the jump is behaving like I'm using a simple motion value applied to a dynamic actor. The jump is not behaving like the charachter physics yet. Thank you! $\endgroup$ – chicOrtiz Jul 4 '17 at 15:29
1
$\begingroup$

I believe what you are asking for is not possible in Blender 2.78b. We will need to recreate the jump functionality.

The jump pads will require a float property called ['jumpSpeed'] and collision enabled in its physics tab. Static physics type should work.

The rest is explained below.

#if we put the python controler in modual mode,
#then it can pass the currentController as the first argument
def input(cont):
    #if you have problems with floating after a jump, then increse Max Fall Speed
    own = cont.owner

    #if were going to use the Characture Wrapper, then we need to get it first
    import bge
    pysOwn = bge.constraints.getCharacter(own)

    #this is how i handle keybinds
    clicked = bge.logic.keyboard.active_events
    click = {bge.logic.KX_INPUT_JUST_ACTIVATED, bge.logic.KX_INPUT_ACTIVE}

    #if the KEY is not in active_events then dict.get() will return None
    forward = clicked.get(bge.events.WKEY)
    backward = clicked.get(bge.events.SKEY)
    leftward = clicked.get(bge.events.AKEY)
    rightward = clicked.get(bge.events.DKEY)
    spaceward = clicked.get(bge.events.SPACEKEY)

    #if the jump count is less then the max jumps then we can jump
    if spaceward == bge.logic.KX_INPUT_JUST_ACTIVATED and own['jumpCount'] < pysOwn.maxJumps:
        #we can get a sensor even if its not connected to the current controller
        #it may have to be connected to at least one controller
        #if the collision sensor hits at least one object with the jumpSpeed property then we get it,
        #otherwise this get None
        hitObj = own.sensors['Collision'].hitObject
        #if theres a hitObj, then we use the jumpSpeed provided by that object,
        #otherwise we use the default on the char
        if hitObj:
            jumpSpeed = hitObj['jumpSpeed']
        else:
            jumpSpeed = own['jumpSpeed']

        #we move the char along the z axis by the jumpSpeed
        x = pysOwn.walkDirection.x
        y = pysOwn.walkDirection.y
        z = pysOwn.walkDirection.z + jumpSpeed
        pysOwn.walkDirection = (x,y,z)

        #this will trigger the property sensor, so we know when to stop jumping
        own['jumping'] = True
        #this sets the number of times we've jumped scence landind
        own['jumpCount'] += 1


    #if the char is on the ground or has the walkAir ablity then it can move, otherwise it can't
    if pysOwn.onGround or own['walkAir']:

        #we'r going to replace the current walkDirection with a new one
        x = 0
        y = 0
        z = pysOwn.walkDirection.z

        speed = own['walkSpeed']

        if forward in click:
            y += speed
        if backward in click:
            y -= speed
        if leftward in click:
            x -= speed
        if rightward in click:
            x += speed

        #this converts our local vector into a world vector
        from mathutils import Vector
        vec = Vector((x,y,z))
        vec = own.worldOrientation * vec

        #apply the walkDirection
        pysOwn.walkDirection = vec




def stopJump(cont):
    #this function asumes it will only be run if own['jumping'] == True
    own = cont.owner
    import bge
    pysOwn = bge.constraints.getCharacter(own)

    #if the char is on the ground, stop jumping and reset
    if pysOwn.onGround:
        pysOwn.walkDirection = (0,0,0)
        own['jumping'] = False
        own['jumpCount'] = 0

logic

$\endgroup$
  • $\begingroup$ Hello Otto! Thank you for your time. I tried to apply your jump setup withouth sucess. I hosted my attempt here [link]drive.google.com/file/d/0Byr4NYScNOlRWFdibHJPTWZ6R2c/… I don't know how I should trigger the jump. I confess that your python script is too advanced for me :) $\endgroup$ – chicOrtiz Jul 4 '17 at 15:34
0
$\begingroup$
from bge import constraints

cont = logic.getCurrentController()
owner = cont.owner

character = constraints.getCharacter(owner)

# When colliding use:
character.gravity = value float

# Set a different value for each platform you want to change the height of the jump
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.