introduction
Dans ce didacticiel, vous apprenez à créer, Highway Dodge, un jeu simple mais addictif. Highway Dodge est facile à prendre en main et à jouer, mais il offre la qualité addictive d’autres jeux populaires de l’App Store.
Highway Dodge commence par placer le joueur dans une voiture de course sur l’autoroute. Pendant le jeu, le joueur doit éviter le trafic venant en sens inverse sur l’autoroute en tapant sur l’une des trois voies disponibles. Pour chaque voiture esquivée, le joueur reçoit un point et la partie est terminée pour le joueur lorsqu’une voiture venant en sens inverse heurte la voiture de course. Au fil du temps, les voitures venant en sens inverse sortent de plus en plus vite pour offrir un véritable défi au joueur.
Exigences
Ce jeu est construit en utilisant Lua et le SDK Corona. Au minimum, vous devez avoir un compte avec Corona Labs et le SDK Corona installé. Vous pouvez récupérer gratuitement le SDK Corona sur le Site Web de Corona Labs. Pour ce tutoriel, j’ai utilisé build 2015.2731 du SDK Corona.
1. Configurer Highway Dodge
Allons-y et commençons Highway Dodge en créant un modèle vierge. Ouvrez le Simulateur Corona et choisissez Nouveau projet du Fichier menu. Une fois que vous avez le Créer un nouveau projet fenêtre ouverte, entrez Highway Dodge comme nom du projet, choisissez un modèle vierge et définissez la largeur sur 400 et la hauteur à 600. Laissez l’orientation par défaut définie sur Droit.


Après avoir mis en place votre projet, télécharger les images pour Highway Dodge. Créez un nouveau dossier dans votre nouveau projet, nommez-le images et ajoutez les images à ce dossier. Votre projet devrait maintenant ressembler à ceci:


