mirror of
https://forge.apps.education.fr/phroy/frankie-on-platform.git
synced 2024-01-27 11:32:04 +01:00
Animation de la réception + saut en arrière
This commit is contained in:
parent
1ea166549b
commit
5eb497a982
22
#README.md#
Normal file
22
#README.md#
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Frankie on Platform
|
||||||
|
|
||||||
|
Frankie on Platform est un mini-jeu de plateforme. Ce mini-jeu est une démontration / tutoriel pour la découverte du développement sous [**Blender/UPBGE**](https://upbge.org/) et [**Blender/Armory3d**](https://armory3d.org/).
|
||||||
|
|
||||||
|
La version Armory3d peut directement être jouée dans un navigayeur web (html5) : https://www.phroy.org/fop/
|
||||||
|
|
||||||
|
![capture d'écran](img/capture-01.png)
|
||||||
|
|
||||||
|
Ce mini-jeu est une déclinaison pour UPBGE et Armory3d du projet n°2 du livre ["Créez vos propres jeux 3D comme les pros" (Éditions Graziel)](https://graziel.com/fr/livres/8-creez-vos-propres-jeux-3d-comme-les-pros-avec-le-blender-game-engine-9791093846002.html) de Grégory Gossellin De Bénicourt.
|
||||||
|
|
||||||
|
Il a été inspiré du jeu open source [Yo Frankie !](https://apricot.blender.org) (Blender Institute) et du film d'animation [Big Buck Bunny](https://studio.blender.org/films/big-buck-bunny/) (Blender Institute).
|
||||||
|
|
||||||
|
### Téléchargement
|
||||||
|
|
||||||
|
Les binaires (Game Engine Runtime) sont hébergés sur [phroy.org](https://www.phroy.org/cloud/index.php/s/Qr68yptBeicSK4a).
|
||||||
|
|
||||||
|
### Développement
|
||||||
|
|
||||||
|
La version de Blender/UPBGE utilisée est la version 0.36 alpha du 29 avril 2023 : [UPBGE-0.36-Alpha-*-x86_64-2023-04-29](https://mega.nz/folder/k9MW1KiZ#UOKzjh3IQ0GEgjQ6GUc7ug/folder/YsshHCha).
|
||||||
|
|
||||||
|
Les fichiers sources sont hébergés sur la forge de l'AEIF : https://forge.aeif.fr/phroy/frankie-on-platform
|
||||||
|
|
BIN
fop-06.blend
BIN
fop-06.blend
Binary file not shown.
200
fop.py
200
fop.py
@ -37,6 +37,18 @@ snd_amb = [
|
|||||||
[aud.Sound('asset/sounds/amb_forest.wav'),9, False],
|
[aud.Sound('asset/sounds/amb_forest.wav'),9, False],
|
||||||
[aud.Sound('asset/sounds/amb_frog_1.wav'),4, True]]
|
[aud.Sound('asset/sounds/amb_frog_1.wav'),4, True]]
|
||||||
|
|
||||||
|
# Végétation : Modificateur (noeuds géométriques), avancement (spawn actif)
|
||||||
|
scatter=[
|
||||||
|
["Plateau 1 - Fleurs roses", [0, 1]],
|
||||||
|
["Plateau 1 - Champignons", [0, 1]],
|
||||||
|
["Plateau 2 - Fleurs rouges", [0, 1, 2, 3]],
|
||||||
|
["Plateau 3 - Champignons", [1, 2, 3,4,5]],
|
||||||
|
["Plateau 3 - Fleurs blanches", [1, 2, 3,4,5]],
|
||||||
|
["Plateau 4 - Fleurs violettes", [4, 5, 6]],
|
||||||
|
["Plateau 5 - Fleurs violettes", [5, 6]],
|
||||||
|
["Plateau 6 - Grandes fleurs 1", [6, 7, 8]],
|
||||||
|
["Plateau 6 - Grandes fleurs 2", [6, 7, 8]]]
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Mouvements
|
# Mouvements
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@ -95,7 +107,6 @@ def deplacement(cont):
|
|||||||
pas_angulaire = 0.05
|
pas_angulaire = 0.05
|
||||||
pas_angulaire_fps = 0.025
|
pas_angulaire_fps = 0.025
|
||||||
force_saut = 400
|
force_saut = 400
|
||||||
recul_camera = 40
|
|
||||||
idle=True
|
idle=True
|
||||||
|
|
||||||
# Avancer : Flèche haut - Up arrow
|
# Avancer : Flèche haut - Up arrow
|
||||||
@ -132,7 +143,7 @@ def deplacement(cont):
|
|||||||
obj['courrir']=False
|
obj['courrir']=False
|
||||||
|
|
||||||
# Reculer : Flèche bas - Down arrow
|
# Reculer : Flèche bas - Down arrow
|
||||||
if (keyboard.inputs[bge.events.DOWNARROWKEY].status[0] == ACTIVATE or joy_leftstick_y>0.5) and obj['saut']==False and obj['chute']==False:
|
if (keyboard.inputs[bge.events.DOWNARROWKEY].status[0] == ACTIVATE or joy_leftstick_y>0.5) and obj['chute']==False:
|
||||||
idle=False
|
idle=False
|
||||||
obj.applyMovement((0,pas_lineaire,0), True)
|
obj.applyMovement((0,pas_lineaire,0), True)
|
||||||
start, end, speed, layer = 1, 20, 2, 0
|
start, end, speed, layer = 1, 20, 2, 0
|
||||||
@ -168,20 +179,53 @@ def deplacement(cont):
|
|||||||
audiodev.play(snd_frankie_jump)
|
audiodev.play(snd_frankie_jump)
|
||||||
|
|
||||||
# Touche le sol -> plus de saut ni de chute
|
# Touche le sol -> plus de saut ni de chute
|
||||||
objs_sol=('Terrain', 'Platforme', 'Pont 1', 'Pont 2')
|
objs_sol=('Terrain', 'Plateforme', 'Pont 1', 'Pont 2')
|
||||||
for obj_sol in objs_sol:
|
for obj_sol in objs_sol:
|
||||||
if obj.collide(scene.objects[obj_sol])[0]:
|
if obj.collide(scene.objects[obj_sol])[0]:
|
||||||
if obj.collide(scene.objects[obj_sol])[1] is not None:
|
if obj.collide(scene.objects[obj_sol])[1] is not None:
|
||||||
if len(obj.collide(scene.objects[obj_sol])[1])>0:
|
if len(obj.collide(scene.objects[obj_sol])[1])>0:
|
||||||
if obj['saut']:
|
if obj['saut']:
|
||||||
obj['sol_tics']+=1
|
obj['sol_tics']+=1
|
||||||
if obj['sol_tics']>3: # 3 : nombre de tics sur le sol pour annuler le saut
|
if obj['sol_tics']>=3: # 3 : nombre de tics sur le sol pour annuler le saut
|
||||||
|
# Animation réception
|
||||||
|
if keyboard.inputs[bge.events.UPARROWKEY].status[0] == ACTIVATE or joy_leftstick_y<-0.5:
|
||||||
|
start, end, speed, layer = 1, 33, 2, 2
|
||||||
|
obj_rig.playAction('Frankie-courrir_stop', start, end, layer, 1, 1.0, PLAY, 0.0, 0, speed)
|
||||||
obj['saut']=False
|
obj['saut']=False
|
||||||
obj['sol_tics']=0
|
obj['sol_tics']=0
|
||||||
obj['chute_tics']=0
|
obj['chute_tics']=0
|
||||||
obj['chute']=False
|
obj['chute']=False
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# Plateforme (coller Frankie à la plateforme)
|
||||||
|
# obj_ray = obj.rayCast((0,0,1), dist=-1, prop='plateforme')
|
||||||
|
# print (obj_ray)
|
||||||
|
# if obj_ray[0] is not None:
|
||||||
|
# obj['plateforme'] = True
|
||||||
|
# obj.setParent(scene.objects['Plateforme'])
|
||||||
|
# else:
|
||||||
|
# if obj['plateforme']:
|
||||||
|
# obj.setParent(None)
|
||||||
|
# obj['plateforme'] = False
|
||||||
|
|
||||||
|
|
||||||
|
# if obj:
|
||||||
|
# # do something
|
||||||
|
# pass
|
||||||
|
# plateforme
|
||||||
|
# if obj['plateforme']==False:
|
||||||
|
# if obj.collide(scene.objects['Platforme'])[0]:
|
||||||
|
# if obj.collide(scene.objects[obj_sol])[1] is not None:
|
||||||
|
# if len(obj.collide(scene.objects[obj_sol])[1])>0:
|
||||||
|
# obj['plateforme'] = True
|
||||||
|
# obj.setParent(scene.objects['Plateforme'])
|
||||||
|
# else:
|
||||||
|
# if obj.collide(scene.objects['Platforme'])[0]:
|
||||||
|
# pass
|
||||||
|
# else:
|
||||||
|
# obj.setParent(None)
|
||||||
|
# obj['plateforme'] = False
|
||||||
|
|
||||||
# Chute
|
# Chute
|
||||||
if obj.worldPosition.z < obj['chute_z'] and obj['saut']==False:
|
if obj.worldPosition.z < obj['chute_z'] and obj['saut']==False:
|
||||||
obj['chute_tics']+=1
|
obj['chute_tics']+=1
|
||||||
@ -194,9 +238,68 @@ def deplacement(cont):
|
|||||||
|
|
||||||
# Attente
|
# Attente
|
||||||
if idle:
|
if idle:
|
||||||
|
# obj['saut'] = False
|
||||||
start, end, speed, layer = 1, 268, 2, 0
|
start, end, speed, layer = 1, 268, 2, 0
|
||||||
obj_rig.playAction('Frankie-attente', start, end, layer, 1, 1.0, LOOP, 0.0, 0, speed)
|
obj_rig.playAction('Frankie-attente', start, end, layer, 1, 1.0, LOOP, 0.0, 0, speed)
|
||||||
|
|
||||||
|
# Retour au dernier checkpoint
|
||||||
|
if keyboard.inputs[bge.events.RKEY].status[0] == ACTIVATE or 9 in joy_events :
|
||||||
|
obj_spawn = scene.objects['Spawn '+str(obj['spawn'])]
|
||||||
|
obj.worldPosition = obj_spawn.worldPosition
|
||||||
|
obj.applyRotation((0, 0, -obj.worldOrientation.to_euler().z+obj_spawn['sens']), False)
|
||||||
|
start, end, speed, layer = 1, 84, 2, 1
|
||||||
|
obj_rig.playAction('Frankie-respawn', start, end, layer, 1, 1.0, PLAY, 0.0, 0, speed)
|
||||||
|
obj['saut'] = False
|
||||||
|
obj['chute_tics'] = 0
|
||||||
|
obj['chute'] = False
|
||||||
|
obj['courrir_tics'] = 0
|
||||||
|
obj['courrir'] = False
|
||||||
|
|
||||||
|
# Saut sur les téléportes (mode debug) : avancer
|
||||||
|
if JUST_ACTIVATED in keyboard.inputs[bge.events.ZKEY].queue and obj['spawn_debug']<8 and obj['debugg']:
|
||||||
|
obj['spawn_debug'] +=1
|
||||||
|
obj['saut'] = False
|
||||||
|
obj['chute_tics'] = 0
|
||||||
|
obj['chute'] = False
|
||||||
|
obj['courrir_tics'] = 0
|
||||||
|
obj['courrir'] = False
|
||||||
|
obj_spawn = scene.objects['Spawn '+str(obj['spawn_debug'])]
|
||||||
|
obj.worldPosition = obj_spawn.worldPosition
|
||||||
|
obj.applyRotation((0, 0, -obj.worldOrientation.to_euler().z+obj_spawn['sens']), False)
|
||||||
|
|
||||||
|
# Saut sur les téléportes (mode debug) : reculer
|
||||||
|
if JUST_ACTIVATED in keyboard.inputs[bge.events.AKEY].queue and obj['spawn_debug']>0 and obj['debugg']:
|
||||||
|
obj['spawn_debug'] -=1
|
||||||
|
obj['saut'] = False
|
||||||
|
obj['chute_tics'] = 0
|
||||||
|
obj['chute'] = False
|
||||||
|
obj['courrir_tics'] = 0
|
||||||
|
obj['courrir'] = False
|
||||||
|
obj_spawn = scene.objects['Spawn '+str(obj['spawn_debug'])]
|
||||||
|
obj.worldPosition = obj_spawn.worldPosition
|
||||||
|
obj.applyRotation((0, 0, -obj.worldOrientation.to_euler().z+obj_spawn['sens']), False)
|
||||||
|
|
||||||
|
###
|
||||||
|
# Suivi par la caméra
|
||||||
|
###
|
||||||
|
|
||||||
|
def camera_track (cont):
|
||||||
|
obj = cont.owner
|
||||||
|
obj_cam = scene.objects['Camera']
|
||||||
|
obj.worldPosition = scene.objects['Frankie'].worldPosition
|
||||||
|
|
||||||
|
# Clavier
|
||||||
|
keyboard = bge.logic.keyboard
|
||||||
|
|
||||||
|
# Manette
|
||||||
|
joy_index = 0 #int from 0 to 6
|
||||||
|
joy = bge.logic.joysticks[joy_index]
|
||||||
|
if joy is not None :
|
||||||
|
joy_events = joy.activeButtons
|
||||||
|
else:
|
||||||
|
joy_events=[]
|
||||||
|
joy_leftstick_x, joy_leftstick_y, joy_rightstick_x, joy_rightstick_y = 0, 0, 0, 0
|
||||||
|
|
||||||
# Caméra FPS
|
# Caméra FPS
|
||||||
if JUST_ACTIVATED in keyboard.inputs[bge.events.FKEY].queue :
|
if JUST_ACTIVATED in keyboard.inputs[bge.events.FKEY].queue :
|
||||||
if obj_cam['fps_mode']==0:
|
if obj_cam['fps_mode']==0:
|
||||||
@ -229,6 +332,7 @@ def deplacement(cont):
|
|||||||
time.sleep(0.15) # Change trop rapidement
|
time.sleep(0.15) # Change trop rapidement
|
||||||
|
|
||||||
# Recul caméra
|
# Recul caméra
|
||||||
|
recul_camera = 40
|
||||||
if (keyboard.inputs[bge.events.EKEY].status[0] == ACTIVATE or 10 in joy_events) and obj_cam['macro']==False:
|
if (keyboard.inputs[bge.events.EKEY].status[0] == ACTIVATE or 10 in joy_events) and obj_cam['macro']==False:
|
||||||
obj_cam.applyMovement((0,0,recul_camera), True)
|
obj_cam.applyMovement((0,0,recul_camera), True)
|
||||||
obj_cam['macro'] = True
|
obj_cam['macro'] = True
|
||||||
@ -236,49 +340,7 @@ def deplacement(cont):
|
|||||||
obj_cam.applyMovement((0,0,-recul_camera), True)
|
obj_cam.applyMovement((0,0,-recul_camera), True)
|
||||||
obj_cam['macro'] = False
|
obj_cam['macro'] = False
|
||||||
|
|
||||||
# Retour au dernier checkpoint
|
|
||||||
if keyboard.inputs[bge.events.RKEY].status[0] == ACTIVATE or 9 in joy_events :
|
|
||||||
obj_spawn = scene.objects['Spawn '+str(obj['spawn'])]
|
|
||||||
obj.worldPosition = obj_spawn.worldPosition
|
|
||||||
obj.applyRotation((0, 0, -obj.worldOrientation.to_euler().z+obj_spawn['sens']), False)
|
|
||||||
start, end, speed, layer = 1, 84, 2, 1
|
|
||||||
obj_rig.playAction('Frankie-respawn', start, end, layer, 1, 1.0, PLAY, 0.0, 0, speed)
|
|
||||||
obj['saut'] = False
|
|
||||||
obj['chute_tics'] = 0
|
|
||||||
obj['chute'] = False
|
|
||||||
obj['courrir_tics'] = 0
|
|
||||||
obj['courrir'] = False
|
|
||||||
|
|
||||||
# Saut sur les téléportes (mode debug) : avancer
|
|
||||||
if JUST_ACTIVATED in keyboard.inputs[bge.events.ZKEY].queue and obj['spawn']<8 and obj['debugg']:
|
|
||||||
obj['spawn'] +=1
|
|
||||||
obj['saut'] = False
|
|
||||||
obj['chute_tics'] = 0
|
|
||||||
obj['chute'] = False
|
|
||||||
obj['courrir_tics'] = 0
|
|
||||||
obj['courrir'] = False
|
|
||||||
obj_spawn = scene.objects['Spawn '+str(obj['spawn'])]
|
|
||||||
obj.worldPosition = obj_spawn.worldPosition
|
|
||||||
obj.applyRotation((0, 0, -obj.worldOrientation.to_euler().z+obj_spawn['sens']), False)
|
|
||||||
|
|
||||||
# Saut sur les téléportes (mode debug) : reculer
|
|
||||||
if JUST_ACTIVATED in keyboard.inputs[bge.events.AKEY].queue and obj['spawn']>0 and obj['debugg']:
|
|
||||||
obj['spawn'] -=1
|
|
||||||
obj['saut'] = False
|
|
||||||
obj['chute_tics'] = 0
|
|
||||||
obj['chute'] = False
|
|
||||||
obj['courrir_tics'] = 0
|
|
||||||
obj['courrir'] = False
|
|
||||||
obj_spawn = scene.objects['Spawn '+str(obj['spawn'])]
|
|
||||||
obj.worldPosition = obj_spawn.worldPosition
|
|
||||||
obj.applyRotation((0, 0, -obj.worldOrientation.to_euler().z+obj_spawn['sens']), False)
|
|
||||||
|
|
||||||
###
|
|
||||||
# Suivi par la caméra
|
|
||||||
###
|
|
||||||
|
|
||||||
def camera_track (cont):
|
|
||||||
cont.owner.worldPosition = scene.objects['Frankie'].worldPosition
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Cycle
|
# Cycle
|
||||||
@ -290,6 +352,7 @@ def camera_track (cont):
|
|||||||
|
|
||||||
def init(cont):
|
def init(cont):
|
||||||
obj = cont.owner
|
obj = cont.owner
|
||||||
|
obj_frankie = scene.objects['Frankie']
|
||||||
|
|
||||||
# Init EEVEE
|
# Init EEVEE
|
||||||
eevee.use_taa_reprojection = True
|
eevee.use_taa_reprojection = True
|
||||||
@ -308,21 +371,27 @@ def init(cont):
|
|||||||
scene.active_camera = scene.objects["Camera_depart"]
|
scene.active_camera = scene.objects["Camera_depart"]
|
||||||
|
|
||||||
# Mode debug
|
# Mode debug
|
||||||
scene.objects['Frankie']['debugg']=True # 'debug' est réservé
|
obj_frankie['debugg']=True # 'debug' est réservé
|
||||||
|
|
||||||
# Init de Frankie
|
# Init de Frankie
|
||||||
scene.objects['Frankie']['chute_z'] = scene.objects['Frankie'].worldPosition.z
|
obj_frankie['chute_z'] = scene.objects['Frankie'].worldPosition.z
|
||||||
scene.objects['Frankie']['spawn']=0
|
obj_frankie['spawn']=0
|
||||||
|
obj_frankie['spawn_debug']=0
|
||||||
|
|
||||||
|
# Afficher la végétation (noeuds géométriques)
|
||||||
|
for i in range(len (scatter)):
|
||||||
|
if obj_frankie['spawn'] in scatter[i][1]:
|
||||||
|
bpy.data.objects["Terrain"].modifiers[scatter[i][0]].show_viewport = True
|
||||||
|
else:
|
||||||
|
bpy.data.objects["Terrain"].modifiers[scatter[i][0]].show_viewport = False
|
||||||
|
|
||||||
# Cacher les pancartes
|
# Cacher les pancartes
|
||||||
for i in range (1, 7):
|
for i in range (1, 7):
|
||||||
scene.objects['Pancarte '+str(i)].setVisible(False,True)
|
scene.objects['Pancarte '+str(i)].setVisible(False,True)
|
||||||
|
|
||||||
# Afficher la végétation -> noeuds géométriques
|
|
||||||
|
|
||||||
# Mise en route de la plateforme
|
# Mise en route de la plateforme
|
||||||
start, end, speed, layer = 1, 200, 0.5, 0
|
start, end, speed, layer = 1, 200, 0.5, 0
|
||||||
scene.objects['Platforme'].playAction('Platforme-action', start, end, layer, 1, 1.0, LOOP, 0.0, 0, speed)
|
scene.objects['Plateforme'].playAction('Plateforme-action', start, end, layer, 1, 1.0, LOOP, 0.0, 0, speed)
|
||||||
|
|
||||||
###
|
###
|
||||||
# Chute
|
# Chute
|
||||||
@ -351,10 +420,20 @@ def checkpoint(cont):
|
|||||||
obj = cont.owner
|
obj = cont.owner
|
||||||
obj_i=int(obj.name[6:-7])
|
obj_i=int(obj.name[6:-7])
|
||||||
obj_frankie = scene.objects['Frankie']
|
obj_frankie = scene.objects['Frankie']
|
||||||
|
|
||||||
|
# Spawn
|
||||||
if obj_i > obj_frankie['spawn']:
|
if obj_i > obj_frankie['spawn']:
|
||||||
obj_frankie['spawn']=obj_i
|
obj_frankie['spawn'] = obj_i
|
||||||
|
obj_frankie['spawn_debug'] = obj_i
|
||||||
scene.objects['Pancarte '+str(obj_i)].setVisible(True,True)
|
scene.objects['Pancarte '+str(obj_i)].setVisible(True,True)
|
||||||
|
|
||||||
|
# Végétation (noeuds géométriques)
|
||||||
|
for i in range(len (scatter)):
|
||||||
|
if obj_frankie['spawn'] in scatter[i][1]:
|
||||||
|
bpy.data.objects["Terrain"].modifiers[scatter[i][0]].show_viewport = True
|
||||||
|
else:
|
||||||
|
bpy.data.objects["Terrain"].modifiers[scatter[i][0]].show_viewport = False
|
||||||
|
|
||||||
###
|
###
|
||||||
# Ressort
|
# Ressort
|
||||||
###
|
###
|
||||||
@ -370,6 +449,21 @@ def ressort(cont):
|
|||||||
obj_ressort.playAction(obj_ressort.name+'-action', start, end, layer, 1, 1.0, PLAY, 0.0, 0, speed)
|
obj_ressort.playAction(obj_ressort.name+'-action', start, end, layer, 1, 1.0, PLAY, 0.0, 0, speed)
|
||||||
obj_frankie.applyForce((0, 0,force_saut), True)
|
obj_frankie.applyForce((0, 0,force_saut), True)
|
||||||
|
|
||||||
|
###
|
||||||
|
# Plateforme
|
||||||
|
###
|
||||||
|
|
||||||
|
def plateforme(cont):
|
||||||
|
obj = cont.owner
|
||||||
|
sensor = obj.sensors['Ray']
|
||||||
|
print ("plateforme sensor.positive :", sensor.positive)
|
||||||
|
if sensor.positive:
|
||||||
|
obj['plateforme'] = True
|
||||||
|
obj.setParent(scene.objects['Plateforme'])
|
||||||
|
else:
|
||||||
|
obj['plateforme'] = False
|
||||||
|
obj.removeParent()
|
||||||
|
|
||||||
###
|
###
|
||||||
# Ambiance sonore
|
# Ambiance sonore
|
||||||
###
|
###
|
||||||
|
Loading…
Reference in New Issue
Block a user