import bge # Bibliothèque Blender Game Engine (UPBGE) import bpy # Blender import math, time, random import aud # Sounds ############################################################################### # fop.py # @title: module principale du jeu Frankie on Platform # @project: Frankie on Platform # @lang: fr # @authors: Philippe Roy # @copyright: Copyright (C) 2023 Philippe Roy # @license: GNU GPL ############################################################################### # Scène scene = bge.logic.getCurrentScene() eevee = bpy.context.scene.eevee audiodev = aud.Device() # print("Objets de la scène : ", scene.objects) # Lister les objets de la scène # Constantes UPBGE JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED ACTIVATE = bge.logic.KX_INPUT_ACTIVE PLAY = bge.logic.KX_ACTION_MODE_PLAY LOOP = bge.logic.KX_ACTION_MODE_LOOP # Sons d'action snd_frankie_jump = aud.Sound('asset/sounds/frankie_jump.wav') # Sons d'ambiance : fichier son , temps (en s) entre chaque impulsion, activation aléatoire à 50% lors de l'impulsion (oui/non) snd_amb = [ [aud.Sound('asset/sounds/amb_bird_1.wav'),10, True], [aud.Sound('asset/sounds/amb_bird_2.wav'),25, True], [aud.Sound('asset/sounds/amb_cricket_1.wav'),2, True], [aud.Sound('asset/sounds/amb_forest.wav'),9, False], [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 ############################################################################### ### # Flèches pour avancer, reculer et tourner ### def deplacement(cont): obj = cont.owner obj_rig = scene.objects['Frankie-rig'] obj_cam = scene.objects['Camera'] # 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 joy_axis = joy.axisValues[0:4] joy_leftstick_x = joy_axis[0] joy_leftstick_y = joy_axis[1] joy_rightstick_x = joy_axis[2] joy_rightstick_y = joy_axis[3] else: joy_events=[] joy_leftstick_x, joy_leftstick_y, joy_rightstick_x, joy_rightstick_y = 0, 0, 0, 0 # Evènements de la manette # print ("leftstick : ", joy_leftstick_x , joy_leftstick_y) # print ("rightstick : ", joy_rightstick_x , joy_rightstick_y) # if joy_events: # print(joy_events) # Panneau de départ (Intro) if obj_cam['intro']: if keyboard.inputs[bge.events.UPARROWKEY].status[0] == ACTIVATE: obj_cam['intro'] = False if keyboard.inputs[bge.events.DOWNARROWKEY].status[0] == ACTIVATE: obj_cam['intro'] = False if keyboard.inputs[bge.events.LEFTARROWKEY].status[0] == ACTIVATE: obj_cam['intro'] = False if keyboard.inputs[bge.events.RIGHTARROWKEY].status[0] == ACTIVATE: obj_cam['intro'] = False if joy_leftstick_y<-0.5 or joy_leftstick_y>0.5 or joy_leftstick_x<-0.5 or joy_leftstick_x>0.5 : obj_cam['intro'] = False if obj_cam['intro'] == False: scene.active_camera = scene.objects["Camera"] return # Paramètres de mouvement pas_lineaire = 0.1 pas_courrir = 0.2 pas_angulaire = 0.05 pas_angulaire_fps = 0.025 force_saut = 400 idle=True # Avancer : Flèche haut - Up arrow if (keyboard.inputs[bge.events.UPARROWKEY].status[0] == ACTIVATE or joy_leftstick_y<-0.5) and obj['chute']==False: idle=False # Planer if obj['saut']: obj.applyMovement((0,-pas_lineaire,0), True) start, end, speed, layer = 1, 13, 2, 0 obj_rig.playAction('Frankie-planer', start, end, 0, 1, 1.0, PLAY, 0.0, 0, speed) obj['courrir_tics']=0 obj['courrir']=False else: # Avancer normalement if obj['courrir_tics']<40: # 40 : nombre de tics pour courrir obj.applyMovement((0,-pas_lineaire,0), True) obj['courrir_tics']+=1 start, end, speed, layer = 1, 18, 2, 0 obj_rig.playAction('Frankie-avancer', start, end, 0, 1, 1.0, PLAY, 0.0, 0, speed) # Courrir else: obj.applyMovement((0,-pas_courrir,0), True) obj['courrir']=True start, end, speed, layer = 1, 18, 2, 0 obj_rig.playAction('Frankie-courrir', start, end, layer, 1, 1.0, PLAY, 0.0, 0, speed) # Arrêt de la course if (keyboard.inputs[bge.events.UPARROWKEY].status[0] != ACTIVATE and joy_leftstick_y>-0.5) and obj['courrir_tics']>0: # Arrêt de la course obj['courrir_tics']=0 obj['courrir']=False # Reculer : Flèche bas - Down arrow if (keyboard.inputs[bge.events.DOWNARROWKEY].status[0] == ACTIVATE or joy_leftstick_y>0.5) and obj['chute']==False: idle=False obj.applyMovement((0,pas_lineaire,0), True) start, end, speed, layer = 1, 20, 2, 0 obj_rig.playAction('Frankie-reculer', start, end, layer, 1, 1.0, PLAY, 0.0, 0, speed) # Tourner gauche : Flèche gauche - Left arrow if (keyboard.inputs[bge.events.LEFTARROWKEY].status[0] == ACTIVATE or joy_leftstick_x<-0.5) and obj['chute']==False: idle=False if obj_cam['fps_mode']==0: obj.applyRotation((0, 0,pas_angulaire), True) else: obj.applyRotation((0, 0,pas_angulaire_fps), True) start, end, speed, layer = 1, 12, 2, 0 obj_rig.playAction('Frankie-gauche', start, end, 0, 1, 1.0, PLAY, 0.0, 0, speed) # Tourner droite : Flèche droit - Right arrow if (keyboard.inputs[bge.events.RIGHTARROWKEY].status[0] == ACTIVATE or joy_leftstick_x>0.5) and obj['chute']==False: idle=False if obj_cam['fps_mode']==0: obj.applyRotation((0, 0,-pas_angulaire), True) else: obj.applyRotation((0, 0,-pas_angulaire_fps), True) start, end, speed, layer = 1, 12, 2, 0 obj_rig.playAction('Frankie-droite', start, end, layer, 1, 1.0, PLAY, 0.0, 0, speed) # Saut if (keyboard.inputs[bge.events.SPACEKEY].status[0] == ACTIVATE or 3 in joy_events) and obj['chute']==False and obj['saut']==False: idle=False obj['saut']=True obj.applyForce((0, 0,force_saut), True) start, end, speed, layer = 1, 34, 2, 1 obj_rig.playAction('Frankie-sauter', start, end, layer, 1, 1.0, PLAY, 0.0, 0, speed) audiodev.play(snd_frankie_jump) # Touche le sol -> plus de saut ni de chute objs_sol=('Terrain', 'Plateforme', 'Pont 1', 'Pont 2') for obj_sol in objs_sol: if obj.collide(scene.objects[obj_sol])[0]: if obj.collide(scene.objects[obj_sol])[1] is not None: if len(obj.collide(scene.objects[obj_sol])[1])>0: if obj['saut']: obj['sol_tics']+=1 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['sol_tics']=0 obj['chute_tics']=0 obj['chute']=False 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 if obj.worldPosition.z < obj['chute_z'] and obj['saut']==False: obj['chute_tics']+=1 obj['chute_z'] = obj.worldPosition.z if obj['chute_tics']>30: # 30 : nombre de tics pour déclarer la chute idle=False obj['chute']=True start, end, speed, layer = 1, 33, 2, 0 obj_rig.playAction('Frankie-tomber', start, end, layer, 1, 1.0, LOOP, 0.0, 0, speed) # Attente if idle: # obj['saut'] = False start, end, speed, layer = 1, 268, 2, 0 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 if JUST_ACTIVATED in keyboard.inputs[bge.events.FKEY].queue : if obj_cam['fps_mode']==0: obj_cam['fps_mode'] = 1 scene.active_camera = scene.objects["Camera_fps"] elif obj_cam['fps_mode']==1: obj_cam['fps_mode'] = 2 scene.active_camera = scene.objects["Camera_fps2"] else: obj_cam['fps_mode'] = 0 scene.active_camera = scene.objects["Camera"] if 0 in joy_events: if obj_cam['fps_mode']==0 or obj_cam['fps_mode']==2: obj_cam['fps_mode'] = 1 scene.active_camera = scene.objects["Camera_fps"] time.sleep(0.15) # Change trop rapidement else: obj_cam['fps_mode'] = 0 scene.active_camera = scene.objects["Camera"] time.sleep(0.15) # Change trop rapidement if 1 in joy_events: if obj_cam['fps_mode']==0 or obj_cam['fps_mode']==1: obj_cam['fps_mode'] = 2 scene.active_camera = scene.objects["Camera_fps2"] time.sleep(0.15) # Change trop rapidement else: obj_cam['fps_mode'] = 0 scene.active_camera = scene.objects["Camera"] time.sleep(0.15) # Change trop rapidement # 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: obj_cam.applyMovement((0,0,recul_camera), True) obj_cam['macro'] = True if (keyboard.inputs[bge.events.EKEY].status[0] != ACTIVATE and 10 not in joy_events) and obj_cam['macro']==True: obj_cam.applyMovement((0,0,-recul_camera), True) obj_cam['macro'] = False ############################################################################### # Cycle ############################################################################### ### # Initialisation de la scène ### def init(cont): obj = cont.owner obj_frankie = scene.objects['Frankie'] # Init EEVEE eevee.use_taa_reprojection = True eevee.use_ssr = True # Screen space reflection eevee.use_ssr_refraction = True # Screen space refractions eevee.use_ssr_halfres = True eevee.use_gtao = False eevee.taa_render_samples = 64 eevee.taa_samples = 16 eevee.use_volumetric_lights = True eevee.use_volumetric_shadows = False eevee.shadow_cascade_size='1024' eevee.shadow_cube_size='512' # Intro scene.active_camera = scene.objects["Camera_depart"] # Mode debug obj_frankie['debugg']=True # 'debug' est réservé # Init de Frankie obj_frankie['chute_z'] = scene.objects['Frankie'].worldPosition.z 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 for i in range (1, 7): scene.objects['Pancarte '+str(i)].setVisible(False,True) # Mise en route de la plateforme start, end, speed, layer = 1, 200, 0.5, 0 scene.objects['Plateforme'].playAction('Plateforme-action', start, end, layer, 1, 1.0, LOOP, 0.0, 0, speed) ### # Chute ### def chute(cont): obj = cont.owner obj_rig = scene.objects['Frankie-rig'] if obj.worldPosition.z<=-10 : 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 ### # Checkpoint ### def checkpoint(cont): obj = cont.owner obj_i=int(obj.name[6:-7]) obj_frankie = scene.objects['Frankie'] # Spawn if obj_i > obj_frankie['spawn']: obj_frankie['spawn'] = obj_i obj_frankie['spawn_debug'] = obj_i 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 ### def ressort(cont): obj = cont.owner sensor = obj.sensors['Collision'] force_saut = 1000 obj_ressort=scene.objects[obj.name[:-7]] obj_frankie = scene.objects['Frankie'] if sensor.positive: start, end, speed, layer = 1, 16, 0.5, 0 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) ### # 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 ### def snd_amb_play(cont): obj = cont.owner if obj['snd_amb']: for snd in snd_amb: if round(obj['snd_amb_timer'] % snd[1], 2) <= 0.02 : if snd[2]: if random.randint(0,1)==1: audiodev.play(snd[0]) else: audiodev.play(snd[0])