青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 96  文章 - 255  trackbacks - 0
<2025年10月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

E-mail:zbln426@163.com QQ:85132383 長期尋找對戰略游戲感興趣的合作伙伴。

常用鏈接

留言簿(21)

隨筆分類

隨筆檔案

SDL相關網站

我的個人網頁

我的小游戲

資源下載

搜索

  •  

積分與排名

  • 積分 - 494779
  • 排名 - 39

最新評論

閱讀排行榜

評論排行榜

作者:龍飛

1.1:游戲中的退出習慣。

        如同我們經常遇到的游戲,一般想退出的時候,我們會習慣性的按下ESC——即使游戲不會馬上退出,也一般會調出一個帶有退出選擇的菜單。我們希望修房子的時候,最好先計劃在哪里修門,所以,我認為應該優先掌握“退出游戲”的方法。簡單的說,我們啟動了一個SDL程序,我們希望按下ESC就能退出,怎么實現?

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

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

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

1.3:當前窗口。

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

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

1.4:一段演示按下ESC(或者點x)退出SDL窗口的程序。
///////////////////
//按下ESC(或者點x)退出SDL窗口
//聯系我: znln426@163.com
//再別流年的技術實驗室
//http://m.shnenglu.com/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(
64048032, 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:兩個細節問題。

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

FeedBack:
# re: SDL入門教程(三):1、如何實現按下ESC退出程序? 2008-04-16 11:39 WANGYY
請問一下,為什么atexit(SDL_Quit)在窗口創建之前啊?那不是把SDL退出了,還創建窗口等這些事情有什么用呢?
我試過,把atexit(SDL_Quit)放在最后退出窗口之后跟樓主那樣是一樣的效果
但就是不明白為什么,請指教,謝謝!  回復  更多評論
  
# re: SDL入門教程(三):1、如何實現按下ESC退出程序?[未登錄] 2008-04-16 11:57 lf426
atexit()的效果相當于在main()終止的時候執行,無論是正常退出,比如return 0,或者異常退出,比如exit (-1)或者其他異常的情況下,只要main()結束了,atexit()就會調用,放在main()的任何位置理論上都是可以的。
不過后面的章節我使用對象來管理SDL的裝載與退出了,就用不上atexit()了。  回復  更多評論
  
# re: SDL入門教程(三):1、如何實現按下ESC退出程序? 2009-03-25 15:03 hello
SDL_Event gameEvent;
SDL_PollEvent(&gameEvent);
if ( &gameEvent != 0 ){
...
}

這里&gameEvent永遠也不會為空啊  回復  更多評論
  
# re: SDL入門教程(三):1、如何實現按下ESC退出程序? 2009-03-26 15:04 LHNing
@hello
應該是你調試的假象吧  回復  更多評論
  
# re: SDL入門教程(三):1、如何實現按下ESC退出程序?[未登錄] 2009-04-02 11:19 haha
@LHNing

SDL_PollEvent(&gameEvent);

人家hello是說

不管你在這個函數里做什么, 你也不可能改變gameEvent這個局部變量的內存地址, 即 &gameEvent 是不會變的!

扯什么什么假象啊....
  回復  更多評論
  
# re: SDL入門教程(三):1、如何實現按下ESC退出程序? 2009-04-28 11:07 liigo
思路很條理,表達很清晰  回復  更多評論
  
# re: SDL入門教程(三):1、如何實現按下ESC退出程序? 2009-06-19 10:22 akira
if ( &gameEvent != 0 )


寫出這樣的代碼頁好意思拿出來啊?笑  回復  更多評論
  
# re: SDL入門教程(三):1、如何實現按下ESC退出程序? 2009-07-19 18:23 林某
面向對象!C++是面向對象的語言,這么寫程序不倫不類。  回復  更多評論
  
