Need help making checkpoints in my game


(BLE01) #1

Hello, I am new to Blender and Python and I have to make a game for my school project. I am making a 2D platformer and I want checkpoints so when my character dies it doesn’t have to start again at the beginning of the level but somewhere in between wherever that checkpoint may be.

So I was thinking I need to have a Collision Sensor that detects if my character has passed a checkpoint. Then if it did it has to save its location in to an array that I can refer to when the character dies. I currently run in to the issue that it saves the player location when this collision sensor is active but the list is empty again as soon as the sensor is not active anymore.

My current code:

# Configuration senCP Attributes
    senCP.propName = 'checkpoint'
    senCP.useMaterial = False
    senCP.usePulseCollision = True
    
    # Status senCP Attributes
    hitObj = senCP.hitObject
    hitObjects = senCP.hitObjectList


    
    # Activate Checkpoint
    start = scene.objects ['Start']
    checkpoints = []
    
    if senCP.positive:
        checkpoints.append(player.worldPosition)
    
    # This is just to see if the location is saved in the list
    print (checkpoints)

I run in to a couple of problems here:

  • When I print (checkpoints) it only shows the player location when the sensor is active. After that (when the player has passed the checkpoint) the list is empty.
  • I currently use a static object that detects collision as a checkpoint. However I want to work towards a system where the player is not interrupted by a collision because this might result in bugs like if the player repeatedly walks over the same checkpoint it might fall of the platform. I want to avoid that.

So I need help, you guys got any solutions or alternatives I can use here?


(Monster) #2

It might sound a little stupid, but what do you expect to happen with the list?

For more information I suggest to search the forum for saveload, savepoints and such things.


(Nick Manchul) #3

I did not try to solve your problem (with the code), but made on its understanding such a fairly universal solution:


import bge

cont = bge.logic.getCurrentController()
own = cont.owner
scene = bge.logic.getCurrentScene()

player01 = scene.objects['player01']


sens01 = cont.sensors['message01']


player_pos01 = player01.position

resp01 = [float(i) for i in own['resp01'].split(',')]
resp02 = [float(i) for i in own['resp02'].split(',')]
resp03 = [float(i) for i in own['resp03'].split(',')]
resp04 = [float(i) for i in own['resp04'].split(',')]
    
if sens01.positive:
    player01.setLinearVelocity([0.0, 0.0, 0.0], True) 
    if player_pos01[0] < resp02[0] and player_pos01[2] > resp02[2]:
        player01.position = resp01
        own["check_point"] = 1
    if player_pos01[0] < resp03[0] and player_pos01[2] < resp02[2]:
        player01.position = resp02
        own["check_point"] = 2
    if player_pos01[0] > resp03[0]:
        player01.position = resp03
        own["check_point"] = 3

Then you can add a save script, and all - even after leaving the game, the next time you start, the player starts on the saved checkpoint (need a small code).
The properties “bullet” can be used for lava, and the abyss, and any deadly object - in the example a simple plane on the floor.

Thank you, I myself thought a little - a warm-up for the brains.


(Cotaks) #4
  1. you call checkpoints every tic/frame, but you also set it to empty ( [] ) every frame. So you should make it global.
    Anice way for this is using a function like this:

checkpoints = []


def checkpoints(cont):
    
    own = cont.owner
    scene = own.scene
    senCP = cont.sensors['Collision']
    
    # Configuration senCP Attributes
    senCP.propName = 'checkpoint'
    senCP.useMaterial = False
    senCP.usePulseCollision = True
    
    # Status senCP Attributes
    hitObj = senCP.hitObject
    hitObjects = senCP.hitObjectList


    # Activate Checkpoint
    start = scene.objects ['Start']
  
    if senCP.positive:
        checkpoints.append(player.worldPosition)
    
    # This is just to see if the location is saved in the list
    print (checkpoints)

or define checkpoints as a global (not sure if that works, never used it this way)

global checkpoints
  1. instead of static, put it on sensor, that is where sensors are made for, sensor objects are like ghosts, it detects but does not interfere.

(dtrip) #5

At checkpoints you have two things =

  1. A hitbox ( an invisible sensor type box with Collision (with player)). And in the collision logic it saves the number of checkpoint in file checkpoint.txt.

  2. An empty for that checkpoint. This is used to spawn the player there, in case this checkpoint is ever used.

So as you walk past the level, touching hitbox1 will write (save) the number 1 into checkpoint.txt. Later touching hitbox2 will save 2, etc.

Then when the player dies and the level restarts, at the beginning of the level you read checkpoint.txt and if it contains number 2, you spawn the player at empty2. If checkpoint.txt contains the number 3, you spawn the player at empty3, etc.

When you successfully finish a level, you should remember to write 0 to checkpoint.txt, since you are essentially beginning a new level now.