Tuto 3 : des acteurs multiples

Un jeu comporte souvent des sprites du même type, comme par exemple les bombes larguées par un vaisseau, les pièces récoltées par un personnage, etc...

Un seul acteur en plus

Voila un script inspiré du précédent, qui permet maintenant de déclencher et animer un tir à partir de la position du vaisseau lorsque le joueur appuie sur la barre d'espace.

Tuto 3

Un tir est caractérisé par ses coordonnées. Les coordonnées initiales du tir sont déterminées à partir de celles du vaisseau, sachant que ces coordonnées correspondent au coin en haut à gauche.
On déplace ensuite le tir jusqu’à ce qu’il sorte de l’écran.


import pyxel

pyxel.init(128, 128, title="Super Jeu")

###############################
# FONCTIONS GÉRANT LE VAISSEAU #
###############################

def bouge_vaisseau():

    global vaisseau_x, vaisseau_y, tir_x, tir_y, tire # la variable 'tire' sert à savoir si le tir a déjà été déclenché

    if pyxel.btn(pyxel.KEY_RIGHT): 
        if (vaisseau_x < 120) :
            vaisseau_x = vaisseau_x + 1
    if pyxel.btn(pyxel.KEY_LEFT):
        if (vaisseau_x > 0) :
            vaisseau_x = vaisseau_x - 1
    if pyxel.btn(pyxel.KEY_DOWN):
        if (vaisseau_y < 120) :
            vaisseau_y = vaisseau_y + 1
    if pyxel.btn(pyxel.KEY_UP):
        if (vaisseau_y > 0) :
            vaisseau_y = vaisseau_y - 1

    if pyxel.btnr(pyxel.KEY_SPACE) and tire == False:   # si la touche "ESPACE" a été appuyée, et que le tir n'a pas déjà été déclenché :
        tire = True                                     # alors on déclenche le tir,
        tir_x = vaisseau_x + 4                          # en lui donnant comme coordonnées initiales
        tir_y = vaisseau_y - 2                          # celles du milieu du vaisseau.

def affiche_vaisseau():

    # vaisseau (carre 8x8)
    pyxel.rect(vaisseau_x, vaisseau_y, 8, 8, 1)

###########################
# FONCTIONS GÉRANT LE TIR #
###########################

def bouge_tir():

    global tir_y, tire

    if tire == True:            # si le tir a été déclenché :
        if tir_y>0:             # si il n'a pas atteint le haut de l'écran,
            tir_y = tir_y - 2   # alors on le déplace,
        else:
            tire = False        # sinon on "l'efface"

def affiche_tir():

    global tire
    
    if tire == True:
        pyxel.rect(tir_x, tir_y, 1, 4, 10)

##################
# GESTION DU JEU #
##################

def update():

    bouge_vaisseau()
    bouge_tir()

def draw():

    pyxel.cls(0)

    affiche_vaisseau()
    affiche_tir()

########################
#  PROGRAMME PRINCIPAL #
########################

# position initiale du vaisseau
# (origine des positions : coin haut gauche)
vaisseau_x = 60
vaisseau_y = 60

tire = False

# Lancement du jeu
pyxel.run(update, draw)
			

Le problème est qu'un seul tir n'est possible à la fois : comment faire en sorte que plusieurs tirs se déplacent dans la fenêtre en même temps ?

Modifier le script pour qu'au moins un deuxième autre tir puisse être créé alors que le premier a déjà été déclenché.

Une solution : les listes

Impossible de gérer toutes ces variables...

Une solution possible va être alors d'utiliser une liste de listes Python liste_tirs pour gérer un nombre quelconque de tirs simultanés :


import pyxel

pyxel.init(128, 128, title="Super Jeu")

###############################
# FONCTIONS GÉRANT LE VAISSEAU #
###############################

def bouge_vaisseau():

    global vaisseau_x, vaisseau_y

    if pyxel.btn(pyxel.KEY_RIGHT):
        if (vaisseau_x < 120) :
            vaisseau_x = vaisseau_x + 1
    if pyxel.btn(pyxel.KEY_LEFT):
        if (vaisseau_x > 0) :
            vaisseau_x = vaisseau_x - 1
    if pyxel.btn(pyxel.KEY_DOWN):
        if (vaisseau_y < 120) :
            vaisseau_y = vaisseau_y + 1
    if pyxel.btn(pyxel.KEY_UP):
        if (vaisseau_y > 0) :
            vaisseau_y = vaisseau_y - 1

    if pyxel.btnr(pyxel.KEY_SPACE):                             # si la touche "ESPACE" a été appuyée :
        liste_tirs.append([vaisseau_x + 4, vaisseau_y - 2])     # on ajoute à la liste 'liste_tirs' un nouveau tir


def affiche_vaisseau():

    # vaisseau (carre 8x8)
    pyxel.rect(vaisseau_x, vaisseau_y, 8, 8, 1)

###########################
# FONCTIONS GÉRANT LE TIR #
###########################

def bouge_tir(tir):
    ''' tir = liste de deux éléments.
    tir[0] = x
    tir[1] = y
    '''

    if tir[1]>0:                # si il n'a pas atteint le haut de l'écran,
        tir[1] = tir[1] - 2     # alors on le déplace,
    else:
        liste_tirs.remove(tir)  # sinon on le supprime de la liste

def affiche_tir(tir):

    pyxel.rect(tir[0], tir[1], 1, 4, 10)

##################
# GESTION DU JEU #
##################

def update():

    bouge_vaisseau()

    for tir in liste_tirs:
        bouge_tir(tir)

def draw():

    pyxel.cls(0)

    affiche_vaisseau()

    for tir in liste_tirs:
        affiche_tir(tir)

########################
#  PROGRAMME PRINCIPAL #
########################

# position initiale du vaisseau
# (origine des positions : coin haut gauche)
vaisseau_x = 60
vaisseau_y = 60

liste_ tirs = [] # liste des tirs

# Lancement du jeu
pyxel.run(update, draw)
			

On rappelle qu'une liste Python est un objet mutable, qu'il n'est donc pas nécessaire de passer comme argument aux fonctions; on évite du coup le recours à de nombreuses variables globales !

A faire soi-même

A l'aide du même mécanisme, gérer le largage simultané par le vaisseau de bombes ( circulaires ) vers le bas de l'écran.

Suivant