2017年1月11日 星期三

[C/C++自製2D遊戲]#07 實現第一個Class -- [Sprite]

在本篇中,我們會實現2D遊戲引擎的核心物件---Sprite(圖精靈)物件。

本系列前面幾篇文章中,所使用到的程式碼均為標準C語言,
為了邁向物件導向(OOP)之路,從本篇開始我們會使用C++語言來實現物件的部分。
讀者若有一些C++實作OOP的經驗是最好的。

==================
STEP #1:

打開前節專案,新增Sprite.h與Sprite.cpp檔案。


打開Sprite.h,輸入以下宣告:

#ifndef SPRITE_H
#define SPRITE_H
using std::string;

class Sprite{
// public attributes
public:
 int x;
 int y;
 int w;
 int h;
 string filename;

// public methods
 Sprite(string _filename, int _x, int _y, int _w, int _h);
 void Draw();
};
#endif

打開Sprite.cpp,輸入以下程式:

#include <iostream>
#include <stdio.h>
#include "graphics.h"
#include "Sprite.h"

Sprite::Sprite(string _filename, int _x, int _y, int _w, int _h){
 x = _x;
 y = _y;
 w = _w;
 h = _h;
 filename = _filename;
}

void Sprite::Draw(){
 readimagefile(const_cast<char*>(filename.c_str()), x, y, x + w, y + h);
}

程式解說:

  1. 在.h檔中我們宣告了一個class名為Sprite。Sprite利用x,y參數來儲存他的位置;用w,h參數儲存他的寬高;filename字串儲存Sprite圖檔的位置。
  2. 在Sprite的建構函數中,傳入x,y,w,h及filename值用以初始化。
  3. Draw()方法用來繪製此Sprite。
  4. 由於readimagefile()所接受的檔名為(char *)形式,若直接用.c_str()方法得到的將是(const char *),編譯會失誤。因此我們只好使用禁忌魔法 const_cast<char *>()函數,硬是將const char*轉為char *。
字串的實現在C語言下,向來是個大問題。在正規的C語言教學中(不使用C++),字串的操作極有可能超出原本配置的記憶體大小。這個問題一旦發生,整個程式可能會當掉。
故在此處我們利用C++的字串類型sting來操作字串。
使用C++ string物件必須使用std命名空間的子類string:using std:string。
將string輸出至主控台則需匯入<iostream>,如此一來才能使用cout<<。

以C++的風格使用string是必修的基礎課程!即使你已經會C,C++的字串對你可能也是一個陌生的題目,但絕對會比直接用C以byte array來實現字串要方便。

==================
STEP #2:

打開main.cpp,修改如下

#include <stdio.h>
#include <conio.h>
#include "graphics.h"
#include <stdlib.h>
#include "Sprite.h"

int main(){
 
 Sprite sp("games.gif",0,0,64,64);
 initwindow(640,480,"This is my game");

 setactivepage(0);
 setvisualpage(1);
 setcolor(2);
 settextstyle(SANS_SERIF_FONT, HORIZ_DIR, 0);
 outtextxy(200,300,const_cast<char *>(sp.filename.c_str()));
 readimagefile("games.gif", 220, 120, 380, 280);
 swapbuffers();
 getch();
 cleardevice();
 swapbuffers();
 getch();

 //Observe the result after adding paging.
 for(int i; i<1000;i++){
  cleardevice();
  sp.x = sp.x + 1;
  sp.y = sp.y + 2;
  sp.Draw();
  swapbuffers();
  delay(16);
 }
}


  1. 以Sprite物件產生了一個實件sp並做初始化。
  2. 迴圈內直接去調整sp.x與sp.y值,這樣就形同移動了sp。
  3. 呼叫sp.Draw()將sp繪製於page上
按F5運行,可以看到搖桿向右下角移動過去。