一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

SDL入門教程(三):1、如何實(shí)現(xiàn)按下ESC退出程序?

 renhl252 2015-06-12
作者:龍飛

1.1:游戲中的退出習(xí)慣。

        如同我們經(jīng)常遇到的游戲,一般想退出的時(shí)候,我們會(huì)習(xí)慣性的按下ESC——即使游戲不會(huì)馬上退出,也一般會(huì)調(diào)出一個(gè)帶有退出選擇的菜單。我們希望修房子的時(shí)候,最好先計(jì)劃在哪里修門,所以,我認(rèn)為應(yīng)該優(yōu)先掌握“退出游戲”的方法。簡單的說,我們啟動(dòng)了一個(gè)SDL程序,我們希望按下ESC就能退出,怎么實(shí)現(xiàn)?

1.2:事件(event)查詢初探。

        在計(jì)算機(jī)科學(xué)領(lǐng)域,隱喻無處不見。所有的抽象概念,若不是被很好的用形象概念或者已經(jīng)被理解的抽象概念去解釋,其本身很難讓人們明白是什么。事件,在這里指的就是計(jì)算機(jī)所直接感知到的玩家對于其的作用。比如你按下某個(gè)鍵,又松開,移動(dòng)了鼠標(biāo)等等。所有的這些行為都被稱為事件。在計(jì)算機(jī)看來,任何事件的發(fā)生都是有先后的(如果你了解相對論,你就會(huì)知道其實(shí)世界上任意兩點(diǎn)間并不存在“同時(shí)”的概念)。如果計(jì)算機(jī)工作效率很低,這些事件就會(huì)排著隊(duì)列等待接受處理——這里又用到一個(gè)模型的隱喻——隊(duì)列(queue),這是計(jì)算機(jī)算法與數(shù)據(jù)結(jié)構(gòu)知識中很重要的概念,往往意味著其特征是“先進(jìn)先出”。
        我們就從這個(gè)事件隊(duì)列(event queue)的模型去思考吧。要知道,隊(duì)列是有可能為空的,這就如同銀行的服務(wù)窗口前面不會(huì)總是有人排隊(duì)一樣——當(dāng)然,我假設(shè)你不是總呆在北京,也去過一些小城市^^,那么,沒有客戶在窗口前需要被服務(wù)的時(shí)候,這個(gè)窗口的工作人員應(yīng)該是什么狀態(tài)呢?至少有兩種不同的等待方式:一種是什么也不做傻等;一種是邊喝點(diǎn)茶看看報(bào)紙算算賬什么的其他事情邊等待。對于計(jì)算機(jī)來說,第一種停下來等,就是wait;第二種繼續(xù)做其他事情的同時(shí)等,就是poll。前者一看就明白,后者被不知道某位前輩高人翻譯成“輪詢”,好吧,說句實(shí)話,我笨,光看“輪詢”這個(gè)詞,完全無法理解是什么意思-_-!!!
        SDL為我們提供了兩種等待事件的方式:
int SDL_WaitEvent(SDL_Event *event);
int SDL_PollEvent(SDL_Event *event);

        兩個(gè)函數(shù)的返回值都是int,形參是SDL事件結(jié)構(gòu)(C++里面,就把結(jié)構(gòu)看成類吧。)指針SDL_Event*(請注意我把SDL_Event和*連著寫,這意味著在認(rèn)識上,我把SDL_Event*本身看成一種復(fù)合類類型。)我們知道,在C\C++里面,函數(shù)至少有三種基本功能。1、像命令似的起了某種作用;2、通過計(jì)算得到我們需要的返回值;3、指針(C++里面的引用)參數(shù)也可以傳值。這里,我們先忽略SDL_Event結(jié)構(gòu)的構(gòu)造,看看這兩個(gè)函數(shù)的作用。首先,他們不會(huì)引起某種作用;其次,他們的返回值是1或者0;最后,他們會(huì)通過指針參數(shù)傳值,這是重點(diǎn)。
        早期的C里面,是沒有關(guān)鍵字true和false的。通常用1代表true,0代表false。我個(gè)人覺得,在SDL里面,1和0的概念最容易與-1和0的概念混淆。我們在學(xué)習(xí)SDL_Init的時(shí)候,說到返回值0代表成功,-1代表失敗。其實(shí)細(xì)細(xì)想,還是有差別的。0和1是計(jì)算機(jī)固有的數(shù)據(jù)表示方式,而-1是計(jì)算機(jī)原始方式所無法理解的,所以會(huì)代表著異常。所以,在異常退出的時(shí)候,我選擇使用return -1。
        這兩個(gè)函數(shù)的返回值,在等到了事件的時(shí)候,返回1,否則返回0。官方文檔里面用類似while(SDL_PollEvent(&event))的方法引導(dǎo)輪詢機(jī)制的開始,但是我覺得,對于新手來說,這樣的表述不是很直觀。與其間接的問窗口的服務(wù)員有客戶來嗎,還不如自己直接看看有沒客戶(event queue是不是為空)。所以,在后面的例子里面,我實(shí)際上用的是if ( &event != 0 )。

