Bienvenue dans le quatrième tutoriel de notre série sur la création d'un jeu de course à partir de zéro avec le SDK Corona. Dans cette section, nous allons ajouter la gravité, la détection de collision et la possibilité de passer au sprite. Allons-y!
J'espère que les tutoriels ont été utiles et faciles à suivre jusqu'à présent. Comme toujours, si vous avez des questions, n'hésitez pas à laisser un commentaire! La dernière fois, nous avons expliqué comment créer de jolis sprites à partir de spritesheets. Aujourd'hui, nous allons utiliser ce que nous avons appris dans le dernier tutoriel et intégrer ce monstre de sprite à notre jeu actuel. Une fois entré, nous apprendrons à le contrôler et à rendre notre jeu interactif. Pour ce faire, je vais utiliser le code source fourni dans le didacticiel sur les mouvements en arrière-plan et ajouter en premier notre contenu d'animation monstre. Si vous téléchargez les fichiers du didacticiel, vous remarquerez qu'il existe 2 dossiers, appelés "ancien" et "nouveau". Ancien contient tous les fichiers du didacticiel d’application en arrière-plan dont vous avez besoin pour commencer à travailler sur ce didacticiel. Nouveau contient tout le code et tout ce que vous aurez une fois ce didacticiel terminé. Allez-y, téléchargez les fichiers et ouvrez le fichier main.lua à partir de l'ancien dossier. Je vais diviser tout ce que nous faisons en trois sections. Le premier concerne l’organisation de notre jeu, sur lequel nous allons apporter quelques modifications. La seconde couvrira ce que nous avons appris dans le tutoriel d’utilisation des sprites et sa mise en œuvre ici. Nous allons parcourir cette section assez rapidement car les détails de ce qui se passe ont déjà été couverts. La troisième section donnera à notre petit bonhomme la gravité, la détection de collision et la possibilité de sauter!
Jusqu'à présent, nous plaçons nos images dans le code dans l'ordre dans lequel nous voulons qu'elles apparaissent à l'écran. Plus tôt ils seront appelés, plus ils apparaîtront dans les couches à l'écran. Cela fonctionne, mais il existe un meilleur moyen de le faire. Il ne sera pas toujours réaliste de placer chaque image dans l'ordre exact dans lequel vous souhaitez qu'elle apparaisse, et vous voudrez peut-être, à un moment donné, changer l'ordre d'affichage des objets à l'écran. Donc, ouvrez le fichier main.lua de l'ancien dossier et nous allons commencer à faire des changements.
La première chose que nous allons faire est d’ajouter la ligne suivante en haut de la page juste en dessous de display.setStatusBar ligne.
sprite local = require ("sprite")
Ensuite, ajoutez les deux lignes suivantes juste en dessous de l'endroit où nous avons créé le groupe d'affichage des blocs:
lecteur local = display.newGroup () écran local = display.newGroup ()
Le joueur du groupe d’affichage sera le groupe d’affichage qui contient notre sprite héroïque et le groupe d’écrans sera un groupe d’affichage qui contient tout le reste. Mettons un peu plus de code dans et ensuite je finirai d'expliquer.
Insérez le code suivant sous la boucle for où nous instancions nos blocs au sol:
--créer notre feuille de sprite spriteSheet local = sprite.newSpriteSheet ("monsterSpriteSheet.png", 100, 100) monsterSet local = sprite.newSpriteSet (spriteSheet, 1, 7) sprite.add (monsterSet, "en cours d'exécution", 1, 6, 600, 0) sprite.add (monsterSet, "jumping", 7, 7, 1, 1) - définit les différentes variables que nous allons utiliser pour notre sprite de monstre - définit également et démarre la première animation pour le monstre monstre local = sprite. newSprite (monsterSet) monstre: prépare ("en cours d'exécution") monstre: play () monstre.x = 110 monstre.y = 200 - ces 2 variables contrôlent la chute et le saut du monstre monstre.gravity = -6 monstre .accel = 0 - le rectangle utilisé pour notre détection de collision - il sera toujours devant le sprite de monstre - de cette manière, nous savons si le monstre a touché quelque chose de local collisionRect = display.newRect (monster.x + 36, monster .y, 1, 70) collisionRect.strokeWidth = 1 collisionRect: setFillColor (140, 140, 140) collisionRect: setStrokeColor (180, 180, 180) collisionRect.alpha = 0 - utilisé pour tout mettre en place. g sur l'écran dans le groupe d'écran - cela nous permettra de changer l'ordre dans lequel les sprites apparaissent sur - l'écran si nous le voulons. Plus tôt il est placé dans le groupe - plus loin, il retournera écran: insérer écran (arrière-plan) écran: insérer (arrière-plan) écran: insérer (backgroundnear1) écran: insérer (backgroundnear2) écran: insérer (blocs) écran: insérer ( monstre) écran: insérer (collisionRect)
Maintenant, passons en revue cet énorme bloc de code.
Nous allons sauter les deux premières sections. Ces sections créent simplement notre image-objet monstre à partir de notre feuille d’image-objet. Si vous avez des questions sur ce qui se passe là-bas, passez rapidement en revue le dernier tutoriel où nous avons abordé la création d’images-objets à partir de feuilles d’images-objets. Dans la section suivante, j'ai créé une forme de rectangle de base appelée collisionRect. Voici comment nous allons détecter les collisions afin que notre monstre puisse interagir avec le monde. En réalité, nous créons un carré invisible devant notre monstre. Si vous rendez le rectangle visible (c’est-à-dire, changez simplement l’alpha en 100), vous verrez qu’il se trouve juste devant le monstre et flotte un peu au-dessus du sol..
La raison pour laquelle nous faisons cela est que cela nous donnera un système de collision facile à gérer. Parce que nous faisons un jeu de course sans fin, nous nous intéressons principalement à ce qui se passe juste devant le monstre (normalement, ce qui vient derrière lui ne le tuera pas). De plus, nous le soulevons un peu du sol pour que la boîte ne se heurte jamais au sol sous le monstre, seulement les objets se trouvant devant lui. Le monstre lui-même va gérer les collisions avec le sol, nous avons juste besoin de quelque chose pour gérer les collisions avec des objets extérieurs qui pourraient le frapper à l'avant. Cela aura encore plus de sens dans les deux prochains tutoriels, car nous ajoutons des choses pour que monstre se heurte à.
La section suivante est l'endroit où nous insérons tout dans l'écran. L’écran n’est donc qu’un groupe d’affichage. Il n’ya rien de magique. Cependant, en faisant cela, cela nous donne un avantage énorme sur la façon dont nous affichons les choses auparavant, et c’est ainsi que nous contrôlons la manière dont les choses sont ordonnées. Maintenant, peu importe le moment où nous avons créé les sprites, ils apparaîtront maintenant dans l'ordre où nous les avons placés dans le groupe d'affichage écran. Donc, si nous décidions que le monstre passe derrière les objets backgroundNear, il nous suffirait simplement de les insérer dans le groupe d'écran après avoir inséré le monstre..
Ensuite, modifiez votre fonction update () pour ressembler à celle-ci:
fonction locale mise à jour (événement) updateBackgrounds () updateSpeed () updateMonster () updateBlocks () checkCollisions () end
Cela appellera le reste des fonctions que nous devons exécuter pour nous assurer que tout est bien mis à jour. Une chose à noter lorsque vous utilisez votre fonction de mise à jour est que l’ordre est important. Pour notre petit jeu de course à pied, l'ordre n'a pas d'importance car il est appelé trente fois par seconde, ainsi tout ce qui est mis à jour sera pris très rapidement. De plus, il n’existe aucune donnée cruciale qui puisse ruiner les fonctions les unes des autres. Toutefois, vous devrez parfois faire attention à l'ordre dans lequel vous placez les choses. Cela est particulièrement vrai lorsque vous avez plusieurs fonctions qui mettent à jour les mêmes variables de différentes manières. Habituellement, c’est bien une question de bon sens et vous serez en mesure de passer logiquement à travers lequel les choses doivent être traitées en premier..
Voici le reste des fonctions qui effectueront le travail que nous venons d'appeler à partir de la fonction de mise à jour. Placez-les sous la fonction de mise à jour. Assurez-vous de lire les commentaires, car je les utiliserai pour décrire ce qui se passe..
function checkCollisions () wasOnGround = onGround - vérifie si le collisionRect est entré en collision avec quoi que ce soit. C'est pourquoi il est soulevé du sol - un peu, si cela touche le sol, cela signifie que nous avons heurté un mur. Nous vérifions cela en parcourant - toutes les pièces du groupe de blocs et en comparant leurs coordonnées x et y à celles de la collisionRect pour a = 1, blocks.numChildren, 1 do if (collisionRect.y - 10> blocks [ a] .y - 170 et les blocs [a] .x - 40 < collisionRect.x and blocks[a].x + 40 > collisionRect.x) alors speed = 0 end end - c’est là que nous vérifions si le monstre est au sol ou dans les airs, s’il est dans les airs, il ne peut pas sauter (désolé, pas de double saut) pour notre petit monstre, cependant, si vous voulez qu'il puisse faire un double saut comme Mario, il vous suffira simplement - de faire un petit ajustement ici, en ajoutant une deuxième variable appelée quelque chose comme hasJumped. Réglez-la à false normalement, et tournez-le sur - vrai une fois le double saut effectué. Ainsi, il est limité à 2 sauts par saut. - Encore une fois, nous parcourons le groupe de blocs et comparons les valeurs x et y de chacun. pour a = 1, blocs .numChildren, 1 do if (monster.y> = blocs [a] .y - 170 et blocs [a] .x < monster.x + 60 and blocks[a].x > monster.x - 60) then monster.y = bloc [a] .y - 171 onGround = vrai break else onGround = false fin fin fonction updateMonster () --si notre monstre saute, passez à l'animation sautante --si ne continue pas à jouer à l'animation en cours si (surGround), alors - si nous sommes déjà sur le terrain, nous n'avons pas besoin de préparer quoi que ce soit de nouveau si (wasOnGround), puis bien monster: prepare ("en cours d'exécution) monster: play () end else monstre: prépare ("jumping") monstre: play () fin si (monster.accel> 0) puis monster.accel = monster.accel - 1 fin --update la position du monstre accel est utilisée pour nos sauts et --gravity le monstre qui descend. Vous pouvez jouer avec ces 2 variables - pour faire beaucoup de combinaisons de jeu intéressantes comme les situations de "gravité réduite" monster.y = monster.y - monster.accel monster.y = monster.y - monster.gravity - mettre à jour la collisionRect rester devant le monstre collisionRect.y = monster.y end - c'est la fonction qui gère les événements de saut. Si vous touchez l’écran du côté gauche, puis activez la fonction de saut de monstre (événement) si (event.phase == "commencé"), puis si (event.x < 241) then if(onGround) then monster.accel = monster.accel + 20 end end end end
Notez que la fonction touchée n'est jamais appelée. Au bas du code juste en dessous de l'endroit où vous utilisez le minuteur qui appelle la fonction de mise à jour, mettez ce code:
Durée: addEventListener ("touch", touché, -1)
Passons en revue quelques éléments du code que nous venons d'insérer. La fonction touchée passe dans un événement. Chaque "événement" a ses propres propriétés. Quand on dit event.phase == "a commencé" nous disons à Corona que nous souhaitons être informés dès que l'utilisateur touche l'écran. Au contraire, si nous avions dit "terminé" au lieu de commencer, nous dirions à Corona de ne pas nous avertir avant que l'utilisateur ne lève son doigt de l'écran. Les coordonnées du toucher sont également stockées dans l'événement. C’est pourquoi il est important d’utiliser début et fin. Voulez-vous connaître l'emplacement du moment où l'utilisateur touche l'écran pour la première fois ou du moment où il le lâche? Dans la plupart des situations de jeu, vous souhaitez savoir dès que l'utilisateur touche l'écran, mais pas toujours. Pour une référence complète des événements tactiles, cliquez ici (https://developer.anscamobile.com/reference/index/events/touch)..
Ainsi, lorsque vous exécuterez ceci, vous remarquerez que vous ne sautez que si vous touchez le côté gauche de l'écran. La raison pour laquelle nous le faisons est que nous voulons réserver le côté droit de l'écran pour d'autres tâches, telles que le tir de boules de feu. Cela n’entre pas dans le cadre de ce projet, mais nous y arriverons assez tôt! Avec tout cela, nous devrions être prêts à partir.
Avec tout à sa place, vous devriez maintenant avoir un monstre qui peut courir et sauter par terre! Lentement, notre petit tutoriel commence à ressembler à un jeu! Comme toujours, si vous avez des questions, faites-le moi savoir dans la section commentaires ci-dessous et merci de suivre!