Im vorherigen Teil dieser Serie haben wir das Schiff des Spielers bewegt, die Eindringlinge bewegt und festgestellt, wann ein Spielerball einen Eindringling getroffen hat. In diesem letzten Teil der Serie greifen die Angreifer den Spieler an, verwalten die Level und fügen dem Spieler die Möglichkeit hinzu, zu sterben.
1. Kugeln abschießen
Hin und wieder feuert einer der Angreifer eine Kugel ab. Wir werden eine verwenden Timer um das zu erreichen. Fügen Sie den folgenden Code hinzu gamelevel.lua.
function fireInvaderBullet()
if(#invadersWhoCanFire >0) then
local randomIndex = math.random(#invadersWhoCanFire)
local randomInvader = invadersWhoCanFire[randomIndex]
local tempInvaderBullet = display.newImage("laser.png", randomInvader.x , randomInvader.y + invaderSize/2)
tempInvaderBullet.name = "invaderBullet"
scene.view:insert(tempInvaderBullet)
physics.addBody(tempInvaderBullet, "dynamic" )
tempInvaderBullet.gravityScale = 0
tempInvaderBullet.isBullet = true
tempInvaderBullet.isSensor = true
tempInvaderBullet:setLinearVelocity( 0,400)
table.insert(invaderBullets, tempInvaderBullet)
else
levelComplete()
end
end
In dieser Funktion prüfen wir zunächst, ob die invadersWhoCanFire Tabelle enthält mindestens ein Element. In diesem Fall führen wir den Code in der if-Anweisung aus. Andernfalls ist das Level beendet und wir rufen das auf levelComplete Funktion.
Es wird immer mindestens einen Eindringling geben, der eine Kugel abfeuern kann, bis Sie den letzten Eindringling töten invadersWhoCanFire Die Tabelle ist leer.
Innerhalb der if-Anweisung generieren wir eine Zufallszahl randomIndex nach der Anzahl der Artikel in der invadersWhoCanFire Tabelle. Wir wählen dann diesen Artikel, randomInvader, von invadersWhoCanFire Tabelle.
Wir erstellen ein Aufzählungszeichen, geben es ein name Eigenschaft, damit wir sie später identifizieren, in die Szene einfügen und dieselben Eigenschaften wie auf dem Player-Chip festlegen können. Zum Schluss setzen wir den Ball in die ein invaderBullets Tabelle, damit wir später darauf verweisen können.
Jetzt müssen wir den Timer konfigurieren. Fügen Sie Folgendes hinzu: scene:show Methode.
function scene:show(event)
if ( phase == "did" ) then
--SNIP--
Runtime:addEventListener( "collision", onCollision )
invaderFireTimer = timer.performWithDelay(1500, fireInvaderBullet,-1)
end
end
Alle 1500 Millisekunden fireInvaderBullet wird aufgerufen. Beachten Sie, dass der letzte Parameter, den wir übergeben, ist -1Dies bedeutet, dass sich der Timer auf unbestimmte Zeit wiederholt. Jedes Mal, wenn Sie einen Timer erstellen, der sich auf unbestimmte Zeit wiederholt, müssen Sie ihn möglicherweise abbrechen. Wir machen das in der scene:hide Funktion wie unten gezeigt.
function scene:hide(event)
if ( phase == "will" ) then
--SNIP--
Runtime:removeEventListener( "collision", onCollision )
timer.cancel(invaderFireTimer)
end
end
2. Kugeln entfernen
Wie die Bälle des Spielers bewegen sich die Bälle des Eindringlings vom Bildschirm weg und bleiben in Bewegung, wodurch wertvolles Gedächtnis beansprucht wird. Um dies zu beheben, entfernen wir sie wie bei Spielerbällen.
function checkInvaderBulletsOutOfBounds()
if (#invaderBullets > 0) then
for i=#invaderBullets,1,-1 do
if(invaderBullets[i].y > display.contentHeight) then
invaderBullets[i]:removeSelf()
invaderBullets[i] = nil
table.remove(invaderBullets,i)
end
end
end
end
Dieser Code ist sehr ähnlich zu der Überprüfung, ob die Bälle des Spielers außerhalb der Grenzen liegen, daher werde ich seine Implementierung nicht im Detail diskutieren.
3. Erkennen Sie einen Treffer
Schritt 1: Kollisionserkennung
Der nächste Schritt besteht darin, festzustellen, ob der Ball eines Eindringlings den Spieler getroffen hat. Fügen Sie dem folgenden Code hinzu onCollision Funktion.
function onCollision(event)
if ( event.phase == "began" ) then
--SNIP--
if(event.object1.name == "player" and event.object2.name == "invaderBullet") then
table.remove(invaderBullets,table.indexOf(invaderBullets,event.object2))
event.object2:removeSelf()
event.object2 = nil
if(playerIsInvincible == false) then
killPlayer()
end
return
end
if(event.object1.name == "invaderBullet" and event.object2.name == "player") then
table.remove(invaderBullets,table.indexOf(invaderBullets,event.object1))
event.object1:removeSelf()
event.object1 = nil
if(playerIsInvincible == false) then
killPlayer()
end
return
end
end
end
Nach wie vor wissen wir nicht, welches Objekt event.object1 und event.object2 Wir werden also zwei if-Anweisungen verwenden, um beide Situationen zu überprüfen. Wir entfernen die Kugel aus dem Eindringling der invaderBullets Tabelle, entfernen Sie es vom Bildschirm und setzen Sie es auf nil. Wenn der Spieler nicht unbesiegbar ist, töten wir ihn.
Schritt 2: Töte den Spieler
Wenn wir den Spieler töten, gewähren wir ihm eine kurze Unbesiegbarkeitsfrist. Dies gibt dem Benutzer Zeit, sich auf das Spiel zu konzentrieren. numberOfLives Variable ist gleich Wir wissen, dass das Spiel vorbei ist und der Übergang zu Start Szene, in der der Benutzer ein neues Spiel starten kann.
function killPlayer()
numberOfLives = numberOfLives- 1;
if(numberOfLives <= 0) then
gameData.invaderNum = 1
composer.gotoScene("start")
else
playerIsInvincible = true
spawnNewPlayer()
end
end
Schritt 3: Erstellen Sie einen neuen Spieler
das spawnNewPlayer Die Funktion lässt den Leser einige Sekunden lang erscheinen und verschwinden. Es ist ein schöner Effekt, den Benutzer wissen zu lassen, dass das Schiff vorübergehend unbesiegbar ist.
function spawnNewPlayer()
local numberOfTimesToFadePlayer = 5
local numberOfTimesPlayerHasFaded = 0
local function fadePlayer()
player.alpha = 0;
transition.to( player, {time=400, alpha=1, })
numberOfTimesPlayerHasFaded = numberOfTimesPlayerHasFaded + 1
if(numberOfTimesPlayerHasFaded == numberOfTimesToFadePlayer) then
playerIsInvincible = false
end
end
fadePlayer()
timer.performWithDelay(400, fadePlayer,numberOfTimesToFadePlayer)
end
Wir verwenden eine lokale Funktion, fadePlayer, die die verwendet Überleitung Bibliothek zum Ändern der alpha Wert von player. Wir verfolgen die Anzahl der Male player verblasste und platzierte die Unbesiegbarkeit des Spielers auf false Sobald wir die erreichen numberOfTimesToFadePlayer. Wir verwenden einen Timer, um die aufzurufen fadePlayer so oft laufen numberOfTimesToFadePlayer entspricht.
Führen Sie das Spiel aus, um dies zu testen. das player sollte sterben, wenn eine Kugel eines Eindringlings das Schiff trifft. Wenn drei Kugeln das Schiff treffen, müssen Sie zum gebracht werden Start Szene, in der Sie ein neues Spiel starten können.
Kommentieren Sie den Anruf an, um den Test zu erleichtern moveInvaders in dem gameLoop Funktion wie unten gezeigt.
function gameLoop()
checkPlayerBulletsOutOfBounds()
--moveInvaders()
checkInvaderBulletsOutOfBounds()
end
4. Schließe ein Level ab
Wenn Sie es geschafft hätten, alle Eindringlinge zu töten, hätte das Spiel das aufgerufen levelComplete Funktion, die noch nicht existiert. Lass es reparieren. Fügen Sie den folgenden Codeblock hinzu.
function levelComplete()
gameData.invaderNum = gameData.invaderNum + 1
if(gameData.invaderNum <= gameData.maxLevels) then
composer.gotoScene("gameover")
else
gameData.invaderNum = 1
composer.gotoScene("start")
end
end
Wir erhöhen gameData.invaderNum und wenn es kleiner ist als gameData.maxLevels, wir gehen zu Spiel ist aus Szene. Ansonsten hat der Spieler alle Level abgeschlossen und wir setzen zurück gameData.invaderNum beim 1. Wir ziehen um Start Szene, in der der Spieler ein neues Spiel starten kann.
Eine einfache Möglichkeit, dies zu testen, besteht darin, den Anruf an zu kommentieren moveInvaders in dem gameLoop Funktion und verwenden Sie die Tasten, um das Schiff zu bewegen. Wenn es immer noch zu schwierig ist, können Sie auch beide Anrufe an kommentieren killPlayer in dem onCollision Methode.
5. Spiel ist aus
Fügen Sie den folgenden Code hinzu gameover.lua das Spiel auf der Bühne umzusetzen.
local composer = require("composer")
local scene = composer.newScene()
local starFieldGenerator = require("starfieldgenerator")
local pulsatingText = require("pulsatingtext")
local nextLevelButton
local starGenerator
function scene:create( event )
local group = self.view
starGenerator = starFieldGenerator.new(200,group,5)
local invadersText = pulsatingText.new("LEVEL COMPLETE", display.contentCenterX, display.contentCenterY-200,"Conquest", 20,group )
invadersText:setColor( 1, 1, 1 )
invadersText:pulsate()
nextLevelButton = display.newImage("next_level_btn.png",display.contentCenterX, display.contentCenterY)
group:insert(nextLevelButton)
end
function scene:show( event )
local phase = event.phase
composer.removeScene("gamelevel" )
if ( phase == "did" ) then
nextLevelButton:addEventListener("tap",startNewGame)
Runtime:addEventListener ( "enterFrame", starGenerator)
end
end
function scene:hide(event )
local phase = event.phase
if ( phase == "will" ) then
Runtime:removeEventListener("enterFrame", starGenerator)
nextLevelButton:removeEventListener("tap",startNewGame)
end
end
function startNewGame()
composer.gotoScene("gamelevel")
end
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
return scene
Dieser Code ist sehr ähnlich zu Start Szene, so sollten Sie jetzt damit vertraut sein.
6. Kollision mit einem Eindringling
Die letzte Kollisionsprüfung, die wir durchführen müssen, ist eine Kollision zwischen dem Spieler und einem der Angreifer. Fügen Sie dem folgenden Codeblock hinzu onCollision Methode, die wir früher gesehen haben.
function onCollision(event)
--SNIP--
if ( event.phase == "began" ) then
--SNIP--
if(event.object1.name == "player" and event.object2.name == "invader") then
numberOfLives = 0
killPlayer()
end
if(event.object1.name == "invader" and event.object2.name == "player") then
numberOfLives = 0
killPlayer()
end
end
Wie üblich müssen wir die beiden Kollisionssituationen überprüfen. Wir definieren die numberOfLives beim und Ruf an killPlayer. Durch die Definition numberOfLives beim 0 und anrufen killPlayerist das Spiel vorbei und das Spiel geht zu Start Szene.
sept. Mehr Funktionen
Damit ist unser Spiel beendet, aber ich schlage vor, dass Sie versuchen, das Spiel um einige weitere Funktionen zu erweitern. Sie können beispielsweise das Leben des Spielers in einem HUD anzeigen.
Ich habe auch eine UFO-Grafik in die Quelldateien aufgenommen. Sie können versuchen, ein UFO zufällig zu spawnen. Wenn der Spieler es mit einer Kugel trifft, geben Sie ihm ein zusätzliches Leben.
Wenn Sie Hilfe bei diesen Konzepten benötigen, schauen Sie sich meine Flugzeugkampfspielserie auf Tuts + an.
Fazit
Wenn Sie dieser Serie gefolgt sind, sollten Sie jetzt ein voll funktionsfähiges Spiel haben, das den ursprünglichen Space Invaders ähnelt. Entwickeln Sie es und personalisieren Sie es. Ich hoffe, Sie fanden dieses Tutorial hilfreich und haben einige neue Techniken gelernt. Danke fürs Lesen.
Unterstützen Sie unsere Arbeit ❤️
Wenn Ihnen dieser Artikel gefallen hat, können Sie uns mit einem Trinkgeld unterstützen, damit wir weiterhin großartige Inhalte veröffentlichen können.
























