วันพฤหัสบดีที่ 22 กันยายน พ.ศ. 2554

Final project

CMM 342 GAME DEVELOPEMENT I
เสนอ
รศ.ดร.อาษา ตั้งจิตสมคิด

     

     ทุกวันนี้เทคโนโลยีอยู่รอบๆตัวเรามากยิ่งขึ้น หลายๆสิ่งที่เราได้สัมผัสในชีวิตประจำวันล้วนเกี่ยวข้องกับเทคโนโลยีล้วน แล้วทั้งสิ้น หากพูดถึง "เกม" คำๆนี้คงไม่มีใครไม่รู้จักเพราะทุกคนก็ล้วนเคยผ่านการเล่นกันมาแล้ว
  ทางคณะผู้จัดทำจึงมีความสนใจที่จะศึกษาการพัฒนาเกมที่ให้ความเพลิดเพลิน และง่ายต่อการเล่น
ของผู้เล่น  อีกทั้งยังส่งผลให้ทางคณะผู้จัดทำเกิดทักษะในการเขียนเกม  โดยทางคณะผู้จัดทำเลือกที่จะ
พัฒนาเกมลงบนอุปกรณ์เกม PSP (Play Station Portable )
    เกมSamurai Island เป็นเกมแนวAction Advanture โดยจะเป็นการผจญภัยต่อสู้ไปหมู่เกาะต่างๆ




















ชื่อเกมส์ : Samurai Island

ที่มาและความสำคัญของโครงการ
            คณะผู้จัดทำต้องการพัฒนาเกม Samurai Island  ขึ้นเพื่อ ให้สอดคล้องกับการเรียนในรายวิชา  CMM342 Game Development I เป็นการนำองค์ความรู้ที่ได้จากการเรียนมาใช้ให้เกิดประโยชน์ เพื่อที่จะนำความรู้และประสบการณ์ที่ได้รับไปใช้ในการพัฒนาเกมอื่นๆที่มี ระดับสูงขึ้นในโอกาสต่อไป

วัตถุประสงค์
         เพื่อพัฒนาโครงการเกม Samurai Island


