
วิธีการพัฒนาเกมบน iPhone ด้วย Sprite Kit ตอนที่ 3 กับการสร้างกระสุนในเกม Shooting ให้ยิงใส่ศัตรูเพื่อศึกษา การทำงานของ Collision Detect ในเกมครับ
จากบทความก่อนหน้านี้ เราจะเรียนรู้วิธีสร้างเกม 2D แนว Shooting มาบ้างแล้ว หากสงสัยกลับไปอ่านก่อนนะครับที่บทความนี้

- สร้างเกมบน iPhone ด้วย Sprite Kit สำหรับ 2D Game ตอนที่ 1
- สร้างเกมบน iPhone ด้วย Sprite Kit สำหรับ 2D Game ตอนที่ 2
ถ้าไม่มีข้อสงสัยแล้วก็มา เพิ่มการยิงกระสุน กับศึกษา Collision Detect กันครับ
แก้ไขส่วนบนสุดของ MyScene.m ของเราให้เป็นดังนี้ครับ (สังเกตุดีดี)
@interface MyScene()<SKPhysicsContactDelegate> @end @implementation MyScene
เมื่อแก้ไขแล้วให้ เพิ่ม Code ประกาศ Static Variable ใต้
@implementation MyScene
ตามนี้ครับ
static inline CGPoint rwAdd(CGPoint a, CGPoint b) {
return CGPointMake(a.x + b.x, a.y + b.y);
}
static inline CGPoint rwSub(CGPoint a, CGPoint b) {
return CGPointMake(a.x - b.x, a.y - b.y);
}
static inline CGPoint rwMult(CGPoint a, float b) {
return CGPointMake(a.x * b, a.y * b);
}
static inline float rwLength(CGPoint a) {
return sqrtf(a.x * a.x + a.y * a.y);
}
// Makes a vector have a length of 1
static inline CGPoint rwNormalize(CGPoint a) {
float length = rwLength(a);
return CGPointMake(a.x / length, a.y / length);
}
เมื่อได้กำหนดค่าของ Physics ที่กระสุนจะไปแล้ว ก็ได้เวลาสร้างเมธอดของการยิง เมื่อแตะทัชหน้าจอครับ
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch * touch = [touches anyObject]; CGPoint location = [touch locationInNode:self]; SKSpriteNode * projectile = [SKSpriteNode spriteNodeWithImageNamed:@"projectile"]; projectile.position = self.player.position; CGPoint offset = rwSub(location, projectile.position); if (offset.x <= 0) return; [self addChild:projectile]; CGPoint direction = rwNormalize(offset); CGPoint shootAmount = rwMult(direction, 1000); CGPoint realDest = rwAdd(shootAmount, projectile.position); float velocity = 480.0/1.0; float realMoveDuration = self.size.width / velocity; SKAction * actionMove = [SKAction moveTo:realDest duration:realMoveDuration]; SKAction * actionMoveDone = [SKAction removeFromParent]; [projectile runAction:[SKAction sequence:@[actionMove, actionMoveDone]]]; }
กำหนดตำแหน่งเมื่อเกิดการแตะที่หน้าจอให้เป็นจุดหมายของกระสุนที่
CGPoint direction = rwNormalize(offset);
ต่อมาก็มาปรับเรื่องของ Coliision Detect ครับ เมื่อกระสุนเรา ยิงไปโดนศัตรู จะเกิดเหตุการณ์ขึ้นครับ
แก้ไขข้อมูล MyScene.m ส่วนบทสุดดังนี้ครับ
#import "MyScene.h" static const uint32_t projectileCategory = 0x1 << 0; static const uint32_t monsterCategory = 0x1 << 1;
ใส่คำสั่งเล็กน้อยเกี่ยวกับ Physics และ Vector ในการยิงไปโดนที่ initWithSize()
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
self.backgroundColor = [SKColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
self.player = [SKSpriteNode spriteNodeWithImageNamed:@"player2"];
self.player.position = CGPointMake(100,CGRectGetMidY(self.frame));
self.physicsWorld.gravity = CGVectorMake(0,0);
self.physicsWorld.contactDelegate = self;
[self addChild:self.player];
}
return self;
}
เพิ่มการกระทำ เมื่อโดนศัตรูของเรา โดยคำสั่งต่อไปนี้ ในเมธอด addMonster()
monster.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:monster.size]; monster.physicsBody.dynamic = YES; monster.physicsBody.categoryBitMask = monsterCategory; monster.physicsBody.contactTestBitMask = projectileCategory; monster.physicsBody.collisionBitMask = 0;
ทำการจำขนาดของ monster เป็น Rectangle จดจำค่า projectile หรือกระสุน ไว้ และจำค่า monster หรือศัตรูไว้ให้รู้ว่า Object 2 ตัวนี้เกี่ยวข้องกัน
ต่อไปคือ การเพิ่มคำสั่ง CollisionDetection ในเมธอด touchesEnded:withEvent()
หาภาพกระสุนมาชื่อว่า fire.png

