By: admin
20 Feb 2012
บทความนี้เป็นบทความที่ตีพิมพ์ในนิตยสาร Pantip Guide ฉบับที่ 54 (ม.ค. - มี.ค.) โดยเป็นการสอนพัฒนาเกมบนระบบปฏิบัติการ iOS (iPhone / iPod / iPad) ซึ่งในตอนนี้จะอธิบายกล่าวถึงการใส่เสียงพื้นหลังและเสียงเอฟเฟค...
สำหรับในบทความตอนนี้ผมจะเขียนถึงการใส่เสียงพื้นหลังและเสียงเอฟเฟค ซึ่งนับว่าเป็นสิ่งสำคัญอีกอย่างหนึ่งในการทำเกม ถ้ามีเพลงประกอบไพเราะน่าฟังและมีเสียงเอฟเฟคที่สมจริง ก็จะทำให้ผู้เล่นรู้สึกมีอารมณ์ร่วมไปกับเกมมากขึ้น
ในการทำเกมที่สร้างด้วย cocos2d-iphone ไฟล์เสียงที่รองรับมี 3 แบบ คือ CAF, AIF และ WAV เท่านั้น โดยส่วนใหญ่มักนิยมให้ CAF เนื่องจากขนาดไฟล์เล็ก แต่หลายคนอาจจะคุ้นเคยกับไฟล์ WAV มากกว่า ไม่เป็นไรครับ เราสามารถแปลงไฟล์ง่ายๆ โดยการใช้คำสั่ง afconvert ใน Terminal
ขั้นตอนการแปลงไฟล์เริ่มจากเปิดโปรแกรม Terminal ขึ้นมา หากใครไม่รู้ว่าอยู่ตรงไหน ก็ไปที่ Applications > Utilities > Terminal จากนั้นพิมพ์คำสั่งสำหรับแปลงไฟล์โดยมีรูปแบบ ดังนี้
afconvert –d [out data format] –f [out file format] [in file] [out file]
ตัวอย่างเช่น
afconvert –d LEI16 –f ‘caff’ bgsound.wav newbgsound.caf
หรือหากต้องการเปลี่ยน bit rate ก็สามารถทำได้ ด้วยคำสั่ง
afconvert –d aac –f ‘caff’ –b 131072 bgsound.caf newbgsound_128.caf (สำหรับ 128 บิต)
afconvert –d aac –f ‘caff’ –b 32786 bgsound.caf newbgsound_32.caf (สำหรับ 32 บิต)
ขั้นตอนต่อไปเป็นการเตรียมปุ่มสำหรับควบคุมเสียง ซึ่งในตัวอย่างต่อไปนี้จะมีปุ่มควบคุมเสียงจำนวน 2 ปุ่ม คือปุ่มสำหรับควบคุมเสียงพื้นหลัง และปุ่มสำหรับควบคุมเสียงเอฟเฟค ดังรูปที่ 1 โดยจะมีรูปที่ปล่อยไว้ปกติ กับรูปที่แสดงผลตอนใช้นิ้วทัช

รูปที่ 1 กราฟิกปุ่มสำหรับควบคุมเสียง
จากนั้นเริ่มต้นด้วยการสร้างโปรเจคใหม่ชื่อ iOSGame05 และนำรูปทั้ง 4 รูป เข้าไปในโฟวเดอร์ Resources ดังรูปที่ 2-3

รูปที่ 2 สร้างโปรเจคใหม่ชื่อ iOSGame05

