作者:龍飛
SDL創(chuàng)建多線程的函數(shù)SDL_CreateThread()所調(diào)用的是函數(shù)指針,這意味著我們不可以傳入(非靜態(tài))成員函數(shù)的指針。關(guān)于兩種函數(shù)指針我們之前已經(jīng)討論過:
函數(shù)指針與成員函數(shù)指針,我們可以有兩種方法能讓具有普通函數(shù)指針(函數(shù)指針以及靜態(tài)成員函數(shù)指針)的函數(shù)調(diào)用類的私有成員,一是友元函數(shù),另外就是靜態(tài)成員函數(shù)。而能夠受到類私有保護(hù)的,只有靜態(tài)成員函數(shù)。所以,我們可以通過靜態(tài)成員函數(shù)調(diào)用一個(gè)對(duì)象數(shù)據(jù)的形式,實(shí)現(xiàn)對(duì)于創(chuàng)建多線程函數(shù)的封裝。
另外,我們希望測(cè)試在主線程中讀寫線程數(shù)據(jù)的效果,所以添加了兩個(gè)方法show() 和reset(),多線程演示的類源代碼如下:
#include <iostream>
#include "SurfaceClass.hpp"
class AmnArg
{
private:
int beginX;
int beginY;
int endX;
int endY;
const ScreenSurface& screen;
//
static int amn(void* pThat);
public:
AmnArg(int begin_x, int begin_y, int end_x, int end_y, const ScreenSurface& _screen);
SDL_Thread* createThrd();
void show() const;
void reset();
};
其中SurfaceClass.hpp請(qǐng)參考:
http://www.shnenglu.com/lf426/archive/2008/04/14/47038.html實(shí)現(xiàn)函數(shù)如下:
#include "amn.hpp"
AmnArg::AmnArg(int begin_x, int begin_y, int end_x, int end_y, const ScreenSurface& _screen):
beginX(begin_x), beginY(begin_y), endX(end_x), endY(end_y), screen(_screen)
{}
SDL_Thread* AmnArg::createThrd()
{
return SDL_CreateThread(amn, (void*)this);
}
void AmnArg::show() const
{
std::cout << "Now x at: " << beginX << std::endl;
}
void AmnArg::reset()
{
beginX = 0;
}
int AmnArg::amn(void* pThat)
{
AmnArg* pData = (AmnArg*)pThat;
PictureSurface stand("./images/am01.png", pData->screen);
stand.colorKey();
PictureSurface bg("./images/background.png", pData->screen);
const int SPEED_CTRL = 300;
int speedX = (pData->endX - pData->beginX) / SPEED_CTRL;
int speedY = (pData->endY - pData->beginY) / SPEED_CTRL;
for ( int i = 0; i < SPEED_CTRL; i++ ){
pData->beginX += speedX;
pData->beginY += speedY;
bg.blit(pData->beginX, pData->beginY, pData->beginX, pData->beginY, stand.point()->w, stand.point()->h, 2, 2);
stand.blit(pData->beginX, pData->beginY);
pData->screen.flip();
SDL_Delay(10);
}
return 0;
}
最后,我們修改了主演示程序,并測(cè)試了show()和reset()的效果。我們可以看到,直接修改線程數(shù)據(jù)的reset()的結(jié)果也是不可預(yù)知的,所以,我們似乎更應(yīng)該通過改變線程“流”的效果,而不是直接對(duì)數(shù)據(jù)進(jìn)行修改。這個(gè)我們以后再討論了。
#include "SurfaceClass.hpp"
#include "amn.hpp"
int game(int argc ,char* argv[]);
int main(int argc ,char* argv[])
{
int mainRtn = 0;
try {
mainRtn = game(argc, argv);
}
catch ( const ErrorInfo& info ) {
info.show();
return -1;
}
catch ( const char* s ) {
std::cerr << s << std::endl;
return -1;
}
return mainRtn;
}
int game(int argc ,char* argv[])
{
//Create a SDL screen.
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const Uint32 SCREEN_FLAGS = 0; //SDL_FULLSCREEN | SDL_DOUBLEBUF | SDL_HWSURFACE
const std::string WINDOW_NAME = "Amn Test";
ScreenSurface screen(SCREEN_WIDTH, SCREEN_HEIGHT, WINDOW_NAME, 0, SCREEN_FLAGS);
PictureSurface bg("./images/background.png", screen);
bg.blit(0);
screen.flip();
AmnArg test1(0, 250, 600, 250, screen);
SDL_Thread* thread1 = test1.createThrd();
AmnArg test2(0, 0, 400, 0, screen);
SDL_Thread* thread2 = test2.createThrd();
SDL_Event gameEvent;
bool gameOver = false;
while ( gameOver == false ){
while ( SDL_PollEvent(&gameEvent) != 0 ){
if ( gameEvent.type == SDL_QUIT ){
gameOver = true;
}
if ( gameEvent.type == SDL_KEYDOWN ){
if ( gameEvent.key.keysym.sym == SDLK_ESCAPE ){
gameOver = true;
}
if ( gameEvent.key.keysym.sym == SDLK_SPACE ){
test1.show();
test2.show();
}
}
screen.flip();
}
SDL_Delay(100);
}
SDL_KillThread(thread1);
SDL_KillThread(thread2);
return 0;
}
posted on 2008-04-28 14:24
lf426 閱讀(2945)
評(píng)論(2) 編輯 收藏 引用 所屬分類:
SDL入門教程