Article for GamerDeveloperFeaturedGame DevelopmentGame DevelopmentiOS DeveloperProgramming LanguageSwift

เขียนเกมบน iPhone ด้วย SpriteKit กับ Swift ตอนที่ 1 จัดการ Scene

บทเรียนรอบนี้จะเป็นการจัดการข้อมูลไฟล์ภาพ กราฟิกที่จะใช้ในเกมด้วยภาษา Swift ผ่าน Template ของ Xcode6 อย่าง SpriteKit ในเรื่องของการจัดการ Scene เบื้องต้น
โดยปรกติแล้ว XCode6 จะมี Template ของเกมแนบมาให้คือ SpriteKit ที่เราก็เคย แนะนำการพัฒนากันมาตลอดในภาษา Objective-C และได้เคยแนะนำการพัฒนาเกมเบื้องต้นไปบ้างแล้วเกี่ยวกับ Physics ในบทความ เขียนเกม iPhone ด้วย SpriteKit ภาษา Swift กับการใช้หลัก Physics รอบนี้เราจะมาเรียนรู้แบบแตกบทเรียนออกไป ไม่ยาวมากจะได้ฝึกหัดทำกันดู ตามๆ กันไปครับ

เริ่มต้นเขียนเกม เกมนี้ผมจะเน้นเรื่องของการ จัด Scene การวาง Graphics Asset หรือไฟล์ต่างๆ ที่ต้องใช้ ไปจนถึงการเคลื่อนที่ MoveMent ของตัว Object ไปตามมือของเรา ด้วย TouchBegan ปรกติครับ รอบแรกในตอนที่ 1 นี้เราจะมาจัดการเรื่อง Scene กันก่อน

เปิด New Project ขึ้นมาใหม่เลือก Template เป็น SpriteKit ครับ

เปิด New Project ขึ้นมาใหม่เลือก Template เป็น SpriteKit ครับ
เปิด New Project ขึ้นมาใหม่เลือก Template เป็น SpriteKit ครับ

ต่อจากนั้นให้เลือกเป็น iPhone และเป็น SpriteKit นะครับไม่ใช่ SceneKit ตั้งชื่อเกมให้เรียบร้อย

ตั้งชื่อเกม
ตั้งชื่อเกม

เตรียมไฟล์กราฟิก ที่เราจะใช้ทำเกมให้พร้อม ซึ่งผมเลือก ภาพของเรือโจรสลัด และ ฉากหลังเป็นมหาสมุทร ดังนี้

ไฟล์ pirate.png
ไฟล์ pirate.png
ไฟล์ ocean.jpg
ไฟล์ ocean.jpg

นำไฟล์ภาพทั้งสองไปวางไว้ใน Bundle Project ของเราให้เรียบร้อยครับ

วางไฟล์ลงไปใน Bundle Project
วางไฟล์ลงไปใน Bundle Project

เปิดไฟล์ GameViewController ขึ้นมา ในบทเรียนนี้เราจะไม่ ยุ่งเกี่ยวกับ ไฟล์ sks ซึ่งเป็น Subclass ของการสร้าง Scene เราจะยังไม่ได้ใช้งานมันในตอนนี้ ให้ทำการลบ บรรทัด ข้างล่างนี้ออกไป

extension SKNode {
    class func unarchiveFromFile(file : NSString) -> SKNode? {
        if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
            var sceneData = NSData.dataWithContentsOfFile(path, options: .DataReadingMappedIfSafe, error: nil)
            var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)
            
            archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
            let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as GameScene
            archiver.finishDecoding()
            return scene
        } else {
            return nil
        }
    }
}

และแก้ไข เมธอด viewDidLoad() ในส่วนของบรรทัด

if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene

ให้เป็น

if let scene = GameScene.sceneWithSize(view.frame.size)

เป็นการบอกให้ SpriteKit เวอร์ชันใหม่นี้ไม่ต้องไปอ้างถึงไฟล์ sks ที่กล่าวไว้ข้างต้นครับ

ดังนั้นไฟล์ใน GameViewController.Swift จะต้องเป็นแบบนี้ครับ

//
//  GameViewController.swift
//  LineFinger
//
//  Created by DAYDEV on 10/14/2557 BE.
//  Copyright (c) 2557 DAYDEV. All rights reserved.
//

import UIKit
import SpriteKit

class GameViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        if let scene = GameScene.sceneWithSize(view.frame.size) {
            // Configure the view.
            let skView = self.view as SKView
            skView.showsFPS = true
            skView.showsNodeCount = true
            
