Nowy projekt iOS Game. Ustaw rozmiar sceny 320 x 480 i rodzaj

Transkrypt

Nowy projekt iOS Game. Ustaw rozmiar sceny 320 x 480 i rodzaj
Nowy projekt iOS Game. Ustaw rozmiar sceny 320 x 480 i rodzaj symulatora: 4s
Utwórz w projekcie nową grupę zasoby, zaimportuj do niej obrazki i dźwięki.
Player
Umieść sprite’a player, steruj playerem za pomocą dotknięcia ekranu, tak aby obrócił się i podążał do
miejsca dotknięcia. W GameScene.sks: umieść ColorSprite / Texture: player, nadaj name: player
W GameScene.swift posprzataj domyślny kod
var player = SKSpriteNode()
override func didMoveToView(view: SKView) {
player = self.childNodeWithName("player") as! SKSpriteNode
}
Zdefiniuj w klasie GameScene punkt, przypisz mu lokalizację aktualnego dotknięcia.
var punkt: CGPoint? // nie: CGPointZero, bo player będzie dążył na początku do (0,0)
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches { punkt = touch.locationInNode(self) }
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches { punkt = touch.locationInNode(self) }
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches { punkt = touch.locationInNode(self) }
}
Zdefiniuj funkcję updatePlayer() i wywołaj ją we funkcji update()
let pi2 = CGFloat(M_PI)/2
let v: CGFloat = 150;
func updatePlayer() {
if let t: CGPoint = punkt {
// jeśli punkt dotknięcia != null
let p = player.position
let dx = t.x - p.x
let dy = t.y - p.y
let kat = atan2(dy, d.x)
player.runAction(SKAction.rotateToAngle(kat + pi2, duration: 0))
let vx = v*cos(kat)
let vy = v*sin(kat)
player.physicsBody!.velocity = CGVectorMake(vx, vy)
}
}
override func update(currentTime: CFTimeInterval) {
updatePlayer()
}
lub raczej - wywoływana automatycznie po wykonaniu obliczeń symulacji, 1 raz na ramkę
override func didSimulatePhysics() {
updatePlayer()
}
Nadaj spritowi playera właściwości ciała fizycznego: we własciwościach sprite’a ustaw
Body type: rectangle, Dynamic, Allow rotation
odznacz affected by gravity
Niech player zatrzyma się po dojściu do punktu dotknięcia
func updatePlayer() {
if let t: CGPoint = punkt {
// cel
let p = player.position
// start
let dx = t.x - p.x
let dy = t.y - p.y
if abs(dx)>player.frame.width/2 || (dy)>player.frame.height/2 {
let kat = atan2(dy, dx)
player.runAction(SKAction.rotateToAngle(kat + pi2, duration: 0))
let vx = v*cos(kat)
let vy = v*sin(kat)
player.physicsBody!.velocity = CGVectorMake(vx, vy)
}
else {
player.physicsBody?.resting = true
}
}
}
Zombie
W GameScene.sks umieść ColorSprite, texture: zombie, name zombie,
ustaw właściwości fizyczne: Body type: rectangle, Dynamic, Allow rotation, odznacz affected by gravity
sklonuj CMD+D sprite’a kilka razy i rozmieść na scenie.
W GameScene.swift przygotuj tablicę Z dla zombies
var Z = [SKSpriteNode]()
we funkcji didMoveToView() załaduj zombies do tablicy Z
for child in self.children {
if child.name == "zombie" {
if let z = child as? SKSpriteNode {
Z.append(z)
}
}
}
Zombie będą gonić playera, napiszemy funkcję updateZombies(), która będzie aktualizować połozenie
każdego zombie
let vz: CGFloat = 50
// moduł prędkości zombie, składnik klasy
func updateZombies() {
let p = player.position
// cel
for z in Z {
let q = z.position
// start
let dx = p.x - q.x
let dy = p.y - q.y
let kat = atan2(dy,dx)
let obrot = SKAction.rotateToAngle(kat + pi2, duration: 0)
z.runAction(obrot)
z.physicsBody?.velocity = CGVectorMake(vz*cos(kat), vz*sin(kat))
}
}
Obsługa kontaktów ciał fizycznych
W klasie GameScene implementuj protokół SKPhysicsContactDelegate,
we funkcji didMoveToView ustaw
physicsWorld.contactDelegate = self
W GameScene.sks zdefiniuj bity kategorii oraz maski kontaktów i kolizji dla playera i zombies
player: category Mask = 1
contact Mask, collision Mask = 2
player: category Mask = 2
contact Mask, collision Mask = 1
Gdy jakiś zombie dotknir playera:
func didBeginContact(contact: SKPhysicsContact) {
var a = contact.bodyA
var b = contact.bodyB
if a.categoryBitMask>b.categoryBitMask { swap(&a, &b) } // a ma mniejszą kategorię niż b
if a.categoryBitMask==1 && b.categoryBitMask==2 { gameOver(0) }
}
func gameOver(result: Int) {
exit(0)
}
Dodaj drzwi, aby gracz mógł uciec ze sceny.
W GameScene.sks umieść Color Sprite texture: door, name door
ustaw właściwości fizyczne: Body type: rectangle, Dynamic, Allow rotation, odznacz affected by gravity
oraz: category Mask = 3
contact Mask, collision Mask = 1
Wyjście ze sceny
W GameScene.swift zrób obiekt door,
ustaw właściwości fizyczne: body type: Rectangle, odznacz (disable) dynamic, rotation, gravity.
w klasie GameScene:
var door: SKSpriteNode?
we funkcji didMoveToView przypisz mu sprite’a ze sceny sks
door = self.childNodeWithName("door") as? SKSpriteNode
Uzupełnij funkcję obsługi kontaktu i funkcję gameOver:
jeśli player dopadł drzwi, to zacznij grę od początku.
func didBeginContact(contact: SKPhysicsContact) {
var a = contact.bodyA
var b = contact.bodyB
if a.categoryBitMask>b.categoryBitMask { swap(&a, &b) } // a ma mniejszą kategorię niż b
if a.categoryBitMask==1 && b.categoryBitMask==2 { gameOver(0) }
if a.categoryBitMask==1 && b.categoryBitMask==3 { gameOver(1) }
}
func gameOver(result: Int) {
if result == 0 {
exit(0)
}
else {
let s = GameScene(fileNamed: "GameScene")
let t = SKTransition.flipHorizontalWithDuration(1)
self.view?.presentScene(s!, transition: t)
}
}
Scena wynikowa
File / New / File / iOS Resource, SpriteKit Scene, name: MyScene,
ustaw rozmiary: 320 x 480
umieść 2 labele: jeden na informację o wyniku, drugi: „dotknij mnie”
File / New / File / Source file, Swift file, name: MyScene.
import SpriteKit
class MyScene: SKScene {
var result: Int = 0
override func didMoveToView(view: SKView) {
let lab = self.childNodeWithName("SKLabelNode_0") as? SKLabelNode
if result==0 {
self.backgroundColor = SKColor.blackColor()
lab!.text = "jesteś martwy"
}
else {
self.backgroundColor = SKColor.redColor()
lab!.text = "żyjesz"
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
let s = GameScene(fileNamed: "GameScene")
let t = SKTransition.flipHorizontalWithDuration(1)
self.view?.presentScene(s!, transition: t)
}
}
Zmiana w Gamescene.swift
func gameOver(result: Int) {
let s = MyScene(fileNamed: "MyScene")
s!.result = result
let t = SKTransition.flipHorizontalWithDuration(1)
self.view?.presentScene(s!, transition: t)
}
Dzwięki
Muzyka w tle gry - przypisana do playera
Player jako centrum nasłuchiwania innych dźwięków
self.listener = player
// w didMoveToView()
Zombies jako źródła własnych dźwięków
for child in self.children {
// rozszerzenie w didMoveToView()
if child.name == "zombie" {
if let z = child as? SKSpriteNode {
let glos = SKAudioNode(fileNamed: "moan.mp3")
z.addChild(glos)
Z.append(z)
}
}
}
Umieść obrazek podłogi sceny: Color Sprite / texture: background
ważne: umieść podłogę zanim zaczniesz operować światłem, podłoga będzie odbijać światło.
Światło
Dodaj SKLightNode do playera,
dokładnie na źródle jego światła,
parent: player, aby światło podążalo za nim
Falloff: 1,5 (wsp. zanikania światła)
Sam obiekt SKLightNode jest niewidoczny,
widoczne są tylko jego efekty w powiązaniu z innymi obiektami: rozpraszanie swiatła i cienie.
W tym celu dla każdego obiektu na scenie określ:
Lighting Mask: sprite odbija światło z otoczenia,
Shadow Cast Mask: sprite rzuca cień, jeśli stoi na linii światła
Shadowed Mask: określa swiatło sprita gdy sprite jest w cieniu, ale jest na pozycji z niższej od światła.
Ustaw playerowi i wszystkim zombie wszystkie trzy maski na wartość 1.
Ustaw dla sprite’a obrazka tła Lighting Mask = 1, a obie maski cienia na 0 (podłoga odbila światło, ale
nie rzuca cienia)
Kamera
Widok na część sceny i przesuwanie zakresu widoku w ślad za graczem.
Widoczny jest tylko fragment aktualnego poziomu, przez co gra staje się
bardziej nieprzewidywalna, a więc ciekawsza.
W GameScene.sks umieśc obiekt Camera nad playerem,
name: camera, parent: SKScene_0 scale 0.5 dla x i y, (decyduje ile sceny jest widoczne)
We właściwościach sceny ustaw tę kamerę.
Aktualizacja pozycji kamery w funkcji update() klasy GameScene:
override func update(currentTime: CFTimeInterval) {
updatePlayer()
updateZombies()
if let c = self.camera {
c.position = player.position
}
}
Ściany
Aby player i zombie nie wychodziły poza scenę, dodaj sprity z teksturą: wall, dopasuj ich położenie
i wymiary, we właściwościach fizycznych ustaw: body type: Rectangle, odznacz (disable) dynamic,
rotation, gravity.
Na podstawie:
https://www.raywenderlich.com/118225/introduction-sprite-kit-scene-editor

Podobne dokumenty