Advertisement
  1. Code
  2. Corona SDK

Wie man Highway Dodge mit dem Corona SDK baut

Scroll to top
Read Time: 14 min

German (Deutsch) translation by Alex Grigorovich (you can also view the original English article)

What You'll Be Creating

In diesem Tutorial lernen Sie, wie Sie Highway Dodge erstellen, ein einfaches, aber süchtig machendes Spiel. Highway Dodge ist leicht zu erlernen und zu spielen, bietet jedoch die süchtig machende Qualität anderer beliebter Spiele im App Store.

Highway Dodge beginnt damit, dass der Spieler in einem Rennwagen auf der Autobahn platziert wird. Während des Spiels muss der Spieler dem Gegenverkehr auf der Autobahn ausweichen, indem er auf eine der drei verfügbaren Fahrspuren tippt. Für jedes ausgewichene Auto erhält der Spieler einen Punkt und das Spiel ist für den Spieler beendet, wenn ein entgegenkommendes Auto das Rennauto trifft. Mit der Zeit kommen die entgegenkommenden Autos immer schneller heraus, um den Spieler vor eine echte Herausforderung zu stellen.

Anforderungen

Dieses Spiel wurde mit Lua und dem Corona SDK erstellt. Sie müssen mindestens ein Konto bei Corona Labs und das Corona SDK installiert haben. Sie können das Corona SDK kostenlos auf der Corona Labs-Website herunterladen. Für dieses Tutorial habe ich Build 2015.2731 des Corona SDK verwendet.

1. Einrichten von Highway Dodge

Lassen Sie uns direkt einsteigen und Highway Dodge starten, indem Sie eine leere Vorlage erstellen. Öffnen Sie den Corona Simulator und wählen Sie im Menü Datei die Option Neues Projekt. Wenn Sie das Fenster Neues Projekt erstellen geöffnet haben, geben Sie Highway Dodge als Projektnamen ein, wählen Sie eine leere Vorlage aus und stellen Sie die Breite auf 400 und die Höhe auf 600 ein. Belassen Sie die Standardausrichtung auf Aufrecht.

Create New ProjectCreate New ProjectCreate New Project

Downloaden Sie nach dem Einrichten Ihres Projekts die Bilder für Highway Dodge. Erstellen Sie einen neuen Ordner in Ihrem neuen Projekt, benennen Sie ihn als Bilder und fügen Sie die Bilder diesem Ordner hinzu. Ihr Projekt sollte jetzt so aussehen:

A Quick Look at the ProjectA Quick Look at the ProjectA Quick Look at the Project

2. Projekteinstellungen

Lassen Sie uns nach dem Einrichten des Projekts einen kurzen Blick auf zwei wichtige Dateien werfen, build.settings und config.lua.

build.settings

Diese Datei behandelt die Build-Time-Eigenschaften des Spiels. Es speichert Informationen zur Ausrichtung Ihrer App, Symbolinformationen, iOS-Einstellungen und Android-Einstellungen. Das Standard-Setup ist für unser Spiel ausreichend.

config.lua

Diese Konfigurationsdatei steuert die Laufzeit-Eigenschaften des Spiels. Dies umfasst widthheightscalefps (Bilder pro Sekunde) und imageSuffix. Die Eigenschaft, die wir uns ansehen müssen, ist imageSuffix. Die imageSuffix-Eigenschaft wird für die dynamische Bildauswahl verwendet. Kurz gesagt, die App wird angewiesen, auf einem Gerät mit höherer Auflösung ein Bild mit höherer Auflösung zu verwenden.

Ich habe hochauflösende Bilder im Bilderordner bereitgestellt, daher müssen wir config.lua entsprechend aktualisieren. Die config.lua-Datei Ihres Projekts sollte wie folgt aussehen. Ich habe den auskommentierten Push-Benachrichtigungsbereich weggelassen.

1
    application = { content = { width = 400, height = 600, scale = "letterBox", fps = 30, imageSuffix = { ["@2x"] = 2, }, }, }
