GameWnd.c
Upload User: shyhai1508
Upload Date: 2007-06-11
Package Size: 48k
Code Size: 11k
Category:

BREW

Development Platform:

Visual C++

  1. #include "GameWnd.h"
  2. #include "AEEStdLib.h"
  3. #include "AEEAppGen.h"
  4. #include "pfly_res.h"
  5. #include "pfly.h"
  6. #include "commondef.h"
  7. #define MAX_HEIGHT 12800
  8. #define WALL_START_POS_Y 150
  9. #define SCORE_START_X 9
  10. #define DIGIT_WEIGHT 7
  11. //rgCmds中各种对象的索引
  12. #define SPRITE_DIGIT 8
  13. #define SPRITE_PLANE 12
  14. //各种对象的源图像贴索引
  15. #define PIC_START_DIGIT 15
  16. #define PIC_START_WALL 13
  17. //纸飞机在不同飞行角度下的速度表
  18. static const uint16 speedTableX[] = {-4, -3, -3, -2, -1, 0, 1, 2, 3, 3, 4};
  19. static const uint16 speedTableY[] = { 3,  3,  4,  4,  5, 6, 5, 4, 4, 3, 3}; 
  20. static int GameWnd_LoadResources(GameWnd *pthis);
  21. static void GameWnd_UnloadResources(GameWnd *pthis);
  22. static boolean GameWnd_HandleKeyEvent(GameWnd *pthis, AEEEvent eCode, uint16 wParam);
  23. static void GameWnd_NextFrame(GameWnd *pthis);
  24. static boolean GameWnd_IsCrash(GameWnd *pthis);
  25. static void GameWnd_LoadSprites(GameWnd *pthis, const char * pszFile, 
  26. uint16 resID, uint8 unSpriteSize, boolean isTile);
  27. static int16 Random(int16 range);
  28. boolean GameWnd_New(GameWnd *pthis, PflyApp* pMe)
  29. {
  30. pthis->pMe = pMe;
  31. return TRUE;
  32. }
  33. boolean GameWnd_HandleEvent(GameWnd * pthis, AEEEvent eCode, uint16 wParam, uint32 dwParam)
  34. {
  35. switch (eCode) {
  36. case EVT_APP_SUSPEND:
  37. CALLBACK_Cancel(&pthis->cbTimer);
  38. return TRUE;
  39. case EVT_APP_RESUME:
  40. ISHELL_SetTimerEx(pthis->pMe->a.m_pIShell, 0, &pthis->cbTimer);
  41. return TRUE;
  42. case EVT_APP_NO_SLEEP:
  43. // catching this event prevent BREW from going to "sleep"
  44. return TRUE;
  45. default:
  46. return GameWnd_HandleKeyEvent(pthis, eCode, wParam);  
  47. }
  48. }
  49. boolean GameWnd_Open(GameWnd *pthis)
  50. {
  51. AEEDeviceInfo di;
  52. int i;
  53. int8 gridCntX;
  54. pthis->direction = 5;
  55. pthis->keyLeft = FALSE;
  56. pthis->keyRight = FALSE;
  57. pthis->layer = 0;
  58. pthis->crashCounter = 0;
  59. pthis->isCrash = FALSE;
  60. ISHELL_GetDeviceInfo(pthis->pMe->a.m_pIShell, &di);
  61. gridCntX = ((di.cxScreen+12)/16 > 9) ? 9 : (di.cxScreen+12)/16;
  62. //tile索引数组
  63. MEMSET(pthis->BackGroundLayer,0,sizeof(pthis->BackGroundLayer));
  64.     pthis->BackGroundLayer[0] = 2;
  65. pthis->BackGroundLayer[gridCntX-1] = 1;
  66. pthis->BackGroundLayer[gridCntX] = 3;
  67. pthis->BackGroundLayer[15] = 3;
  68. pthis->frameMax.x = gridCntX*16;
  69. pthis->frameMax.y = 256;
  70. pthis->frameStart.x = (di.cxScreen - pthis->frameMax.x)/2;
  71. pthis->frameStart.y = 0;
  72. CALLBACK_Init(&pthis->cbTimer, GameWnd_NextFrame, pthis);
  73. //sprite
  74. MEMSET(pthis->rgCmds, 0, sizeof(pthis->rgCmds));
  75. //score digit
  76. for (i = SPRITE_DIGIT; i < 4+SPRITE_DIGIT; i++) {
  77. pthis->rgCmds[i].x = pthis->frameStart.x 
  78. + SCORE_START_X + (i-SPRITE_DIGIT)*DIGIT_WEIGHT; 
  79. pthis->rgCmds[i].y = pthis->frameStart.y + 0;
  80. pthis->rgCmds[i].unSpriteIndex = PIC_START_DIGIT;
  81. pthis->rgCmds[i].unSpriteSize = SPRITE_SIZE_16X16;
  82. pthis->rgCmds[i].unComposite = 0;
  83. pthis->rgCmds[i].unLayer = 2;
  84. }
  85. //wall
  86. for (i = 0; i < 4; i++) {
  87. pthis->rgCmds[i].x = pthis->frameStart.x 
  88. + 4 + Random((int16) (pthis->frameMax.x - 8 - 32));
  89. pthis->rgCmds[i].y = WALL_START_POS_Y + 56*i;
  90. pthis->rgCmds[i].unSpriteIndex = PIC_START_WALL;
  91. pthis->rgCmds[i].unSpriteSize = SPRITE_SIZE_16X16;
  92. pthis->rgCmds[i].unComposite = 0;
  93. pthis->rgCmds[i].unLayer = 0;
  94. pthis->rgCmds[i+4].x = pthis->rgCmds[i].x + 16;
  95. pthis->rgCmds[i+4].y = pthis->rgCmds[i].y;
  96. pthis->rgCmds[i+4].unSpriteIndex = PIC_START_WALL+1;
  97. pthis->rgCmds[i+4].unSpriteSize = SPRITE_SIZE_16X16;
  98. pthis->rgCmds[i+4].unComposite = 0;
  99. pthis->rgCmds[i+4].unLayer = 0;
  100. }
  101. //plane
  102. pthis->rgCmds[SPRITE_PLANE].x = pthis->frameStart.x + 50;
  103. pthis->rgCmds[SPRITE_PLANE].y = pthis->frameStart.y + 40;
  104. pthis->rgCmds[SPRITE_PLANE].unSpriteIndex = pthis->direction;
  105. pthis->rgCmds[SPRITE_PLANE].unSpriteSize = SPRITE_SIZE_16X16;
  106. pthis->rgCmds[SPRITE_PLANE].unComposite = 0;
  107. pthis->rgCmds[SPRITE_PLANE].unLayer = 1;
  108. //terminator
  109. pthis->rgCmds[SPRITE_PLANE+1].unSpriteSize = SPRITE_SIZE_END;
  110. //tile
  111. MEMSET(pthis->rgMaps, 0, sizeof(pthis->rgMaps));
  112. pthis->rgMaps[0].pMapArray = (uint16*) pthis->BackGroundLayer;
  113. pthis->rgMaps[0].x = pthis->frameStart.x;
  114. pthis->rgMaps[0].y = pthis->frameStart.y;
  115. pthis->rgMaps[0].w = MAP_SIZE_16;
  116. pthis->rgMaps[0].h = MAP_SIZE_1;
  117. pthis->rgMaps[0].unTileSize = TILE_SIZE_16X16;
  118. pthis->rgMaps[0].unFlags = MAP_FLAG_WRAP;
  119. if (GameWnd_LoadResources(pthis) != SUCCESS) {
  120. return FALSE;
  121. }
  122. ISHELL_SetTimerEx(pthis->pMe->a.m_pIShell, 0, &pthis->cbTimer);
  123. return TRUE;
  124. }
  125. void GameWnd_Close(GameWnd *pthis)
  126. {
  127. CALLBACK_Cancel(&pthis->cbTimer);
  128. GameWnd_UnloadResources(pthis);
  129. }
  130. void GameWnd_Free(GameWnd *pthis)
  131. {
  132. CALLBACK_Cancel(&pthis->cbTimer);
  133. GameWnd_UnloadResources(pthis);
  134. }
  135. static int GameWnd_LoadResources(GameWnd *pthis)
  136. {
  137. IBitmap *pbmScreen;
  138. //creates instance of ISprite
  139. ISHELL_CreateInstance(pthis->pMe->a.m_pIShell, AEECLSID_SPRITE, 
  140. (void**)&pthis->pISprite);
  141. //sets IDisplay as its destination
  142. pbmScreen = IDISPLAY_GetDestination(pthis->pMe->a.m_pIDisplay);
  143. ISPRITE_SetDestination(pthis->pISprite, pbmScreen);
  144. IBITMAP_Release(pbmScreen);
  145. //load image for tile
  146. GameWnd_LoadSprites(pthis, PFLY_RES_FILE, IDB_BACKGROUND, TILE_SIZE_16X16, TRUE);
  147. //load image for sprite
  148. GameWnd_LoadSprites(pthis, PFLY_RES_FILE, IDB_SPRITE16, SPRITE_SIZE_16X16, FALSE);
  149. GameWnd_LoadSprites(pthis, PFLY_RES_FILE, IDB_SPRITE32, SPRITE_SIZE_32X32, FALSE);
  150. return SUCCESS;
  151. }
  152. static boolean GameWnd_HandleKeyEvent(GameWnd *pthis, AEEEvent eCode, uint16 wParam)
  153. {
  154. if (eCode == EVT_KEY_PRESS)  {
  155. switch (wParam) {
  156. case AVK_RIGHT:
  157. if (pthis->keyLeft == FALSE) {
  158. pthis->keyRight = TRUE;
  159. }
  160. break;
  161. case AVK_LEFT:
  162. if (pthis->keyRight == FALSE) {
  163. pthis->keyLeft = TRUE;
  164. }
  165. break;
  166. default:
  167. return FALSE;
  168. }
  169. return TRUE;
  170. } else if (eCode == EVT_KEY_RELEASE) {
  171. switch (wParam) {
  172. case AVK_RIGHT:
  173. pthis->keyRight = FALSE;
  174. break;
  175. case AVK_LEFT:
  176. pthis->keyLeft = FALSE;
  177. break;
  178. default:
  179. return FALSE;
  180. }
  181. return TRUE;
  182. } else if(eCode == EVT_KEY) {
  183. switch(wParam) {
  184. case AVK_CLR:
  185. return Pfly_SetActiveWnd(pthis->pMe, IDW_MAINMENU);
  186. default:
  187. return FALSE;
  188. }
  189. }
  190. return FALSE;
  191. }
  192. static void GameWnd_NextFrame(GameWnd *pthis)
  193. {
  194. int i;
  195. ISHELL_SetTimerEx(pthis->pMe->a.m_pIShell, 80, &pthis->cbTimer);
  196. //飞机是否分解
  197. if (pthis->isCrash == FALSE) {
  198. pthis->isCrash = GameWnd_IsCrash(pthis);
  199. if(pthis->keyRight == TRUE ) {
  200. if (pthis->direction<10) {
  201. pthis->direction++;
  202. }
  203. } else if (pthis->keyLeft == TRUE ) {
  204. if (pthis->direction>0) {
  205. pthis->direction--;
  206. }
  207. }
  208. //update coordinate
  209. pthis->rgMaps[0].y += speedTableY[pthis->direction];
  210. if (pthis->rgMaps[0].y >= MAX_HEIGHT) {
  211. pthis->rgMaps[0].y -= MAX_HEIGHT;
  212. }
  213. //update wall
  214. for(i=0; i<4; i++) {
  215. if ((pthis->rgCmds[SPRITE_PLANE].y > 
  216. pthis->rgCmds[i].y+16-speedTableY[pthis->direction])
  217. && pthis->rgCmds[SPRITE_PLANE].y <= pthis->rgCmds[i].y+16) {
  218. pthis->layer++;
  219. }
  220. if (pthis->rgCmds[i].y < -16) {
  221. //init wall
  222. pthis->rgCmds[i].x = pthis->frameStart.x 
  223. + 4 + Random((int16) (pthis->frameMax.x - 8 - 32));
  224. pthis->rgCmds[i].y += 224;
  225. pthis->rgCmds[i].unSpriteIndex = PIC_START_WALL;
  226. pthis->rgCmds[i].unSpriteSize = SPRITE_SIZE_16X16;
  227. pthis->rgCmds[i].unComposite = 0;
  228. pthis->rgCmds[i].unLayer = 0;
  229. pthis->rgCmds[i+4].x = pthis->rgCmds[i].x + 16;
  230. pthis->rgCmds[i+4].y = pthis->rgCmds[i].y;
  231. pthis->rgCmds[i+4].unSpriteIndex = PIC_START_WALL+1;
  232. pthis->rgCmds[i+4].unSpriteSize = SPRITE_SIZE_16X16;
  233. pthis->rgCmds[i+4].unComposite = 0;
  234. pthis->rgCmds[i+4].unLayer = 0;
  235. }
  236. //move wall
  237. pthis->rgCmds[i].y -= speedTableY[pthis->direction];
  238. pthis->rgCmds[i+4].y = pthis->rgCmds[i].y;
  239. }
  240. //update plane
  241. pthis->rgCmds[SPRITE_PLANE].x += speedTableX[pthis->direction]; 
  242. pthis->rgCmds[SPRITE_PLANE].unSpriteIndex = pthis->direction;
  243. //update score digit
  244. pthis->rgCmds[SPRITE_DIGIT+0].unSpriteIndex = PIC_START_DIGIT 
  245. + (pthis->layer/1000)%10;
  246. pthis->rgCmds[SPRITE_DIGIT+1].unSpriteIndex = PIC_START_DIGIT 
  247. + (pthis->layer/100)%10;
  248. pthis->rgCmds[SPRITE_DIGIT+2].unSpriteIndex = PIC_START_DIGIT 
  249. + (pthis->layer/10)%10;
  250. pthis->rgCmds[SPRITE_DIGIT+3].unSpriteIndex = PIC_START_DIGIT 
  251. + pthis->layer%10;
  252. } else {
  253. if(pthis->crashCounter == 1) {
  254. //update image to crash plane
  255. pthis->rgCmds[SPRITE_PLANE].x -= 8;
  256. pthis->rgCmds[SPRITE_PLANE].y -= 8;
  257. pthis->rgCmds[SPRITE_PLANE].unSpriteIndex = 0;
  258. pthis->rgCmds[SPRITE_PLANE].unSpriteSize = SPRITE_SIZE_32X32;
  259. pthis->rgCmds[SPRITE_PLANE].unComposite = 0;
  260. pthis->rgCmds[SPRITE_PLANE].unLayer = 1;
  261. } else if (pthis->crashCounter == 4) {
  262. //update crash image
  263. pthis->rgCmds[SPRITE_PLANE].unSpriteIndex = 1;
  264. } else if (pthis->crashCounter == 7) {
  265. //game over
  266. Pfly_SetActiveWnd(pthis->pMe, IDW_GAMEEND);
  267. return;
  268. }
  269. pthis->crashCounter++;
  270. }
  271. //update tiles and sprites
  272. ISPRITE_DrawTiles(pthis->pISprite, pthis->rgMaps);
  273. ISPRITE_DrawSprites(pthis->pISprite, pthis->rgCmds);
  274. IDISPLAY_Update(pthis->pMe->a.m_pIDisplay);
  275. }
  276. static void GameWnd_LoadSprites(GameWnd *pthis, const char * pszFile, 
  277. uint16 resID, uint8 unSpriteSize, boolean isTile)
  278. {
  279. IBitmap       *pbmScreen = NULL;
  280. IBitmap       *pbmDib = NULL;
  281. IBitmap       *pbmDdb = NULL;
  282. NativeColor    color;
  283. AEEBitmapInfo  bi;
  284. pbmScreen = IDISPLAY_GetDestination(pthis->pMe->a.m_pIDisplay);
  285. pbmDib = ISHELL_LoadResBitmap(pthis->pMe->a.m_pIShell, pszFile, resID);
  286. IBITMAP_GetInfo(pbmDib, &bi, sizeof(bi));
  287. IBITMAP_CreateCompatibleBitmap(pbmScreen, 
  288. &pbmDdb, (uint16)bi.cx, (uint16)bi.cy);
  289. IBITMAP_BltIn(pbmDdb, 0, 0, (uint16)bi.cx, (uint16)bi.cy, 
  290. pbmDib, 0, 0, AEE_RO_COPY);
  291. IBITMAP_Release(pbmDib);
  292. IBITMAP_GetPixel(pbmDdb, 0, 0, &color);
  293. IBITMAP_SetTransparencyColor(pbmDdb, color);
  294. if (isTile == TRUE) {
  295. ISPRITE_SetTileBuffer(pthis->pISprite, unSpriteSize, pbmDdb);
  296. } else {
  297. ISPRITE_SetSpriteBuffer(pthis->pISprite, unSpriteSize, pbmDdb);
  298. }
  299. IBITMAP_Release(pbmDdb);
  300. IBITMAP_Release(pbmScreen);
  301. }
  302. static void GameWnd_UnloadResources(GameWnd *pthis)
  303. {
  304. if (pthis->pISprite) {
  305. ISPRITE_Release(pthis->pISprite);
  306. pthis->pISprite = NULL;
  307. }
  308. }
  309. static boolean GameWnd_IsCrash(GameWnd *pthis)
  310. {
  311. int i;
  312. //判断是否撞边
  313. if (pthis->rgCmds[SPRITE_PLANE].x - pthis->frameStart.x < 8 
  314. || pthis->rgCmds[SPRITE_PLANE].x - pthis->frameStart.x > pthis->frameMax.x - 24) {
  315. return TRUE;
  316. }
  317. //判断是否撞墙
  318. for(i=0; i<4; i++) {
  319. if (pthis->rgCmds[SPRITE_PLANE].x >= pthis->rgCmds[i].x-13 && pthis->rgCmds[SPRITE_PLANE].x <= pthis->rgCmds[i].x+29) {
  320. if (pthis->rgCmds[SPRITE_PLANE].y >= pthis->rgCmds[i].y-14 && pthis->rgCmds[SPRITE_PLANE].y <= pthis->rgCmds[i].y+14) {
  321. return TRUE;
  322. }
  323. }
  324. }
  325. return FALSE;
  326. }
  327. static int16 Random(int16 range)
  328. {
  329. uint16 rand;
  330. GETRAND((byte *)&rand,2);
  331. return range == 0 ? 0 : rand%range;
  332. }