2. Paramètres du projet
Une fois le projet mis en place, examinons rapidement deux fichiers importants, build.settings et config.lua.
build.settings
Ce fichier gère les propriétés de temps de construction du jeu. Il stocke des informations sur l’orientation de votre application, les informations sur les icônes, les paramètres iOS et les paramètres Android. La configuration par défaut est adéquate pour notre jeu.
config.lua
Ce fichier de configuration contrôle les propriétés d’exécution du jeu. Ceci comprend width
, height
, scale
, fps
(images par seconde), et
imageSuffix
. La propriété que nous devons examiner est imageSuffix
. le imageSuffix
La propriété est utilisée pour la sélection d’image dynamique. En un mot, il indique à l’application d’utiliser une image de résolution plus élevée sur un appareil de résolution plus élevée.
J’ai fourni des images haute résolution dans le dossier images, nous devons donc mettre à jour config.lua en conséquence. Tes projets config.lua Le fichier doit ressembler à celui ci-dessous. J’ai omis la section de notification push, qui est commentée.
application = { content = { width = 400, height = 600, scale = "letterBox", fps = 30, imageSuffix = { ["@2x"] = 2, }, }, }
3. Point de lancement
Une fois le projet et la sélection d’image dynamique configurés, passons à main.lua. Ce fichier est le point de lancement de chaque application créée avec le SDK Corona. Dans notre jeu, il contiendra trois lignes de code.
Étape 1
La première ligne masque la barre d’état sur les appareils iOS. Ouvert main.lua et ajoutez la ligne suivante après le commentaire -- Your code here
.
display.setStatusBar( display.HiddenStatusBar )
Étape 2
Ensuite, nous commençons à utiliser composer en exigeant la bibliothèque dans notre jeu. Nous faisons cela en ajoutant la ligne suivante:
local composer = require( "composer" )
Étape 3
Ensuite, nous utilisons composer pour passer à la scène du menu. Nous déplaçons des scènes en appelant la fonction composer.gotoScene()
, en passant la valeur
"scene_menu"
comme paramètre. La valeur "scene_menu"
est le nom de la scène et le nom du fichier que nous créons dans la section suivante.
composer.gotoScene("scene_menu")
Un mot sur Composer
Composer est la bibliothèque officielle de gestion de scène de Corona. Composer permet aux développeurs de créer facilement une scène et d’effectuer une transition entre les scènes. En deux lignes, j’ai pu passer de la scène principale à la scène du menu. Si vous souhaitez en savoir plus sur Composer, visitez Corona’s Guide de la bibliothèque du compositeur
disponible sur le Site Web de Corona Labs Docs.
4. Menu
La scène du menu de notre jeu ne comprendra que quelques éléments. La scène contiendra un graphique d’arrière-plan, un titre et un bouton de démarrage. Nous utiliserons la bibliothèque de widgets intégrée de Corona pour créer le bouton de démarrage. La bibliothèque de widgets nous permet de créer rapidement et facilement des éléments d’interface utilisateur communs. Dans notre jeu, nous l’utiliserons uniquement pour la création de boutons.
Étape 1
Dans le dossier projet de Highway Dodge, créez un nouveau fichier, scene_menu.luaet ouvrez-le dans l’éditeur de texte de votre choix. Au lieu de partir de zéro, nous allons utiliser le modèle de scène disponible sur le site Web de Corona Labs Docs. Avec leur modèle, nous pourrons avancer beaucoup plus rapidement. Dirigez-vous vers Docs de Corona Labs
et copiez / collez le modèle de scène dans scene_menu.lua.
Étape 2
Ajoutez la bibliothèque de widgets à notre jeu en ajoutant la ligne suivante, juste en dessous de la bibliothèque du compositeur.
local widget = require( "widget" )
Étape 3
Nous ajoutons notre arrière-plan en utilisant les graphiques que vous avez téléchargés précédemment. L’arrière-plan doit être positionné au centre de l’écran. dans le scene:create()
fonction et après le screenGroup
variable est déclarée, ajoutez le code suivant:
local background = display.newImageRect(sceneGroup, "images/background.png", 475, 713) background.x = display.contentCenterX background.y = display.contentCenterY
Étape 4
Ensuite, nous devons ajouter les trois voies qui représentent l’autoroute. Nous faisons cela en utilisant une table pour tenir les voies et en créant un for
boucle qui s’exécute trois fois. Placez cet extrait après le graphique d’arrière-plan:
local lanes = {} for i=1,3 do lanes[i] = display.newImageRect(sceneGroup, "images/lane.png", 79, 713) lanes[i].x = (display.contentCenterX - 79*2) + (i*80) lanes[i].y = display.contentCenterY end
Pour m’assurer que les voies sont toujours centrées, j’ai placé les voies sur l’axe des x en utilisant un peu de maths. Cela garantit que les voies restent centrées, quel que soit l’appareil sur lequel le jeu fonctionne.
Étape 5
Nous ajoutons également notre logo pour Highway Dodge en plaçant un objet image près du haut de l’écran.
local logo = display.newImageRect(sceneGroup, "images/logo.png", 300, 150) logo.x = display.contentCenterX logo.y = 75
Étape 6
Avant de pouvoir ajouter notre widget bouton, nous devons créer une fonction qui répond lorsque le bouton est touché. Nous nommerons la fonction handleButtonEvent()
et déplacez le joueur vers la scène du jeu en utilisant composer.gotoScene()
. Nous ne répondrons que lorsque le joueur aura levé le doigt du bouton ou ended
phase de l’événement.
local function handleButtonEvent( event ) if ( "ended" == event.phase ) then composer.gotoScene("scene_game", "slideLeft") end end
Étape 7
Avec la fonction ajoutée, nous pouvons ajouter le bouton. Nous créons le bouton en utilisant widget.newButton
et en lui transmettant quelques valeurs. Nous spécifions la largeur et la hauteur du bouton, les fichiers image du bouton, le texte à afficher, le type de police, la taille de police et la couleur de la police.
Nous indiquons également à Corona quelle fonction appeler lorsque vous appuyez sur le bouton et le positionnons au milieu de l’écran. Les fichiers source de ce didacticiel incluent des commentaires qui expliquent chacune des valeurs utilisées pour configurer le bouton.
local btn_startPlaying = widget.newButton { width = 220, height = 100, defaultFile = "images/btn-blank.png", overFile = "images/btn-blank-over.png", label = "Start Playing", font = system.defaultFontBold, fontSize = 32, labelColor = { default={ 0, 0, 0 }, over={ 0, 0, 0, 0.5 } }, onEvent = handleButtonEvent } btn_startPlaying.x = display.contentCenterX btn_startPlaying.y = display.contentCenterY sceneGroup:insert(btn_startPlaying)
Étape 8
Pour terminer la scène du menu, nous devons supprimer la scène du jeu à sa sortie. Lorsque Corona se déplace entre les scènes, il ne supprime pas toujours la scène précédente. Sans ces lignes, le jeu sera toujours dans une scène de jeu après avoir été joué une fois.
Pour supprimer la scène précédente, nous obtenons le nom de la scène et appelons composer.removeScene()
pour le supprimer s’il existe. Ajoutez le code suivant au scene:show()
fonction.
local prevScene = composer.getSceneName( "previous" ) if(prevScene) then composer.removeScene(prevScene) end
5. Créer la scène de jeu
Nous pouvons maintenant commencer à travailler sur la scène du jeu. Nous utiliserons le même flux de travail que celui utilisé pour créer la scène de menu. Créez un nouveau fichier, scene_game.lua, et copiez / collez le modèle de scène disponible sur Docs de Corona Labs. Une fois le code en place, ouvrez scene_game.lua dans votre éditeur de texte préféré.
Étape 1
Pour nous faciliter le codage de la scène du jeu, nous allons utiliser la bibliothèque de widgets et la bibliothèque de physique. Ce dernier est utilisé pour la détection de collision. Ajoutez le code suivant à scene_game.lua:
local widget = require( "widget" ) local physics = require("physics") physics.start() physics.setGravity(0,0)
Sur les première et deuxième lignes, nous avons respectivement besoin de la bibliothèque de widgets et de la bibliothèque de physique. Nous commençons alors la physique et désactivons la gravité. Nous n’avons pas besoin de la gravité pour notre jeu sur l’autoroute, nous utiliserons plutôt
transition.to()
pour déplacer les voitures.
Étape 2
dans le scene:create()
fonction, nous déclarons un certain nombre de variables que nous utiliserons dans le jeu. Ces variables seront responsables de la voiture du joueur, des voies, des voitures ennemies et du score du joueur. Pour faciliter la lecture, j’ai ajouté quelques commentaires.
-- "scene:create()" function scene:create( event ) local lanes = {} -- create a table called lanes local playerCar -- a variable for the player car local laneID = 1 -- a variable for the land id local enemyCars = {} -- a table to hold the enemy cars local enemyCounter = 1 -- start the enemy counter at 1 to keep track of the enemy cars local sendEnemyFrequency = 2500 -- defines how often to send enemy cars in milliseconds local tmrToSendCars -- a variable to hold a reference to the timer of sending cars local playerScore = 0 -- start the player score at 0 local playerScoreText -- an object to hold the score text object end
Étape 3
Sous les déclarations de variables, nous configurons les fonctions du jeu. Nous implémenterons chaque fonction dans une étape ultérieure. Ajoutez le code suivant après les déclarations de variable dans le scene:create()
fonction.
local function incrementScore() end local function moveCar(event) end local function sendEnemyCar() end local function onPlayAgainTouch() end local function onGlobalCollision(event) end
Étape 4
Après les fonctions, nous ajoutons le fond et les voies. Pour les voies, nous attachons un écouteur d’événement à chaque voie pour les faire réagir aux événements tactiles. Lorsqu’il est touché, l’auditeur appelle le moveCar()
fonction.
local background = display.newImageRect(sceneGroup, "images/background.png", 475, 713) background.x = display.contentCenterX background.y = display.contentCenterY for i=1,3 do lanes[i] = display.newImageRect(sceneGroup, "images/lane.png", 79, 713) lanes[i].x = (display.contentCenterX - 79*2) + (i*80) lanes[i].y = display.contentCenterY lanes[i].id = i lanes[i]:addEventListener("touch", moveCar) end
Étape 5
Avec l’arrière-plan et les voies configurés, il est temps de créer un objet texte pour contenir le score du joueur et créer la voiture du joueur. Le score sera en haut de l’écran et la voiture du joueur sera positionnée sur la voie la plus à gauche. De plus, nous ferons de la voiture du joueur un objet physique dynamique.
playerScoreText = display.newText(sceneGroup, "Score: "..playerScore, 0, 0, native.systemFont, 36) playerScoreText.x = display.contentCenterX playerScoreText.y = 25 playerCar = display.newImageRect(sceneGroup, "images/playerCar.png", 50, 100) playerCar.anchorY = 1 playerCar.x = lanes[1].x playerCar.y = display.contentHeight physics.addBody(playerCar) playerCar.bodyType = "dynamic"
Étape 6
Ensuite, nous définissons une minuterie pour envoyer une voiture en fonction de la valeur du sendEnemyFrequency
variable et créez un écouteur d’événement d’exécution pour les collisions globales.
tmrToSendCars = timer.performWithDelay(sendEnemyFrequency, sendEnemyCar, 0) Runtime:addEventListener( "collision", onGlobalCollision)
6. Ajout de fonctionnalités de jeu
Nous pouvons enfin ajouter des fonctionnalités à notre jeu. Cette section ajoutera du code supplémentaire à chaque fonction que nous avons déclarée dans la section précédente. Nous allons commencer avec incrementScore()
et terminer par onGlobalCollision()
.
incrementScore()
Cette fonction est appelée lorsqu’une voiture ennemie passe devant le joueur et que la transition est terminée. Lorsqu’il est appelé, le score du joueur est augmenté de 1. Ajoutez l’implémentation suivante au incrementScore()
fonction.
-- This function will increment the player score by 1. This function is called when the transition for the enemy car is complete and is off screen. local function incrementScore() playerScore = playerScore + 1 playerScoreText.text = "Score: "..playerScore end
moveCar()
le moveCar()
La fonction est appelée lorsqu’une voie est touchée. Sur le ended
phase de l’événement, nous saisissons l’identifiant de voie et déplaçons la voiture sur la bonne voie. Nous retournons true
à la fin pour indiquer un événement tactile réussi. Ajoutez l’implémentation suivante au moveCar()
fonction.
-- moveCar will respond to the touch event on the lanes local function moveCar(event) if(event.phase == "ended") then laneID = event.target.id -- grab the lane id which will be 1, 2, or 3 transition.to(playerCar, {x=lanes[laneID].x,time=50}) -- move the player car to the appropriate lane return true -- to indicate a successful touch event, return true end end
sendEnemyCar()
le sendEnemyCar()
crée une voiture ennemie, assigne la voiture à une voie, attache un corps physique à la voiture et utilise transition.to()
pour envoyer la voiture vers le bas de l’écran. Pour commencer, créons l’objet voiture ennemie.
enemyCars[enemyCounter] = display.newImageRect(sceneGroup, "images/enemyCar"..math.random(1,3)..".png", 50, 100)
Ensuite, nous définissons l’emplacement x et y de la voiture ennemie. Nous créons également un if-then
déclaration pour assigner la voiture ennemie à la même voie que la voiture du joueur dans 50% du temps. Cela obligera le joueur à se déplacer plus souvent et rendra le jeu plus amusant.
enemyCars[enemyCounter].x = lanes[math.random(1,#lanes)].x -- place the car on a random lane if(math.random(1,2) == 1) then enemyCars[enemyCounter].x = lanes[laneID].x; end -- 50% of the time, place the enemy car on the player car lane. enemyCars[enemyCounter].y = -125 -- place the enemy off screen at the top
Nous devons également faire pivoter la voiture ennemie pour qu’elle soit tournée vers le bas et ajouter un type de corps physique cinématique à la voiture ennemie.
enemyCars[enemyCounter]:scale(1,-1) -- rotate the cars so they are facing down physics.addBody(enemyCars[enemyCounter]) -- add a physics body to enemy cars enemyCars[enemyCounter].bodyType = "kinematic" -- make the bodies kinematic
Avec la voiture ennemie installée, nous utilisons le transition.to()
fonction d’envoyer la voiture ennemie dans l’une des voies. Lorsque la transition est terminée, le jeu appelle une fonction pour supprimer l’objet. J’incrémente également la variable enemyCounter
par 1 pour garder une trace du nombre de voitures ennemies dans le jeu.
transition.to(enemyCars[enemyCounter], {y=display.contentHeight+enemyCars[enemyCounter].height+20, time=math.random(2250,3000), onComplete=function(self) display.remove(self); incrementScore(); end}) -- a transition that moves the enemy car towards the bottom of the screen. On completion, the enemy car object is removed from the game. enemyCounter = enemyCounter + 1 -- increase enemy counter by one for tracking
Enfin, nous voulons que le jeu devienne plus rapide avec le temps. Pour chaque autre voiture envoyée, le jeu recréera le chronomètre et le réglera pour qu’il soit 200 ms plus rapide.
if(enemyCounter%2 == 0) then sendEnemyFrequency = sendEnemyFrequency - 200 if(sendEnemyFrequency < 800) then sendEnemyFrequency = 800; end timer.cancel(tmrToSendCars) tmrToSendCars = timer.performWithDelay(sendEnemyFrequency, sendEnemyCar, 0) end
onPlayAgainTouch()
La fonction la plus courte, onPlayAgainTouch()
, ramène le lecteur au menu principal. C’est ce que la mise en œuvre du onPlayAgainTouch()
la fonction ressemble à.
-- Allow the player to return to the menu local function onPlayAgainTouch() composer.gotoScene("scene_menu", "fade") -- move player to menu end
onGlobalCollision()
le onGlobalCollision()
La fonction est utilisée pour détecter les collisions entre deux objets physiques sur l’écran. Dans notre jeu, nous n’avons que deux types d’objets physiques:
- la voiture du joueur
- la voiture ennemie
Lorsque ces deux objets entrent en collision, le jeu arrête tous les minuteurs, transitions et écouteurs d’événements. De plus, le jeu affiche une scène de jeu qui permet au joueur de rejouer.
Étape 1
Tout d’abord, nous créons un if-then
déclaration qui écoute le began
phase.
if(event.phase == "began") then end
Étape 2
dans le if-then
déclaration, nous arrêtons le jeu. Nous suspendons toutes les transitions, annulons la minuterie, suspendons la physique (même si ce n’est pas nécessaire, c’est un bon appel de nettoyage) et supprimons l’auditeur d’événements des trois voies. Ajoutez le code suivant à l’intérieur du if-then
déclaration:
transition.pause() timer.cancel(tmrToSendCars) physics.pause() for i=1,3 do lanes[i]:removeEventListener("touch", moveCar) end
Étape 3
Une fois la mécanique du jeu arrêtée, nous ajoutons un rectangle opaque et un objet texte qui dit “Jeu terminé!”. Cela donne une bonne indication visuelle que le jeu est terminé.
local gameOverBackground = display.newRect(sceneGroup, 0, 0, display.actualContentWidth, display.actualContentHeight) gameOverBackground.x = display.contentCenterX gameOverBackground.y = display.contentCenterY gameOverBackground:setFillColor(0) gameOverBackground.alpha = 0.5 local gameOverText = display.newText( sceneGroup, "Game Over!", 100, 200, native.systemFontBold, 36 ) gameOverText.x = display.contentCenterX gameOverText.y = 150 gameOverText:setFillColor( 1, 1, 1 )
Étape 4
Pour terminer la fonction de collision globale, nous ajoutons le bouton de lecture qui renvoie le joueur au menu.
local playAgain = widget.newButton { width = 220, height = 100, defaultFile = "images/btn-blank.png", overFile = "images/btn-blank.png", label = "Menu", font = system.defaultFontBold, fontSize = 32, labelColor = { default={ 0, 0, 0 }, over={ 0, 0, 0, 0.5 } }, onEvent = onPlayAgainTouch } playAgain.x = display.contentCenterX playAgain.y = gameOverText.y + 100 sceneGroup:insert(playAgain)
Essai routier
Exécutez l’application pour voir si tout fonctionne comme prévu. Vous devriez pouvoir jouer au jeu, les voitures ennemies devraient apparaître du haut de l’écran et votre score devrait augmenter pour chaque voiture ennemie que vous avez esquivée avec succès.
Conclusion
Merci d’avoir lu mon tutoriel sur la création de Highway Dodge avec le SDK Corona. Vous pouvez télécharger les fichiers source de ce jeu à partir de GitHub. Prenez un moment pour réfléchir à la manière d’améliorer encore le jeu. Si vous recherchez des suggestions, je vous recommande d’ajouter une autre voie, d’ajouter plus de types d’ennemis et même d’ajouter des power-ups sympas.
Laisser un commentaire