Oprettandet af et Mega Jump-spil til iPhone – Del 2

Oprettandet af et Mega Jump-spil til iPhone - Del 2

Vi fortsætter vejledningen om oprettelse af et spil til iPhone på Sprite Kit og Swhvis t. I den første del lykkedes det os at skabe en spilscene, hvor vores helt er placeret, og endda få ham til at adlyde tyngdekraftens love. I denne lektion lærer vi bjerget at interagere med omverdenen, fange “stjerner” og hoppe på platform e …

“Klik for at stjerne te”

Den originale artikel på engelsk kan læses her.

Nu hvor tyngdekraften fungerer i spillade , skal du gøre heltenes fysiske krop ubevægelig, indtil brugeren beslutter at stjerne te spillade . Inde i GameScene .swhvis t-filen skal du finde linjen i createSpiller -metoden, der indstiller den dynamiske egenskab til den fysiske krop af spiller Node-objektet. Skhvis t dens værdi til falsk, som vist her:

 spiller Node.physicsBody?  .dynamisk  = falsk 

 

Vi skriver en kode, der giver brugeren mulighed for at stjerne te spillade ved at klikke på skærmen. Og han skal advar es om dette med en slags indskrhvis t. For eksempel: “Tryk for at starte”. Lad os lægge denne instruktion på skærmen.

Da instruktionerne vil være på HUD-laget, skal du oprette det først. I metoden init (størrelse :), lige efter hvor du tilføjede forgrundsknudepunktet til scenen, skal du indsætte følgende kode:

// HUD  hudNode   = SKNode     () addChild (hudNode)

 

Grafiske aktiver inkluderer et billede, som du skal klikke for at starte spillade . Så tilføj følgende variabel til egenskaberne øverst i GameScene.swhvis t:

// Tryk på For at starte knude   lade  tryk på Stjerne tstartknude   = SKSpriteNode         (imageNamed      : "TapToStart" )

 

