SDL Guide 中文譯版(三上) (轉)

worldblog發表於2007-12-15
SDL Guide 中文譯版(三上) (轉)[@more@]

第三章上 遊戲杆輸入處理

初始化

使用遊戲杆的第一步是初始化遊戲杆子。即在SDL_Init時使用引數SDL_INIT_JOYSTICK。

例3-1 初始化SDL並帶遊戲杆支援

if ( ! SDL_Init( SDL_INIT_VO | SDL_INIT_JOYSTICK ) ) { fprintf(stderr, "Couldn't initialize SDL: %sn", SDL_GetError()); exit(1); }


此例啟動SDL並帶影片和遊戲杆支援。

查詢

至此,我們可以假定初始化以完成。但我們還需指導有沒有、有幾個遊戲杆。即使您指導有一個遊戲杆可用,也最好經常檢查,因為這樣可以幫助檢測遊戲杆被拔掉的情況。

檢查遊戲杆的是SDL_NumJoysticks()。此函式簡單的返回系統中游戲杆的數量。下一步是決定想用哪一個。當然,如果只有一個就不用決定了。SDL_JoystickName取得系統賦給遊戲杆的名字。遊戲杆用序號指定,第一個為0,最後一個為SDL_NumJoysticks - 1。

例3-2 列印所有遊戲杆的名字

printf("%i joysticks were found.nn", SDL_NumJoysticks() ); printf("The names of the joysticks are:n"); for( i=0; i < SDL_NumJoysticks(); i++ ) { printf(" %sn", SDL_JoystickName(i)); }


啟動遊戲杆取得事件

SDL使用事件架構,遊戲杆可以觸發四種事件。

  • SDL_JoyAxisEvent 軸改變
  • SDL_JoyBallEvent 軌跡球座標改變
  • SDL_JoyHatEvent hat(sorry,在下不解何為hat)方向改變
  • SDL_JoyButtonEvent 按鈕按下或釋放

所有啟動的遊戲杆都會觸發事件。為了收到事件,首先要用SDL_ENABLESDL_JoystickEventState,以允許事件。其次要啟動指定的遊戲杆,用SDL_JoystickOpen()。

例3-3 啟動第一個遊戲杆

SDL_Joystick *joystick; SDL_JoystickEventState(SDL_ENABLE); joystick = SDL_JoystickOpen(0);


遊戲杆的指標只在查詢和關閉遊戲杆時有用。

現在為了響應事件,我們需要一個訊息迴圈。所有的SDL至少要接受系統退出訊息。設想我們的訊息迴圈象這樣:

SDL_Event event; /* Other initializtion code goes here */ /* Start main game l here */ while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_KEYDOWN: /* handle keyboard stuff here */ break; case SDL_QUIT: /* Set whatever flags are necessary to */ /* end the main game loop here */ break; } } /* End loop here */


要響應遊戲杆事件,只需新增一個case。軸檢測得有些技巧,因為大部分事件是垃圾。搖桿動一點就會有事件。所以必須設定一個閾值,並且忽略未達到閾值的事件。一般10%是個比較好的閾值。

例3-4 遊戲杆軸事件

case SDL_JOYAXISMOTION: /* Handle Joystick Motion */ if ( ( event.jaxis.value < -3200 ) || (event.jaxis.value > 3200 ) ) { /* code goes here */ } break;


另一個技巧是上下和左右是兩組不同的運動。最重要的軸是軸0(左右)和軸1(上下)。按如下方法作不同處理:

例3-5

case SDL_JOYAXISMOTION: /* Handle Joystick Motion */ if ( ( event.jaxis.value < -3200 ) || (event.jaxis.value > 3200 ) ) { if( event.jaxis.axis == 0) { /* Left-right movement code goes here */ } if( event.jaxis.axis == 1) { /* Up-Down movement code goes here */ } } break;


理想情況下,應該用event.jaxis.value來調整一些值。例如你在用遊戲杆控制飛船,將搖桿推一點則慢速前進,推很多則前進。這樣設計會使使用者的體驗更好。如果你的遊戲杆有更多的軸,可用於其他控制,用法完全一樣,event.jaxis.axis會有不同的值。

例3-6 遊戲杆按鈕事件

case SDL_JOYBUTTONDOWN: /* Handle Joystick Button Presses */ if ( event.jbutton.button == 0 ) { /* code goes here */ } break;


按鈕檢測很簡單,因為只有按下和放開兩個狀態。按下時SDL_JOYBUTTONDOWN觸發,放開時SDL_JOYBUTTONUP觸發。event.jbutton.button指示是哪個按鈕。

最後,程式結束時用SDL_JoystickClose()關閉遊戲杆。例如關閉前面啟動的0號遊戲杆:

SDL_JoystickClose(joystick);


高階遊戲杆函式

軌跡球訊息包含X和Y方向的改變數。

例3-7 軌跡球事件

case SDL_JOYBALLMOTION: /* Handle Joyball Motion */ if( event.jball.ball == 0 ) { /* ball handling */ } break;


此例檢測第一個軌跡球。座標改變數在event.jball.xrel和event.jball.yrel中。

最後是hat事件。hat只報告方向。我們透過位掩碼檢測:

SDL_HAT_CENTERED SDL_HAT_UP SDL_HAT_RIGHT SDL_HAT_DOWN SDL_HAT_LEFT


預定義的組合:

SDL_HAT_RIGHTUP SDL_HAT_RIGHTDOWN SDL_HAT_LEFTUP SDL_HAT_LEFTDOWN


例3-8 遊戲杆hat事件

case SDL_JOYHATMOTION: /* Handle Hat Motion */ if ( event.jhat.hat | SDL_HAT_UP ) { /* Do up stuff here */ } if ( event.jhat.hat | SDL_HAT_LEFT ) { /* Do left stuff here */ } if ( event.jhat.hat | SDL_HAT_RIGHTDOWN ) { /* Do right and down together stuff here */ } break;


除了遊戲杆的數量,還可查詢:

  • SDL_JoystickNumAxes 軸數量
  • SDL_JoystickNumButtons 按鈕數量
  • SDL_JoystickNumBalls 軌跡球數量
  • SDL_JoystickNumHats hat數量

只需將啟動遊戲杆時得到的指標傳給這些函式即可。

例3-9 查詢遊戲杆特性

int number_of_buttons; SDL_Joystick *joystick; joystick = SDL_JoystickOpen(0); number_of_buttons = SDL_JoystickNumButtons(joystick);


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993819/,如需轉載,請註明出處,否則將追究法律責任。

相關文章