รูปที่ 3 นำรูปเข้าในโฟวเดอร์ Resource
จากนั้นเขียนคำสั่งเพื่อประกาศตัวแปร _label, _bgSoundOnItem และ _bgSoundOffItem ซึ่งจะใช้เก็บข้อความแสดงผล ไอเทมสำหรับปุ่มเปิดเสียง และไอเทมสำหรับปุ่มปิดเสียง ตามลำดับ โดยเขียนลงในไฟล์ HelloWorldLayer.h ดังนี้
@interface HelloWorldLayer : CCLayer
{
CCLabelTTF *_label;
CCMenuItem *_bgSoundOnItem;
CCMenuItem *_bgSoundOffItem;
}จากนั้นเพิ่มคำสั่งสำหรับแสดงข้อความ คำสั่งสำหรับแสดงปุ่มที่เอาไว้ควบคุมการเล่นเสียงเอฟเฟค และคำสั่งสำหรับแสดงปุ่มที่เอาไว้ควบคุมการเล่นเสียงพื้นหลัง โดยเขียนไว้ในเมธอด init ที่อยู่ในไฟล์ HelloWorldLayer.m ดังนี้
-(id) init
{
if( (self=[super init])) {
_label = [CCLabelTTF labelWithString:@"Status: BGSound On" fontName:@"Marker Felt" fontSize:32];
CGSize size = [[CCDirector sharedDirector] winSize];
_label.position = ccp( size.width /2 , size.height - (_label.contentSize.height/2) );
[self addChild: _label];
CCMenuItem *fxsdMenuItem = [CCMenuItemImage itemFromNormalImage:@"fxsd1.png" selectedImage:@"fxsd2.png" target:self selector:@selector(fxsdButtonTapped:)];
fxsdMenuItem.position = ccp(150, 200);
CCMenu *fxsdMenu = [CCMenu menuWithItems:fxsdMenuItem, nil];
fxsdMenu.position = CGPointZero;
[self addChild:fxsdMenu];
_bgSoundOffItem = [[CCMenuItemImage itemFromNormalImage:@"bgsd1.png" selectedImage:@"bgsd1.png" target:nil selector:nil] retain];
_bgSoundOnItem = [[CCMenuItemImage itemFromNormalImage:@"bgsd2.png" selectedImage:@"bgsd2.png" target:nil selector:nil] retain];
CCMenuItemToggle *toggleItem = [CCMenuItemToggle itemWithTarget:self selector:@selector(bgSoundOnOffButtonTapped:) items:_bgSoundOnItem, _bgSoundOffItem, nil];
CCMenu *toggleMenu = [CCMenu menuWithItems:toggleItem, nil];
toggleMenu.position = ccp(250, 200);
[self addChild:toggleMenu];
}
return self;
}
จากข้างต้นจะเห็นว่าในแต่ละปุ่มจะมีรูป 2 รูป คือรูปที่แสดงผลปกติ และรูปที่แสดงผลเมื่อคลิ๊กปุ่มหรือทัชที่ปุ่ม
ต่อไปเพิ่มเมธอด fxsdButtonTapped ซึ่งเป็นเมธอดสำหรับให้ทำงานเมื่อกดปุ่มเล่นเสียงเอฟเฟค โดยในเบื้องต้นเมื่อกดปุ่มก็จะให้แสดงข้อความด้านบนเป็น Status: SoundFX On ดังนี้
- (void)fxsdButtonTapped:(id)sender {
[_label setString:@"Status: SoundFX On"];
}เพิ่มเมธอด bgSoundOnOffButtonTapped ซึ่งเป็นเมธอดสำหรับให้ทำงานเมื่อกดปุ่มเล่นเสียงพื้นหลัง ดังนี้
- (void)bgSoundOnOffButtonTapped:(id)sender {
CCMenuItemToggle *toggleItem = (CCMenuItemToggle *)sender;
if (toggleItem.selectedItem == _bgSoundOffItem) {
[_label setString:@"Status: BGSound Off"];
[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];
} else if (toggleItem.selectedItem == _bgSoundOnItem) {
[_label setString:@"Status: BGSound On"];
}
}เมื่อดูแล้วไม่มีข้อผิดพลาดใดๆ ก็รันคำสั่งได้เลย ซึ่งจะได้ผลลัพธ์ดังรูปที่ 4

