TD5 : Empire City

L’objectif de ce TD est de mettre en place la technique du scrolling qui va permettre de déplacer le décor du jeu à l’écran.

Introduction

Présentation

Nous étudierons le jeu de borne d’arcade Empire City, surnom de la ville de New-York. L’action se déroule durant la période de la prohibition. Le décor suit le déplacement du viseur du joueur et défile (scroll) ainsi verticalement et horizontalement ! Le jeu utilise tout l’écran pour afficher la surface de jeu, ce qui le rend particulièrement immersif pour l’époque. Ajouté à cela, un timing bien dosé mettant ainsi en place un gameplay assez addictif et le tour est joué pour un succès planétaire.

Empire City sur borne d'arcade

Test

Vous pouvez tester le jeu en réel sur cette page

  • Cliquez sur : Insert Coin

  • Activez le son

  • Appuyez sur 1 pour 1 player

  • Activez le plein écran

  • CTRL pour tirer / ALT pour esquiver

  • Flèches du clavier pour déplacer le viseur

Mise en place

Téléchargez le projet Empire City et ouvrez le.

Au lancement du programme, vous obtenez ceci :

../_images/demo.png

Le jeu ne réagit pas aux touches du clavier. Rien de particulier se passe à l’écran, le décor reste fixe.

Note

Nous avons mis en place une carte spécialement pour ce projet. Elle est largement inspirée du décor original en version réduite et se trouve dans le fichier map.png.

Notions clefs

Le décor et la zone d’affichage

../_images/exemple.png

Le décor complet du jeu a une résolution de 2000x686 pixels. En graphisme, nous rappelons que le l’axe des \(y\) est orienté de haut en bas. Par conséquent, le centre O du repère du décor se situe en haut à gauche.

Nous représentons par un cadre vert de 400x300 la zone d’affichage du jeu. Sa position est définie par le point E correspondant à son coin haut-gauche. De même, la position du sprite du bandit correspond au point S associé au coin haut-gauche du sprite.

Changement de repère

Dans la figure ci-dessous, le rectangle bleu correspond au décor du jeu (map.png). Le rectangle vert décrit la zone du jeu actuellement affichée à l’écran. Le rectangle rouge correspond au sprite du bandit, il est fixe dans le décor.

../_images/reperes.png

Nous avons trois points :

  • O : origine du repère du décor

  • E : origine du repère de la zone affichée à l’écran.

  • S : origine du sprite du bandit

Indépendamment du repère choisi, la relation suivante est toujours vraie :

\[\overrightarrow{OS} = \overrightarrow{OE} + \overrightarrow{ES}\]

Nous remarquons que le vecteur \(\overrightarrow{OE}\) correspond aux coordonnées du point \(E\) dans le repère du décor par définition. De la même manière, les coordonnées du point \(S\) dans le repère écran correspondent au vecteur \(\overrightarrow{ES}\). Ainsi, nous pouvons écrire la relation suivante : \(S_{décor} = E_{décor} + S_{écran}\) ce qui donne au final :

\[S_{écran} = S_{décor} – E_{décor}\]

Note

Nous pouvons donc choisir la méthode de travail suivante : toutes les coordonnées (bandit, viseur) seront exprimées dans le repère du décor. Nous pouvons effectuer tous nos calculs dans ce repère aussi. Cela est plus facile pour se repérer. Cependant, au moment de l’affichage, nous transposerons ces coordonnées vers le repère écran.

Test du viseur

Comment déterminer si notre joueur tire bien sur le bandit ou à côté ? Avant tout chose, nous supposons que nous disposons des informations suivantes exprimées dans le même repère :

  • V : les coordonnées du viseur

  • S : les coordonnées du sprite du bandit

Ainsi que :

  • L,H : la largeur/hauteur en pixels du sprite du bandit

../_images/viseur.png

Le test à effectuer se résume à :

\[S_x \le V_x \le S_x + L ~~~~ \text{et}~~~~ S_y \le V_y \le S_y + H\]

