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?
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
here is a working example - check_point01_TEST.blend (599 KB) - of course, this files is a free extended help on BGE
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.
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
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.
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.
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.