ขอบเขตของโครงการ 
    1. พัฒนาเกม Samurai Island ด้วย Arsa Framework โดยใช้โปรแกรม Microsoft Visual Studio 2010 และในส่วนกราฟฟิกใช้ และ Adobe Photoshop , Adobe Illustrator
    2. พัฒนาเกมสำหรับเล่นในอุปกรณ์เกม PSP (Play Station Portable  โดยรูปแบบของ
เกม มีผู้เล่นคนเดียว ตะลุยผ่านด่าน โดยมีทั้งหมด 3 ด่าน 

ประโยชน์ของโครงการ 
    1. ได้ศึกษาเกี่ยวกับการสร้างเกม  และสามารถพัฒนาเกม Samurai Island
    2. ได้รับความรู้และประสบการณ์เพื่อนำไปต่อยอดในการสร้างเกมครั้งต่อๆไป

ระยะเวลาในการดำเนินงาน
3 มิถุนายน -  23  กันยายน 2554








เดือน/สัปดาห์
มิถุนายน
กรกฎาคม
สิงหาคม
กันยายน
1
2
3
4
1
2
3
4
1
2
3
4
1
2
3
4
ประชุมเลือกประเภทเกมที่ต้องการพัฒนา
 X
 X














ศึกษาและค้นคว้าข้อมูล
 X
 X
 X
 X
X
 X
 X
 X
 X
 X
 X
 X
 X
 X


ออกแบบเกมและกราฟิก


X
 X
 X
 X
 X









เขียนเกม






 X
 X
 X
 X
 X
 X




ทดสอบเกม











 X
 X



แก้ไข ปรับปรุงเกม











 X
 X
 X


นำเสนอ














X


ผู้จัดทำ
52214503  นางสาวกันต์ฐณัชชา    ดอกกุหลาบ
52214532  นายนนทพงษ์               เสือเทศ
52214553  นายอัฐพล                    หน่อเมืองคำ
52214565  นายณัฐพล                   ธิติชัยยงกิตต์
52214566  นายณัฐวุฒิ                  ทิพย์อมรวิวัฒน์






เอกสารที่เกี่ยวข้อง
Arsa Framework
ARSA Farmework เป็นเครื่องมือที่ช่วยในการพัฒนาเกม 2 มิติ และ 3 มิติ โดยผู้เขียนได้แจกจ่ายให้
นักพัฒนาเกมส์ได้ใช้ฟรี ซึ่งเป็นเรื่องน่ายินดีในการสร้างเครื่องพัฒนาเกมส์ในบ้านเรา
โครงสร้าง ARSA Farmework แบบ 2 มิติ ประกอบด้วย class ต่างๆมากมาย เพื่อจัดการหน้าจอ เปิดปิดดหมดเกมส์ใน
ความละเอียดต่างๆเพื่อโหลดและแสดงภาพไปที่หน้าจอ สามารถแสดงภาพได้ทั้ง bmp,jpg,pcx,psd,png และ tga
รวมถึงการแสดงแบบ animation เพื่อจัดการเสียงต่างๆ และอีกมากมายในการอานวยความสพดวกให้กับนักพัฒนาเกมส์
2 มิติ
สาหรับเกม 3 มิติ ARSA Farmework ถูออกแบบมาเพื่อรองรับเกม 3 มิติในแบบ Cross Platform สามารถแสดงผลได้
แบบ Engine ระดับ World Wildทาให้เกมส์มีความเร็วในการแสดงผลเพิ่มขึ้นและได้ภาพที่สมจริง สมดุลกับธรรมชาติ




พื้นฐานภาษา C++
ภาษา C++ (อ่านว่า ซี-พลัส-พลัส) เป็นลูกผสมระหว่างภาษา Simula และภาษา C โดยรับเอาแนวคิดของ
ภาษา C มากกว่า 95% ประยุกต์เข้ากับแนวคิดเชิงวัตถุของ Simula ทาให้ภาษา C++ เป็นลูกผสมระหว่าง Procedural
Language และ Object Oriented Language เราไม่สามารถบอกได้ว่า C++ เป็น OOP100% โดยเราอาจเลือกเขียน
แบบภาษา C ได้อีกแบบหนึ่ง
ภาษา C++ เป็นภาษาโปรแกรมภาษาหนึ่งที่ได้รับการพัฒนาขึ้นมาไม่นานนักและเป็นภาษาที่มีความสามารถสูง
ดังนั้น ในบทนี้จะเสนอความเป็นมาของภาษา C++ รูปแบบการเขียนโปรแกรมขั้นต้น เพื่อเรียนรู้ถึงองค์ประกอบต่างๆ ที่
จาเป็นในการเขียนโปรแกรมด้วยภาษา C++ เช่น การเขียนคอมเมนต์ การประกาศตัวแปร ชนิดข้อมูลที่ควรรู้ รวมทั้ง
ข้อสังเกตที่น่าสนใจในภาษา C++ เช่น ตัวดาเนินการต่างๆ การจัดการกับการเกิดส่วนล้น (Overflow) เป็นต้น
ความเป็นมาของภาษา C++
C++ มีรากฐานมาจากภาษา C และเป็นภาษาที่คลุมภาษา C ไว้ C++ ยังคงรักษาความสามารถและความยืดหยุ่น
ของ C ในการเขียนโปรแกรมระบบต่า รวมทั้งโปรแกรมควบคุมฮาร์ดแวร์ ที่สาคัญกว่านั้น คือ C++ ให้การสนับสนุนการ
เขียนโปรแกรมแบบ Object-Oriented C++จัดเป็นภาษาที่มีความสามารถมากกว่า ADA และ Modula-2 ขณะที่ยังคง
ความมีประสิทธิภาพและความกะทัดรัดของภาษา C ไว้ ดังนั้น จึงเป็นภาษาโปรแกรมภาษาหนึ่งที่ยอมให้โปรแกรมเมอร์
เขียนโปรแกรมแบบมีโครงสร้าง และเขียนโปรแกรมเชิงวัตถุได้อย่างมีประสิทธิภาพ
C++ เป็นภาษาผสม (Hybrid Language) โดยอาจแก้ปัญหาหนึ่งด้วยวิธี Object-Oriented ล้วนๆ หรืออาจ
แก้ปัญหาด้วยการใช้ภาษาแบบเก่า ซึ่งมีโครงสร้างบางอย่างเพิ่มขึ้นจากภาษา C ในทางปฏิบัติในการแก้ปัญหามักจะ
สะท้อนให้เห็นวิธีการทั้ง 2 แบบ
C++ ถูกพัฒนาโดย Bjane Stroustrup ที่ Bell Labs ในช่วงทศวรรษ 1980 Dr.Stroustrup พัฒนาภาษานี้ขึ้นเพื่อ
เขียนซอฟต์แวร์จาลองเหตุการณ์ (Event-Driven Simulation) ที่มีความซับซ้อน ซึ่งมRick Mascitti เป็นผู้ตั้งชื่อของภาษานี้ให้กับเขา
C++ ถูกออกแบบให้ส่งเสริมการพัฒนาซอฟต์แวร์ขนาดใหญ่ โดยเพิ่มการตรวจสอบ Type เข้าไป เมื่อเปรียบเทียบ
กับ C แล้วจะลดข้อผิดพลาดลงได้มาก เพราะว่าภาษา C ยอมให้โปรแกรมเมอร์ควบคุมระบบในระดับต่าได้โดยตรง
โปรแกรมเมอร์จานวนมากจึงทางานโดยเริ่มจากโครงสร้างระดับต่า แล้วนาส่วนต่างๆ เหล่านี้มาประกอบกันเป็นโครงสร้าง
ใหญ่ แต่ในภาษา C++ จะทาในทางตรงกันข้าม คือ กาหนดโครงสร้างใหญ่ก่อนนามาสัมพันธ์กัน แล้วจึงกาหนดโครงสร้าง
ย่อยๆ ต่อไป
รูปแบบการเขียนโปรแกรม C++
ภาษาโปรแกรม C++ เป็นภาษาโปรแกรมที่ไม่มีรูปการเขียนตายตัว กล่าวคือ ไม่ต้องกาหนดว่าองค์ประกอบของ
โปรแกรมจะต้องเขียนอยู่ในบรรทัดหรือบนหน้ากระดาษส่วนไหน ดังนั้น โปรแกรมเมอร์จึงมีอิสระที่จะวางรูปแบบของ
โปรแกรม แต่โปรแกรมเมอร์ที่มีประสบการณ์ย่อมทราบดีว่าการเขียนโปรแกรมรูปแบบที่ดีนั้นจะต้องอ่านง่าย สะดวกต่อ
การแก้ไขข้อผิดพลาดของโปรแกรม และง่ายต่อการดูแลรักษาโปรแกรม แต่อย่างไรก็ตาม เราสามารถเขียนตามระเบียบ
แบบแผนมาตรฐานของภาษา C++ ซึ่งมีข้อปฏิบัติง่ายๆ ดังต่อไปนี้
1.การเขียนประโยคตัวเตรียมประมวลผล #include ไว้ที่ตาแหน่งเริ่มต้นของโปรแกรม
2.เขียนบรรทัดละหนึ่งคาสั่ง
3.เขียนกลุ่มคาสั่งที่อยู่ภายในบล็อกแบบย่อหน้า
4.ให้มีการเว้นวรรคตรงเครื่องหมายตัวดาเนินการทั้งก่อนและหลังเครื่องหมาย เช่น n =4
ระเบียบแบบแผนอีกลักษณะหนึ่งที่พึงปฏิบัติ คือ การเขียนชื่อตัวแปร ถ้าเขียนด้วยชื่อสั้นๆ จะลดโอกาสที่จะพิมพ์ผิด
แต่ในขณะเดียวกันก็ควรจะเป็นชื่อที่สื่อความหมายว่าตัวแปรนั้นแทนอะไร การเขียนรูปแบบนี้ เรียกว่า รหัสคาสั่งเอกสาร
ในตัวเอง (Self-Documenting Code) โปรแกรมเมอร์ C++ เกือบทั้งหมดนิยมเขียนชื่อตัวแปรด้วยพิมพ์เล็ก ยกเว้นในกรณี
ที่ชื่อตัวแปรประกอบด้วยคาหลายๆ คาจะเขียนตัวอักษรตัวแรกของคาที่มาต่อท้ายด้วยตัวพิมพใ์ หญ่ เช่น
Char Middle Initial;
Unsigned Max Unsigned Int;
เหตุผลที่เขียนแบบนี้ เพราะจะทาให้อ่านง่ายกว่าเขียนด้วยตัวพิมพ์เล็กเพียงอย่างเดียว
เช่น Middleinitial และ Maxunsignedint หรือมีอีกวิธีหนึ่งที่นิยมให้เช่นกัน คือ การใช้เครื่องหมาย สัญประกาศ
(underscore ‘_’) เป็นตัวแยกคาแทนช่องว่าง เช่น
Char middle_initial;
Unsigned Max Unsigned Int;
โปรแกรม Visual Studio
Visual Studio คือ ซอฟต์แวร์ประเภท IDE (Integrated Development Environment) ช่วยให้ผู้พัฒนาโปรแกรมสามารถ
เขียนโปรแกรมด้วยความสะดวกสบายขึ้น สามารถแก้ไขข้อผิดพลาดในการเขียนโปรแกรมได้ง่าย รวดเร็ด
โปรแกรม Photoshop
โปรแกรม Photoshop เป็นโปรแกรมที่มีความสามารถในการออกแบบกราฟิก เพื่อนาไปใช้ร่วมกับงานในด้าน
ต่าง ๆ เช่น งานกราฟิกที่เกี่ยวกับสื่อสิ่งพิมพ์ทุกประเภท งานกราฟิกบนเว็บไซต์และการตกแต่งภาพถ่ายจากกล้องดิจิตอล
ซึ่งอาจกล่าวได้ว่าเป็นโปรแกรมที่มีผู้นิยมนามาใช้ในการออกแบบและตกแต่งภาพถ่ายกันมากที่สุด
Photoshop เป็นโปรแกรมที่ใช้ในการสร้างภาพและ การตกแต่งภาพที่กาลังเป็นที่นิยมอย่างสูงสุด ในปัจจุบัน
เนื่องจากเป็นโปรแกรมที่ทางานได้อย่างมีประสิทธิภาพ และผลงานที่ได้เหมาะที่จะใช้กับงานสิ่งพิมพ์ นิตยสารงานมัล
ติมิเดียและสร้างกราฟิกสาหรับเว็บที่นับวัน กาลังพัฒนาไปอย่างไม่หยุดยั้ง และถึงแม้ว่า Photoshop จะเป็นโปรแกรมที่มี
ประสิทธิภาพสูง แต่การใช้งานกลับไม่ยาก อย่างที่หลายคนคิด เราสามารถเรียนรู้การใช้งานในโปรแกรม Photoshop ได้
อย่างรวดเร็ว แม้ว่าเราจะมีพื้นฐานทางคอมพิวเตอร์ไม่มากก็ตาม
โปรแกรม Illustrator
โปรแกรม Illustrator เป็นโปรแกรมสาหรับสร้างภาพลายเส้นที่มีความคมชัดสูง งานภาพประกอบและงานกราฟิก
แบบ 2 มิติต่างๆ เช่น การสร้างโลโก้สินค้า จนไปถึงการจัดเลย์เอาต์งานสิ่งพิมพ์ และมีเครื่องมึอที่ช่วยเหลือในงานเว็บไซต์
อีกด้วย ภาพกราฟิกสามารถแบ่งได้เป็น 2 แบบคือ 1.ภาพแบบพิกเซล (pixel) คือ ภาพที่เกิดจากจุดภาพในรูปภาพที่
รวมกันเป็นภาพขึ้น โดยภาพหนึ่งๆ จะประกอบไปด้วยจุดภาพหรือพิกเซลมากมาย และเเต่ละภาพที่สร้างขึ้นจะมีความ
หนาเเน่นของจุดภาพ หรือบางครั้งแทนว่าความละเอียด (ความคมชัด)ที่เเตกต่างกันไป จึงใช้ในการบอกคุณสมบัติของ
ภาพ จอภาพ หรือ อุปกรณ์แสดงผลภาพได้ 2.ภาพกราฟิกส์เวกเตอร์ (vector graphics) คือ ภาพที่เกิดจากการกาหนด
พิกัดและการคานวณค่าบนระนาบสองมิติ รวมทั้งมุมและระยะทาง ตามทฤษฎีเวกเตอร์ในทางคณิตศาสตร์ ในการ
ก่อให้เกิดเป็น เส้น หรือรูปภาพ ข้อดีคือ ทาให้สามารถย่อขยายได้ โดยคุณภาพไม่เปลี่ยนแปลง ข้อเสียคือภาพไม่เหมือน
ภาพจริงเป็นได้เพียงภาพวาด หรือใกล้เคียงภาพถ่ายเท่านั้น ข้อมูลภาพพวกนี้ได้เเก่ไฟล์สกุล eps, ai (adobe illustrator)
เป็นต้น ** โปรแกรม Illustrator ทางานแบบ vector graphics
ความแตกต่างระหว่างรูปแบบ vector และแบบ pixel
โปรแกรม Premiere Pro
โปรแกรมในการตัดต่อวิดีโอ (Video) และไฟล์เสียง (Audio) เพื่อนามาประกอบกันเป็นภาพยนตร์ โดยเป็นหนึ่ง
ในโปร แกรมตระกูล Adobe ที่ได้รับการพัฒนาอย่างต่อเนื่อง เพื่อให้ตัวโปรแกรมมีประสิทธิภาพ และความสามารถที่เพิ่ม
มากขึ้น รวมทั้งหน้าตาของโปรแกรมที่พัฒนาให้ใช้ได้ง่ายขึ้น จึงทาให้ Adobe Premiere พัฒนามาจนถึงเวอร์ชั่น ที่เรียกว่า
Adobe Premiere Pro CS4 ซึ่งเป็นเวอร์ชั่นใหม่ที่สุดในขณะนี้ มีความสามารถหลัก คือ การตัดต่อไฟล์วิดีโอซึ่ง ผสมผสาน
ไฟล์วิดีโอหลาย ๆ ไฟล์ให้เรียงต่อกันแล้วนามาผ่านกระบวนการตัดต่อ ใส่เอ็ฟเฟ็ค ปรับเสียง สร้างชื่อเรื่องข้อความ
จนกระทั่งได้ไฟล์ภาพยนตร์ที่สมบูรณ์ รวมทั้งมีการเคลื่อนไหวและมีการเปลี่ยนฉากที่ลงตัว จากนั้นยังสามารถแปลงไฟล์ที่
เสร็จแล้วไปเป็นไฟล์ในรูปแบบต่าง ๆ
การดำเนินการโครงการ
อุปกรณ์ที่ใช้ในการดาเนินงาน
- คอมพิวเตอร์
- แสกนเนอร์
- กล้องถ่ายรูป
- เครื่องเล่นเกมส์ PSP
ซอฟร์แวร์ที่ใช้สาหรับการดาเนินงาน
- Visual Studio 2010
- Arsa Framework
- Adobe Photoshop
- Adobe Illustrator
- Adobe Flash
การดาเนินการ

1.ประชุมเลือกประเภทเกมที่ต้องการพัฒนา
2.ศึกษาและค้นคว้าข้อมูล
3.ออกแบบเกมและกราฟิก
4.เขียนเกม
5.ทดสอบเกม
6.แก้ไข ปรับปรุงเกม
7.นำเสนอ





ภาคผนวก



ตัวละคร





CODE GAME

#include <cdx_app_wiz.h>
#include <iostream>

#define S_INTRO                   0
#define S_TITLE_MENU 1
#define S_PLAYING          2
#define S_GAMEOVER         3
#define S_WON              4
#define P_WALK                    0
#define P_ATTACK           1
#define P_ATTACKED         2
int page = S_INTRO;

using namespace std;
// ------------------------------------------------------------------
// CDX Objects
// ------------------------------------------------------------------
CDXScreen* Screen = 0; // The screen object, every program must have one
CDXInput* Input = 0;
FPSmanager* Fps = 0;
CDXSprite* gover = 0;

CDXSprite* title_bg = 0;


int score = 0;

class Animation {
public:
       Animation(CDXSprite *unit) {
              this->unit = unit;
       }
       void duration(unsigned int a = 1, unsigned int b = 2, unsigned int delay = 0, bool loop = true) {
              this->a = a - 1;
              this->b = b - 1;
              this->delay = delay;
              this->loop = loop;
       }
       unsigned int getLastFrame() {
              return this->c_frame + 1;
       }
       void shuffle(unsigned int f) {
              this->c_frame = rand() % f;
       }

       unsigned int play() {
              if (!this->loop) {
                     if (this->c_frame < this->a) {
                           this->c_frame = this->a;
                     }
              } else {
                     if (this->c_frame > this->b || this->c_frame < this->a) {
                           this->c_frame = this->a;
                     }
              }
              this->unit->SetFrame(this->c_frame);
              if (this->c_delay >= this->delay || !this->delay) {
                     this->c_delay = 0;
                     this->c_frame += (this->a < this->b) ? 1 : -1;
              } else {
                     this->c_delay++;
              }
              return this->c_frame;
       }
       ~Animation();
private:
       CDXSprite *unit;
       unsigned int a;
       unsigned int b;
       unsigned int delay;
       bool loop;
       unsigned int c_frame;
       unsigned int c_delay;
};

typedef struct {
       CDXSprite *image;
       int x, y;
} Background;
Background bgs[20];

int world_x;

typedef struct
{
       CDXSprite *sp;
       Animation *an;
       char heading;
       bool active;
       int x, y;
       int pstate;
} Fin;
Fin *rudof = new Fin();
Fin *boss = new Fin();
int hp_rudof = 500;
int hp_rudof_max = 500;
int hp_boss = 200;
int hp_boss_max = 200;

const int $_mon = 10;
typedef struct {
       int o, p;
       int acceleration;
       int size;
       CDXSprite *src;
       bool active;
       Animation *an;
       int x_total;
       int mon_hp;
} MON;
MON mon[$_mon];

typedef struct {
       char* filename;
       int width, height;
       int a_start, a_stop, a_delay;
} Mon_Filename;

Mon_Filename mon_filename[3];

// ------------------------------------------------------------------
// cdx_Init - handles initialization of the CDX objects
// ------------------------------------------------------------------

int stage = 1;
int back = 0;
int boss_atk = 0;
BOOL cdx_Init() {
       Screen = new CDXScreen();
       Screen->Create();
       Screen->CreateWindowed(480, 272, 32, SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_INIT_TIMER);

       Input = new CDXInput();
       Input->Create();

       Fps = new FPSmanager();
       SDL_initFramerate(Fps);
       SDL_setFramerate(Fps, 30);

       // TODO: Initialize your own CDX objects here


       title_bg = new CDXSprite();
       title_bg->Create("images/title_bg.png", 480, 272, 1);

       gover = new CDXSprite();
       gover->Create("images/gameover.png", 480, 272, 1);


       for (int i = 0; i < 15; i++) {
              bgs[i].image = new CDXSprite();
              char buffer[80];
              sprintf(buffer, "images/bg_%02d_ (%d).png", stage, i + 1);
              bgs[i].image->Create(buffer, 1);
              bgs[i].x = 100 * i;
              bgs[i].image->SetPosX(bgs[i].x);
       }

       rudof->sp = new CDXSprite();
       rudof->sp->Create("rudof.png", 80, 80, 1);
       rudof->an = new Animation(rudof->sp);
       rudof->an->duration(1, 1, 2);
       rudof->active = 1;
       rudof->x = 50;
       rudof->y = 120;
       rudof->sp->SetPos(rudof->x, rudof->y);
       rudof->pstate = P_WALK;

       mon_filename[0].filename = "mark.png";
       mon_filename[1].filename = "mark2.png";
       mon_filename[2].filename = "mark3.png";

       mon_filename[0].width = 70;
       mon_filename[1].width = 70;
       mon_filename[2].width = 70;

       mon_filename[0].height = 70;
       mon_filename[1].height = 70;
       mon_filename[2].height = 70;

       mon_filename[0].a_start = 1;
       mon_filename[1].a_start = 1;
       mon_filename[2].a_start = 1;

       mon_filename[0].a_stop = 8;
       mon_filename[1].a_stop = 8;
       mon_filename[2].a_stop = 8;

       mon_filename[0].a_delay = 1;
       mon_filename[1].a_delay = 1;
       mon_filename[2].a_delay = 1;

       if (score <= 19) {
              for (int u = 0; u < $_mon; u++) {
                     mon[u].o = rand() % 480 + 480;
                     mon[u].p = 130;
                     mon[u].acceleration = 2 * (stage * 2);
                     mon[u].size = 1;
                     mon[u].active = true;
                     mon[u].mon_hp = 10;
                     mon[u].src = new CDXSprite();
                     if (mon[u].size == 1) {
                           mon[u].src->Create("mark.png", 70, 70, 1);
                           mon[u].src->SetPos(mon[u].o, mon[u].p);
                     }
                     mon[u].an = new Animation(mon[u].src);
                     mon[u].an->duration(1, 8, 1);
                     mon[u].an->shuffle(5);
              }
       }
       if (stage = 1) {
              boss->sp = new CDXSprite();
              boss->sp->Create("boss.png", 80, 98, 1);
              boss->an = new Animation(boss->sp);
              boss->an->duration(1, 4, 3);
              boss->active = true;
              boss->x = 350;
              boss->y = 100;
       }

       return TRUE;
}

// ------------------------------------------------------------------
// cdx_DeInit - handles cleanup of CDX objects
// ------------------------------------------------------------------
void cdx_DeInit(void) {
       // TODO: Destroy your CDX objects here

       SAFEDELETE(boss->sp);

       SAFEDELETE(rudof->sp);
       for (int u = 0; u < $_mon; u++) {
              SAFEDELETE(mon[u].src);
       }
       for (int i = 0; i < 15; i++)
              SAFEDELETE(bgs[i].image);

       SAFEDELETE(gover);
      
       SAFEDELETE(title_bg);
      

       SAFEDELETE(Fps);
       SAFEDELETE(Input);
       SAFEDELETE(Screen);
}

// ------------------------------------------------------------------
// cdx_DoFrame - performs drawing of the current frame
// ------------------------------------------------------------------
void cdx_DoFrame() {
       Input->Update();

       Screen->GetBackEx()->Fill(0);

       // TODO: Add code to draw your objects during each frame

       switch (page) {
       default:
       case S_INTRO:
             
              page = S_TITLE_MENU;
              break;

       case S_TITLE_MENU:
              title_bg->Draw(Screen->GetBack(), 0, 0, CDXBLT_TRANS);
              TextXY(Screen->GetBack(), 0, 200, 255, 255, 255, 255, ETA_CENTER, "Press Start to continue");
              if (Input->GetKeyState(SDLK_RETURN) || Input->GetKeyState(CDXKEY_JOYBUTN11))
                     page = S_PLAYING;
              break;

       case S_PLAYING:
             

              if (world_x > 0)
                     world_x = 0;
              if (world_x < -1500 + 480)
                     world_x = -1500 + 480;
              for (int i = 0; i < 15; i++) {
                     bgs[i].image->SetPosX(world_x + bgs[i].x);
                     if (bgs[i].x <= (-1) * (world_x - 500))
                           bgs[i].image->Draw(Screen->GetBack(), 0, 0, CDXBLT_TRANS);
              }

              if (score <= 19) {
                     for (int u = 0; u < $_mon; u++) {
                           if (mon[u].src->GetPosX() < 0 || !mon[u].active) {
                                  mon[u].o = rand() % 480 + 480;
                                  mon[u].p = 130;
                                  mon[u].acceleration = 2 * (stage * 2);
                                  mon[u].size = 1;
                                  mon[u].mon_hp = 10;
                                  mon[u].src->SetPos(mon[u].o, mon[u].p);
                                  mon[u].active = true;
                           }
                           if (rudof->sp->SpriteHit(mon[u].src) && mon[u].active && rudof->active && mon[u].o - rudof->x <= 100) {
                                  mon[u].mon_hp -= 1;
                                  rudof->an->duration(19, 20, 5);
                           }

                           mon[u].an->play();
                           mon[u].o = mon[u].src->GetPosX() - mon[u].acceleration;
                           mon[u].src->SetPosX(mon[u].o);
                           if (mon[u].active)
                                  mon[u].src->Draw(Screen->GetBack(), 0, 0, CDXBLT_TRANS);

                     }
              }

              for (int u = 0; u < $_mon; u++) {
                     if (rudof->active && abs(mon[u].o - rudof->x) <= 50 && score < 20 && rudof->x > -15) {
                           hp_rudof -= 5;
                           rudof->pstate = P_ATTACKED;
                     } else if (rudof->active && abs(mon[u].o - rudof->x) <= 80 && score < 20 && rudof->x <= -20) {
                           hp_rudof--;
                           rudof->pstate = P_ATTACKED;
                     }
              }
              if (rudof->pstate == P_ATTACKED) {
                     rudof->an->duration(19, 20, 4);
                     if (back < 15) {
                           rudof->x -= 7;
                           back++;
                     } else {
                           back = 0;
                           rudof->pstate = P_WALK;
                     }
              }
             
              if (rudof->x < 0)
                     rudof->x = 0;
              if (rudof->x > 400)
                     rudof->x = 400;

              for (int u = 0; u < $_mon; u++)
                     mon[u].acceleration = 2;

              if (rudof->pstate == P_WALK) {
                     if (rudof->heading == 'R')
                           rudof->an->duration(1, 1);

                     if (rudof->heading == 'L')
                           rudof->an->duration(6, 6);
                     if (Input->GetKeyState(SDLK_RIGHT) || Input->GetKeyState(CDXKEY_JOYBUTN9)) {
                           rudof->x += 6;
                           world_x -= 5;
                           for (int u = 0; u < $_mon; u++)
                                  mon[u].acceleration = 5;
                           rudof->an->duration(2, 4, 2);
                           rudof->heading = 'R';
                     } else if (rudof->x > 20 && Input->GetKeyState(SDLK_LEFT) || Input->GetKeyState(CDXKEY_JOYBUTN7)) {
                           rudof->x -= 6;
                           world_x += 5;

                           for (int u = 0; u < $_mon; u++)
                                  mon[u].acceleration = -5;

                           rudof->an->duration(7, 9, 2);
                           rudof->heading = 'L';
                     } else if (Input->GetKeyState(SDLK_DOWN) || Input->GetKeyState(CDXKEY_JOYBUTN6)) {
                           for (int u = 0; u < $_mon; u++)
                                  mon[u].acceleration = 2;
                           if (rudof->heading == 'R')
                                  rudof->an->duration(5, 5);
                           if (rudof->heading == 'L')
                                  rudof->an->duration(10, 10);
                     }
                     for (int u = 0; u < $_mon; u++) {
                           if (mon[u].active && (Input->GetKeyState(SDLK_z) || Input->GetKeyState(CDXKEY_JOYBUTN3))) {

                                  if (rudof->heading == 'R') {
                                         rudof->an->duration(11, 18, 1);
                                  }

                                  if (rudof->heading == 'L') {
                                         rudof->an->duration(21, 28, 1);
                                  }
                                  if (mon[u].mon_hp <= 0) {
                                         score += 1;
                                         mon[u].active = false;
                                  }
                           }
                     }
              }
              if (rudof->active) {
                     if (hp_rudof <= 0)
                           hp_rudof = 0;
                     int hp = (float(hp_rudof) / (100 * (float(hp_rudof_max) / 100))) * 100;
                     int color;

                     if (hp >= 0)
                           color = 0xff0000FF;
                     if (hp >= 15)
                           color = 0xff5400FF;
                     if (hp >= 40)
                           color = 0xffc000FF;
                     if (hp >= 75)
                           color = 0x72ec10FF;

                     boxColor(Screen->GetBack(), rudof->x - 1, rudof->y - 1, rudof->x + 1 + rudof->sp->GetBlockWidth(), rudof->y + 3, 0x000000C8);
                     boxColor(Screen->GetBack(), rudof->x, rudof->y, rudof->x + (hp * (float(rudof->sp->GetBlockWidth()) / 100)), rudof->y + 2, color);
                     rudof->an->play();
                     rudof->sp->SetPos(rudof->x, rudof->y);
                     rudof->sp->Draw(Screen->GetBack(), 0, 0, CDXBLT_TRANS);
              }

              if (score >= 20) {
                     if (boss->active) {
                           int hp = (float(hp_boss) / (100 * (float(hp_boss_max) / 100))) * 100;
                           int color;

                           if (hp >= 0)
                                  color = 0xff0000FF;
                           if (hp >= 15)
                                  color = 0xff5400FF;
                           if (hp >= 40)
                                  color = 0xffc000FF;
                           if (hp >= 75)
                                  color = 0x72ec10FF;

                           boxColor(Screen->GetBack(), boss->x - 1, boss->y - 1, boss->x + 1 + boss->sp->GetBlockWidth(), boss->y + 3, 0x000000C8);
                           boxColor(Screen->GetBack(), boss->x, boss->y, boss->x + (hp * (float(boss->sp->GetBlockWidth()) / 100)), boss->y + 2, color);

                           TextXY(Screen->GetBack(), 20, 50, 255, 0, 0, 255, ETA_CENTER, "HP Boss : %d", hp_boss);

                          
                                  if (boss->x - (rudof->x + rudof->sp->GetWidth()) > 20)
                                         boss->x -= 3;
                                  if (boss->x - (rudof->x + rudof->sp->GetWidth()) < 20)
                                         boss->x += 3;
                    
                           boss->an->play();
                           boss->sp->SetPos(boss->x, boss->y);
                           boss->sp->Draw(Screen->GetBack(), 0, 0, CDXBLT_TRANS);

                           if (rudof->sp->SpriteHit(boss->sp) && (Input->GetKeyState(SDLK_z) || Input->GetKeyState(CDXKEY_JOYBUTN3))) {
                                  hp_boss--;
                           }

                           if (hp_boss <= 0) {
                                  hp_boss = 0;
                                  boss->active = false;
                           }

                           if (boss->sp->GetWidth() + boss->x > 480)
                                  boss->x = 480 - boss->sp->GetWidth();

                           if (rudof->active && abs(boss->x - rudof->x) <= 50 && boss->active) {
                                  hp_rudof -= 10;
                                  rudof->pstate = P_ATTACKED;
                           }

                           if (rand() % 5< 2) {
                                  boss->pstate = P_ATTACK;
                                  if (rudof->heading == 'R') {
                                         if (boss_atk < 8) {
                                                boss->x -= 8;
                                                boss_atk++;
                                         } else {
                                                boss_atk = 0;
                                                boss->pstate = P_WALK;
                                         }
                                  }
                                  if (rudof->heading == 'L') {
                                         if (boss_atk < 8) {
                                                boss->x += 8;
                                                boss_atk++;
                                         } else {
                                                boss_atk = 0;
                                                boss->pstate = P_WALK;
                                         }
                                  }
                                  rudof->pstate = P_WALK;
                           }
                     }

                     // Change Stage
                     if (Input->GetKeyState(SDLK_h) || Input->GetKeyState(CDXKEY_JOYBUTN3)== CDXKEY_PRESS && hp_boss == 0 && stage<=3) {
                          
                           stage++;
                           rudof->heading = 'R';
                           world_x = 0;
                           rudof->x = 50;
                           boss->active = true;
                           hp_boss = 0.5 * (stage + 1); //////////
                           hp_boss_max = 0.5 * (stage + 1); //////////
                          
                           score = 0;
                           rudof->pstate = P_WALK;
                           back = 0;
                           for (int i = 0; i < 15; i++) {
                                  SAFEDELETE(bgs[i].image);
                                  bgs[i].image = new CDXSprite();
                                  char buffer[80];
                                  sprintf(buffer, "images/bg_%02d_ (%d).png", stage, i + 1);
                                  bgs[i].image->Create(buffer, 1);
                                  bgs[i].x = 100 * i;
                                  bgs[i].image->SetPosX(bgs[i].x);
                           }
                           for (int u = 0; u < $_mon; u++) {
                                  SAFEDELETE(mon[u].src);
                                  mon[u].o = rand() % 480 + 480;
                                  mon[u].p = 130;
                                  mon[u].acceleration = 2 * (stage * 2);
                                  mon[u].size = 1;
                                  mon[u].active = true;
                                  mon[u].mon_hp = 10;
                                  mon[u].src = new CDXSprite();
                                  if (mon[u].size == 1) {
                                         mon[u].src->Create(mon_filename[stage - 1].filename, mon_filename[stage - 1].width, mon_filename[stage - 1].height, 1);
                                         mon[u].src->SetPos(mon[u].o, mon[u].p);
                                  }
                                  mon[u].an = new Animation(mon[u].src);
                                  mon[u].an->duration(mon_filename[stage - 1].a_start, mon_filename[stage - 1].a_stop, mon_filename[stage - 1].a_delay);
                           }
                           if (stage == 2) {
                                  SAFEDELETE(boss->sp);
                                  boss->sp = new CDXSprite();
                                  boss->sp->Create("boss2.png", 96, 96, 1);
                                  boss->an = new Animation(boss->sp);
                                  boss->an->duration(4, 6, 3);
                                  boss->active = true;
                                  boss->x = 350;
                                  boss->y = 100;
                           }
                           if (stage == 3) {
                                  SAFEDELETE(boss->sp);
                                  boss->sp = new CDXSprite();
                                  boss->sp->Create("boss3.png", 96, 96, 1);
                                  boss->an = new Animation(boss->sp);
                                  boss->an->duration(4, 6, 3);
                                  boss->active = true;
                                  boss->x = 350;
                                  boss->y = 100;

                           }
                     }
              }

              TextXY(Screen->GetBack(), 20, 20, 0, 200, 0, 255, ETA_CENTER, "Score : %d", score);
              TextXY(Screen->GetBack(), 20, 10, 0, 200, 00, 255, ETA_CENTER, "HP Hero : %d", hp_rudof);

              if (hp_rudof <= 0) {
                     page = S_GAMEOVER;
              }
      
              break;

       case S_GAMEOVER:
              gover->Draw(Screen->GetBack(), 0, 0, CDXBLT_TRANS);
              TextXY(Screen->GetBack(), 0, 200, 255, 255, 255, 255, ETA_CENTER, "Press start to retry");
              if (Input->GetKeyState(SDLK_RETURN) || Input->GetKeyState(CDXKEY_JOYBUTN11)) {
                     rudof->active = 1;
                     rudof->x = 50;
                     rudof->y = 120;
                     hp_rudof = hp_rudof_max;
                     rudof->pstate = P_WALK;
                     back = 0;

                     for (int u = 0; u < $_mon; u++) {
                           mon[u].active = false;
                     }

                     score = 0;

                     page = S_PLAYING;
              }
              break;

       case S_WON:
             
              break;
       }

       Screen->Flip(0, 0, 1);
       SDL_framerateDelay(Fps);
}

int main(int argc, char* args[]) {
#ifdef _PSP

#ifndef NDEBUG
       pspDebugScreenInit( );
#endif

       SetupCallbacks( );
#endif

       cdx_Init();

       while (1) {
#ifdef WIN32
              if( Input->GetKeyState(SDLK_ESCAPE) )
              break;
#endif

              cdx_DoFrame();
       }

       cdx_DeInit();

       return 0;
}

รีวีวเกม


รีวิวCODE GAME 




รันเกมลงบนPSP EP.1


รันเกมลงบนPSP EP.2





Simulate