# re: SDL入門教程(三):1、如何實現按下ESC退出程序? 2009-08-16 20:07 路過
SDL_PollEvent(&gameEvent);
if ( &gameEvent != 0 ){

估計作者的原意是:
if (SDL_PollEvent(&gameEvent) != 0 ){

因為后面的解釋是按照后者的
估計作者犯了低級錯誤而已
  回復  更多評論
  
# re: SDL入門教程(三):1、如何實現按下ESC退出程序?[未登錄] 2009-10-07 09:47 xosen
我們分析兩種情況下的模型。使用if的函數,實際上每次循環只查詢event一次;而使用while的時候,內嵌的while循環會一直對“懸而未解”的事件隊列(event queue)“彈”(這個隱喻意味著某個event一旦被處理,就不再屬于queue的一個元素)出的頭值進行處理,直到事件隊列為空。這似乎更符合理想的模型。但是實際上,計算機的效率并不是我們假設的那樣低,event queue在一個外循環期間,始終保持兩種狀態:要么為空,要么最多一個。換句話說,你不可能在一次gameOver==false的循環期間,為event queue擠進去1個之上(>1)的event,這就是if與while效果相同的原因。

用if和while是完全不一樣的處理方式  回復  更多評論
  
# re: SDL入門教程(三):1、如何實現按下ESC退出程序? 2009-11-05 21:34 metin9527
沒錯,if和while是完全不同的,if可以使后面的doSomeLoopThings()每次循環得到執行,如果使用while poll事件的話,如果事件不斷,后面的doSomeLoopThings()會得不到執行!  回復  更多評論
  
# re: SDL入門教程(三):1、如何實現按下ESC退出程序? 2013-05-03 15:47 匿名
@akira
這么寫沒錯,運行正常  回復  更多評論
  
# re: SDL入門教程(三):1、如何實現按下ESC退出程序? 2013-12-16 16:17 許思維
@hello同學說的對,if ( &gameEvent != 0 )永遠也不會成立。
樓主@lf426,你的最后一句:
“你不可能在一次gameOver==false的循環期間,為event queue擠進去1個之上(>1)的event,這就是if與while效果相同的原因。”
你的這句話不正確。也與你倒數第二句“計算機的效率并不是我們假設的那樣低”有沖突。你這兩句話是不是打錯了,請你仔細檢查?
實際上,一個gameOver==false循環期間,event queue很可能被置入多于一個event。因為就一般情況而言,doSomeLoopThings執行所需的時間是未知的,可能比例子中的一個輸出多的多,event queue必定會捕捉在此期間的所有事件,當然不會只有1個。
在doSomeLoopThings中加入延時(SDL_Delay(1000))即可驗證:
void doSomeLoopThings()
{
std::cout << ".";
SDL_Delay(500);
return;
}
// 再對while(gameOver==false)略作修改:
while( gameOver == false ){
SDL_Event gameEvent;
int ecount = 0;
while ( SDL_PollEvent(&gameEvent) != 0 ){
ecount++;
if ( gameEvent.type == SDL_QUIT ){
gameOver = true;
}
if ( gameEvent.type == SDL_KEYUP ){
if ( gameEvent.key.keysym.sym == SDLK_ESCAPE ){
gameOver = true;
}
}
}
std::cout << "processed " << ecount << " events!\n";
doSomeLoopThings();
}
  回復  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
      <noscript id="pjuwb"></noscript>
            <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
              <dd id="pjuwb"></dd>
              <abbr id="pjuwb"></abbr>
              狠狠综合久久av一区二区老牛| 亚洲国产欧美在线| 国产一区二区剧情av在线| 欧美午夜精品久久久久久人妖 | 亚洲欧美色婷婷| 一本久久青青| 午夜精品久久久久影视| 久久久精品999| 欧美成人日本| 日韩亚洲欧美一区二区三区| 99精品久久久| 香蕉av777xxx色综合一区| 久久精品30| 欧美日韩成人在线播放| 国产美女精品一区二区三区| 伊人久久大香线蕉综合热线| 亚洲久久一区二区| 欧美在线影院在线视频| 欧美激情精品久久久久久蜜臀| 日韩天天综合| 欧美一区二区私人影院日本| 欧美激情视频一区二区三区免费| 国产精品色婷婷| 亚洲精品一区在线观看香蕉| 久久成人资源| 日韩图片一区| 免费久久久一本精品久久区| 国产精品一卡二卡| 一本大道久久a久久精品综合 | 99在线热播精品免费| 久久成人久久爱| 日韩网站在线| 蜜桃伊人久久| 韩日午夜在线资源一区二区| 亚洲一区二区三区在线看| 欧美成人a∨高清免费观看| 一区二区三区精品在线| 欧美成人69| 麻豆精品在线观看| 国产精品日韩在线| 日韩视频精品在线| 久久―日本道色综合久久| 亚洲午夜在线视频| 欧美日韩精品三区| 亚洲激情婷婷| 麻豆亚洲精品| 亚洲一区免费视频| 欧美日韩免费观看中文| 亚洲黄色视屏| 欧美激情第六页| 久久乐国产精品| 国产一区二区三区久久久久久久久| 亚洲一级黄色片| 亚洲美女av在线播放| 欧美夫妇交换俱乐部在线观看| 在线播放豆国产99亚洲| 免费欧美在线| 欧美成人精品1314www| 亚洲国产一区在线| 亚洲国产成人一区| 欧美风情在线| 亚洲视频一区二区| 亚洲深夜av| 国产麻豆综合| 久久一区二区精品| 老色批av在线精品| 亚洲欧洲一区二区三区| 亚洲激情精品| 欧美日韩在线播放三区| 亚洲一区二区三区在线视频| 亚洲男人的天堂在线观看| 国产视频在线观看一区二区| 久久夜色精品国产欧美乱极品| 久久噜噜亚洲综合| 亚洲精品欧美极品| av成人免费在线观看| 国产精品区一区二区三| 久久九九久久九九| 你懂的视频一区二区| 亚洲五月婷婷| 久久av红桃一区二区小说| 在线观看视频一区二区欧美日韩| 亚洲国产精彩中文乱码av在线播放| 欧美日韩高清不卡| 久久精品二区三区| 老牛嫩草一区二区三区日本| 在线视频精品一区| 欧美影视一区| 99国产精品私拍| 性一交一乱一区二区洋洋av| 亚洲日本久久| 亚洲欧美日韩一区二区三区在线观看| 伊人久久综合97精品| 夜夜狂射影院欧美极品| 韩国av一区二区三区在线观看| 亚洲高清自拍| 国产一二三精品| 91久久综合亚洲鲁鲁五月天| 国产午夜精品一区二区三区视频| 亚洲精品乱码久久久久久| 亚洲国产日韩欧美在线动漫| 亚洲精品美女在线观看| 欧美极品aⅴ影院| 裸体一区二区| 欧美精品123区| 免费日本视频一区| 亚洲欧美www| 亚洲人线精品午夜| 欧美精品一级| 久久久精品欧美丰满| 欧美日韩第一区日日骚| 久久在线播放| 国产精品区一区二区三| 91久久精品www人人做人人爽| 国产综合自拍| 亚洲一区二区三区四区五区午夜 | 欧美日韩视频在线第一区| 久久这里只有精品视频首页| 国产精品美女xx| 亚洲人成久久| 亚洲免费观看在线视频| 久久在精品线影院精品国产| 久久久一本精品99久久精品66| 国产精品看片资源| av不卡在线| 亚洲影音先锋| 欧美无砖砖区免费| 国产精品久久久久久五月尺| 欧美激情一区二区三区蜜桃视频| 在线播放日韩| 久久美女艺术照精彩视频福利播放| 欧美呦呦网站| 国内成人精品2018免费看| 香蕉久久国产| 久久久久网站| 伊人精品久久久久7777| 久久精品视频免费观看| 久久先锋资源| 伊人成人开心激情综合网| 久久婷婷丁香| 亚洲高清视频在线| 一区二区三区|亚洲午夜| 欧美日本精品在线| 亚洲视频免费在线| 久久国产精品免费一区| 国产日产亚洲精品| 欧美一区午夜精品| 免费日韩av片| 一本色道综合亚洲| 国产精品日本精品| 久久久www成人免费精品| 免费看亚洲片| 中文亚洲欧美| 国产手机视频精品| 蜜乳av另类精品一区二区| 亚洲日韩中文字幕在线播放| 亚洲主播在线观看| 好看的日韩视频| 久久频这里精品99香蕉| 亚洲二区视频| 欲色影视综合吧| 欧美大片91| 日韩一级精品| 亚洲欧美精品伊人久久| 国产综合欧美| 欧美日韩亚洲视频一区| 欧美一二区视频| 亚洲高清视频在线| 欧美中文字幕在线观看| 亚洲国产精品嫩草影院| 欧美日韩国产一中文字不卡 | 你懂的网址国产 欧美| 一区二区三区四区五区视频| 久久男女视频| 亚洲手机视频| 亚洲国产导航| 国产亚洲人成a一在线v站| 蜜臀av在线播放一区二区三区| 欧美在线你懂的| 亚洲欧美另类中文字幕| 免播放器亚洲一区| 国产精品99久久久久久久女警| 国产视频欧美视频| 欧美日韩在线观看一区二区| 久久精品一区二区三区中文字幕 | 夜夜嗨av一区二区三区中文字幕| 国产一区二区三区视频在线观看| 欧美伦理影院| 蜜臀99久久精品久久久久久软件| 亚洲欧美另类国产| 99国产精品久久| 亚洲国产欧美一区| 蜜臀av国产精品久久久久| 久久av二区| 亚洲欧美一区二区精品久久久| 亚洲国产精选| 一区二区自拍| 欧美日韩一二三四五区| 99视频精品全部免费在线| 亚洲人成在线观看|