Développer un homebrew sur PSP
Le LUA
Exemple en LUA
Pour cet exemple nous aurons besoin des images suivantes :
- Un fond :
- Un sol :
- 7 images d'un personnage :
pour le déplacement vers la droite
pour le déplacement vers la gauche
pour la position arrêt (on utilisera un effet miroir pour le tourner dans l'autre sens).
Chargement des images
1 -- Chargement des images 2 luigi_stand = Image.load("img/luigi-stand.png") 3 luigi_run1 = Image.load("img/luigi-run1.png") 4 luigi_run2 = Image.load("img/luigi-run2.png") 5 luigi_run3 = Image.load("img/luigi-run3.png") 6 sol = Image.load("img/ground.png") 7 fond = Image.load("img/background.png") 8 9 luigi_run1_left = Image.load("img/luigi-run1-left.png") 10 luigi_run2_left = Image.load("img/luigi-run2-left.png") 11 luigi_run3_left = Image.load("img/luigi-run3-left.png") 12
On commence ici par charger les images dont nous aurons besoin. Les images étant relativement légère, nous pouvons toutes les charger immédiatement.
Structure du joueur
13 -- Structure du personnage 14 15 joueur = { 16 x = 200; -- c'est la position en X de départ 17 y = 188; -- c'est la position en Y de départ 18 marche = 0; -- utile pour l'animation 19 img = luigi_stand; -- c'est l'image de départ du joueur 20 } 21 22 23 joueur.gravity = 188 24 joueur.jumpspeed = 10 25 joueur.jumpstate = "au sol" 26
On définit une structure qui renseignera des propriétés du personnage.
- "joueur.marche" nous servira à animer notre personnage.
- "joueur.jumpspeed" nous servira à rendre les sauts plus réaliste (vitesse décroissante au début du saut, vitesse croissante dans la chute).
- "joueur.jumpstate" nous servira à définir l'état du personnage (en train de sauter ou non).
Début de la boucle principale
27 -- Initialement tourné vers la droit 28 statut = "droite" 29 30 -- Boucle principale 31 while true do 32 screen:clear() -- on nettoie l'écran 33 pad = Controls.read() -- on écoute la pression sur les touches 34 35
A chaque tour de boucle, on va vider l'écran (ligne 32) puis on va écouter la pression sur les touches (ligne 33) et la mémoriser dans la variable pad.
Deux cas de figures se présentent, soit le personnage est tourné vers la droite, soit il est tourné vers la gauche. Commençons par le côté droit.
Le saut
36 if statut == "droite" then 37 38 -- saut 39 if pad:cross() and joueur.jumpstate == "au sol" then joueur.jumpstate = "en saut" end 40
Si la touche "croix" est pressée, on souhaite effectuer un saut. Pour cela on regarde le statut de saut actuel du personnage et on vérifie qu'il est bien au sol. Si tel est le cas, on change son statut par "en saut".
41 -- si on saute alors on diminue la vitesse de saut (+ réaliste) 42 if joueur.jumpstate == "en saut" then 43 joueur.jumpspeed = joueur.jumpspeed - 0.5 44 joueur.gravity = joueur.gravity - joueur.jumpspeed 45 end 46 47 if joueur.gravity < 0 then 48 joueur.jumpstate = "retombe" 49 end 50
Si notre personnage est bien en train de sauter, on diminue doucement sa vitesse de saut (ligne 43) et on décremente sa valeur "gravity" de la vitesse de saut (ligne 44). Cela aura pour effet de ralentir la montée du personnage, comme s'il subissait une attraction vers le bas.
Si a un moment la valeur "gravity" passe sous 0, alors notre personnage va commencer sa chute. On change donc son état de saut.
51 -- si gravite < 188 et qu'il retombe, on accélère la chute (+ réaliste) 52 if joueur.gravity < 188 and joueur.jumpstate == "retombe" then 53 joueur.gravity = joueur.gravity + (joueur.jumpspeed + 3) 54 end 55 56 -- gravite a 188 (niveau du sol) 57 if joueur.gravity == 188 then 58 joueur.jumpspeed = 10 59 joueur.jumpstate = "au sol" 60 end 61 62 -- on s'assure de ne pas dépasser le niveau du sol 63 if joueur.gravity > 188 then joueur.gravity = 188 end 64 65 -- position du personnage en y = niveau gravité 66 joueur.y = joueur.gravity 67 --fin saut 68
On continue ensuite en faisant l'inverse par rapport à précédemment. On augmente la vitesse de chute puis on regarde si le joueur atteint le sol (ligne 57). Si tel est le cas on réinitialise sa vitesse de saut et son état de saut. Cependant, comme on n'est pas sûre de nous arrêter à la valeur juste, on vérifie que la "gravity" ne dépasse pas la valeur maximale, si oui on la repositonne à sa valeur initiale. Enfin on positionne le joueur à la hauteur qu'il faut (ligne 66).
Le déplacement
69 -- appui touche droite 70 if pad:right() then 71 joueur.x = joueur.x + 3 72 joueur.marche = joueur.marche+3 73 end 74 75 -- appui touche gauche 76 if pad:left() then statut = "gauche" end 77
On est parti de l'hypothèse que notre personnage était tourné vers la droite. Dans ce cas, si la touche "droite" est pressée, on va augmenter la position "x" de notre personnage. On incrémentera également la valeur "marche". Si c'est la touche "gauche" qui est pressée, on traitera le cas plus tard mais on positionne le statut de notre personnage.
78 -- gestion de l'animation de marche 79 if joueur.marche>=0 and joueur.marche <=5 then joueur.img = luigi_run1 end 80 if joueur.marche>=5 and joueur.marche <=10 then joueur.img = luigi_run2 end 81 if joueur.marche>=10 and joueur.marche <=15 then joueur.img = luigi_run3 end 82 if joueur.marche>15 then joueur.marche = 0 end 83 84
C'est ici que nous utiliserons la variable "marche". Nous avons trois images pour faire marcher notre personnage. On va donc fixer des seuils à partir desquels l'image de notre personnage changera. En ayant incrémenter "marche" à chaque pas en avant, la valeur passera le premier seuil, puis le deuxième et enfin le troisième. Au-delà on réinitialise "marche" pour recommencer l'animation.
85 -- positionnement des images 86 screen:blit(0,0,fond) 87 screen:blit(0,220,sol) 88 screen:blit(joueur.x, joueur.y,joueur.img) 89 90 -- rafraichissement 91 screen.waitVblankStart() 92 screen.flip() 93 94 end -- fin si statut droite 95 96
On positionne toutes les images (le fond, le sol et notre personnage) puis on rafraichit l'affichage. Enfin, on termine la condition selon laquelle notre personnage est tourné vers la droite.
Et maintenant ?
On refait exactement la même mais pour le côté gauche.
97 if statut=="gauche" then 98 99 -- saut 100 if pad:cross() and joueur.jumpstate == "au sol" then joueur.jumpstate = "en saut" end 101 102 -- si on saute alors on diminue la vitesse de saut (+ réaliste) 103 if joueur.jumpstate == "en saut" then 104 joueur.jumpspeed = joueur.jumpspeed - 0.5 105 joueur.gravity = joueur.gravity - joueur.jumpspeed 106 end 107 108 if joueur.gravity < 0 then 109 joueur.jumpstate = "retombe" 110 end 111 112 -- si gravité < 188 et qu'il retombe, on accélère la chute (+ réaliste) 113 if joueur.gravity < 188 and joueur.jumpstate == "retombe" then 114 joueur.gravity = joueur.gravity + (joueur.jumpspeed + 3) 115 end 116 117 -- gravité a 188 (niveau du sol) 118 if joueur.gravity == 188 then 119 joueur.jumpspeed = 10 120 joueur.jumpstate = "au sol" 121 end 122 123 -- on s'assure de ne pas dépasser le niveau du sol 124 if joueur.gravity > 188 then joueur.gravity = 188 end 125 126 -- position du personnage en y = niveau gravite 127 joueur.y = joueur.gravity 128 --fin saut 129 130 -- appui touche gauche 131 if pad:left() then 132 joueur.x = joueur.x - 3 133 joueur.marche = joueur.marche+3 134 end 135 136 -- appui touche droite 137 if pad:right() then statut = "droite" end 138 139 -- gestion de l'animation de marche 140 if joueur.marche>=0 and joueur.marche <=5 then joueur.img = luigi_run1_left end 141 if joueur.marche>=5 and joueur.marche <=10 then joueur.img = luigi_run2_left end 142 if joueur.marche>=10 and joueur.marche <=15 then joueur.img = luigi_run3_left end 143 if joueur.marche >15 then joueur.marche = 0 end 144 145 146 147 -- positionnement des images 148 screen:blit(0,0,fond) 149 screen:blit(0,220,sol) 150 screen:blit(joueur.x, joueur.y,joueur.img) 151 152 screen.waitVblankStart() 153 screen.flip() 154 end -- fin si statut gauche 155 156 end
Résultat
Nous avons donc notre Luigi qui peut se déplacer de droite à gauche et sauter dans un décor simple. Le script peut être chargé et exécuter avec un LUAPlayer.