Movement and Jump for an FPS

Does anyone know a really good tutorial for movement and jump for an FPS using “wasd”? I already have a good mouse look system. I have tried many systems for jumping and movement but all of them are flawed. One didn’t allow diagonal movement, one had a bad jumping system.
PS. I really like the jumping and movement in MineCraft. The jumping allows you to easily and smoothly go up to the next level.
PSS. Please only suggest tutorials that show techniques that you have used and have experience with and really work smoothly.

Here’s a simple jump to get you started. I’ve just given you “w”, up the y axis. Note here that you will only jump when the w key is pressed and you are on the floor. The plane is static with a property called floor. The cube is dynamic and is momentarily given an upward and a horizontal velocity. Gravity here is set at 25.

Attachments

simplejump.blend (457 KB)

Here is what I’m using in my FPS.

First Copy the script in the next post, and paste it in your Blend. (Name it Movement.py)

Then select your Player, and give it these Float properties, and values. (walking 5,running 15,jumping 5).
Then open your Logic Editor, and add these Logic Bricks. (make sure to name your bricks, and spell them correctly, or this won’t work.


That’s about it. Hope that helps. If you need more. Just PM me.

def main():
     
    # get current controller
    controller = bge.logic.getCurrentController()
    
    # get object script attached to
    obj = controller.owner
    
    # get servo control named move
    servo = controller.actuators["move"]    
    
    # check for user added properties
    check_Prop(obj, servo)
    
    # extract linear velocity from servo
    lin_Speed = servo.linV
        
    ###
            
    # moving forward/back
    lin_Speed = forward_back(obj, controller, lin_Speed)
    
    # moving left/right
    lin_Speed = left_right(obj, controller, lin_Speed)
    
    # running
    lin_Speed = run(obj, controller, lin_Speed) 
    
    # jumping
    lin_Speed = jump(obj, controller, lin_Speed)
    
    # diagonal movement 
    lin_Speed = move_Diagonal(obj, controller, lin_Speed)
        
    # ground
    touch_ground = ground(controller)
    
    # servo settings
    lin_Speed = servo_settings(obj, servo, touch_ground, lin_Speed)
        
    ###

    # use servo control
    move(obj, controller, servo, lin_Speed)
    
    # stop without sliding
    stop(obj, controller, servo, touch_ground, lin_Speed)
    
    
###

def check_Prop(obj, servo):
            
    # check for walk speed
    if "walking" not in obj:            
        
        # Not set? Use default walk speed
        obj["walking"] = 10.0                       

    # check for user set run speed
    if "running" not in obj:            
        
        # Not set? Use default run speed
        obj["running"] = 1.5 * obj["walking"]       

    # check user set jump amount
    if "jumping" not in obj:
        
        # Not set?  Use default jump force
        obj["jumping"] = 10.0
        
    # Check for jump once   
    if "jump_once" not in obj:
        
        # Not set?  Use default 
        obj["jump_once"] = 1
    
    # check for servo status        
    if "servo_status" not in obj:
        
        # not set?  use default
        obj["servo_status"] = "Off"
    
    # check for touch ground
    if "touch_ground" not in obj:
        
        # not set?  Use default
        obj["touch_ground"] = 0
    
###

def forward_back(obj, controller, lin_Speed):
            
    # get sensors named forward and back
    forward = controller.sensors["forward"]
    back = controller.sensors["back"]
    
    # extract linX, linY and linZ from linV 
    linX, linY, linZ = lin_Speed        
                
    ### ground -- forward/back 
                
    # forward key       
    if forward.positive == True and back.positive == False: 
        
        # forward linear velocity
        linY = obj["walking"]
                        
    # back key      
    elif back.positive == True and forward.positive == False:
        
        # back linear velocity
        linY = -obj["walking"]
    
    # no key
    elif back.positive == False and forward.positive == False:
        
        # no linear velocity
        linY = 0.0
    
    # both keys
    elif back.positive == True and forward.positive == True:
        
        # no linear velocity
        linY = 0.0


    ### save linear velocity
    lin_Speed = [linX, linY, linZ]
    
    return lin_Speed


###

def left_right(obj, controller, lin_Speed):

    # get sensors named left and right
    left = controller.sensors["left"]
    right = controller.sensors["right"]
    
    # extract linX, linY and linZ from linV 
    linX, linY, linZ = lin_Speed
            
    
    ###  ground -- left/right

    # slide left key
    if left.positive == True and right.positive == False:
        
        # move left linear velocity
        linX = -obj["walking"]
                
    # slide right key
    elif right.positive == True and left.positive == False:
        
        # move right linear velocity
        linX = obj["walking"]
    
    # no key    
    elif left.positive == False and right.positive == False:
        
        # no linear velocity
        linX = 0.0
        
    # both keys 
    elif left.positive == True and right.positive == True:
        
        # no linear velocity
        linX = 0.0
                
    ### save linear velocity
    lin_Speed = [linX, linY, linZ]
    
    return lin_Speed


###

def run(obj, controller, lin_Speed):

    # # extract x, y and z from linear speed
    linX, linY, linZ = lin_Speed
    
    # get keyboard sensor named run
    runSen = controller.sensors["run"]

    # running
    if runSen.positive == True:
        
        # forward/back
        linX_Run = obj["running"] * ( linX / obj["walking"] )
        
        # left/right
        linY_Run = obj["running"] * ( linY / obj["walking"] )
        
        # set running speed
        linX = linX_Run
        linY = linY_Run
        
    ############ save linear velocity
    lin_Speed = [linX, linY, linZ]
    
    return lin_Speed
        
###

def jump(obj, controller, lin_Speed):
    
    # get keyboard sensor named jump
    jump = controller.sensors["jump"]
    
    # extract x, y and z from linear speed
    linX, linY, linZ = lin_Speed
    
    ############# ground -- jumping
    
    # jump key pressed
    if jump.positive == True:
        
        # one key press = one jump
        if obj["jump_once"] == 1:
                    
            # only one jump
            obj["jump_once"] = 0
            
            # set jump force
            linZ = obj["jumping"]
            
    # jump key released
    elif jump.positive == False:
        
        # reset jump once to true
        obj["jump_once"] = 1
        
        # no jump force
        linZ = 0.0
            
    ### save linear velocity
    lin_Speed = [linX, linY, linZ]
    
    return lin_Speed

    
###

def move_Diagonal(obj, controller, lin_Speed):
            
    # # extract x, y and z from linear speed
    linX, linY, linZ = lin_Speed

    ###  ground -- diagonal
    
    # diagonal movement
    if linX != 0.0 and linY != 0.0:
        
        # diagonal linear speed.
        linX = 0.707 * linX
        linY = 0.707 * linY
                
    ### save linear velocity
    lin_Speed = [linX, linY, linZ]
    
    return lin_Speed
                    

###

def ground(controller):
    
    # get ground collision sensor named ground
    ground = controller.sensors["ground"]
        
    # Touching the ground?  
    if ground.positive == True:
        
        # 1 = True
        touch_ground = 1
    
    elif ground.positive == False:
        
        # 0 = False
        touch_ground = 0
    
    
    return touch_ground
    

###

def servo_settings(obj, servo, touch_ground, lin_Speed):    
        
    # # extract x, y and z from linear speed
    linX, linY, linZ = lin_Speed

    ###
    
    # touching the ground 
    if touch_ground == 1:
                    
        # stop
        if linX == 0.0 and linY == 0.0 and linZ == 0.0:
    
            # set to stop without sliding
            servo.forceLimitX = [0.0, 0.0, False]       
            servo.forceLimitY = [0.0, 0.0, False]
            servo.forceLimitZ = [0.0, 0.0, False]
            
        # moving    
        elif (linX != 0.0 or linY != 0.0) and linZ == 0.0:
        
            # set force limits
            servo.forceLimitX = [-1000.0, 1000.0, True] ####  for left/right movement   
            servo.forceLimitY = [-1000.0, 1000.0, True] ####  for forward/back movement
            servo.forceLimitZ = [0.0, 0.0, True]        ####  for gravity       
        
        # jump
        elif linZ != 0.0:
            
            # force limits              
            servo.forceLimitX = [0.0, 0.0, True]            ####  sideways momentum     
            servo.forceLimitY = [0.0, 0.0, True]            ####  forward/back momentum
            servo.forceLimitZ = [-1000.0, 10000.0, True]    ####  jump force        
    
            
    ### not touching the ground
    
    elif touch_ground == 0:
            
        # no force applied      
        linX = 0.0
        linY = 0.0
        linZ = 0.0
                        
        # in air -- no limits
        servo.forceLimitX = [0.0, 0.0, True]    ####  sideways momentum     
        servo.forceLimitY = [0.0, 0.0, True]    ####  forward/back momentum
        servo.forceLimitZ = [0.0, 0.0, True]    ####  gravity and jump momentum
                    
    ### save linear velocity
    lin_Speed = [linX, linY, linZ]
    
    return lin_Speed

###   
    
def move(obj, controller, servo, lin_Speed):
        
    # extract x, y and z from linear speed
    linX, linY, linZ = lin_Speed
    
    # only need to turn servo control on if it isn't turned off
    if (linX != 0.0 or linY != 0.0 or linZ != 0.0) and obj["servo_status"] != "On":
    
        # turn servo control on
        controller.activate(servo)
        
        # save servo status as on
        obj["servo_status"] = "On"                          
    
    # make it move 
    servo.linV = lin_Speed  
    
###  

def stop(obj, controller, servo, touch_ground, lin_Speed):
    
    # extract x, y and z from linear speed
    linX, linY, linZ = lin_Speed
    
    # no force being applied    
    if linX == 0.0 and linY == 0.0 and linZ == 0.0:     

        # get delay sensor named stop
        stop_Delay = obj.sensors["stop"]
        
        # Stop if touching ground
        if touch_ground == 1 and obj["servo_status"] == "On": 
                                                    
            # start Delay sensor
            stop_Delay.reset()
            
            # save servo status as off      
            obj["servo_status"] = "Off"
                
        elif obj["servo_status"] == "Off":
                                                    
            # Delay sensor is done
            if stop_Delay.positive == False:
                
                # turn servo control off
                controller.deactivate(servo)                            
                
### 

# get 2.55 GameLogic module
import bge

# run main program
main()