ขั้นตอนการพัฒนาแอพพลิเคชันเกมบน XCode และ Cocos2D สำหรับการสร้างฉากเปิดเกม และแมนูสำหรับเลือกเข้าสู่เกมเบื้องต้นสำหรับ iOS Developer มือใหม่ในบทสำหรับการสร้างเมนูนั้น ผมได้ขอยืมบทความ และชุด Source Code บางตัวจากเว็บไซต์ http://www.thaiiosdev.com/node/155 มาประยุกต์เล็กน้อยสำหรับบทความนี้ครับ (ยังไงก็ขอขอบคุณเว็บไซต์ ThaiiOSDev มากครับ)
หลังจากที่ได้รู้จักกับชุดพัฒนาเกมแบบ 2 มิติบน iOS อย่าง Cocos2D และได้เรียนรู้วิธีติดตั้งไปแล้ว ต่อมาจะเป็นขั้นตอนการพัฒนาเกมด้วย Cocos2D เกมแรกของคุณ
เริ่มต้นพัฒนา XCode และ Cocos2D
ให้ทำการสร้าง New Project ขึ้นมาใหม่ โดยเลือก Template เป็น Cocos2d-iphone (Cocos2D iOS)
ทำการ “Run” ทดสอบก่อนว่ามีปัญหาอะไรหรือไม่ ด้วยSource Code เบื้องต้นถ้่าไม่มีปัญหาจะพบหน้าจอ Hello World! ถ้าไม่มีปัญหาให้ปิด iOS Simulator ที่กำลังทดลอง แอพพลิเคชันของเราออก ในชุด Source Code เบื้องต้นนั้นเราจะไม่ไปยุ่งกับมัน ให้ทำการ New File เข้าไปใน Project โดยเลือกเป็น CCNode Class
ให้เราเลือก Subclass ของNew File ให้เป็น CCLayer ขึ้นมาใหม่ แล้วตั้งชื่อว่า MenuScene เพื่อสร้างหน้าเมนูของเกม
เปิดไฟล์ MenuScene.h ขึ้นมาเพิ่มฟังก์ชัน scene เข้าไป
#import
#import "cocos2d.h"
@interface MenuScene : CCLayer {
}
+(id) scene;
@end
หลังจากนั้นให้ไปแก้ไขที่ไฟล์ MenuScene.m โดยเพิ่มคำสั่งให้อยู่ในรูปแบบนี้
#import "MenuScene.h"
@implementation MenuScene
+(id) scene
{
CCScene *scene = [CCScene node];
MenuScene *layer = [MenuScene node];
[scene addChild:layer];
return scene;
}
@end
ต่อมาให้สร้างคำสั่ง Init เพื่อแสดงผล หน้าเมนูสำหรับเข้าเล่นเกมของเรา
คำสั่งของ Cocos2D ที่เป็น Class ในการแสดงผล เมนูตัวอักษรนั้น จะต้องแสดงผลทับกับไฟล์ของตัวอักษรในเครื่องคอมพิวเตอร์ของเราโดยจะมีรูปแบบ Class ในการเรียกแสดงผล ตัวอักษรต่างๆ ในเกมรูปแบบดังนี้
CCLabelTTF *Var = [CCLabelTTF labelWithString:@"Menu" fontName:@"FontName" fontSize:42];
[self addChild:Var];
รูปแบบข้างต้นเป็นรูปแบบของการเรียกใช้เมนูสำหรับ สร้างเกม ต่อมาเพิ่มคำสั่งในไฟล์ MenuScene.m ลงไปว่า
-(id) init
{
if( (self=[super init] )) {
//เก็บขนาดของหน้าจอ
CGSize size = [[CCDirector sharedDirector] winSize];
//สร้างเมนูจากข้อความและกำหนดตำแหน่งการวาง
CCLabelTTF *menu = [CCLabelTTF labelWithString:@"Menu" fontName:@"Marker Felt" fontSize:42];
menu.position = ccp(size.width/2, size.height-50);
CCLabelTTF *menuPlay = [CCLabelTTF labelWithString:@"Play" fontName:@"Marker Felt" fontSize:30];
menuPlay.position = ccp(size.width/2, size.height-120);
CCLabelTTF *menuHowToPlay = [CCLabelTTF labelWithString:@"How To Play" fontName:@"Marker Felt" fontSize:30];
menuHowToPlay.position = ccp(size.width/2, size.height-170);
CCLabelTTF *menuAbout = [CCLabelTTF labelWithString:@"About Us" fontName:@"Marker Felt" fontSize:30];
menuAbout.position = ccp(size.width/2, size.height-220);
[self addChild:menu];
[self addChild:menuPlay];
[self addChild:menuHowToPlay];
[self addChild:menuAbout];
//เพื่อให้สามารถ Touch หน้าจอได้
self.isTouchEnabled = YES;
}
return self;
}
ต่อมาเพิ่ม คำสั่งสำหรับตรวจสอบว่า เราทัชหน้าจอตรงกับ ตำแหน่งพิกัดที่วางเมนู “Play” บนหน้าจอหรือไม่
-(BOOL) ccTouchesBeganed:(NSSet *) touches withEvent:(UIEvent *) event
{
return YES;
}
และเพิ่มคำสั่งสำหรับกิจกรรมหลังจากทำการทัช เสร็จแล้ว หรือปล่อยนิ้วออกจากหน้าจอ
-(void) ccTouchesEnded:(NSSet *) touches withEvent:(UIEvent *) event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
//ตรวจสอบตำแหน่งที่เรา Touch ว่าตรงกับเมนู Play หรือไม่
if (location.x >= 170 && location.x <= 320 && location.y >= 180 && location.y <= 220)
{
NSLog(@"(%f, %f)", location.x, location.y);
//แสดงตำหน่งที่เรา Touch ใน Console
}
}
สุดท้าย เราต้องเพิ่มคำสั่งการคิืนความจำของแอพพลิเคชันลงไป เพราะแอพพลิเคชันประเภทเกมจะกินความจำมาก
-(void) dealloc
{
[super dealloc];
}
ต่อมาให้สร้าง New File ขึ้นมาใหม่ เป็น CCLayer เช่นเดียวกับไฟล์ MenuScene ตั้งชื่อว่า PlayScene
ทำการเพิ่มคำสั่งลงไปในไฟล์ PlayScene.h ดังนี้
#import
#import "cocos2d.h"
@interface PlayScene : CCLayer {
}
+(id)scene;
@end
ต่อมาให้เพิ่มคำสั่งเข้าไปที่ไฟล์ PlayScene.m
#import "PlayScene.h"
@implementation PlayScene
+(id) scene
{
CCScene *scene = [CCScene node];
PlayScene *layer = [PlayScene node];
[scene addChild:layer];
return scene;
}
@end
ต่อมาให้เพิ่มคำสั่ง Init ลงไปในไฟล์ PlayScene.m ต่อจากคำสั่ง scene เมื่อครู่ ก่อนปิด @end
-(id) init
{
if( (self=[super init] )) {
CGSize size = [[CCDirector sharedDirector] winSize];
CCLabelTTF *label = [CCLabelTTF labelWithString:@"Play" fontName:@"Marker Felt" fontSize:42];
label.position = ccp(size.width/2, size.height-50);
[self addChild:label];
//เพื่อให้สามารถ Touch หน้าจอได้
self.isTouchEnabled = YES;
}
return self;
}
สุดท้ายให้เพิ่มคำสั่งคืนความจำลงไปปิดท้าย
-(void)dealloc
{
[super dealloc];
}
กลับไปแก้ไข MenuScene.m ที่ส่วนของ Header ให้รู้จักกับคำสั่งของหน้า PlayScene โดยเพิ่ม
#import "MenuScene.h"
#import "PlayScene.h"
@implementation MenuScene
และเพิ่มคำสั่งเพิ่มเติมที่ ฟังก์ชัน -(void) ccTouchesEnded:(NSSet *) touches withEvent:(UIEvent *) event
ดังนี้
จากเดิมคือ
if (location.x >= 170 && location.x <= 320 && location.y >= 180 && location.y <= 220)
{
NSLog(@"(%f, %f)", location.x, location.y);//แสดงตำหน่งที่เรา Touch ใน Console
}
ให้เป็น
if (location.x >= 170 && location.x <= 320 && location.y >= 180 && location.y <= 220)
{
NSLog(@"(%f, %f)", location.x, location.y);//แสดงตำหน่งที่เรา Touch ใน Console
//เปลี่ยนไปยังหน้า PlayScene
[[CCDirector sharedDirector] replaceScene:[CCTransitionFlipX transitionWithDuration:1.5f scene:[PlayScene node]]];
}
เพื่อเป็นการเปลี่ยนให้เราสามารถกดปุ่ม "Play” แล้วเปลี่ยนหน้าไปเป็นไฟล์ PlayScene
ต่อมาให้ไปแก้ไขที่ไฟล์ IntroLayer.m โดยให้เพิ่ม #import “MenuScene.h” ลงในส่วน Header ดังนี้
#import "IntroLayer.h"
#import "HelloWorldLayer.h"
#import "MenuScene.h"
#pragma mark - IntroLayer
แล้วให้เลื่อนไปที่ฟังก์ชัน makeTransition ข้างล่าง
ให้ทำการเปลี่ยน คำสั่งจากเดิมคือ
-(void) makeTransition:(ccTime)dt
{
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0 scene:[HelloWorldLayer scene] withColor:ccWHITE]];
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0 scene:[MenuScene scene] withColor:ccWHITE]];
}
@end
เปลี่ยนให้เป็น
-(void) makeTransition:(ccTime)dt
{
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0 scene:[HelloWorldLayer scene] withColor:ccWHITE]];
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0 scene:[MenuScene scene] withColor:ccWHITE]];
}
@end
เพื่อเป็นการเรียกหน้า MenuScene ที่เป็นหน้าเมนูแรกของเราปรากฏขึ้นมา โดยลอง "Run” ตัวแอพพลิเคชันของเราก่อน จะได้หน้าจอดังนี้
เปิด Project ก่อนหน้านี่ที่ได้สร้างขึ้นมาแล้ว อย่างตัว Project ของผมคือ "FirstGame” ให้ทำการเปิด Project ขึ้นมาสิ่งแรกที่เราจะทำคือตกแต่งหน้าจอ Title และเมนูของเกมเราให้ดูน่าสนใจก่อน ดังนั้นเราต้องเตรียมภาพฉากหลังของเกมขึ้นมา 1 ภาพตั้งชื่อว่า BG.png ซึ่งตัวอย่างที่ผมจะใช้คือภาพด้านล่าง ให้คัดลอก import นำไปไว้ใน Project ของเรา
ต่อมาให้เราไปที่ไฟล์ MenuScene.m เพิ่มเติมคำสั่งลงไปเล็กน้อยในฟังก์ชัน init() ซึ่งคำสั่งสำหรับเรียกภาพกราฟิกของ Cocos2D นั้นก็คือคำสั่ง CCSprite นั่นเอง ให้แทรกคำสั่งนี้ลงไปตามนี้ ก่อนบรรทัดประกาศเมนู
if( (self=[super init] )) {
//เก็บขนาดของหน้าจอ
CGSize size = [[CCDirector sharedDirector] winSize];
//Background
CCSprite *bg = [CCSprite spriteWithFile:@"BG.png"];
[bg setPosition:ccp(size.width / 2, size.height / 2)];
//Background
ส่วนของ //Background คือคำสั่งในการเรียกไฟล์ BG.png เมื่อแทรกคำสั่งลงไปแล้วต้องทำการ add Object ลงไปเหมือน เมนู ให้เพิ่ม คำสั่งในกา add ตัวแปล bg ลงไปก่อนบรรทัดของการ add เมนู หากวางบรรทัดล่างสุด ระบบจะเข้าใจว่าเป็น Layerหรือชั้นข้อมูลที่สูงที่สุด Background จะบังเมนูที่เราสร้างไว้ ดังนั้นต้องไว้บรรทัดบนสุด
[self addChild:bg z:0];
[self addChild:menu];
[self addChild:menuPlay];
[self addChild:menuHowToPlay];
[self addChild:menuAbout];
ทำการแก้ไข บรรทัดของเมนูแรกของเราให้เป็นค่าว่าง โดยแก้ไขจากเดิม
CCLabelTTF *menu = [CCLabelTTF labelWithString:@"Menu" fontName:@"Marker Felt" fontSize:42];
menu.position = ccp(size.width/2, size.height-50);
ให้กลายเป็น
CCLabelTTF *menu = [CCLabelTTF labelWithString:@" " fontName:@"Marker Felt" fontSize:42];
menu.position = ccp(size.width/2, size.height-50);
แล้วทดลอง "Run” แอพพลิเคชันของเรา เพื่อดูผลลัพธ์ ผลลัพธ์จะปรากฏดังตัวอย่างข้างล่าง
สิ่งที่ได้จากบทเรียนนี้ คือขั้นตอนการสร้างเมนูสำหรับแอพพลิเคชันเกมของคุณ