2
  

3. Startpunkt

Fahren wir mit der Einrichtung des Projekts und der dynamischen Bildauswahl mit main.lua fort. Diese Datei ist der Startpunkt jeder App, die mit dem Corona SDK erstellt wurde. In unserem Spiel werden drei Codezeilen enthalten sein.

Schritt 1

In der ersten Zeile wird die Statusleiste auf iOS-Geräten ausgeblendet. Öffnen Sie main.lua und fügen Sie nach dem Kommentar die folgende Zeile hinzu -- Your code here.

1
    display.setStatusBar( display.HiddenStatusBar )
2
  

Schritt 2

Danach verwenden wir Composer, indem wir die Bibliothek für unser Spiel benötigen. Dazu fügen wir die folgende Zeile hinzu:

1
    local composer = require( "composer" )
2
  

Schritt 3

Wie verwenden den Komponisten, um zur Menüszene zu gelangen. Wir verschieben Szenen, indem wir die Funktion composer.gotoScene() aufrufen und den Wert "scene_menu" als Parameter übergeben. Der Wert "scene_menu" ist der Name der Szene und der Name der Datei, die wir im nächsten Abschnitt erstellen.

1
    composer.gotoScene("scene_menu")
2
  

Ein Wort zum Komponisten

Composer ist die offizielle Szenenverwaltungsbibliothek von Corona. Mit Composer können die Entwickler auf einfache Weise eine Szene erstellen und zwischen Szenen wechseln. In zwei Zeilen konnte ich von der Hauptszene zur Menüszene übergehen. Wenn Sie mehr über Composer erfahren möchten, besuchen Sie den Composer Library Guide von Corona, der auf der Corona Labs Docs-Website verfügbar ist.

4. Menü

Die Menüszene unseres Spiels besteht nur aus wenigen Elementen. Die Szene enthält eine Hintergrundgrafik, einen Titel und eine Startschaltfläche. Wir werden die integrierte Widget-Bibliothek von Corona verwenden, um die Startschaltfläche zu erstellen. Mit der Widget-Bibliothek können wir schnell und einfach allgemeine Elemente der Benutzeroberfläche erstellen. In unserem Spiel verwenden wir es nur für die Erstellung von Schaltflächen.

Schritt 1

Erstellen Sie im Projektordner von Highway Dodge eine neue Datei, scene_menu.lua, und öffnen Sie sie in einem Texteditor Ihrer Wahl. Anstatt bei Null anzufangen, verwenden wir die Szenenvorlage, die auf der Corona Labs Docs-Website verfügbar ist. Mit ihrer Vorlage können wir uns viel schneller bewegen. Gehen Sie zu Corona Labs Docs und kopieren Sie die Szenenvorlage in scene_menu.lua.

Schritt 2

Fügen Sie die Widget-Bibliothek zu unserem Spiel hinzu, indem Sie die folgende Zeile direkt unter der Komponistenbibliothek hinzufügen.

1
    local widget = require( "widget" )
2
  

Schritt 3

Wir fügen unseren Hintergrund anhand der zuvor heruntergeladenen Grafiken hinzu. Der Hintergrund sollte in der Mitte des Bildschirms positioniert sein. Fügen Sie in der Funktion scene:create() den folgenden Code hinzu, nachdem die Variable screenGroup deklariert wurde:

1
    local background = display.newImageRect(sceneGroup, "images/background.png", 475, 713) background.x = display.contentCenterX background.y = display.contentCenterY
2
  

Schritt 4

Dann müssen wir die drei Fahrspuren hinzufügen, die die Autobahn darstellen. Dazu verwenden wir eine Tabelle, um die Spuren zu halten, und erstellen eine for-Schleife, die dreimal ausgeführt wird. Platzieren Sie dieses Snippet nach der Hintergrundgrafik:

1
    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
2
  

