วิธีการเขียนเกมด้วย Sprite Kit บน iPhone สำหรับสร้างเกม 2D กับการควบคุมตำแหน่งของตัวละครให้เคลื่อนไปมาเมื่อมีการแตะหน้าจอในตำแหน่งแนวดิ่งได้อย่างง่ายครับเป็นการเขียนโปรแกรม Objective C ให้สามารถเคลื่อนตำแหน่งของตัวละครได้อย่างง่ายดายครับ เมื่อมีการแตะหน้าจอตำแหน่งต่างๆ ครับ
เริ่มต้นพัฒนา
สร้าง New Project ขึ้นมาใหม่เป็น SpriteKit Game ครับ
ตั้งชื่อ Project ให้เรียบร้อยหลังจากนั้นก็เริ่มกันได้เลยครับ
ในตัวอย่างนี้จะใช้ player.png มาเป็นตัวละครครับ โดยผมไปหาภาพมาจากเว็บไซต์ http://design.tutsplus.com ดังนี้
ต่อมาปรับแนวตั้งแนวนอนของ แอพพลิเคชันของเราครับ ผมจะเน้นไปที่การวางเกมในแนวนอนก่อนแล้วกัน เลือกเครื่องหมายถูกออกไปจาก Portrait ครับ
สร้าง ตัว Player หรือตัวละครเกมของเราก่อน เปิดไฟล์ MyScene.h ขึ้นมาครับ ประกาศตัวแปรตามนี้
#import <SpriteKit/SpriteKit.h> @interface MyScene : SKScene @property (nonatomic) SKSpriteNode * hero; @end
เพิ่ม Synthesize ตัวแปร hero ที่ MyScene.m ครับ แก้ไขส่วนของ header ใหม่เป็นดังนี้
#import "MyScene.h. @interface MyScene()<SKPhysicsContactDelegate> @end @implementation MyScene @synthesize hero;
คำสั่ง initWithSize() ก็จะต้องเป็นแบบนี้นะครับ
-(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { self.backgroundColor = [SKColor whiteColor]; self.physicsWorld.gravity = CGVectorMake(0,0); self.physicsWorld.contactDelegate = self; //เตรียม Add Hero } return self; }
ต่อมาประกาศส่วนของ SceneDelegate ขึ้นมาทั้ง Hero และ BG ครับ เป็น Static Const
#import "MyScene.h" static const uint32_t heroCategory = 0x1 << 0; static const uint32_t obstacleCategory = 0x1 << 1;
รอบนี้เราจะเพิ่ม เมธอดมาแทนที่ให้โหลดภาพกราฟิกของ Player เข้าไปเรียกใช้ เมธอด addHero() เพื่อเป็นการเรียกแสดงแบบ OOP ครับ สร้างเมธอด addHero() ดังนี้
-(void)addHero { //initalizing spaceship node hero = [SKSpriteNode spriteNodeWithImageNamed:@"player"]; [hero setScale:0.5]; hero.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:hero.size]; hero.physicsBody.categoryBitMask = heroCategory; hero.physicsBody.dynamic = YES; hero.physicsBody.contactTestBitMask = obstacleCategory; hero.physicsBody.collisionBitMask = 0; hero.name = @"hero"; hero.position = CGPointMake(120,160); [self addChild:hero]; }
เป็นการโหลด ภาพ player.png เข้าไปเก็บไว้ในตัวแปร hero และมีการสร้าง Class ของเมธอดมันโดยเฉพาะใน addHero() ครับ
ไปที่ไฟล์ ViewController.m อีกครั้ง เคลียร์ไฟล์ ViewController ในส่วนของไฟล์ทั้งหมดให้เป็นตามนี้ครับ
#import "ViewController.h" #import "MyScene.h" @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; // Configure the view. SKView * skView = (SKView *)self.view; if (!skView.scene) { skView.showsFPS = YES; skView.showsNodeCount = YES; // Create and configure the scene. SKScene * scene = [MyScene sceneWithSize:skView.bounds.size]; scene.scaleMode = SKSceneScaleModeAspectFill; // Present the scene. [skView presentScene:scene]; } } - (BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientations { if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { return UIInterfaceOrientationMaskAllButUpsideDown; } else { return UIInterfaceOrientationMaskAll; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } @end
กลับมาที่ ไฟล์ MyScene.m ให้แก้ไขส่วนของ
-(id)initWithSize:(CGSize)size { }
ตามนี้ครับ
-(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { self.backgroundColor = [SKColor whiteColor]; self.physicsWorld.gravity = CGVectorMake(0,0); self.physicsWorld.contactDelegate = self; [self addHero]; // เรียก add Hero } return self; }
ลอง Run ดูรอบแรกก่อนว่ามีอะไรติดขัดไหม
ต่อมาเราจะทำให้มันเคลื่อนไหวไปตามตำแหน่งที่ แตะหน้าจอครับ เปิดไฟล์ MyScene.h ขึ้นมา ประกาศตัวแปรเพิ่มดังนี้
@property (strong,nonatomic) SKAction * actionMoveUp; @property (strong,nonatomic) SKAction * actionMoveDown;
กลับไปเพิ่ม Synthesize ใน MyScene.m ตามนี้ครับ
@synthesize actionMoveDown; @synthesize actionMoveUp;
แก้ไข MyScene.m ส่วนของเมธอด addHero() ให้เป็นดังนี้ครับ
-(void)addHero { //initalizing spaceship node hero = [SKSpriteNode spriteNodeWithImageNamed:@"player"]; [hero setScale:0.5]; hero.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:hero.size]; hero.physicsBody.categoryBitMask = heroCategory; hero.physicsBody.dynamic = YES; hero.physicsBody.contactTestBitMask = obstacleCategory; hero.physicsBody.collisionBitMask = 0; hero.name = @"hero"; hero.position = CGPointMake(120,160); [self addChild:hero]; actionMoveUp = [SKAction moveByX:0 y:30 duration:.2]; actionMoveDown = [SKAction moveByX:0 y:-30 duration:.2]; }
เพิ่ม เมธอด -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event ขึ้นมาตามด้วยคำสั่งต่อไปนี้ครับ
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { /* Called when a touch begins */ UITouch *touch = [touches anyObject]; CGPoint touchLocation = [touch locationInNode:self.scene]; if(touchLocation.y >hero.position.y){ if(hero.position.y < 270){ [hero runAction:actionMoveUp]; } }else{ if(hero.position.y > 50){ [hero runAction:actionMoveDown]; } } }
ถ้าการแตะหน้าจอนั้น ตำแหน่งของ hero เราในแกน y อยู่น้อยกว่า 270 จะทำให้ตัวละคร hero เราเลื่อนไปข้างบนด้วย Action ที่ชื่อ actionMoveUp ครับ เช่นกันถ้าตำแหน่งสูงกว่า 50 ของความสูงหน้าจอก็จะเลื่อนลงด้วย actionMoveDown ครับ
ทดสอบ Run ตัวแอพพลิเคชันของเราดูครับ
ไม่ยากอีกแล้วครับ หวังว่าคงจะลองทำตามกันดูได้อย่าง ไหลลื่นนะครับ Source Code นั้นยังไม่ให้ครับ เพราะคิดว่าจะ ทำทีเดียวพร้อมกับฉาก Background เลื่อนในบทความต่อไปเลยดีกว่า
อ่านต่อที่: เขียนเกมบน iPhone ด้วย Sprite Kit การสร้างฉาก Background ให้เลื่อนได้