In deze tutorial leer je hoe je Apple's Sprite Kit-framework kunt gebruiken om een Missile Command-game voor de iPad te maken. Onderweg leer je meer over verschillende kernbegrippen zoals sprites, aanrakingen, natuurkunde, botsingen en explosies. Het doel van de tweede zelfstudie is om natuurkunde, botsingen en explosies toe te voegen. De tweede zelfstudie breidt ook de spelervaring uit door een modus voor meerdere spelers toe te voegen.
Herinner je je Missile Command? Atari bracht de originele game uit op 8 maart 1981. Het was een actiegame gebouwd voor Arcade-systemen en werd erg populair over de hele wereld.
Sinds de release in 1981 werden verschillende aanpassingen doorgevoerd voor verschillende platforms. Het is nu tijd voor jou om het originele spel opnieuw te maken met behulp van moderne technologieën, iOS, Objective-C en de iPad.
Je kunt nog steeds het originele spel spelen. Kijk eens naar IGN en herleef enkele herinneringen aan je jeugd.De onderstaande schermafbeelding geeft u een idee van hoe het eindresultaat eruit zal zien. Als je het leuk vindt wat je ziet, gaan we aan de slag.
Om deze tutorial te voltooien, heb je Xcode 5 en de nieuwste iOS 7 SDK nodig. U kunt Xcode 5 en de SDK downloaden van het iOS Dev Center.
Aan het einde van elke sectie vindt u een of meer uitdagingen. Het doel van deze uitdagingen is om u te helpen de technieken en technologieën te leren die in deze zelfstudie worden gebruikt. Sommige zijn eenvoudig, terwijl andere een grotere uitdaging vormen en een goed begrip van het Sprite Kit-raamwerk vereisen. Met uitzondering van de laatste uitdaging, onthoud dat de uitdagingen niet vereist zijn om de tutorial te voltooien. We hopen echter dat u ze een kans geeft.
Als je vragen hebt over het Sprite Kit-framework, raden we je aan om onze andere Sprite Kit-handleidingen over Mobiletuts te bekijken+.
Start Xcode 5 en maak een nieuw Sprite Kit-project door te selecteren Nieuw> Project ... van de het dossier menu. Kies de SpriteKit Game sjabloon, geef uw project een naam Missile Command, en selecteer iPad uit de apparaten menu.
Wanneer het project is ingesteld, voegt u de bronnen van het project toe, die u kunt downloaden via de link bovenaan de pagina. We zullen beginnen door ons te concentreren op de Mijn scene
klasse. Binnen MyScene.m
, je zult twee methoden vinden, initWithSize:
en touchesBegan: withEvent:
.
In initWithSize:
, verwijder of becommentarieer de code die gerelateerd is aan de SKLabelNode
bijvoorbeeld omdat we het niet nodig hebben in deze tutorial. Bekijk de bijgewerkte implementatie van initWithSize:
beneden.
- (id) initWithSize: (CGSize) size self = [super initWithSize: size]; if (self) self.backgroundColor = [SKColor colorWithRed: 0.15 green: 0.15 blue: 0.3 alpha: 1.0]; terugkeer zelf;
In touchesBegan: withEvent:
, we doen iets soortgelijks. Voorlopig zou de methode alleen de logica moeten bevatten voor aanraakdetectie en de locatie van de aanraking van de gebruiker. Deze wijzigingen geven u een waarschuwing voor het compileren, maar dat komt later in deze zelfstudie.
- (ongeldig) raaktBegan: (NSSet *) raakt aan metEvent: (UIEvent *) -gebeurtenis voor (UITouch * touch in touch) CGPoint location = [touch locationInNode: self];
Je volgende stap is om twee nieuwe klassen te maken. De eerste klasse, MenuScene
, wordt gebruikt voor het hoofdmenu en de tweede klas, MultiScene
, wordt gebruikt voor de multiplayer-interface. Beide klassen zijn subklassen van SKScene
. De Mijn scene
klasse wordt gebruikt om de interface voor één speler te implementeren.
Zoals we in de Mijn scene
klasse, moeten we een initializer voor elke klas implementeren. Voorlopig stelt de initializer alleen de achtergrondkleur van de scène in zoals we die hebben gezien MyScene.m
. De initialisator van de MenuScene
klas moet ook de speltitel instellen. Om dat te doen, moeten we voor een paar dingen zorgen.
SKSpriteNode
voorwerp.zPosition
.schaal
.positie
.Bekijk de implementatie van initWithSize:
van de MenuScene
klasse voor opheldering.
- (id) initWithSize: (CGSize) size self = [super initWithSize: size]; if (self) self.backgroundColor = [SKColor colorWithRed: (198.0 / 255.0) groen: (220.0 / 255.0) blauw: (54.0 / 255.0) alpha: 1.0]; SKSpriteNode * title = [SKSpriteNode spriteNodeWithImageNamed: @ "title"]; title.zPosition = 2; title.scale = 0,4; title.position = CGPointMake (size.width / 2, size.height / 2); [self addChild: title]; terugkeer zelf;
Je zou nu een hoofdmenu en een titel moeten hebben. Het is tijd om de hoofdweergavecontroller bij te werken zodat het menu wordt weergegeven telkens wanneer de toepassing wordt gestart. Open ViewController.m
, zoek de viewDidLoad
methode, en vervang de SKScene
bijvoorbeeld met een instantie van de MenuScene
klasse zoals hieronder getoond.
- (void) viewDidLoad [super viewDidLoad]; // Configureer de weergave. SKView * skView = (SKView *) self.view; skView.showsFPS = YES; skView.showsNodeCount = YES; // Maak en configureer de scène. SKScene * scene = [MenuScene sceneWithSize: skView.bounds.size]; scene.scaleMode = SKSceneScaleModeAspectFill; // Presenteer de scène. [skView presentScene: scène];
Vergeet niet om het header-bestand van de te importeren MenuScene
klasse.
#import "ViewController.h" #import "MenuScene.h"
Super goed. Het is tijd om uw project te bouwen en uit te voeren om te controleren of alles correct werkt. Je zou een interface moeten zien die lijkt op de onderstaande screenshot.
Uitdaging: Om een unieke ervaring te creëren, dagen we je uit om het volgende te doen.
MenuScene
titelobject.Voordat we objecten toevoegen aan het spel, moeten we de mogelijkheid toevoegen om door het spel te navigeren. Verklaar twee UIButton
instanties in de MenuScene
klasse en een variabele, sizeGlobal
, van type CGSize
om de grootte van het scherm op te slaan. Deze laatste helpt ons bij het positioneren van de objecten op het scherm. Bijwerken MenuScene.m
zoals hieronder getoond.
#import "MenuScene.h" @interface MenuScene () CGSize sizeGlobal; UIButton * singlePlayerButton; UIButton * multiPlayerButton; @end
set sizeGlobal
naar grootte
in de initialisator van de klasse, zoals weergegeven in het onderstaande codefragment.
- (id) initWithSize: (CGSize) size self = [super initWithSize: size]; if (self) self.backgroundColor = [SKColor colorWithRed: (198.0 / 255.0) groen: (220.0 / 255.0) blauw: (54.0 / 255.0) alpha: 1.0]; SKSpriteNode * title = [SKSpriteNode spriteNodeWithImageNamed: @ "title"]; title.zPosition = 2; title.scale = 0,4; title.position = CGPointMake (size.width / 2, size.height / 2); [self addChild: title]; sizeGlobal = maat; terugkeer zelf;
Vervolgens declareer drie methoden in de MenuScene
klasse.
didMoveToView:
om de knoppen te presenteren wanneer het spel overgaat naar de menuweergave.moveToSinglePlayerGame
die het spel naar de Mijn scene
scène en verwijdert de knoppen.moveToMultiPlayerGame
die het spel naar de MultiScene
scène en verwijdert ook de knoppen.In didMoveToView:
, de applicatie verifieert of de scèneovergang zonder problemen heeft plaatsgevonden. Als er geen problemen zijn opgetreden, laadt de toepassing de bronnen, geeft deze weer voor de gebruiker en geeft de knoppen een directe indruk.
- (void) didMoveToView: (SKView *) view UIImage * buttonImageNormal = [UIImage imageNamed: @ "singleBtn.png"]; singlePlayerButton = [UIButton-knopWithType: UIButtonTypeRoundedRect]; singlePlayerButton.frame = CGRectMake (sizeGlobal.height / 8, sizeGlobal.width / 2 + 250, buttonImageNormal.size.width, buttonImageNormal.size.height); singlePlayerButton.backgroundColor = [UIColor clearColor]; [singlePlayerButton setTitleColor: [UIColor whiteColor] forState: UIControlStateNormal]; UIImage * strechableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth: 12 topCapHeight: 0]; [singlePlayerButton setBackgroundImage: strechableButtonImageNormal forState: UIControlStateNormal]; [singlePlayerButton addTarget: self action: @selector (moveToSinglePlayerGame) forControlEvents: UIControlEventTouchUpInside]; [self.view addSubview: singlePlayerButton]; UIImage * buttonImageNormal2 = [UIImage imageNamed: @ "multiBtn.png"]; multiPlayerButton = [UIButton-knopWithType: UIButtonTypeRoundedRect]; multiPlayerButton.frame = CGRectMake (sizeGlobal.height / 2 + 100, sizeGlobal.width / 2 + 250, buttonImageNormal2.size.width, buttonImageNormal2.size.height); multiPlayerButton.backgroundColor = [UIColor clearColor]; [multiPlayerButton setTitleColor: [UIColor whiteColor] forState: UIControlStateNormal]; UIImage * strechableButtonImageNormal2 = [buttonImageNormal2 stretchableImageWithLeftCapWidth: 12 topCapHeight: 0]; [multiPlayerButton setBackgroundImage: strechableButtonImageNormal2 forState: UIControlStateNormal]; [multiPlayerButton addTarget: self action: @selector (moveToMultiPlayerGame) forControlEvents: UIControlEventTouchUpInside]; [self.view addSubview: multiPlayerButton];
In didMoveToView:
, wij bellen moveToSinglePlayerGame
en moveToMultiPlayerGame
. Laten we deze methoden vervolgens implementeren. In elke methode moeten we het volgende doen.
Mijn scene
of MultiScene
.Kun je deze methoden alleen implementeren? Als je het niet zeker weet, kijk dan eens naar hun implementaties hieronder.
- (void) moveToSinglePlayerGame SKScene * scene = [MyScene sceneWithSize: self.view.bounds.size]; scene.scaleMode = SKSceneScaleModeAspectFill; SKTransition * transition = [SKTransition revealWithDirection: SKTransitionDirectionLittle duration: 1]; SKView * skView = (SKView *) self.view; [skView presentScene: scene transition: transition]; [singlePlayerButton removeFromSuperview]; [multiPlayerButton removeFromSuperview];
- (void) moveToMultiPlayerGame SKScene * scene = [MultiScene sceneWithSize: self.view.bounds.size]; scene.scaleMode = SKSceneScaleModeAspectFill; SKTransition * transition = [SKTransition revealWithDirection: SKTransitionDirectionLittle duration: 1]; SKView * skView = (SKView *) self.view; [skView presentScene: scene transition: transition]; [singlePlayerButton removeFromSuperview]; [multiPlayerButton removeFromSuperview];
Vergeet niet om een importinstructie toe te voegen voor de header-bestanden van Mijn scene
en MultiScene
.
#import "MenuScene.h" #import "MyScene.h" #import "MultiScene.h" @interface MenuScene () CGSize sizeGlobal; UIButton * singlePlayerButton; UIButton * multiPlayerButton; @end
Bouw uw project en voer de applicatie uit in de iOS Simulator of op een fysiek apparaat. Het spel zou nu moeten lijken op de onderstaande screenshot.
Het hoofdmenu is voltooid. Het is tijd om je te concentreren op de interface voor één speler van het spel (Mijn scene
). De Mijn scene
klasse bevat de meeste logica van het spel. De eerste stap is om de kogelschietende bloemen onder aan het scherm te plaatsen. We maken drie bloemen met elk unieke eigenschappen.
Je zult ook het aantal geëxplodeerde raketten volgen en die waarde in een andere laten zien SKLabelNode
genaamd labelMissilesExploded
. Zoals u hieronder kunt zien, hebben we een aantal instantievariabelen of Ivar
s. Het doel van elk ivar wordt duidelijk wanneer we het initWithSize:
methode in Mijn scene
.
#import "MyScene.h" @interface MyScene () CGSize sizeGlobal; SKLabelNode * labelflowerBullets1; SKLabelNode * labelflowerBullets2; SKLabelNode * labelflowerBullets3; SKLabelNode * labelMissilesExploded; int positie; int monstersDead; int missileExploded; int flowerBullets1; int flowerBullets2; int flowerBullets3; @end
In initWithSize:
, we instantiëren en configureren de verschillende SKLabelNode
instanties.
- (id) initWithSize: (CGSize) size if (self = [super initWithSize: size]) self.backgroundColor = [SKColor colorWithRed: (198.0 / 255.0) groen: (220.0 / 255.0) blauw: (54.0 / 255.0) alpha : 1.0]; positie = size.width / 3; sizeGlobal = maat; [self addFlowerCommand]; // Label Informing Missiles Exploded labelMissilesExploded = [SKLabelNode labelNodeWithFontNamed: @ "Hiragino-Kaku-Gothic-ProN"]; labelMissilesExploded.text = [NSString stringWithFormat: @ "Explodeerde raketten:% d", missileExploded]; labelMissilesExploded.fontSize = 30; labelMissilesExploded.position = CGPointMake (size.width / 2, size.he-labelMissilesExploded.frame.size.height); labelMissilesExploded.zPosition = 3; [self addChild: labelMissilesExploded]; flowerBullets1 = 10; flowerBullets2 = 10; flowerBullets3 = 10; labelflowerBullets1 = [SKLabelNode labelNodeWithFontNamed: @ "Hiragino-Kaku-Gothic-ProN"]; labelflowerBullets1.text = [NSString stringWithFormat: @ "% d", flowerBullets1]; labelflowerBullets1.fontSize = 30; labelflowerBullets1.position = CGPointMake (position-position / 2, labelflowerBullets1.frame.size.height / 2); labelflowerBullets1.zPosition = 3; [self addChild: labelflowerBullets1]; labelflowerBullets2 = [SKLabelNode labelNodeWithFontNamed: @ "Hiragino-Kaku-Gothic-ProN"]; labelflowerBullets2.text = [NSString stringWithFormat: @ "% d", flowerBullets2]; labelflowerBullets2.fontSize = 30; labelflowerBullets2.position = CGPointMake (positie * 2-positie / 2, labelflowerBullets2.frame.size.height / 2); labelflowerBullets2.zPosition = 3; [self addChild: labelflowerBullets2]; labelflowerBullets3 = [SKLabelNode labelNodeWithFontNamed: @ "Hiragino-Kaku-Gothic-ProN"]; labelflowerBullets3.text = [NSString stringWithFormat: @ "% d", flowerBullets3]; labelflowerBullets3.fontSize = 30; labelflowerBullets3.position = CGPointMake (positie * 3-positie / 2, labelflowerBullets3.frame.size.height / 2); labelflowerBullets3.zPosition = 3; [self addChild: labelflowerBullets3]; terugkeer zelf;
In initWithSize:
, we bellen ook addFlowerCommand
, die we nog niet hebben besproken. De implementatie is niet moeilijk zoals je hieronder kunt zien. In addFlowerCommand
, we instantiëren er drie SKSpriteNode
exemplaren, één voor elke bloem, en plaats ze onderaan het scherm met behulp van positie
.
- (void) addFlowerCommand for (int i = 1; i <= 3; i++) SKSpriteNode *flower = [SKSpriteNode spriteNodeWithImageNamed:@"flower.png"]; flower.zPosition = 2; flower.position = CGPointMake(position * i - position / 2, flower.size.height / 2); [self addChild:flower];
Je kunt nu het project bouwen en het uitvoeren in de iOS Simulator om de interface voor één speler voor de game te zien.
We hebben bloemen, maar we hebben nog steeds wat monsters nodig. Het is tijd om het te implementeren addMonstersBetweenSpace:
methode. In deze methode maken we drie monsters en plaatsen deze tussen de bloemen. De positie van de monsters wordt bepaald door de spaceOrder
variabel. We plaatsen de monsters willekeurig met behulp van getRandomNumberBetween: tot:
, die een willekeurig getal genereert tussen twee gegeven nummers.
- (void) addMonstersBetweenSpace: (int) spaceOrder for (int i = 0; i< 3; i++) int giveDistanceToMonsters = 60 * i -60; int randomMonster = [self getRandomNumberBetween:0 to:1]; SKSpriteNode *monster; if (randomMonster == 0) monster = [SKSpriteNode spriteNodeWithImageNamed:@"protectCreature4"]; else monster = [SKSpriteNode spriteNodeWithImageNamed:@"protectCreature2"]; monster.zPosition = 2; monster.position = CGPointMake(position * spaceOrder - giveDistanceToMonsters, monster.size.height / 2); [self addChild:monster];
De implementatie van getRandomNumberBetween: tot:
wordt hieronder getoond.
- (int) getRandomNumberBetween: (int) from naar: (int) naar return (int) from + arc4random ()% (naar - van + 1);
We roepen addMonstersBetweenSpace:
tweemaal in de initWithSize:
methode van de Mijn scene
klasse.
- (id) initWithSize: (CGSize) size if (self = [super initWithSize: size]) self.backgroundColor = [SKColor colorWithRed: (198.0 / 255.0) groen: (220.0 / 255.0) blauw: (54.0 / 255.0) alpha : 1.0]; // ... // // Monsters toevoegen [self addMonsters Tussenruimte: 1]; [self addMonstersB tussenruimteSpace: 2]; terugkeer zelf;
Nu we bloemen en monsters hebben, is het tijd om de raketten toe te voegen. We moeten het volgende doen om dit te bereiken.
SKAction
om een methode aan te roepen.SKAction
om die actie te herhalen.addMissilesFromSky:
, die willekeurig drie nieuwe raketten zal genereren en ze aan de scène zal toevoegen. We zullen de SKAction
instanties in initWithSize:
. Bekijk de bijgewerkte implementatie van initWithSize:
beneden.
- (id) initWithSize: (CGSize) size if (self = [super initWithSize: size]) self.backgroundColor = [SKColor colorWithRed: (198.0 / 255.0) groen: (220.0 / 255.0) blauw: (54.0 / 255.0) alpha : 1.0]; // ... // // Acties aanmaken SKAction * wait = [SKAction waitForDuration: 2]; SKAction * createMissiles = [SKAction runBlock: ^ [self addMissilesFromSky: size]; ]; SKAction * updateMissiles = [SKAction sequence: @ [wait, createMissiles]]; [self runAction: [SKAction repeatActionForever: updateMissiles]]; terugkeer zelf;
De implementatie van addMissilesFromSky:
wordt hieronder getoond.
- (void) addMissilesFromSky: (CGSize) size int numberMissiles = [self getRandomNumberBtween: 0 to: 3]; voor (int i = 0; i < numberMissiles; i++) SKSpriteNode *missile; missile = [SKSpriteNode spriteNodeWithImageNamed:@"enemyMissile"]; missile.scale = 0.6; missile.zPosition = 1; int startPoint = [self getRandomNumberBetween:0 to:size.width]; missile.position = CGPointMake(startPoint, size.height); int endPoint = [self getRandomNumberBetween:0 to:size.width]; SKAction *move =[SKAction moveTo:CGPointMake(endPoint, 0) duration:15]; SKAction *remove = [SKAction removeFromParent]; [missile runAction:[SKAction sequence:@[move,remove]]]; [self addChild:missile];
Als u uw toepassing bouwt en uitvoert, moet het resultaat er ongeveer zo uitzien als het onderstaande screenshot.
Uitdaging: Dit is geweldig, maar we hebben echt meer monsters nodig. We dagen je uit om het volgende te doen.
We kunnen wat beweging zien, maar we hebben het belangrijkste onderdeel van het spel nodig, gebruikersinteractie. We voegen gebruikersinteractie toe door gebruik te maken van twee methoden, touchesBegan: withEvent:
en positionOfWhichFlowerShouldBegin:
. Om gebruikersinteractie toe te voegen, moeten we het volgende in aanmerking nemen.
De bijgewerkte implementatie van touchesBegan: withEvent:
wordt hieronder getoond.
- (ongeldig) raaktBegan: (NSSet *) raakt aan metEvent: (UIEvent *) -gebeurtenis voor (UITouch * touch in touch) CGPoint location = [touch locationInNode: self]; // Keer terug als de gebruiker onder een bloem tikt (location.y < 120) return; int bulletBeginning = 0; if (location.x >= 0 && location.x < position) bulletBeginning = position-position/2; if (flowerBullets1 > 0) flowerBullets1--; else if (flowerBullets1 == 0 && flowerBullets2> 0) flowerBullets2--; [labelflowerBullets2 setText: [NSString stringWithFormat: @ "% d", flowerBullets2]]; bulletBeginning = [zelfpositieOfWelkebloemBeitje: 2]; else if (flowerBullets3> 0) flowerBullets3--; [labelflowerBullets3 setText: [NSString stringWithFormat: @ "% d", flowerBullets3]]; bulletBeginning = [zelfpositieWhichFlowerShouldBegin: 3]; else terug; [labelflowerBullets1 setText: [NSString stringWithFormat: @ "% d", flowerBullets1]]; else if ((location.x> = position && location.x < position*2)) bulletBeginning = position*2-position/2; if(flowerBullets2 > 0) flowerBullets2--; else if (location.x < sizeGlobal.width/2) if(flowerBullets1 > 0) flowerBullets1--; [labelflowerBullets1 setText: [NSString stringWithFormat: @ "% d", flowerBullets1]]; bulletBeginning = [zelfpositieOfWelkebloemBeitje: 1]; else if (flowerBullets3> 0) flowerBullets3--; [labelflowerBullets3 setText: [NSString stringWithFormat: @ "% d", flowerBullets3]]; bulletBeginning = [zelfpositieWhichFlowerShouldBegin: 3]; else terug; else if (flowerBullets3> 0) flowerBullets3--; [labelflowerBullets3 setText: [NSString stringWithFormat: @ "% d", flowerBullets3]]; bulletBeginning = [zelfpositieWhichFlowerShouldBegin: 3]; else if (flowerBullets1> 0) flowerBullets1--; [labelflowerBullets1 setText: [NSString stringWithFormat: @ "% d", flowerBullets1]]; bulletBeginning = [zelfpositieOfWelkebloemBeitje: 1]; else terug; [labelflowerBullets2 setText: [NSString stringWithFormat: @ "% d", flowerBullets2]]; else bulletBeginning = positie * 3-positie / 2; if (flowerBullets3> 0) flowerBullets3--; else if (flowerBullets3 == 0 && flowerBullets2> 0) flowerBullets2--; [labelflowerBullets2 setText: [NSString stringWithFormat: @ "% d", flowerBullets2]]; bulletBeginning = [zelfpositieOfWelkebloemBeitje: 2]; else if (flowerBullets1> 0) flowerBullets1--; [labelflowerBullets1 setText: [NSString stringWithFormat: @ "% d", flowerBullets1]]; bulletBeginning = [zelfpositieOfWelkebloemBeitje: 1]; else terug; [labelflowerBullets3 setText: [NSString stringWithFormat: @ "% d", flowerBullets3]];
Ook al is dat een heleboel code om doorheen te gaan, het is niet zo ingewikkeld. U controleert of er voor elke bloem kogels over zijn en detecteert de zone waarin de gebruiker tikte door op te roepen positionOfWhichFlowerShouldBegin:
, die we in een moment bespreken. Tegelijkertijd controleren we of de gebruiker onder de bloem heeft getikt, waardoor de bloem geen kogel kan schieten.
if (location.y < 120) return;
De positionOfWhichFlowerShouldBegin:
methode retourneert de positie die overeenkomt met een specifieke zone waarin de gebruiker heeft getikt. Vergeet niet dat je het scherm in drie delen hebt verdeeld om de drie bloemen te positioneren, zodat je de zone moet detecteren waarin de gebruiker heeft getikt en deze aan een van de bloemen koppelt. De bloem die op de kogel schiet, is degene die zich het dichtst bij de kraan van de gebruiker bevindt. Dit is wat de implementatie van positionOfWhichFlowerShouldBegin:
lijkt op.
- (int) positieWelkeFlowerShouldBegin: (int) nummer terugkeerpositie * nummer - positie / 2;
Om de kogels te laten bewegen, moeten we een andere maken SKSpriteNode
aanleg. Elke kogel heeft een duur en een SKAction
geassocieerd. Deze logica is ook opgenomen in touchesBegan: withEvent:
. Bekijk de bijgewerkte implementatie hieronder.
- (ongeldig) raaktBegan: (NSSet *) raakt aan metEvent: (UIEvent *) -gebeurtenis voor (UITouch * touch in touch) CGPoint location = [touch locationInNode: self]; // ... // SKSpriteNode * bullet = [SKSpriteNode spriteNodeWithImageNamed: @ "flowerBullet"]; bullet.zPosition = 1; bullet.scale = 0.6; bullet.position = CGPointMake (bulletBeginning, 110); bullet.color = [SKColor redColor]; bullet.colorBlendFactor = 0,5; zweefduur = (2 * location.y) /sizeGlobal.width; SKAction * move = [SKAction moveTo: CGPointMake (location.x, location.y) duration: duration]; SKAction * remove = [SKAction removeFromParent]; [bullet runAction: [SKAction-reeks: @ [verplaatsen, verwijderen]]]; [self addChild: bullet];
Als u uw toepassing bouwt en uitvoert, moeten de bloemen kogels kunnen schieten. Ze ontploffen nog niet, maar dat regelen we in de volgende tutorial.
Uitdaging: Ben je toe aan een nieuwe uitdaging? Bekijk deze uitdagingen.
Als je de stappen in deze tutorial hebt gevolgd, zou je nu de basis moeten hebben van het Missile Command-spel met behulp van het Sprite Kit-framework. Als u vragen of feedback heeft, kunt u hieronder een reactie achterlaten.