วิธีการพัฒนาเกม สำหรับผู้ที่ต้องการเขียนเกมบน iPhone หรือ iOS7 ด้วย Sprite Kit กับการบังคับให้ตัวละครในเกมวิ่งตาม Line ที่เราวาดบนหน้าจอสมาร์ทโฟนแบบง่ายครับ
เริ่มต้นให้เปิด XCode 5.1 ขึ้นมาครับ (ที่ใช้ปัจจุบันตอนนี้) แล้ว New Project เป็น Sprite Kit สำหรับเขียนเกม 2D บน แพลตฟอร์ม iOS7 ครับ ตั้งชื่อ Project ให้เรียบร้อยเลยครับ
ต่อมาให้ไปแก้ไขไฟล์ MyScene.m ให้เป็นดังนี้ครับ เพื่อล้างค่า Project Sample เครื่องบินก่อนหน้านี้
#import "MyScene.h" @implementation MyScene -(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { /* Setup your scene here */ self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0]; } return self; } -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { /* Called when a touch begins */ } -(void)update:(CFTimeInterval)currentTime { /* Called before each frame is rendered */ } @end
ลองทำการ “Run” ตัว Project ของเราก่อนครับเพื่อดูว่า ไม่มีอะไรผิดพลาด
เมื่อทดสอบเสร็จแล้วต่อมา เราต้องมีการประกาศ ตัวแปรสำหรับ BG และ Character ครับ ให้สร้าง Group ชื่อ Graphics ขึ้นมาก่อน
เอาภาพ BG และ Character ที่เตรียมมาแล้วไปวางใน Group ของ Bundles Project เราครับ แล้วเขียน Code เพิ่มใน MyScene.m ใน เมธอด -(id)initWithSize:(CGSize)size ดังนี้
-(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { /* Setup your scene here */ SKSpriteNode *bg = [SKSpriteNode spriteNodeWithImageNamed:@"BG"]; bg.anchorPoint = CGPointZero; [self addChild:bg]; SKSpriteNode * character = [SKSpriteNode spriteNodeWithImageNamed:@"here"]; character.position = CGPointMake(self.size.width / 2.0f, self.size.height / 2.0f); [self addChild:character]; } return self; }
โดยเรียก BG.png เป็นฉากหลัง และ here.png เป็น Character ครับ ทดสอบโดยการ “Run” ตัว Project อีกครั้ง ว่าถูกต้องหรือเปล่า?
นั่นคือสัญญาณที่ดีครับไม่มีปัญหาอะไร ต่อมาก็เริ่ม เขียน Code ให้ตัวละครของเราเดินทางตามเส้นที่เราลากไปมาบนเกมกันครับ เราจะต้องสร้าง Class ขึ้นมาใหม่ ตั้งชื่อว่า Player ครับ
เปิดไฟล์ Player.h ขึ้นมาครับ เพิ่ม เมธอดใหม่ประกาศขึ้นมา คือ เมธอดในการเก็บค่า Point ของตำแหน่งที่เรากดลงหน้าจอ และ เมธอด Walk สำหรับให้ ตัวละครเราเดินตามไป
#import <SpriteKit/SpriteKit.h> @interface Player : SKSpriteNode - (void)addNewPoint:(CGPoint)point; - (void)walk:(NSNumber *)dt; @end
สำหรับ ไฟล์ Player.m นั้นให้เรากำหนดการเคลื่อนไหวของตัวละครเราหน่อยครับ ประกาศคำสั่งตามนี้
#import "Player.h" static const int POINTS_PER_SEC = 80; @implementation Player { NSMutableArray *_wayPoints; CGPoint _velocity; } - (instancetype)initWithImageNamed:(NSString *)name { if(self = [super initWithImageNamed:name]) { _wayPoints = [NSMutableArray array]; } return self; }
มีการกำหนด Constant ตัวแปรเป็น ความเร็วการเคลื่อนไหวต่อวินาที 80 ครับ ตามด้วยกำหนด NSMutableArray ขึ้นมา และ CGPoint สำหรับเก็บค่าปลายทางที่เราจะทำการ Touch ที่หน้าจอ
เพิ่ม เมธอดใน Player.m อีกที 2 เมธอด ตามด้วยคำสั่งดังนี้ครับ
- (void)addNewPoint:(CGPoint)point { [_wayPoints addObject:[NSValue valueWithCGPoint:point]]; } - (void)walk:(NSNumber *)dt { CGPoint currentPosition = self.position; CGPoint newPosition; //1 if([_wayPoints count] > 0) { CGPoint targetPoint = [[_wayPoints firstObject] CGPointValue]; CGPoint offset = CGPointMake(targetPoint.x - currentPosition.x, targetPoint.y - currentPosition.y); CGFloat length = sqrtf(offset.x * offset.x + offset.y * offset.y); CGPoint direction = CGPointMake(offset.x / length, offset.y / length); _velocity = CGPointMake(direction.x * POINTS_PER_SEC, direction.y * POINTS_PER_SEC); //2 TODO: Add movement logic here newPosition = CGPointMake(currentPosition.x + _velocity.x * [dt doubleValue], currentPosition.y + _velocity.y * [dt doubleValue]); self.position = newPosition; //3 if(CGRectContainsPoint(self.frame, targetPoint)) { [_wayPoints removeObjectAtIndex:0]; } } }
เป็นการคำนวณ ระยะ ของตำแหน่งที่เราแตะ และ คำนวณต้นทางไป ยังปลายทางเรียบร้อย ต่อมาไปที่ไฟล์ MyScene.m ครับ ทำการ Import Header ของ Player.h ลงไป พร้อมตัวแปรเพิ่มเติมครับ
#import "MyScene.h" #import "Player.h" @implementation MyScene { Player *_movingPlayer; NSTimeInterval _lastUpdateTime; NSTimeInterval _dt; }
มีการเก็บ Interval ในการรับ เวลาของการเคลื่อนไหวของตัวละครเข้ามา เพื่อใช้กับเมธอด update() ที่มีอยู่ ได้อย่างสมบูรณ์ครับต่อจากนั้น แก้ไข เมธอด -(id)initWithSize() จากเดิมคือ
-(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { /* Setup your scene here */ SKSpriteNode *bg = [SKSpriteNode spriteNodeWithImageNamed:@"BG"]; bg.anchorPoint = CGPointZero; [self addChild:bg]; SKSpriteNode *character = [SKSpriteNode spriteNodeWithImageNamed:@"here"]; character.position = CGPointMake(self.size.width / 2.0f, self.size.height / 2.0f); [self addChild:character]; } return self; }
ให้เป็น
-(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { /* Setup your scene here */ SKSpriteNode *bg = [SKSpriteNode spriteNodeWithImageNamed:@"BG"]; bg.anchorPoint = CGPointZero; [self addChild:bg]; Player *character = [[Player alloc] initWithImageNamed:@"here"]; character.name = @"player"; character.position = CGPointMake(self.size.width / 2.0f, self.size.height / 2.0f); [self addChild:character]; } return self; }
เป็นการจำ Node ของ Player ขึ้นมาว่าชื่อ Player สำหรับอ้างอิงครับ ต่อมาไปแก้ไข เมธอด touchBegan() ดังนี้
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { /* Called when a touch begins */ CGPoint touchPoint = [[touches anyObject] locationInNode:self.scene]; SKNode *node = [self nodeAtPoint:touchPoint]; if([node.name isEqualToString:@"player"]) { [(Player *)node addNewPoint:touchPoint]; _movingPlayer = (Player *)node; } }
เพิ่มเมธอดใหม่เข้าไปอีกนิดคือ
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { CGPoint touchPoint = [[touches anyObject] locationInNode:self.scene]; if(_movingPlayer) { [_movingPlayer addNewPoint:touchPoint]; } }
อย่าลืมอัพเด็ท Interval ของ เมธอด update() ครับผม
-(void)update:(CFTimeInterval)currentTime { /* Called before each frame is rendered */ _dt = currentTime - _lastUpdateTime; _lastUpdateTime = currentTime; [self enumerateChildNodesWithName:@"player" usingBlock:^(SKNode *character, BOOL *stop) { [(Player *)character walk:@(_dt)]; }]; }
เอาล่ะ ลองทดสอบ “Run” ตัว Project ของเราหน่อยดีกว่า
ทำการ Slide หน้าจอไปตาม ตำแหน่งต่างๆ ตัวละครของเราจะเดินตามมันไปครับ ตามเส้นที่เราวาดไว้ ทุกอย่างเลย
ดาวน์โหลด Source Code : http://adf.ly/nNqrx
หวังว่าคงจะช่วยเหลือเพื่อนๆ ที่ต้องการเขียนเกมบน iOS7 ด้วย Sprite Kit ได้นะครับ
เพิ่มเติม
สำหรับใครที่สนใจพัฒนาแอพพลิเคชัน บน iOS7.1 สามารถซื้อหนังสือของ เว็บไซต์ Daydev ได้แล้วตาม รายละเอียดนี้ครับ
[fb_embed_post href=”https://www.facebook.com/photo.php?fbid=777971808913916&set=a.390784317632669.96833.323517721025996&type=1/” width=”600″/]