รูปที่ 4 แสดงผลปุ่มกดสำหรับควบคุมเสียง
เมื่อเราลองกดปุ่มทั้งสองปุ่มจะเห็นว่าแตกต่างการโดยแบบแรกเอาไว้สำหรับเล่นเสียงเอฟเฟค การทำงานของปุ่มคือเมื่อเรากดจะเปลี่ยนเป็นอีกรูป และเมื่อปล่อยจะกลับเป็นรูปเดิม ซึ่งปุ่มแบบนี้จะใช้คลาส CCMenuItem ส่วนปุ่มสำหรับควบคุมเสียงพื้นหลังการทำงานของปุ่มจะเปลี่ยนรูปเมื่อเรากดแล้วปล่อย และเมื่อกดแล้วปล่อยอีกครั้งก็จะเปลี่ยนเป็นรูปเดิม วนแบบนี้ไปเรื่อยๆ ซึ่งปุ่มแบบนี้จะใช้คลาส CCMenuItemToggle
เมื่อเราได้ปุ่มสำหรับควบคุมเสียงเรียบร้อยแล้ว ขั้นตอนต่อไปเป็นการนำเสียงเข้ามาโดยนำเข้ามาโปรเจค โดยในตัวอย่างนี้มี 2 ไฟล์คือ bgsound.caf และ fxsound.caf ดังรูปที่ 5

รูปที่ 5 นำไฟล์เสียงเข้าในโปรเจค
สำหรับการเล่นเสียงใน cocos2d-iphone มีคลาสสำเร็จรูปมาให้เราใช้ โดยคลาสที่ใช้สำหรับเล่นเสียงคือคลาส SimpleAudioEngine ซึ่งเรา import เข้ามาด้วยคำสั่ง
#import "SimpleAudioEngine.h"
เพิ่มคำสั่งเพื่อให้เปิดมาแล้วเล่นเสียงเลย ดังนี้
-(id) init
{
…
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"bgSound.caf"];
}
return self;
}เพิ่มคำสั่งเมื่อกดปุ่มให้เล่นเสียงตามที่กำหนด โดยถ้าต้องการเล่นเสียงเอฟเฟคที่เล่นครั้งเดียวจะใช้คำสั่ง playEffect แต่ถ้าต้องการเล่นเสียงพื้นหลังที่วนลูปไปเรื่อยๆ จะใช้คำสั่ง playBackgroundMusic ดังนี้
- (void)fxsdButtonTapped:(id)sender {
[_label setString:@"Status: SoundFX On"];
[[SimpleAudioEngine sharedEngine] playEffect:@"fxSound.caf"];
}
- (void)bgSoundOnOffButtonTapped:(id)sender {
CCMenuItemToggle *toggleItem = (CCMenuItemToggle *)sender;
if (toggleItem.selectedItem == _bgSoundOffItem) {
[_label setString:@"Status: BGSound Off"];
[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];
} else if (toggleItem.selectedItem == _bgSoundOnItem) {
[_label setString:@"Status: BGSound On"];
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"bgSound.caf"];
}
}ปิดท้ายด้วยการเขียนคำสั่งเพื่อคืนหน่วยความจำ ดังนี้
- (void) dealloc
{
[_label release];
_label = nil;
[_bgSoundOffItem release];
_bgSoundOffItem = nil;
[_bgSoundOnItem release];
_bgSoundOnItem = nil;
[super dealloc];
}
เป็นอันเสร็จเรียนร้อย ถ้าไม่มีอะไรผิดพลาดเมื่อเรากดรัน ก็จะมีเสียงพื้นหลังเริ่มเล่นและเล่นวนลูปไปเรื่อยๆ และถ้ากดปุ่มเล่นเสียงเอฟเฟคก็จะเล่นเสียงเอฟเฟคออกมา โดยเราสามารถกดได้ด้วยความถี่บ่อยๆ ได้
จากบทความข้างต้นนี้ถ้าใครมีเกมอยู่แล้วจากบทความที่ผ่านๆ มา ก็ลองนำเสียงเข้าไปในเกม ก็จะทำให้เกมเราดูสนุกมากขึ้น ลองดูนะครับ!
มนตรี อินทโชติ
Recent comments
50 weeks 6 days ago
50 weeks 6 days ago
51 weeks 3 days ago
1 year 28 weeks ago
1 year 28 weeks ago
1 year 35 weeks ago
1 year 35 weeks ago
1 year 36 weeks ago
2 years 8 weeks ago
2 years 8 weeks ago