1.3:當(dāng)前窗口。

        如果你有興趣研究SDL的官方文檔,看到事件介紹(Introduction to Events)部分,也許會(huì)對以下問題感覺到奇怪:SDL的事件查詢機(jī)制是與SDL_INIT_VIDEO同時(shí)裝載的。為什么呢?
        我們知道,我們開發(fā)的游戲?qū)嶋H上是運(yùn)行在操作系統(tǒng)的平臺上的。當(dāng)前的操作系統(tǒng),都是多任務(wù)的操作系統(tǒng)。具體說到GUI,有個(gè)很重要的概念就是你目前操作的是哪個(gè)程序,也就是更形象的概念——當(dāng)前窗口。有些event可能是各個(gè)窗口,甚至包括系統(tǒng)本身共享的,比如鼠標(biāo)移動(dòng)(這不是絕對的,只是有可能);有些event只會(huì)被當(dāng)前窗口接受,就如同你不會(huì)希望同時(shí)開著兩個(gè)Word文件在編輯,修改一個(gè)文件的時(shí)候,另外一個(gè)也被無情的修改了。所以,SDL程序運(yùn)行的時(shí)候,只有指定了哪個(gè)窗口是這個(gè)程序的窗口,并且這個(gè)窗口是當(dāng)前窗口的時(shí)候,大部分event才能被正確的響應(yīng)。
        注意,console窗口不是SDL程序的運(yùn)行窗口,它屬于操作系統(tǒng)本身。我們要打開SDL的程序窗口,需要引入一個(gè)新函數(shù):

SDL_Surface *SDL_SetVideoMode(int width, int height, int bitsperpixel, Uint32 flags);
        我們這里僅僅是為了打開SDL的程序窗口來引入這個(gè)函數(shù),只做個(gè)簡單介紹:1、這個(gè)函數(shù)本身有作用——打開SDL程序窗口;2、前三個(gè)參數(shù)分別是這個(gè)打開窗口的寬,高和位深,最后那個(gè)flags我們這里只介紹SDL_SWSURFACE,這個(gè)位標(biāo)表示把返回值的數(shù)據(jù)建立在系統(tǒng)內(nèi)存里面。

1.4:一段演示按下ESC(或者點(diǎn)x)退出SDL窗口的程序。
///////////////////
//按下ESC(或者點(diǎn)x)退出SDL窗口
//聯(lián)系我: znln426@163.com
//再別流年的技術(shù)實(shí)驗(yàn)室
//http://www./lf426/
///////////////////

#include <iostream>
#include "SDL/SDL.h"

void pressESCtoQuit();
void doSomeLoopThings();

int main(int argc,char* argv[])
{
    try {
        if ( SDL_Init(SDL_INIT_VIDEO == -1 ))
            throw SDL_GetError();
    }
    catch ( const char* s ) {
        std::cerr << s << std::endl;
        return -1;
    }
    atexit(SDL_Quit);

    SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
    std::cout << "Program is running, press ESC to quit.\n";
    pressESCtoQuit();
    std::cout << "GAME OVER" << std::endl;

    return 0;
}

void pressESCtoQuit()
{
    std::cout << "pressESCtoQuit() function begin\n";
    bool gameOver = false;
    while( gameOver == false ){
        SDL_Event gameEvent;
        SDL_PollEvent(&gameEvent);
        if ( &gameEvent != 0 ){
            if ( gameEvent.type == SDL_QUIT ){
                gameOver = true;
            }
            if ( gameEvent.type == SDL_KEYDOWN ){
                if ( gameEvent.key.keysym.sym == SDLK_ESCAPE ){
                    gameOver = true;
                }
            }
        }
        doSomeLoopThings();
    }
    return;
}