Afficher le décor

Pour extraire le fond et l’afficher à l’écran, nous utilisons le code suivant dans l’exemple fourni :

zone = pygame.Rect( 800, 300, screeenWidth, screenHeight )
screen.blit(fond,(0,0),area = zone)

Nous définissons d’abord une zone dans le repère du décor correspondant à un rectangle. Ensuite, on extrait la partie du décor correspondant à ce rectangle pour la coller dans la zone d’affichage grâce à la fonction screen.blit(…).

To-do List

  • Positionnez le point E de telle sorte que le bas de la cloche soit postionnée en haut à gauche de la zone d’affichage :

    • Ouvrez l’image map.png dans mspaint (clic droit sur le fichier puis choisir modifier)

    ../_images/cloche.png
    • Positionnez le curseur de la souris sur le bas de la cloche

    • Lisez les coordonnées en bas de la fenêtre de mspaint :

    • Postionnez ce point dans le coin haut gauche de l’affichage au démarrage :

    ../_images/result.png
  • Créez des variables pour stocker les coordonnées du point S dans le repère du décor

    • Initialisez ces valeurs pour que le jeu commence sur le devant de l’église

  • Affichez le viseur à l’écran

    • Chargez l’image du viseur dans un sprite

    • Créez les variables correspondantes pour stocker les coordonnées du point V

    • Initialisez V pour que le viseur se situe au milieu de la fenêtre de jeu

    • Dessinez le viseur à l’écran

    • Attention, pour que le sprite du viseur soit centré sur le point V, il faut le décaler de la moitié de sa largeur :

    ../_images/centrage.png
  • Gérez l’appui des touches clavier haut/bas/gauche/droite

    • Modifiez la position du viseur

    • A ce niveau, le décor ne bouge pas encore

  • Mise en place du scrolling

    • Nous allons définir dans la fenêtre de jeu une zone en orange dans laquelle le viseur évolue librement sans déclencher de scrolling

    • Si le centre du viseur doit entrer dans la zone bleue, alors on déclenche un scrolling en déplaçant le point E dans la même direction que le viseur. A noter que si V et E se déplace de la même manière, alors, le viseur reste fixe sur l’écran ! Seul le fond a bougé !

    • Vous choisirez la taille de la zone orange en testant différentes valeurs

    ../_images/zone.png
  • Le joueur peut maintenant scroller et sortir de la zone de la map

    • Lorsque le scrolling crée des valeurs erronées pour le point S, corrigez-les pour éviter tout problème !

  • Faîtes apparaître le premier bandit !

    • Choisissez un sprite parmi les fichiers disponibles

    • Dès le démarrage du jeu, sauvegardez la valeur de l’horloge dans une variable T0

    • int(pygame.time.get_ticks()/1000) retourne le temps en seconde

    • Trois secondes après le démarrage du jeu, faîtes apparaître le bandit sur le trottoir

    • Tirez sa position en x aléatoirement

    • La fonction random.random() retourne un numérique entre 0 et 1

    • Choisissez comme ordonnée une valeur qui le positionne sur le trottoir

  • Gérez le tir en détectant l’appui sur la barre espace

    • Si le tir est réussi, le méchant disparaît.

    • Faîtes réapparaître un nouveau méchant 3 secondes après la mort du précédent

    • Après chaque tir, faîtes dévier la position du viseur vers le haut pour un peu plus de réalisme

  • Aide au joueur

    • Lorsque le viseur est trop éloigné du méchant, faîtes apparaître les sprites flèche gauche ou droite pour aider le joueur à localiser le bandit

  • Gérez les bandits aux fenêtres

    • Repérez quatre coordonnées de fenêtres et choisissez un sprite « bandit_window »

    • Faîtes apparaître aléatoirement les bandits sur le trottoir ou à une fenêtre

    • Dans le cas du bandit placé à la fenêtre, choisissez au hasard une des quatre fenêtres présélectionnées