Um sicherzustellen, dass die Fahrspuren immer zentriert sind, habe ich die Fahrspuren mit ein wenig Mathematik auf der x-Achse platziert. Dadurch wird sichergestellt, dass die Bahnen unabhängig vom Gerät, auf dem das Spiel ausgeführt wird, zentriert bleiben.

Schritt 5

Wir fügen auch unser Logo für Highway Dodge hinzu, indem wir ein Bildobjekt oben auf dem Bildschirm platzieren.

1
    local logo = display.newImageRect(sceneGroup, "images/logo.png", 300, 150) logo.x = display.contentCenterX logo.y = 75
2
  

Schritt 6

Bevor wir unser Schaltflächen-Widget hinzufügen können, müssen wir eine Funktion erstellen, die reagiert, wenn die Schaltfläche berührt wird. Wir werden die Funktion handleButtonEvent() benennen und den Player mit composer.gotoScene() zur Spielszene verschieben. Wir werden nur antworten, wenn der Spieler seinen Finger vom Knopf gehoben hat oder in der ended Phase des Ereignisses.

1
    local function handleButtonEvent( event ) if ( "ended" == event.phase ) then composer.gotoScene("scene_game", "slideLeft") end end
2
  

Schritt 7

Mit der hinzugefügten Funktion können wir die Schaltfläche hinzufügen. Wir erstellen die Schaltfläche, indem wir widget.newButton verwenden und einige Werte an sie übergeben. Wir geben die Breite und Höhe der Schaltfläche, die Bilddateien für die Schaltfläche, den anzuzeigenden Text, den Schrifttyp, die Schriftgröße und die Schriftfarbe an.

Wir teilen Corona auch mit, welche Funktion beim Drücken der Taste aufgerufen werden soll, und positionieren sie in der Mitte des Bildschirms. Die Quelldateien dieses Lernprogramms enthalten Kommentare, in denen die einzelnen Werte zum Einrichten der Schaltfläche erläutert werden.

1
    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)
2
  

Schritt 8

Um die Menüszene abzuschließen, müssen wir die Spielszene beim Beenden entfernen. Wenn Corona zwischen Szenen wechselt, wird die vorherige Szene nicht immer entfernt. Ohne diese Zeilen befindet sich das Spiel immer in einer Spiel-über-Szene, nachdem es einmal gespielt wurde.

Um die vorherige Szene zu entfernen, rufen wir den Szenennamen ab und rufen composer.removeScene() auf, um sie zu entfernen, falls vorhanden. Fügen Sie der folgenden Code hinzu scene:show() -Funktion.

1
    local prevScene = composer.getSceneName( "previous" ) if(prevScene) then composer.removeScene(prevScene) end
2
  

5. Erstellen der Spielszene

Wir können jetzt anfangen, an der Spielszene zu arbeiten. Wir verwenden denselben Workflow wie beim Erstellen der Menüszene. Erstellen Sie eine neue Datei, scene_game.lua, und kopieren Sie die in Corona Labs Docs verfügbare Szenenvorlage. Sobald Sie den Code installiert haben, öffnen Sie scene_game.lua in Ihrem bevorzugten Texteditor.

Schritt 1

Um uns das Codieren der Spielszene zu erleichtern, werden wir die Widget-Bibliothek und die Physikbibliothek verwenden. Letzteres dient zur Kollisionserkennung. Fügen Sie den folgenden Code zu scene_game.lua hinzu:

1
    local widget = require( "widget" ) local physics = require("physics") physics.start() physics.setGravity(0,0)
2
  

In der ersten und zweiten Zeile benötigen wir die Widget-Bibliothek bzw. die Physik-Bibliothek. Wir beginnen dann mit der Physik und deaktivieren die Schwerkraft. Wir brauchen keine Schwerkraft für unser Autobahnspiel, stattdessen verwenden wir transition.to(), um die Autos zu bewegen.

Schritt 2

