Introduction

L’objectif de cette activité est de se préparer au concours la Nuit Du Code :

  • prendre connaissance de ses modalités ;
  • s’initier au moteur de jeux “rétros” Pyxel.

Un autre objectif est de développer son autonomie, compétence essentielle, et sa capacité à apprendre de nouvelles technologies.

Le concours

Première partie - le concours

Étudier les modalités du concours  :

  • sa présentation générale, les six catégories, l’évolution du nombre de participants, les univers…
  • le cahier des charges et les règles,
  • les critères d’évaluation du concours,
  • exemples de réalisation (recenser et catégoriser les jeux essayés).

Préparer une synthèse, par exemple sous forme de résumé ou de carte mentale.

Au diadème, les consignes sont de constituer des binômes.

Deuxième partie - Pyxel

Pour pouvoir participer au concours, il faut au préalable se former à la bibliothèque Pyxel. Comme pour toute technologie, il faut pour cela être motivé pour l’étudier : par exemple avoir un projet de création de jeu vidéo (ou simplement vouloir gagner le concours). Les stratégies d’apprentissages dépendent ensuite de chacun ; par exemple :

Les compétences à maîtriser sont :

  • afficher du texte, une forme géométrique ou une image ;
  • déplacer des objets graphiques ;
  • gérer les interactions (clavier, souris) ;
  • gérer les collisions ;
  • jouer une musique de fond, émettre des sons.

Pyxel comprend un éditeur de ressources (graphismes et audio) ; noter qu’il peut être utilisé, mais de façon limitée (en cours du moins) — les compétences artistiques sortant du domaine des compétences de la formation.

Mise en place de l’environnement de développement

Un environnement de développement web existe : Studio Pyxel. La consigne est de ne pas l’utiliser : un des objectifs pédagogiques étant de développer sa compétence à configurer son environnement de développement — compétence essencielle pour un développeur.

Pyxel est une bibliothèque additionnelle de Python, qu’il faut installer. C’est une bonne pratique de le faire de manière isolée (pour ne pas interférer avec le système ou d’autres applications), dans un environnement “virtuel" : c’est un dossier dans lequel une copie du SDK Python est installée :

python3 -m venv pyxel-venv      #créé l'environnement (une seule fois)
source pyxel-venv/bin/activate  #à faire à chaque session
pip3 install pyxel              #installe Pyxel (une seule fois)

Premier pas

Créer un fichier premier_pas.py avec un contenu du type :

import pyxel

def update():
    pass

def draw():
    pyxel.cls(0)
    pyxel.text(10, 10, "Premier pas", 5)

if __name__ == "__main__":
    pyxel.init(320, 240, title="Premier pas")
    pyxel.run(update, draw)

Lancer le programme avec la commande pyxel run premier_pas.py.

Premiers pas (programmation orientée objets)

from __future__ import annotations
import pyxel
from typing import List

class Sprite:
    def __init__(self, game: Game, x: int, y: int, width: int, height: int):
        self.game: Game = game
        self.x : int = x
        self.y : int = y
        self.width : int = width
        self.height : int = height
        self.speedX : int = 0
        self.speedY : int = 0

    def update(self):
        # Déplace le sprite en fonction de sa vitesse.
        self.x += self.speedX
        self.y += self.speedY

    def draw(self):
        # Dessine le sprite sous la forme d'un rectangle blanc (à redéfinir).
        pyxel.rect(self.x, self.y, self.width, self.height, 7)

    def collide(self, other: Sprite) -> bool:
        # Indique si le sprite est en collision avec l'autre sprite
        # @param other le sprite avec lequel on vérifie la collision
        # @return True s'il y a collision, False sinon
        return  self.x < (other.x + other.width) and (self.x + self.width) > other.x and \
                self.y < (other.y + other.height) and (self.y + self.height) > other.y

    def destroy(self):
        # Supprime le sprite de la liste des sprites du jeu.
        self.game.sprites.remove(self)


class Game:
    def __init__(self, width: int, height: int, title: str):
        self.width = width
        self.height = height
        self.sprites = []
        pyxel.init(width, height, title=title, fps=60)
        self.sprites.append(Sprite(self, 0, 0, 4, 4))

    def run(self):
        pyxel.run(self.update, self.draw)

    def update(self):
        for sprite in self.sprites.copy(): #copie superficielle (liste modifiée lors du parcours)
            sprite.update()

    def draw(self):
        pyxel.cls(0)
        for sprite in self.sprites:
            sprite.draw()

if __name__ == "__main__":
    Game(320, 240, "Classes de base").run()

Conseil: créer des sous-classes de Sprite et de Game.