For at få vist den nyoprettede knude skal du tilføje følgende kode til init (størrelse 🙂 -metoden lige efter linjen, der tilføjer hero-knude n:

// Tryk for at starte  tryk på Startstartnode .position     = CGPoint         (x      : selv .størrelse.bredde  / 2, y    : 180,0 ) hudNode.addChild (tapToStartNode)

 

Byg og løb for at se “Tryk for at starte” lige over heltenes sprite :

Oprettelse af et Mega Jump-spil til iPhone - Del 2

For at håndtere berøringer og begynde at spille skal du tilføje følgende metode til klassen GameScene.swhvis t:

tilsidesætte  func          rører Begyndt (rører ved : NSSet , med begivenhed Event : UIEvent ) {                           // 1       // Hvis vi allerede spiller, skal du ignorere berøringer  hvis  spiller .physicsBody   !.dynamisk  { Vend tilbage  }                         // 2       // Fjern knap Tryk for at starte  tapToStartNode.removeFromParent     () // 3       // Start afspilleren ved at sætte dem i fysiksimuleringen  spiller .physicsBody? .dynamisk  = rigtigt  // 4     spiller .physicsBody? .applyImpulse (CGVector   (dx   : 0,0 , D y : 20,0 )) }

 

Lad os se nærmere på denne metode:

1. Vi er nødt til at sikre, at heltenoden er dynamisk. I så fald skal du blot ignorere berøringshændelsen.

2. Fjern noden mærket “Tryk for at starte”.

3. Vi gør den fysiske krop af heltenes node dynamisk, så fysikmotoren kan påvirke den.

4. Vi informerer heltenes knude om den oprindelige opadgående impuls, så den begynder at bevæge sig.

Byg og kør. Når du klikker på skærmen, forsvinder indskriften ‘Tab til start’, og heltenes sprite kastes op, men ikke længe – tyngdekraften tager sin vejafgift.

Spilobjekter: nå ud til stjernerne!

For at give din karakter noget at gøre andet end bare at hoppe op, er det tid til at tilføje stjerner. Stjerner spiller en vigtig rolle i Uber Jump: de skal indsamles af spilleren for at gå til det næste niveau.

For at komme i gang skal du bare oprette en stjerne i spillade og få det til at fungere fuldt ud, og i den næste del af lektionen gennemfører vi hele niveauet.

Ifølge scenariet i spillade Uber Jump, som Mega Jump, når heltenes sprite stiger en vis afstand over stjernen, platformen eller ethvert andet objekt, fjernes dette objekt fra scenen. Da noder og stjerner og platforme begge opfylder denne betingelse, giver det mening at underklasse SKNode for alle spilobjekter.

Opret en ny Cocoa Touch-klasse med navnet GameObjectNode og underklasse SKNode. Sørg for, at Swift er installeret som sprog.

Oprettelse af et Mega Jump-spil til iPhone - Del 2

GameObjectNode-klassen inkluderer følgende funktionalitet:

1. Fjernelse af scenen fra det objekt, hvorfra heltenes knudepunkt bevægede sig væk i en større afstand end den angivne.

2. Registrering af kollisioner mellem heltenoden og objektet. Denne metode Vend tilbage erer en boolsk værdi, der giver besked, hvis helten har krydset med et objekt i spillade , hvilket vil føre til behovet for at opdatere HUD-laget. For eksempel, hvis spilleren scorede point.

Udskift koden i GameObjectNode.swift med følgende:

importere  SpriteKit  klasse  GameObjectNode: SKNode { func collisionWithPlayer   (player: SKNode) ->    Bool    { Vend tilbage  falsk  } func checkNodeRemoval (spillerY : CGFloat ) { if spillerY>  selv .position.y    +  300,0  { selv .removeFromParent() } } }

 

Vi kalder metoden collisionWithPlayer, når heltenoden kolliderer med et objekt, og vi kalder også checkNodeRemoval hver ramme, så vi straks kan fjerne den unødvendige node fra scenen.

I GameObjectNode-klassen er collisionWithPlayer-metoden bare en stub. Vi definerer den komplade te metode separat i hver af de underklasser, der oprettes til dine spilobjekter.

Metoden checkNodeRemoval kontrollerer, om heltenes node har flyttet mere end 300 point fra denne node. I så fald fjerner metoden noden fra dens overordnede og fjerner den således fra scenen.

Stjerneklasse

Nu hvor vi har en basisklasse til spillade s interaktive noder, kan vi oprette en klasse til stjernerne. For at holde tingene enkle, lad os tilføje alle GameObjectNode-underklasser på én gang til GameObjectNode.swift-filen. Tilføj følgende kode efter GameObjectNode-klassen.

klasse  StarNode  : GameObjectNode { tilsidesætte  func collisionWithPlayer(player: SKNode) -> Bool { // Forøg afspilleren  player.physicsBody? .velocity  = CGVector(dx: player.physicsBody!.velocity.dx, dy  : 400,0 ) // Fjern denne stjerne  selv .removeFromParent() // HUD skal opdateres for at vise de nye stjerner og score  Vend tilbage  rigtigt  } }

 

En kollision med en stjerne kaster heltens knude op ad ordinaten. Du spørger måske, “hvorfor bruger vi ikke fysikmotorens kraft eller momentum til at gøre dette?”

Hvis vi brugte kraft eller impuls, ville den ønskede effekt ikke altid være der. For eksempel, hvis en heltens knude bevæger sig ned ad skærmen og styrter ned i en stjerne, så vil påvirkningskraften på helten være meget mindre, end når han bevæger sig op.

Følgende diagram illustrerer dette meget tydeligt:

Oprettelse af et Mega Jump-spil til iPhone - Del 2

Løsningen på dette problem er at ændre hastigheden på spillerens node direkte. Som du ved, er hastighedsvektoren sammensat af vandrette og lodrette komponenter.

X-aksens hastighed bør ikke ændre sig, da den kun påvirkes af accelerometeret, som vi implementerer senere. I ovenstående metode indstiller vi den lodrette projektionshastighed til kollisionen ved en fast værdi på 400. Så kollisionen får de samme konsekvenser uanset hvad spilleren gjorde, før han kolliderede med stjernen.

Åbn GameScene.swift, og tilføj følgende metode:

func createStarAtPosition    (position: CGPoint) -> StarNode   { // 1 lade  node = StarNode() lade  positionen  = CGPoint(x: position.x    skalaFaktor, y : position.y) node.position   = positionen  node.name   = "NODE_STAR"  // 2 var sprite: SKSpriteNode sprite = SKSpriteNode(imageNamed: "Stjerne" ) node.addChild   (sprite) // 3 node.physicsBody   = SKFysikBody (circleOfRadius : sprite.størrelse .width  / 2) // 4 node.physicsBody? .dynamisk  = falsk  Vend tilbage  node }

 

Koden ovenfor skal være kendt for dig nu:

1. Vi opretter en forekomst af StarNode-klassen og indstiller dens position.

2. Tilføj derefter stjernegrafikken ved hjælp af SKSpriteNode.

3. Føj til en node en fysisk krop i form af en cirkel, som vi har brug for for at opdage kollisioner med andre objekter i spillade .

4. Endelig gør vi den fysiske krop statisk, fordi vi ikke ønsker, at tyngdekraften eller andre fysiske simuleringer påvirker stjernerne.

Tilføj nu følgende kode til init (størrelse 🙂 -metoden, lige før hvor vi oprettede heltenoden. Vi ønsker, at stjernerne skal være bag afspilleren, men også på forgrundsnoden, så vi er nødt til at tilføje dem før spillerens node.

// Tilføj en stjerne  lade  star = createStarAtPosition(CGPoint(x: 160, y: 220)) forgrundNode.addChild (star)

 

Byg og kør spillet. Klik på startknappen og se helten sprite kollidere med stjernen.

Oprettelse af et Mega Jump-spil til iPhone - Del 2

Vores Ulta hopperen ramte hovedet på stjernen. Det gik ikke efter planen! Hvorfor tror du, dette skete? Forsøge at gætte.

Og her er løsningen:

Fysikmotoren håndterer kollisioner mellem helten og stjerneknuderne. Helteknudens fysiske krop krydser stjerneknudens fysiske krop, som er statisk og derfor ubevægelig. Stjerneknuden stopper bevægelsen af ​​spillerens knude.

Kollisionsdetektering og bitmasker

For at opdage kollisioner mellem helten og stjerneknudepunkterne er vi nødt til at modtage kollisionshændelsen og kalde collisionWithPlayer-metoden i GameObjectNode-klassen.

Nu er det tid til at se på emnet krydsende bitmasker i Sprite Kit.

Der er tre bitmaskerelaterede egenskaber til kommunikation af kollisionsoplysninger til fysiske kroppe, som du kan bruge til at bestemme, hvordan den fysiske krop interagerer med andre fysiske kroppe i spillet.

1.categoryBitMask definerer den kollisionskategori, som den fysiske krop tilhører.

2. collisionBitMask indstiller kollisionskategorien for de kroppe, som det givne legeme krydser hinanden med. Her betyder ordet “kryds”, at objekterne nøjagtigt kolliderer med hinanden. For eksempel, når du spiller som en tredjepersonsskytter, vil du have, at heltenes sprite kolliderer med fjendens sprites, men passerer gennem andre spillers sprites.

3. kontakt TestBitMask beder Sprite Kit-motoren om at underrette dig, når en given fysisk krop kommer i kontakt med fysiske kroppe, der tilhører en af ​​de kategorier, du har angivet. For eksempel i vores spil ønsker vi, at Sprite Kit fortæller os, hvornår en spillers sprite rører ved en stjerne eller platform. Ved at bruge de korrekte kombinationer af indstillinger til contactTestBitMask og collisionBitMask kan du programmere Sprite Kit, så objekter passerer gennem hinanden, og det giver dig besked, når dette sker. På denne måde kan vi udløse begivenheder.

Den første ting at gøre er at indstille dine kategorier. Åbn GameObjectNode.swift, og tilføj følgende struktur over klassedefinitionerne:

struct  CollisionCategoryBitmask  { statisk  let Player: UInt  32    = 0x00  statisk  let Star: UInt32 = 0x01  statisk  let Platform : UInt32 = 0x02  }

 

Vend tilbage til GameScene.swift. For at indstille heltenes opførsel under kollisioner skal du tilføje følgende kode i bunden af ​​createPlayer-metoden lige før retursætningen:

// 1 playerNode.physicsBody? .usesPreciseCollisionDetection  = rigtigt  // 2 playerNode.physicsBody? .categoryBitMask  = CollisionCategoryBitmask.Player  // 3 playerNode.physicsBody? .collisionBitMask  = 0 // 4 playerNode.physicsBody? .contactTestBitMask  = CollisionCategoryBitmask.Star |  CollisionCategoryBitmask.Platform

 

Lad os se nærmere på denne kodeblok:

interessant 6,1-tommer iPhone 12 og iPhone 12 Pro sælges først Apple annoncerer lanceringen af ​​iPhone 12 fra dag til dag

1. Da dette er et spil i hurtig bevægelse, skal Sprite Kit bruge nøjagtig kollisionsdetektering til helteknudens fysiske krop. Når alt kommer til alt er hele plot af Uber Jump bygget på disse kollisioner. Derfor har vi brug for, at de fanges så nøjagtigt som muligt! (flere CPU-cyklusser vil være involveret)

2. Vi tildeler en kategori til den fysiske kropsbitmaske. Det tilhører kategorien CollisionCategoryPlayer.

3. Ved at sætte collisionBitMask til nul, fortæller vi Sprite Kit, at vi ikke ønsker, at det skal simulere nogen kollision mellem afspilningsknudepunktet. Dette er fordi vi selv vil håndtere disse kollisioner!

4. Vi fortæller Sprite Kit, at vi ønsker at blive underrettet, når en heltknude berører stjerner eller platforme.

Lad os nu oprette stjerneknudepunktet. Tilføj følgende kode i bunden af ​​createStarAtPosition-metoden, før retursætningen:

 node.physicsBody? .categoryBitMask  = CollisionCategoryBitmask.Star node.physicsBody? .CollisionBitMask  = 0

 

Alt her ligner opsætning af en heltknude. Vi tildeler stjernekategorien og indstiller egenskaben collisionBitMask til nul, så den ikke kolliderer med noget. Vi tildeler imidlertid ikke contactTestBitMask her, hvilket betyder, at Sprite Kit ikke giver os besked, når noget objekt rører ved stjernen. Vi har allerede instrueret Sprite Kit om at sende underretninger, når helten rører ved en stjerne, og bortset fra stjernen vil han ikke røre ved noget, så der er ikke behov for at sende underretninger fra stjernen.

Sprite Kit sender kontaktmeddelelser for de noder, vi valgte, ved at kalde didBeginContact -metoden for SKFysikKontakt Delegate-delegaten. Indstil selve scenen som den fysiske verdensdelegerede ved at tilføje SKPhysicsContactDelegate-protokollen til GameScene-klassedefinitionen. Det skal se sådan ud:

class GameScene: SKScene , SKPhysicsContactDelegate  { // Lagdelte noder  ...

 

Gør nu scenen til en delegeret til at modtage kontaktmeddelelser ved at tilføje følgende linje til init (størrelse 🙂 lige efter linjen, der indstiller tyngdekraften:

// Indstil kontaktdelegat  physicsWorld.contactDelegate  = selv 

 

Endelig tilføj følgende metode til GameScene.swift for at håndtere kollisionshændelser:

func didBeginContact(contact: SKPhysicsContact) { // 1 var updateHUD    = falsk  // 2 let whichNode   = (contact.bodyA.node   ! =  player) ? contact.bodyA.node : contact.bodyB.node  let Andet  = whichNode as GameObjectNode // 3 updateHUD = other.collisionWithPlayer (player) // Opdater HUD, hvis det er nødvendigt  if updateHUD { // 4 TODO: Opdater HUD i del 2  } }

 

Lad os se nærmere på denne kode:

1. Vi initialiserer updateHUD-flag, som vi vil bruge i slutningen af ​​metoden til at opdatere HUD under disse kollisioner og beregne scoren.

2. SKPhysicsContact garanterer ikke, hvilken fysisk krop, der fungerer som bodyA, og hvilken der fungerer som bodyB. Men vi ved, at alle kollisioner i dette spil vil være mellem heltenoden og GameObjectNode. Derfor bestemmer denne linje, hvilken der ikke er en heltknude.

3. Når vi har fundet ud af, hvilket objekt der ikke er en heltenode, kalder vi metoden collisionWithPlayer: i GameObjectNode-klassen.

4. Her opdaterer vi HUD, hvis det kræves. Vi udfører HUD-implementeringen i anden del af lektionen, så der er intet her bortset fra en kommentar.

Byg og kør spillet. Klik for at starte. Ved kollision kaster stjernen heltenes sprite til en vis højde og fjernes derefter fra scenen. Godt arbejde!

Oprettelse af et Mega Jump-spil til iPhone - Del 2

Nå, der er gjort meget hårdt arbejde! Lad os tage en velfortjent pause. I det næste afsnit vil vi tilføje nye type r uber-stjerner såvel som en lydeffekt.

Bemærk: Hvis du gerne vil vide mere om detektion af pin og kollision i Sprite Kit, skal du tjekke “iOS Games by Tutorials”, som indeholder tre store kapitler om motorfysik.

Flere slags stjerner

Uber Jump vil indeholde to typer stjerner: dem der tilføjer et point og specielle stjerner der tilføjer fem point på én gang. Hver stjerne har sin egen grafik. Samlingen i StarNode-klassen hjælper os med at identificere typen af ​​stjerne.

Tilføj følgende samling øverst på GameObjectNode.swift:

enum   StarType   : Int { sag  Normal   = 0 sag  Særlig  }

 

For at gemme stjernetypen skal du tilføje følgende egenskab øverst i klassen StarNode:

var starType : StarType!

 

Når vi opretter en stjerne, skal vi nu specificere dens type, så i GameScene.swift skal du tilføje parameteren starType til signaturen til metoden createStarAtPosition: så den ser sådan ud:

func createStarAtPosition(position: CGPointaf typen Type : StarType) -> StarNode {

 

Inde i createStarAtPosition (position: ofType 🙂 skal du erstatte de tre kodelinjer (som opretter og tilføjer SKSpriteNode) med følgende:

node.starType  = type var sprite: SKSpriteNode if type ==    .Særlig  { sprite = SKSpriteNode(imageNamed: "StarSpecial" ) } else { sprite = SKSpriteNode(imageNamed: "Stjerne" ) } node.addChild(sprite)

 

Først indstiller vi stjernetypen. Derefter kontrollerer vi typen, når vi opretter sprite for at tilføje det relevante billede.

Det er kun at specificere stjernetypen, når du opretter den. I metoden init (størrelse 🙂 i klassen GameScene.swift skal du finde den linje, som vi kalder createStarAtPosition, og ændre den som følger:

let star = createStarAtPosition(CGPoint(x: 160, y: 220), af Type : .Særlig )

 

Tildel StarType.Specielt til vores stjerne.

Byg løb. Vores stjerne blev lyserød! Senere tilføjer vi et scoringssystem, og forskellene i stjernetyper bliver tydeligere.

Oprettelse af et Mega Jump-spil til iPhone - Del 2

Ringer! Tilføjelse af en lydeffekt

Det ville være rart, hvis heltenes kollision med stjernen var ledsaget af et lydsignal. Download stjernelydeffekten herfra og træk filen ind i vores Xcode-projekt. Sørg for, at indstillingen “Destination: Kopier emner efter behov” er valgt, og at UberJump-målet er valgt.

Sprite Kit bruger SKAction til at afspille lyde. Åbn GameObjectNode.swift, og tilføj følgende egenskab til klassen over StarNode:

let starSound  = SKAction.playSoundFileNamed ("StarPing.wav" , ventFor afslutning : falsk )

 

Nu er det kun at gengive lydeffekten under kollisionen mellem helten og stjernen.

I collisionWithPlayer () -metoden i StarNode-klassen skal du erstatte selv .removeFromParent () med:

// Afspil lyd  runAction (starSound, færdiggørelse : { // Fjern denne stjerne  selv .removeFromParent() })

 

Koden starter SKAction, afspiller lydfilen og fjerner stjernen, når handlingen er slut.

Byg og kør. Så snart heltenes sprite rammer stjernen, vil du høre en ringelyd.

Spilobjekter: platforme

Vores næste opgave er at tilføje en platform. Vi opretter en ny underklasse af GameObjectNode-klassen til platformene. Som med stjernerne har vi brug for to typer platforme: en type platform skal være uforgængelig, og de andre skal forsvinde, i det øjeblik helten springer af dem.

I GameObjectNode.swift skal du tilføje følgende samling over klassedefinitionen af ​​GameObjectNode for at definere to platformstyper:

enum PlatformType   : Int { sag  Normal = 0 sag  Pause  }

 

Dernæst skal vi oprette en PlatformNode -klasse. Føj følgende kode til GameObjectNode.swift:

class PlatformNode: GameObjectNode { var platformType  : PlatformType! tilsidesætte  func collisionWithPlayer(player: SKNode) -> Bool { // 1 // Bounce kun spilleren, hvis han falder  if player.physicsBody? .velocity.dy <  0 { // 2 player.physicsBody? .velocity  = CGVector(dx: player.physicsBody!.velocity.dx, dy: 250,0 ) // 3 // Fjern, hvis det er en Break-type platform  if platformType == .Pause  { self.removeFromParent() } } // 4 // Ingen stjerner til platforme  Vend tilbage  falsk  } }

 

Lad os se nærmere på denne kode:

1. I overensstemmelse med spilscenariet skal heltenes knude kun hoppe ud af platformen, når den falder, det vil sige når den har en negativ dy-værdi af dens hastighed (hastighedsegenskab). Denne kontrol forhindrer også heltenoden i at krydse platformene, når den bevæger sig op ad skærmen.

2. Vi fortæller heltenes knudepunkt en opadgående hastighed for at hoppe ud af platformen. Dette gøres på samme måde som tidligere for stjernerne, men med en lavere værdi. Stjernerne er køligere, ikke?

3. Hvis platformen er af platformType.Pause -typen, fjerner vi den fra scenen.

4. Ultrajumperen scorer ikke point, når han hopper ud af platformen, eller når han hopper på den, så der er ingen grund til at opdatere HUD.

For at tilføje en platform til scenen skal du åbne GameScene.swift og indtaste følgende metode:

func createPlatformAtPosition  (position: CGPointaf typen Type : PlatformType) -> PlatformNode  { // 1 let node = PlatformNode() let thePosition = CGPoint(x: position.x  skalaFaktor, y : position.y) node.position = thePosition node.name = "NODE_PLATFORM"  node.platformType  = type // 2 var sprite: SKSpriteNode if type == .Break { sprite = SKSpriteNode(imageNamed: "PlatformBreak" ) } else { sprite = SKSpriteNode(imageNamed: "Platform" ) } node.addChild(sprite) // 3 node.physicsBody = SKFysikBody (rektangelOfSize : sprite.size) node.physicsBody? .dynamisk  = falsk  node.physicsBody? .categoryBitMask  = CollisionCategoryBitmask.Platform node.physicsBody? .CollisionBitMask  = 0 return node }

 

Denne metode ligner meget createStarAtPosition (_: OfType :), men bemærk følgende hovedpunkter:

1. Vi opretter en forekomst af PlatformNode og indstiller dens position, navn og type.

2. Vælg det relevante billede til SKSpriteNode afhængigt af platformstypen.

3. Vi skaber platformens fysik inklusive typen af ​​kollisioner.

For at tilføje en platform skal du indsætte følgende kode i init (størrelse 🙂 -metoden lige før linjen, der opretter stjernen:

// Tilføj en platform  let platform = createPlatformAtPosition(CGPoint(x: 160, y: 320), af Type : .Normal ) forgrundNode.addChild (platform)

 

Byg og kør spillet. Klik for at starte og se Hero Sprite strøm fra stjernen og derefter hoppe på platformen!

Oprettelse af et Mega Jump-spil til iPhone - Del 2

Hvor skal jeg hen?

Bøde! Som du kan forestille dig, er det ikke så svært at lave et spil som Mega Jump. Med Uber Jump lærte vi alt det grundlæggende, som vi kan bruge videre på vores vej til at lave et godt spil.

I slutningen af ​​artiklen kan du downloade Xcode-projektet, der indeholder alt det, vi lærte i dette kursus.

I den næste del vil vi bruge accelerometeret til at kontrollere heltenes bevægelse langs X-aksen. Vi vil også indlæse et antal egenskaber fra en ekstern plist-fil og tilføje et scoringssystem. En masse interessante ting er endnu ikke kommet.

Hvis du har spørgsmål, tanker eller forslag til fremtidige lektioner, bedes du give din kommentar nedenfor.

Fortsat om en uge ….

Download Xcode-kilde.

Download grafiske ressourcer til lektionen.

Rate article
Mobiltelefoner-nyheder, anmeldelser og hackere.
Add a comment