SKSpriteNode * projectile = [SKSpriteNode spriteNodeWithImageNamed:@"fire"]; projectile.position = self.player.position; projectile.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:projectile.size.width/2]; projectile.physicsBody.dynamic = YES; projectile.physicsBody.categoryBitMask = projectileCategory; projectile.physicsBody.contactTestBitMask = monsterCategory; projectile.physicsBody.collisionBitMask = 0; projectile.physicsBody.usesPreciseCollisionDetection = YES;
เมื่อเกิดการกระทับกันให้ NSLog ขึ้นมาว่า “Hit” ครับ แล้วทำการเคลียร์ตัวแปรของศัตรูที่บินไปมาออกไปจากหน้าจอทันที
- (void)projectile:(SKSpriteNode *)projectile didCollideWithMonster:(SKSpriteNode *)monster {
NSLog(@"Hit");
[projectile removeFromParent];
[monster removeFromParent];
self.monstersDestroyed++;
if (self.monstersDestroyed > 10) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Game Finish!" message:@"Play Again?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil];
// optional - add more buttons:
[alert addButtonWithTitle:@"OK"];
[alert show];
}
}
เพิ่มเงื่อนไขมาว่าถ้าเราโจมตีศัตรูได้มากกว่า 10 ตัวให้มีการเรียก UIAlertView ขึ้นมาบอกว่าเราผ่านด่านแล้วครับ
เปิดไฟล์ MyScene.h ขึ้นมา เพิ่มคำสั่งต่อไปนี้ลงไปเพื่อเตรียมพร้อมสำหรับการเล่นใหม่ในแต่ละครั้งเมื่อจบเกม
#import <SpriteKit/SpriteKit.h> @interface MyScene : SKScene @property (nonatomic) SKSpriteNode * player; @property (nonatomic) NSTimeInterval lastSpawnTimeInterval; @property (nonatomic) NSTimeInterval lastUpdateTimeInterval; @property (nonatomic) int monstersDestroyed; @end
ทำการ Synthesize ตัวแปรที่เพิ่มเข้าไปที่ MyScene.m ครับ
@synthesize player; @synthesize lastSpawnTimeInterval; @synthesize lastUpdateTimeInterval; @synthesize monstersDestroyed;
เพิ่มเมธอดสำหรับเริ่มเกมใหม่ลงไปครับ didBeginContact()
- (void)didBeginContact:(SKPhysicsContact *)contact
{
SKPhysicsBody *firstBody, *secondBody;
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 projectile:(SKSpriteNode *) firstBody.node didCollideWithMonster:(SKSpriteNode *) secondBody.node];
}
}
ทดสอบเกมของเราอีกครั้งโดยการ Run แล้วลอง ยิงกระสุนใส่ศัตรูสัก 10 ตัวดูครับ จะพบว่าเกม Shooting แบบง่ายของเรานั้นเสร็จสมบูรณ์แล้ว เอาไปอวดเพื่อนได้เลย!
Source Code ของ Project นี้ดาวน์โหลดได้ที่: http://adf.ly/gS6vt
บทความที่เกี่ยวข้อง
- สร้างเกมบน iPhone ด้วย Sprite Kit สำหรับ 2D Game ตอนที่ 1
- สร้างเกมบน iPhone ด้วย Sprite Kit สำหรับ 2D Game ตอนที่ 2