            /* Sprite Kit applies additional optimizations to improve rendering performance */
            skView.ignoresSiblingOrder = true
            
            /* Set the scale mode to scale to fit the window */
            scene.scaleMode = .AspectFill
            
            skView.presentScene(scene)
        }
    }

    override func shouldAutorotate() -> Bool {
        return true
    }

    override func supportedInterfaceOrientations() -> Int {
        if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
            return Int(UIInterfaceOrientationMask.AllButUpsideDown.toRaw())
        } else {
            return Int(UIInterfaceOrientationMask.All.toRaw())
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Release any cached data, images, etc that aren't in use.
    }

    override func prefersStatusBarHidden() -> Bool {
        return true
    }
}

เปิดไฟล์ GameScene.Swift ขึ้นมา ลบข้อมูล เมธอดเดิมๆ ที่ Template สร้างไว้ออกให้หมด ทำการจัดการ Scene เริ่มต้นของเราให้เรียบร้อย ให้สร้าง เมธอดฟังก์ชันใหม่เกี่ยวกับ init() ใส่เข้าไป ดังนี้

import SpriteKit

class GameScene: SKScene {
    
    override init(size: CGSize) {
        super.init(size: size)
        
        let background = SKSpriteNode(imageNamed: "ocean.jpg")
        background.anchorPoint = CGPoint(x: 0, y: 0)
        addChild(background)
        
        let boat = SKSpriteNode(imageNamed: "pirate")
        boat.position = CGPoint(x: size.width / 2, y: size.height / 2)
        addChild(boat)
    }
    
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

เราสร้างตัวแปรชื่อ background มาเก็บข้อมูลฉากหลังคือ ocean.jpg ไว้เซ็ตค่าตำแหน่งเริ่มต้นของหน้าจอที่ พิกัด x,y ที่ (0,0) และสร้างตัวแปร boat เก็บข้อมูลไฟล์ png ที่ชื่อ pirate กำหนดพิกัดการแสดงผลที่กลางหน้าจอของแอพพลิเคชันของเรา

สรุปก็คือไฟล์ GameScene.Swift จะต้องมีภาพรวมของ Source Code ดังนี้

//
//  GameScene.swift
//  LineFinger
//
//  Created by DAYDEV on 10/14/2557 BE.
//  Copyright (c) 2557 DAYDEV. All rights reserved.
//

import SpriteKit

class GameScene: SKScene {
    
    override init(size: CGSize) {
        super.init(size: size)
        
        let background = SKSpriteNode(imageNamed: "ocean.jpg")
        background.anchorPoint = CGPoint(x: 0, y: 0)
        addChild(background)
        
        let boat = SKSpriteNode(imageNamed: "pirate")
        boat.position = CGPoint(x: size.width / 2, y: size.height / 2)
        addChild(boat)
    }
    
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func didMoveToView(view: SKView) {
        /* Setup your scene here */
    }
    
    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        /* Called when a touch begins */
    }
   
    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
    }
}

ทำการ Run ตัว Project เกม SpriteKit ของเราทันที

เกมพร้อม
เกมพร้อม

จะเห็นว่า เกมของเราพร้อมแล้วในเรื่องของการเพิ่ม Object และ Sprite Graphics ที่วางบน Background พร้อมสรรพ ลองทำตามดูนะครับ คงไม่ต้องมี Source Code หรอกมั้งนะ

บทความต่อไปเป็นการทำให้เรือขยับได้ครับอ่านต่อที่ เขียนเกม iPhone ด้วย SpriteKit กับ Swift ตอนที่ 2 จัดการ Class

อ้างอิง: http://www.raywenderlich.com/

Asst. Prof. Banyapon Poolsawas

อาจารย์ประจำสาขาวิชาการออกแบบเชิงโต้ตอบ และการพัฒนาเกม วิทยาลัยครีเอทีฟดีไซน์ & เอ็นเตอร์เทนเมนต์เทคโนโลยี มหาวิทยาลัยธุรกิจบัณฑิตย์ ผู้ก่อตั้ง บริษัท Daydev Co., Ltd, (เดย์เดฟ จำกัด)

Related Articles

Back to top button

Adblock Detected

เราตรวจพบว่าคุณใช้ Adblock บนบราวเซอร์ของคุณ,กรุณาปิดระบบ Adblock ก่อนเข้าอ่าน Content ของเรานะครับ, ถือว่าช่วยเหลือกัน