ต่อจากนี้จะเป็นการอธิบาย 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::array mlist;
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

ไม่มีความคิดเห็น:
แสดงความคิดเห็น