void doSomeLoopThings()
{
    std::cout << ".";
    return;
}

1.5:兩個(gè)細(xì)節(jié)問題。

        我們修改pressESCtoQuit()函數(shù)兩個(gè)小地方:
void pressESCtoQuit()
{
    std::cout << "pressESCtoQuit() function begin\n";
    bool gameOver = false;
    while( gameOver == false ){
        SDL_Event gameEvent;
        while ( SDL_PollEvent(&gameEvent) != 0 ){
            if ( gameEvent.type == SDL_QUIT ){
                gameOver = true;
            }
            if ( gameEvent.type == SDL_KEYUP ){
                if ( gameEvent.key.keysym.sym == SDLK_ESCAPE ){
                    gameOver = true;
                }
            }
        }
        doSomeLoopThings();
    }
    return;
}
        我們把引起輪詢機(jī)制的if換成了while。我們前面說過,查詢&gameEvent是不是為空,是為了強(qiáng)調(diào)SDL_PollEvent()使用指針參數(shù)傳了值。而事實(shí)上,if是判斷,while不僅僅是判斷,而且還是循環(huán)。但是更換這兩個(gè)關(guān)鍵字似乎并沒有出現(xiàn)不同,為什么呢?
        我們分析兩種情況下的模型。使用if的函數(shù),實(shí)際上每次循環(huán)只查詢event一次;而使用while的時(shí)候,內(nèi)嵌的while循環(huán)會(huì)一直對“懸而未解”的事件隊(duì)列(event queue)“彈”(這個(gè)隱喻意味著某個(gè)event一旦被處理,就不再屬于queue的一個(gè)元素)出的頭值進(jìn)行處理,直到事件隊(duì)列為空。這似乎更符合理想的模型。但是實(shí)際上,計(jì)算機(jī)的效率并不是我們假設(shè)的那樣低,event queue在一個(gè)外循環(huán)期間,始終保持兩種狀態(tài):要么為空,要么最多一個(gè)。換句話說,你不可能在一次gameOver==false的循環(huán)期間,為event queue擠進(jìn)去1個(gè)之上(>1)的event,這就是if與while效果相同的原因。
        我們修改的第二個(gè)細(xì)節(jié)是把SDL_KEYDOWN換成了SDL_KEYUP,這是為了提醒大家,按下某個(gè)鍵和按下某個(gè)鍵再松開,是兩種不同的event。
posted on 2008-02-04 03:31 lf426 閱讀(6099) 評論(13)  編輯 收藏 引用 所屬分類: SDL入門教程

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    精品久久少妇激情视频| 91欧美日韩一区人妻少妇| 亚洲精品成人福利在线| 日韩特级黄片免费观看| 国产精品一区二区丝袜| 高清免费在线不卡视频| 欧美大胆女人的大胆人体| 欧美夫妻性生活一区二区| 中文字幕禁断介一区二区| 男人大臿蕉香蕉大视频| 国产性情片一区二区三区| 欧美精品女同一区二区| 国产内射在线激情一区| 亚洲视频一区二区久久久| 女人高潮被爽到呻吟在线观看| 日本免费一本一二区三区| 欧美黑人黄色一区二区| 国产精品尹人香蕉综合网| 日本高清中文精品在线不卡| 麻豆视传媒短视频免费观看| 内射精子视频欧美一区二区| 亚洲国产精品av在线观看| 九九热精彩视频在线免费| 日本熟女中文字幕一区| 好吊妞视频免费在线观看| 亚洲精品偷拍一区二区三区| 伊人天堂午夜精品草草网| 在线免费看国产精品黄片| 国产对白老熟女正在播放| 欧美日韩国产综合特黄| 日本二区三区在线播放| 欧美人妻免费一区二区三区| 午夜色午夜视频之日本| 国产亚洲二区精品美女久久 | 日本在线 一区 二区| 欧美日韩国产自拍亚洲| 99久久精品午夜一区二| 亚洲精品偷拍一区二区三区| 国产成人精品视频一区二区三区| 欧美一区日韩二区亚洲三区| 好吊视频一区二区在线|