This article of the game uses Spritekit and swift language to complete.
Spritekit is Apple's own game engine that fits the underlying API of the iOS system, but architecture and implementation mimic cocos2d. So the use of the fact that the difference is not small, just spritekit more lightweight.
Program entry
The main function, like OC, points the entry to Appdelegate, and the cocoa touch frame is almost like OC, just rewritten with Swift.
These templates come with a method that doesn't differ from the OC project ...
Start writing a game
Let's say you know ccnode,ccsprite,ccscene and so it looks like spritekit almost no matter what.
Override Func Viewwilllayoutsubviews () { super.viewwilllayoutsubviews () var skview:skview = Self.view As Skview if!skview.scene { //debug Skview.showsfps = True Skview.showsnodecount = True var scene: Skscene = Gamescene.scenewithsize (skView.bounds.size) Scene.scalemode =. Aspectfill skview.presentscene (Scene) } }
Because when the Viewdidload method is called, Skview has not been added to the view hierarchy, so it does not have a corresponding orientation and layout change. So Skview's Bounds property is not the correct value at this time, but the default vertical screen corresponding value, it seems this time is not a good time to initialize the scene. So we need to move this part of the code into the method that will layout the child view.
Play background music
Here we use Avaudioplayer to play music. The controller declares an attribute var backgroundmusicplayer:avaudioplayer?
Func Setupmedia () { var error:nserror? Let Backgroundmusicurl:nsurl = Nsbundle.mainbundle (). Urlforresource (Bg_music_name, withextension: "CAF") Backgroundmusicplayer = Avaudioplayer (contentsofurl: Backgroundmusicurl, Error: &error) if error { println ("Load background music error: \ (Error)") } else { c6/>backgroundmusicplayer!. Numberofloops =-1 backgroundmusicplayer!. Preparetoplay () backgroundmusicplayer!. Play () } }
Override Func Viewdidload () { super.viewdidload () Setupmedia () }
Starts playing when the view loading is complete.
Game scene
We have built a Skscene subclass for game display and logic writing. Class Gamescene:skscene
Victory failure Scenario
Class Gameoverscene:skscene {convenience init (size:cgsize, Won:bool) {self.init (size:size) sel F.backgroundcolor = Skcolor (red:1.0, green:1.0, blue:1.0, alpha:1.0) Self.setupmsglabel (Iswon:won) Self.directoraction ()} func Setupmsglabel (Iswon won:bool) {var msg:string = won? "Yow won!": "You Lose: [" var msglabel = Sklabelnode (fontnamed: "Chalkduster") Msglabel.text = Msg Msglabel.fontsize = Msglabel.fontcolor = Skcolor.blackcolor () msglabel.position = Cgpointmake (self . SIZE.WIDTH/2, SELF.SIZE.HEIGHT/2) Self.addchild (Msglabel)} func directoraction () {var actions: anyobject[] = [Skaction.waitforduration (3.0), Skaction.runblock ({var reveal = Sktransition.fliphorizontalwith Duration (0.5) var gamescene = Gamescene (size:self.size) self.view.presentScene (Gamescene, Transitio N:reveal)})] Var sequence = skaction.sequence (Actions) self.runaction (sequence)}}
A simple page that shows the game wins and fails, with just a label and some action.
Initialization
var player:skspritenode! Hero Elf var lastspawntimeinterval:nstimeinterval!//Record last time and update time var lastupdatetimeinterval:nstimeinterval! var monstersdestroyed:int! Record the number of monsters that have been wiped out
Init (size:cgsize) { super.init (size:size) Self.backgroundcolor = Skcolor (red:1.0, green:1.0, blue:1.0, Alpha : 1.0) player = Skspritenode (imagenamed: "Player") player.position = Cgpointmake (SELF.PLAYER.SIZE.WIDTH/2, SELF.FRAME.SIZE.HEIGHT/2) self.addchild (player) monstersdestroyed = 0 lastspawntimeinterval = 0 Lastupdatetimeinterval = 0 gamelevel.nextlevel () //physics self.physicsWorld.gravity = Cgvectormake ( 0, 0) self.physicsWorld.contactDelegate = self }
Some properties are declared and are assigned during construction. Instantiate the Hero Wizard. The primary physical engine properties are set.
Add Monsters
Func Addmonster () {var monster = Skspritenode (imagenamed: "Monster")//location var miny = m ONSTER.SIZE.HEIGHT/2 var maxy = self.frame.size.height-monster.size.height/2 var rangey = Maxy-miny var actualy = arc4random ()% rangey + miny monster.position = cgpointmake (Self.frame.size.width + monste R.SIZE.WIDTH/2, actualy) Self.addchild (monster)//physics monster.physicsbody = Skphysicsbody (rectangleOfSize:monster.size) Monster.physicsBody.dynamic = True Monster.physicsBody.categoryBitMask = Mon Stercategory Monster.physicsBody.contactTestBitMask = projectilecategory Monster.physicsBody.collisionBitMas k = 0//speed var minduration = 2.0 var maxduration = 4.0 var rangeduration = Maxdurat ion-minduration var actualduration = arc4random ()% rangeduration + minduration var actionmove = S Kaction.moveto (CgpointmaKe (-MONSTER.SIZE.WIDTH/2, actualy), duration:actualduration) var actionmovedone = Skaction.removefromparent () var loseaction = Skaction.runblock ({var reveal = sktransition.fliphorizontalwithduration (0.5) VA R gameoverscene = Gameoverscene (size:self.size, Won:false) self.view.presentScene (gameoverscene, Transition: Reveal)}) Monster.runaction (Skaction.sequence ([Actionmove, Loseaction, Actionmovedone])}
The monsters were initialized, physically configured, and the speed was set and allowed to act, assuming that beyond the left bounds the game failed, assuming that the ninja-sent darts would be destroyed, partly by collision detection, which will be mentioned later.
Join Darts
When we click the end of the screen, we need to launch a dart to attack.
The system has its own monitoring method, as in Uikit.
Override Func touchesended (touches:nsset!, withevent event:uievent!) { //Get touch var touch = Touches.anyobject () as Uitouch var location = Touch.locationinnode (self) // Bullet Action self.addprojectile (location:location) }
And then a bullet-adding method.
Func addprojectile (#location: cgpoint) {var projectile = Skspritenode (imagenamed: "Projectile") projecti Le.position = player.position//physics projectile.physicsbody = Skphysicsbody (circleofradius:proje CTILE.SIZE.WIDTH/2) Projectile.physicsBody.dynamic = True Projectile.physicsBody.categoryBitMask = Projectil Ecategory Projectile.physicsBody.contactTestBitMask = monstercategory Projectile.physicsBody.collisionBitMas K = 0 Projectile.physicsBody.usesPreciseCollisionDetection = true var offset = nisub (location, Proje ctile.position) If Offset.x < 0 {return} self.addchild (projectile)/direct unit vector var direction = ninormalize (offset)//to screen ' s edge var shootamount = Nimult (direction, 100 0)//now loc var realdest = Niadd (Shootamount, projectile.position)//action var veloc ity = 480.0/1.0 VAr realmoveduration = Double (self.size.width)/velocity var actionmove = Skaction.moveto (Realdest, Duratio n:realmoveduration) var actionmovedone = skaction.removefromparent () var sequence = Skaction.sequence ([acti OnMove, Actionmovedone]) projectile.runaction (sequence) self.runaction (skaction.playsoundfilenamed (" PEW-PEW-LEI.CAF ", Waitforcompletion:false))}
Like monsters, we initialize the dart, configure the physical state, and then determine its vector direction based on the location of the click and the location of the hero, so that he can start moving. Then let him move up in that direction.
Game assist in determining the direction of movement we used some of our own definition of closure functions, and because Swift is a type-safe language, very often we can not directly operate on different types of numeric values, so as in C + +, Swift can also do operator overloading.
Overload@infix func% (Lhs:uint32, rhs:float), float { return float (LHS)% float (RHS)} @infix func% (lhs:uint (rhs:double), double { return double (LHS)% double (RHS)}let Niadd = {(A:cgpoint, b:cgpoint), Cgpoint I N Cgpointmake (a.x + b.x, A.Y + b.y)}let nisub = {(A:cgpoint, b:cgpoint)-Cgpoint in Cgpointmake (a.x-b.x, A.y-b. Y)}let Nimult = {(A:cgpoint, b:float), Cgpoint in Cgpointmake (a.x * b, a.y * b)}let nilength = {(A:cgpoint) CGFloat in CGFloat (sqrt (Double (a.x * a.x + a.y * a.y))}
Unit Vectorlet ninormalize = {(A:cgpoint), cgpoint in var length = Nilength (a) return Cgpointmake (a.x/ Length, A.y/length)}
The right time to join the monster
It is noted that we have not previously called the method of adding monsters, the number of frames per second in the iOS system is 60, while in Skscene, the refresh frame will have the default method update to write the game logic.
Override func Update (currenttime:nstimeinterval) { var timesincelast:cftimeinterval = currenttime- Lastspawntimeinterval lastupdatetimeinterval = currenttime If timesincelast > 1 { timesincelast = Double (Gamelevel.toraw ())/60.0 lastupdatetimeinterval = currenttime } Self.updatewithtimesincelastupdate (timesincelast:timesincelast) }
Then we'll be able to join the beast.
Func updatewithtimesincelastupdate (#timeSinceLast: cftimeinterval) { Lastspawntimeinterval = Lastspawntimeinterval + timesincelast if Lastspawntimeinterval > 1 { lastspawntimeinterval = 0 Self.addmonster () } }
Collision detection
Finally, the collision logic needs to be defined.
There is a proxy method callback when the physical model is connected.
Func didbegincontact (contact:skphysicscontact) { var firstbody:skphysicsbody! var secondbody:skphysicsbody! if (Contact.bodyA.categoryBitMask < Contact.bodyB.categoryBitMask) { firstbody = Contact.bodya; Secondbody = Contact.bodyb; } else { firstbody = Contact.bodyb; Secondbody = Contact.bodya; } if (Firstbody.categorybitmask & projectilecategory)! = 0 && (Secondbody.categorybitmask & monstercategory)! = 0 { self.didcollide (projectile:firstBody.node as Skspritenode, Monster:secondBody.node as Skspritenode) } }
At this point we want to make the following logic when monsters and darts collide
Func didcollide (#projectile: Skspritenode, Monster:skspritenode) { projectile.removefromparent () Monster.removefromparent () monstersdestroyed = monstersdestroyed + 1 if monstersdestroyed > { var reveal = Sktransition.fliphorizontalwithduration (0.5) var gameoverscene = Gameoverscene (Size:self.size, Won:true ) Self.view.presentScene (Gameoverscene, transition:reveal) } }
So the whole Ninja Dart monster game is over.
Here are the Games:
Game code: Click to open the link
The above is all the content of this blog post. Welcome to correct and discuss.
Write a ninja game with Swift and Spritekit