ต่อจากนี้จะเป็นการอธิบาย Code
CDXSprite *jet; CDXSprite *bg; CDXSprite *logo; CDXSnd* g_snd; POINT pos; int score = 0; int game_stage = 1; int live = 3;
ประกาศตัวแปร CDXSprite ไว้เก็บพวกภาพ sprite ต่าง ๆ
CDXSnd ไว้เก็บค่าเสียง
POINT เก็บค่าตำแหน่งของตัวละคร
score คือ คะแนน
game_stage ใช้เก็บว่าตอนนี้อยู่หน้าไหน
live คือ จำนวนชีวิตของเรา
typedef struct { CDXSprite *missile; POINT pos, di, vel; }Missile_info; irr::core::arraymlist; irr::core::array elist; bool AddMis( char* name, const POINT& pos, const POINT& di, const POINT& vel ); void UpdateMis(void); void RemoveMis(void);
สร้าง โครงสร้างของตัวแปะชื่อ Missile_info
ต่อมาก็สร้าง Missile_info ชื่อ mlist ใช้กับกระสุนและ elist ใช้กับศัตรู
ประกาศชื่อ function ไว้ใช้ก่อน
bool AddMis( char* name, const POINT& pos, const POINT& di, const POINT& vel ) { Missile_info* minfo = new Missile_info( ); minfo->missile = new CDXSprite( ); minfo->missile->Create( name, 1 ); minfo->pos = pos; minfo->di = di; minfo->vel = vel; mlist.push_back( minfo ); return true; }สร้างฟังชั่นชื่อ AddMis ใช้เพื่อเรียกกระสุนออกมา (รายละเอียดดูใน WP2)
void UpdateMis(void) { for( irr::u32 i = 0; i != mlist.size(); i++ ) { mlist[i]->pos.x += mlist[i]->di.x * mlist[i]->vel.x; mlist[i]->pos.y += mlist[i]->di.y * mlist[i]->vel.y; mlist[i]->missile->SetPos( mlist[i]->pos.x, mlist[i]->pos.y ); mlist[i]->missile->Draw( Screen->GetBack(), 0, 0, CDXBLT_TRANS ); } }สร้างฟังชั่น UpdateMis ไว้ใช้สำหรับทำให้กระสุนขยับโดยเราสามารถกำหนดที่หลังได้ว่าต้องการให้ไปทางไหน
bool AddEnemy( char* name, const POINT& pos, const POINT& di, const POINT& vel ) { Missile_info* enemy = new Missile_info( ); enemy->missile = new CDXSprite( ); enemy->missile->Create( name, 1 ); enemy->pos = pos; enemy->di = di; enemy->vel = vel; elist.push_back( enemy ); return true; }
สร้างฟังชั่น AddEnemy เพื่อใช้เรียกสร้าง ศตรูเจ้ามาในเกม
void insterEnemy(void) { POINT di = { 0, 1 }; POINT vel = { 0, rand() % 5+3 }; POINT pos = { rand() % 400 + 40,rand() % 150*-1}; AddEnemy( "boss.png", pos, di, vel ); }
สำหรับฟังชั่นนี้จะเป็นการสร้างศัตรูออกมาโดยที่จะสุ่มทั้งความเร็วและ ตำแหน่งของศัตรู
void inEnemy(void) { for(int i = 0;i < rand() % 3+1;i ++) { insterEnemy(); } }จะเป็นการสั่งให้ฟังชั่น insterEnemy ทำงานโดยจำนวนรอบที่ทำงานนั้นจะเกิดจากการสุ่ม
void UpdateEnemy(void) { for( irr::u32 i = 0; i != elist.size(); i++ ) { elist[i]->pos.x += elist[i]->di.x * elist[i]->vel.x; elist[i]->pos.y += elist[i]->di.y * elist[i]->vel.y; elist[i]->missile->SetPos( elist[i]->pos.x, elist[i]->pos.y ); elist[i]->missile->Draw( Screen->GetBack(), 0, 0, CDXBLT_TRANS ); } }สั่งให้ศัตรูขยับ
void RemoveMis(void) { for( irr::u32 i = 0; i != mlist.size(); ++i ) { if( mlist[i]->pos.x < 0 || mlist[i]->pos.x > 480 || mlist[i]->pos.y < 0 || mlist[i]->pos.y > 272 ) { SAFEDELETE( mlist[i]->missile ); SAFEDELETE( mlist[i] ); mlist.erase( i ); --i; continue; } for( irr::u32 q = 0; q != elist.size(); ++q ) { if(mlist[i]->missile->SpriteHit(elist[q]->missile) ) { score += 100; SAFEDELETE( mlist[i]->missile ); SAFEDELETE( mlist[i] ); mlist.erase( i ); --i; SAFEDELETE( elist[q]->missile ); SAFEDELETE( elist[q] ); elist.erase( q ); --q; break; } if(elist.size() < 3) { inEnemy(); } } } for( irr::u32 i = 0; i != elist.size(); ++i ) { if( elist[i]->pos.x < 0 || elist[i]->pos.x > 480 || elist[i]->pos.y < -150 || elist[i]->pos.y > 272 ) { SAFEDELETE( elist[i]->missile ); SAFEDELETE( elist[i] ); elist.erase( i ); --i; inEnemy(); continue; } if(elist[i]->missile->SpriteHit(jet) ) { SAFEDELETE( elist[i]->missile ); SAFEDELETE( elist[i] ); elist.erase( i ); --i; inEnemy(); pos.x = 200; pos.y = 200; live -=1; continue; } } }สำหรับอันนี้จะขอแยกออกเป็นส่วนๆ
for( irr::u32 i = 0; i != mlist.size(); ++i ) { if( mlist[i]->pos.x < 0 || mlist[i]->pos.x > 480 || mlist[i]->pos.y < 0 || mlist[i]->pos.y > 272 ) { SAFEDELETE( mlist[i]->missile ); SAFEDELETE( mlist[i] ); mlist.erase( i ); --i; continue; } for( irr::u32 q = 0; q != elist.size(); ++q ) { if(mlist[i]->missile->SpriteHit(elist[q]->missile) ) { score += 100; SAFEDELETE( mlist[i]->missile ); SAFEDELETE( mlist[i] ); mlist.erase( i ); --i; SAFEDELETE( elist[q]->missile ); SAFEDELETE( elist[q] ); elist.erase( q ); --q; break; } if(elist.size() < 3) { inEnemy(); } } }สำหรับ if แรกจะเป็นการบอกว่าถ้ากระุสุนเกินหน้าจอออกไปก็ให้ ลบ กระสุ่นนั้นๆออกไป และสำหรับ if ที่ 2 จะเป็นการเช็คว่ากระสุนชนกับศัตรูหรือยัง ถ้าชนแล้วก็ บวกคะแนนเข้าไป 100 และสั่งลบทั้งกระสุนและศัตรูออกไป และสั่ง break เนื่องจากในตอนแรกนั้นใช้ continue แต่ตัว code นั้นไม่ทำงานเพราะมันไปอ้างอิงกับตำแหน่งที่ถูกลบไปแล้ว และสำหรับ if สุดท้ายนั้นจะเป็นการเช็กว่ามีจำนวนศัตรูอยู่ในเกมมากกว่า 3 ตัวหรือไม่ ถ้าไม่ก็จะไปส่งให้ศัตรูเกิดออกมาอีก
for( irr::u32 i = 0; i != elist.size(); ++i ) { if( elist[i]->pos.x < 0 || elist[i]->pos.x > 480 || elist[i]->pos.y < -150 || elist[i]->pos.y > 272 ) { SAFEDELETE( elist[i]->missile ); SAFEDELETE( elist[i] ); elist.erase( i ); --i; inEnemy(); continue; } if(elist[i]->missile->SpriteHit(jet) ) { SAFEDELETE( elist[i]->missile ); SAFEDELETE( elist[i] ); elist.erase( i ); --i; inEnemy(); pos.x = 200; pos.y = 200; live -=1; continue; } }สำหรับส่วนนี้จะเป็นส่่วนของศัตรูทั้งหมด โดย if แรกจะเช็คว่าศัตรูนั้นออกไปนอกจอหรือยังถ้าออกไปแล้วก็สั่งลบ ส่วน if ที่ 2 จะเช็กว่าศัตรูได้ชนกับตัวผู้เล่้นหรือไม่ ถ้าชนก็จะลบออกไปเช่นกัน แต่จะลบจำนวนชีวิตไป 1 และย้ายตำแหน่งของผู้เล่นไปไว้ที่ x = 200 y = 200
g_snd = new CDXSnd( ); g_snd->Create( ); jet = new CDXSprite( ); jet->Create( "me.png", 1 ); bg = new CDXSprite( ); bg->Create( "bg.png", 1 ); logo = new CDXSprite( ); logo->Create( "logo.png", 1 ); pos.x = 200; pos.y = 200; insterEnemy();อยู่ใน BOOL cdx_Init() เป็นการโหลดภาพฉากหลัง ตัวผู้เล่น โลโก้ และเสียงเข้ามาในเกม กำหนดจุดเกิดของผู้เล่นพร้อมทั้ง สั่งให้ศัตรูชุดแรกเกิด
for( irr::u32 i = 0; i != mlist.size(); ++i ) { SAFEDELETE( mlist[i]->missile ); SAFEDELETE( mlist[i] ); mlist.erase( i ); --i; } for( irr::u32 i = 0; i != elist.size(); ++i ) { SAFEDELETE( elist[i]->missile ); SAFEDELETE( elist[i] ); elist.erase( i ); --i; } SAFEDELETE( jet ); SAFEDELETE( bg ); SAFEDELETE( logo ); SAFEDELETE( Fps ); SAFEDELETE( Input ); SAFEDELETE( Screen ); SAFEDELETE( g_snd );สั่งคืนค่าตัวแปรของทั้งหมดในเกม อยู่ใน void cdx_DeInit( void ) ส่วน void cdx_DoFrame()
if(game_stage == 1) { if( Input->GetKeyState(SDLK_SPACE) == CDXKEY_PRESS || Input->GetKeyState(CDXKEY_JOYBUTN11) == CDXKEY_PRESS ) game_stage = 2; logo->SetPos( 0,50 ); logo->Draw( Screen->GetBack(), 0, 0, CDXBLT_TRANS ); }แสดงภาพของ Logo และเมื่อกดที่ space bar หรือ start ใน psp แล้วจะเป็นกาีรเปลี่ยนไปเป็นหน้า start game
if(game_stage == 2) { TextXY( Screen->GetBack(), 20, 150, 233, 227, 66, 255, ETA_CENTER ,"Start Game" ); if( Input->GetKeyState(SDLK_RETURN)|| Input->GetKeyState(CDXKEY_JOYBUTN3)) game_stage = 3; }เป็นหน้า start game ที่ แสดงคำว่า Start Game ให้กด enter หรือ ปุ่มสี่เหลี่ยมเพื่อเข้าเกม
if(game_stage == 3) { if( (Input->GetKeyState(SDLK_RIGHT)||Input->GetKeyState(CDXKEY_JOYBUTN9)) && (pos.x < 438)) pos.x += 8; if( (Input->GetKeyState(SDLK_LEFT)|| Input->GetKeyState(CDXKEY_JOYBUTN7))&&(pos.x > 5)) pos.x -= 8; if( (Input->GetKeyState(SDLK_UP)||Input->GetKeyState(CDXKEY_JOYBUTN8)) && (pos.y > 0)) pos.y -= 8; if( (Input->GetKeyState(SDLK_DOWN)||Input->GetKeyState(CDXKEY_JOYBUTN6)) && (pos.y < 200)) pos.y += 8;เนื่อจากในส่วนนี้เยอะจึงจะแยกเป็นส่วนๆ ในส่วนนี้จะเป็นการควบคุมตัวละครโดยใช้ปุ่มลูกศร
bg->SetPos( 0,0 ); bg->Draw( Screen->GetBack(), 0, 0, CDXBLT_TRANS ); jet->SetPos( pos.x, pos.y ); jet->Draw( Screen->GetBack(), 0, 0, CDXBLT_TRANS ); TextXY( Screen->GetBack(), 390, 20, 233, 227, 66, 255 ,"Score : " ); TextXY( Screen->GetBack(), 20, 20, 233, 227, 66, 255, ETA_RIGHT ,"%d", score ); TextXY( Screen->GetBack(), 20, 150, 233, 227, 66, 255, ETA_RIGHT ,"%d", live );แสดงภาพฉากหลัง ตัวละคร และตัวอักษรต่างๆ ในที่นี้คือ คะแนน และ จำนวนชีวิต
POINT di = { 0, -1 }; POINT vel = { 0, 10 }; if( Input->GetKeyState(SDLK_SPACE) == CDXKEY_PRESS ||Input->GetKeyState(CDXKEY_JOYBUTN3) == CDXKEY_PRESS ) { AddMis( "shot_me.png", pos, di, vel ); g_snd->Play( "missile.wav" ); }กด space เป็นการยิงโดยโหลดเสียงด้วย
if((score < 5000) || (live > 1)) { UpdateMis( ); RemoveMis( ); UpdateEnemy(); }กำหนดว่าถ้าคะแนนน้อยกว่า 500 หรือ จำนวนชีวิตมากกว่า 1 แล้ว สั่งให้ ฟังชั่นเหล่านี้ทำงาน
if(score >= 5000) { TextXY( Screen->GetBack(), 20, 150, 233, 227, 66, 255, ETA_CENTER ,"You Win" ); if( Input->GetKeyState(SDLK_SPACE) == CDXKEY_PRESS || Input->GetKeyState(CDXKEY_JOYBUTN11) == CDXKEY_PRESS ) { score = 0; live = 3; game_stage = 1; } }ถ้าคะแนนเกิน 5000 แล้วขึ้นว่า You Win และถ้ากด space bar แล้วจะกำหนดถ้า คะแนนเป็น 0 จำนวนชีวิตเป็น 3 และ กลับไปหน้า โลโก้
if(live <= 0) { TextXY( Screen->GetBack(), 20, 150, 233, 227, 66, 255, ETA_CENTER ,"Game Over" ); if( Input->GetKeyState(SDLK_SPACE) == CDXKEY_PRESS || Input->GetKeyState(CDXKEY_JOYBUTN11) == CDXKEY_PRESS ) { score = 0; live = 3; game_stage = 1; } }
ถ้าจำนวนชีวิตเหลือ 0 แล้วให้ขึ้น Game Over และถ้ากด space bar แล้วจะกำหนดถ้า คะแนนเป็น 0 จำนวนชีวิตเป็น 3 และ กลับไปหน้า โลโก้
Game Play
ไม่มีความคิดเห็น:
แสดงความคิดเห็น