Le moteur physique fourni avec Corona Game Edition est un outil incroyablement puissant et facile à utiliser. Dans ce tutoriel, nous allons couvrir la réalisation d’un match de basketball rudimentaire en utilisant cette technologie passionnante..
display.setStatusBar (display.HiddenStatusBar) physique locale = nécessite "physique" physics.start () physics.setGravity (9.81, 0) - 9,81 m / s * s dans la direction positive x physics.setScale (80) - 80 pixels par mètre physics.setDrawMode ("normal")
La première chose que nous faisons (comme dans de nombreux programmes) est de supprimer la barre d’état en haut de l’écran. Ensuite, nous faisons l’instruction require nécessaire à l’utilisation de la physique et stockons le résultat dans la variable "physics", qui porte bien son nom. Les choses deviennent plus intéressantes dans les prochaines lignes. Dans la cinquième ligne, nous définissons l'accélération gravitationnelle. En règle générale, la gravité est définie à 9,8 m / s * s dans la direction positive, mais dans ce cas, nous souhaitons que la gravité soit attirée dans la direction x positive, car l'application aura une orientation paysage. De plus, nous avons réglé l’échelle à 80 pixels par mètre. Ce nombre peut varier un peu en fonction de la taille des objets de votre application et vous devrez peut-être vous en servir pour donner à votre jeu la sensation correcte. J'ai choisi 80 px / m parce que je veux adapter environ 15 pieds d'espace vertical sur l'écran. Sachant cela, il suffit d'une simple conversion d'unité pour obtenir une valeur.
Remarque: Il est important d'essayer de tout relier aux objets du monde réel dans les applications avec la physique. Plus vous utilisez de mesures réelles, moins il y aura de doute et plus votre application semblera réaliste..
Nous complétons ces quelques lignes en réglant le mode d'affichage sur normal. Cette ligne facilite le passage ultérieur au mode débogage si nous devons corriger certains comportements involontaires lors de collisions. Définir ceci à la normale est le comportement par défaut et dessine les formes comme l'utilisateur les verra dans le jeu final.
local background = display.newImage ("CourtBackground.png") score local = display.newText ("Score: 0", 50, 300) score: setTextColor (0, 0, 0) score.rotation = -90 score.size = 36 étage local = display.newRect (320, 0, 1, 480) local lWall = display.newRect (0, 480, 320, 1) local rWall = display.newRect (0, -1, 320, 1) plafond local = display.newRect (-1, 0, 1, 480) staticMaterial = densité = 2, frottement = .3, bounce = .4 physics.addBody (sol, "static", staticMaterial) physics.addBody (lWall, "static ", staticMaterial) physics.addBody (rWall," static ", staticMaterial) physics.addBody (plafond," static ", staticMaterial)
Ce bloc établit les limites de l'arène et les propriétés de tous les objets statiques de l'application. Nous commençons par ajouter une image simple à l'arrière-plan. À l'intérieur du rectangle blanc dans l'image d'arrière-plan, nous positionnons du texte pour afficher le score actuel. Comme l'application sera affichée en mode paysage, nous effectuons également ici les ajustements de rotation nécessaires. L’arène doit piéger la balle dans la partie visible de l’écran. Nous y parvenons avec quatre rectangles statiques (sol, mur, mur, plafond) placés juste à l’écart..
Ensuite, nous ramenons la physique dans l'équation. Au lieu de retaper la table pour les propriétés physiques de chaque objet, nous créons un nom de table, staticMaterial, à réutiliser pour chacun des murs et l'objectif lui-même. J'ai choisi des valeurs assez standard pour ces propriétés, bien que je vous encourage à jouer avec elles. Nous devons encore franchir une étape: informer Corona que ces objets doivent participer aux calculs de la physique. Nous faisons cela en appelant la fonction addBody de l'objet physique. Cette fonction prend trois arguments:
Nous avons déjà déterminé les propriétés et les objets, il ne reste donc que le modificateur facultatif. Nous utilisons «statique» pour empêcher la gravité, ou toute autre force, de déplacer nos murs!
-- Créez l’objectif local vertPost = display.newRect (110, 5, 210, 10) vertPost: setFillColor (33, 33, 33) local horizPost = display.newRect (110, 10, 10, 40) horizPost: setFillColor (33, 33). , 33) panneau local = display.newRect (55, 50, 85, 5) panneau: setFillColor (33, 33, 33) physics.addBody (vertPost, "static", staticMaterial) physics.addBody (horizPost, "static", staticMaterial) physics.addBody (panneau, "static", staticMaterial) --Créez la balle locale ball = display.newCircle (50, 200, 10) balle: setFillColor (192, 99, 55) physics.addBody (balle, densité = 0,8, frottement = 0,3, rebond = 0,6, rayon = 10)
D'un seul coup, nous créons le reste des éléments visuels de notre application. Cela devrait tous sembler très familier. Il y a juste deux choses que je voudrais souligner. Tout d'abord, certaines des valeurs pour le positionnement de l'objectif peuvent sembler fausses. Cela tient compte de l'orientation paysage. Le but apparaîtra verticalement lorsque vous faites pivoter l'appareil sur le côté. Assurez-vous également d’inclure la propriété radius dans la table des propriétés de la balle afin qu’elle se comporte correctement..
fonction locale drag (événement) local ball = event.target phase locale = event.phase si "commencé" == phase puis display.getCurrentStage (): setFocus (ball) - Stocke la position initiale ball.x0 = event.x - ball .x ball.y0 = event.y - ball.y - Évitez les forces de gravité event.target.bodyType = "kinematic" - Arrêtez le mouvement actuel, le cas échéant event.target:setLinearVelocity (0, 0) event.target.angularVelocity = 0 sinon si "déplacé" == phase puis ball.x = event.x - ball.x0 ball.y = event.y - ball.y0 elseif "terminé" == phase ou "annulé" == phase puis affiche. getCurrentStage (): setFocus (nil) event.target.bodyType = "dynamic" end end retourne la vraie boule de fin: addEventListener ("touch", faites glisser)
Cette fonction nous donne un support de base très simple. Certains des points forts comprennent la définition du type de corps de la balle sur cinématique afin que la gravité ne tire pas la balle hors de la main de l'utilisateur (Remarque: assurez-vous de redéfinir la dynamique après la fin du contact.). Les lignes qui suivent sont tout aussi importantes. Là on arrête tout le mouvement de la balle quand on la touche pour éviter le même problème que nous avions avec la gravité.
Si vous exécutez l'application telle qu'elle est actuellement, vous remarquerez probablement que la balle perd tout son élan dès que vous cessez de la toucher. Pour remédier à cela, nous devons créer une fonction permettant de suivre la vitesse de la balle, puis régler correctement la vitesse de la balle à la fin du toucher..
vitesse localeX = 0 vitesse locale = 0 local prevTime = 0 locale prevX = 0 locale prevY = 0 fonction trackVelocity (événement) local timePassed = event.time - prevTime = prevTime + timePassed speedX = (ball.x - prevX) / (timePassed / 1000) speedY = (ball.y - prevY) / (timePassed / 1000) prevX = ball.x prevY = ball.y end Runtime: addEventListener ("enterFrame", trackVelocity)
Nous créons trackVelocity en tant qu'écouteur de l'événement enterFrame. Il est donc appelé à chaque fois que l'écran est redessiné. Ce qu'il fait est de trouver le changement de vitesse sur le changement de temps pour trouver la vitesse de la balle en pixels par seconde. Il n'y a vraiment pas grand chose. Ajoutez la ligne suivante à la fonction glisser pour définir correctement la vitesse linéaire de la balle.
balle: setLinearVelocity (speedX, speedY)
Nous commençons par un peu plus de travail visuel, mais à présent, vous devriez être un pro des rectangles, cela devrait donc être indolore. Le code suivant crée la jante. Notez que la partie centrale de la jante ne fera pas partie du système physique car nous voulons que la balle passe librement..
rimBack local = display.newRect (110, 55, 5, 7) rimBack: setFillColor (207, 67, 4) rim localFront = display.newRect (110, 92, 5, 3) rimFront: setFillColor (207, 67, 4) local rimMiddle = display.newRect (110, 62, 5, 30) rimMiddle: setFillColor (207, 67, 4) physics.addBody (rimBack, "static", staticMaterial) physics.addBody (rimFront, "static", staticMaterial)
Ensuite, nous avons besoin d’un moyen de savoir quand le ballon est passé à travers le but. Pour ce faire, le moyen le plus simple consiste à désigner un "petit carré" près de la jante comme "zone de score". Chaque fois que la balle est dans cette zone, nous pouvons augmenter le score. Pour éviter que le score ne soit mal calculé lorsque le ballon traîne autour du bord, nous gardons trace du temps du dernier but et nous assurons qu'il y a une séparation adéquate entre chaque but successif. Un délai d'une seconde devrait bien fonctionner.
scoreCtr = 0 local lastGoalTime = 1000 fonction monitorScore (événement) si event.time - lastGoalTime> 1000 puis si ball.x> 103 et ball.x < 117 and ball.y > 62 et ball.y < 92 then scoreCtr = scoreCtr + 1 print(score) lastGoalTime = event.time score.text = "Score: "… scoreCtr end end end Runtime:addEventListener("enterFrame", monitorScore)
Même si cette application aurait pu être créée avec la version standard du SDK Corona, il aurait fallu beaucoup de travail en essayant de suivre les collisions, les frictions, la gravité, etc. Corona Game Edition prend en charge les tâches physiques les plus difficiles, laissant plus de temps pour vous concentrer sur le contenu et le gameplay de votre jeu.