In der Funktion scene:create() deklarieren wir eine Reihe von Variablen, die wir im Spiel verwenden werden. Diese Variablen sind für das Spielerauto, die Fahrspuren, die feindlichen Autos und die Spielerwertung verantwortlich. Um das Lesen zu vereinfachen, habe ich einige Kommentare hinzugefügt.

1
    -- "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
2
  

Schritt 3

Unterhalb der Variablendeklarationen richten wir die Funktionen für das Spiel ein. Wir werden jede Funktion in einem späteren Schritt implementieren. Fügen Sie nach den Variablendeklarationen in der folgenden Code hinzu scene:create() -Funktion.

1
    local function incrementScore() end local function moveCar(event) end local function sendEnemyCar() end local function onPlayAgainTouch() end local function onGlobalCollision(event) end
2
  

Schritt 4

Nach den Funktionen fügen wir den Hintergrund und die Spuren hinzu. Für die Fahrspuren fügen wir jeder Fahrspur einen Ereignis-Listener hinzu, damit sie auf Berührungsereignisse reagieren. Bei Berührung ruft der Listener die Funktion moveCar() auf.

1
    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
2
  

Schritt 5

Wenn der Hintergrund und die Fahrspuren eingerichtet sind, ist es Zeit, ein Textobjekt zu erstellen, in dem die Spielerwertung gespeichert und das Spielerauto erstellt wird. Die Punktzahl befindet sich oben auf dem Bildschirm und das Spielerauto befindet sich ganz links. Außerdem machen wir das Spielerauto zu einem dynamischen Physikobjekt.

1
    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"
2
  

Schritt 6

Als Nächstes setzen wir einen Timer, um ein Auto basierend auf dem Wert der Variablen sendEnemyFrequency zu senden und einen Laufzeitereignis-Listener für globale Kollisionen zu erstellen.

1
    tmrToSendCars = timer.performWithDelay(sendEnemyFrequency, sendEnemyCar, 0) Runtime:addEventListener( "collision", onGlobalCollision)
2
  

6. Hinzufügen der Spielfunktionalität

Wir können unserem Spiel endlich Funktionen hinzufügen. In diesem Abschnitt wird jeder Funktion, die wir im vorherigen Abschnitt deklariert haben, zusätzlicher Code hinzugefügt. Wir beginnen mit incrementScore() und enden mit onGlobalCollision().

incrementScore()

Diese Funktion wird aufgerufen, wenn ein feindliches Auto am Spieler vorbeifährt und der Übergang abgeschlossen ist. Beim Aufruf wird die Spielerpunktzahl um 1 erhöht. Fügen Sie der Funktion incrementScore() die folgende Implementierung hinzu.

1
    -- 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
2
  

moveCar()

Die Funktion moveCar() wird aufgerufen, wenn eine Spur berührt wird. In der ended Phase des Ereignisses greifen wir zur Spurkennung und bewegen das Auto auf die richtige Spur. Wir geben am Ende true zurück, um ein erfolgreiches Touch-Ereignis anzuzeigen. Fügen Sie der Funktion moveCar() die folgende Implementierung hinzu.

1
    -- 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
2
  

sendEnemyCar()

Die Funktion sendEnemyCar() erstellt ein feindliches Auto, weist das Auto einer Fahrspur zu, fügt dem Auto einen Physikkörper hinzu und sendet das Auto mit transition.to() zum unteren Bildschirmrand. Lassen Sie uns zunächst das feindliche Autoobjekt erstellen.

1
    enemyCars[enemyCounter] = display.newImageRect(sceneGroup, "images/enemyCar"..math.random(1,3)..".png", 50, 100)
2
  

Dann setzen wir die x- und y-Position des feindlichen Autos. Wir erstellen auch eine if-then-Anweisung, um das feindliche Auto in 50% der Fälle derselben Spur zuzuweisen, auf der sich das Spielerauto befindet. Dies zwingt den Spieler, sich häufiger zu bewegen, und macht das Spiel mehr Spaß.

1
    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
2
  

Wir müssen auch das feindliche Auto so drehen, dass es nach unten zeigt, und dem feindlichen Auto einen kinematischen Physikkörpertyp hinzufügen.

1
    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
2
  

Wenn das feindliche Auto eingerichtet ist, verwenden wir die Funktion transition.to(), um das feindliche Auto auf eine der Fahrspuren zu schicken. Wenn der Übergang abgeschlossen ist, ruft das Spiel eine Funktion zum Entfernen des Objekts auf. Ich erhöhe auch den variablen enemyCounter um 1, um die Anzahl der feindlichen Autos im Spiel zu verfolgen.

1
    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
2
  

Schließlich möchten wir, dass das Spiel mit der Zeit schneller wird. Für jedes andere Auto, das gesendet wird, erstellt das Spiel den Timer neu und stellt ihn auf 200ms schneller ein.

1
    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
2
  

onPlayAgainTouch()

Die kürzeste Funktion, onPlayAgainTouch(), bringt den Player zum Hauptmenü zurück. So sieht die Implementierung der Funktion onPlayAgainTouch() aus.

1
    -- Allow the player to return to the menu local function onPlayAgainTouch() composer.gotoScene("scene_menu", "fade") -- move player to menu end
2
  

onGlobalCollision()

Die Funktion onGlobalCollision() wird verwendet, um Kollisionen zwischen zwei beliebigen Physikobjekten auf dem Bildschirm zu erkennen. In unserem Spiel haben wir nur zwei Arten von Physikobjekten:

  • das Spielerauto
  • das feindliche Auto

Wenn diese beiden Objekte kollidieren, stoppt das Spiel alle Timer, Übergänge und Ereignis-Listener. Zusätzlich zeigt das Spiel eine Spiel-über-Szene an, mit der der Spieler erneut spielen kann.

Schritt 1

Zuerst erstellen wir eine if-then-Anweisung, die auf die began Phase wartet.

1
    if(event.phase == "began") then end
2
  

Schritt 2

In der if-then-Anweisung stoppen wir das Spiel. Wir halten alle Übergänge an, brechen den Timer ab, unterbrechen die Physik (auch wenn dies nicht erforderlich ist, ist es ein guter Bereinigungsanruf) und entfernen den Ereignis-Listener von allen drei Spuren. Fügen Sie den folgenden Code in die if-then-Anweisung ein:

1
    transition.pause() timer.cancel(tmrToSendCars) physics.pause() for i=1,3 do lanes[i]:removeEventListener("touch", moveCar) end
2
  

Schritt 3

Nachdem die Spielmechanik gestoppt wurde, fügen wir ein undurchsichtiges Rechteck und ein Textobjekt mit der Aufschrift "Game Over!" hinzu. Das gibt einen guten visuellen Hinweis darauf, dass das Spiel beendet wurde.

1
    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 )
2
  

Schritt 4

Um die globale Kollisionsfunktion abzuschließen, fügen wir die Schaltfläche "Wiederholen" hinzu, mit der der Player zum Menü zurückkehrt.

1
    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)
2
  

Probefahrt

Führen Sie die Anwendung aus, um festzustellen, ob alles, wie erwartet, funktioniert. Sie sollten in der Lage sein, das Spiel zu spielen, feindliche Autos sollten oben auf dem Bildschirm erscheinen und Ihre Punktzahl sollte sich für jedes feindliche Auto erhöhen, dem Sie erfolgreich ausweichen.

Abschluss

Vielen Dank, dass Sie mein Tutorial über Erstellung von Highway Dodge mit dem Corona SDK gelesen haben. Sie können die Quelldateien für dieses Spiel von GitHub herunterladen. Nehmen Sie sich einen Moment Zeit, um zu überlegen, wie Sie das Spiel weiter verbessern können. Wenn Sie nach Vorschlägen suchen, würde ich empfehlen, eine weitere Spur hinzuzufügen, mehr Feindtypen hinzuzufügen und sogar einige coole Power-Ups hinzuzufügen.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.