snake_gui.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. #include <string.h>
  2. #include <rtthread.h>
  3. #include <rtgui/rtgui.h>
  4. #include <rtgui/rtgui_app.h>
  5. #include <rtgui/widgets/container.h>
  6. #include <rtgui/widgets/window.h>
  7. #include <rtgui/widgets/button.h>
  8. #include "snake.h"
  9. #define LATTICE_SIZE (20)
  10. #define FOOD_MAX (8)
  11. #define WALL_COLOR RTGUI_RGB(255, 0, 0)
  12. #define SNAKE_COLOR RTGUI_RGB(0, 100, 200)
  13. #define SNAKE_HEAD_COLOR RTGUI_RGB(180, 70, 130)
  14. #define BACKGROUND_COLOR RTGUI_RGB(153, 153, 0)
  15. #define FOOD_COLOR RTGUI_RGB(128, 0, 0)
  16. #define min(a, b) ((a) < (b) ? (a) : (b))
  17. static rtgui_timer_t *timer;
  18. static rt_size_t room_size_x, room_size_y;
  19. static rt_size_t lattice_size_x, lattice_size_y;
  20. static struct rtgui_rect room_rect, lattice_rect;
  21. map_t* map;
  22. SNAKE_DIR run_state;
  23. rt_int32_t snake_len;
  24. rt_int32_t food_num;
  25. point_t second_node;
  26. static void snake_fill_lattice(struct rtgui_dc *dc,
  27. rt_uint32_t x,
  28. rt_uint32_t y,
  29. rtgui_color_t color)
  30. {
  31. struct rtgui_rect rect;
  32. // coordinate conversion
  33. y = (lattice_size_y - 1) - y;
  34. RTGUI_DC_BC(dc) = color;
  35. rect.x1 = lattice_rect.x1 + (LATTICE_SIZE * x);
  36. rect.x2 = rect.x1 + LATTICE_SIZE;
  37. rect.x1 += 2;
  38. rect.y1 = lattice_rect.y1 + (LATTICE_SIZE * y);
  39. rect.y2 = rect.y1 + LATTICE_SIZE;
  40. rect.y1 += 2;
  41. rtgui_dc_fill_rect(dc, &rect);
  42. }
  43. static void snake_draw(struct rtgui_widget *widget)
  44. {
  45. struct rtgui_dc *dc;
  46. struct rtgui_rect rect;
  47. rt_uint32_t i;
  48. dc = rtgui_dc_begin_drawing(widget);
  49. if (dc == RT_NULL)
  50. {
  51. rt_kprintf("dc == RT_NULL\r\n");
  52. return;
  53. }
  54. /* get room size, run once frist. */
  55. if((room_size_x == 0) || (room_size_y == 0))
  56. {
  57. rt_size_t tmp;
  58. rtgui_widget_get_rect(widget, &rect);
  59. rt_kprintf("rect => x1:%d x2:%d, y1:%d y2:%d\r\n", rect.x1, rect.x2, rect.y1, rect.y2);
  60. room_size_x = rect.x2 - rect.x1;
  61. room_size_y = rect.y2 - rect.y1;
  62. memcpy(&room_rect, &rect, sizeof(struct rtgui_rect));
  63. rt_kprintf("room_rect => x1:%d x2:%d, y1:%d y2:%d\r\n",
  64. room_rect.x1, room_rect.x2,
  65. room_rect.y1, room_rect.y2);
  66. lattice_size_x = (room_rect.x2 - room_rect.x1) / LATTICE_SIZE;
  67. lattice_size_y = (room_rect.y2 - room_rect.y1) / LATTICE_SIZE;
  68. lattice_size_x -= 2;
  69. lattice_size_y -= 2;
  70. rt_kprintf("lattice_size_x:%d lattice_size_y:%d\r\n",
  71. lattice_size_x,
  72. lattice_size_y);
  73. tmp = (room_rect.x2 - room_rect.x1) - (LATTICE_SIZE * lattice_size_x);
  74. lattice_rect.x1 = room_rect.x1 + (tmp / 2);
  75. lattice_rect.x2 = lattice_rect.x1 + (LATTICE_SIZE * lattice_size_x);
  76. tmp = (room_rect.y2 - room_rect.y1) - (LATTICE_SIZE * lattice_size_y);
  77. lattice_rect.y1 = room_rect.y1 + (tmp / 2);
  78. lattice_rect.y2 = lattice_rect.y1 + (LATTICE_SIZE * lattice_size_y);
  79. rt_kprintf("lattice_rect => x1:%d x2:%d, y1:%d y2:%d\r\n",
  80. lattice_rect.x1, lattice_rect.x2,
  81. lattice_rect.y1, lattice_rect.y2);
  82. /* create snake. */
  83. {
  84. point_t start;
  85. map = map_init(lattice_size_x, lattice_size_y);
  86. if (map != RT_NULL)
  87. {
  88. start.x = snake_init_pointx;
  89. start.y = snake_init_pointy;
  90. run_state = SNAKE_DIR_DOWN;
  91. if (snake_init(&start, snake_length_init, run_state, map))
  92. {
  93. food_num = 1;
  94. food_init(map, food_num);
  95. }
  96. else
  97. {
  98. map_deinit(map);
  99. map = RT_NULL;
  100. }
  101. }
  102. }
  103. }
  104. RTGUI_DC_BC(dc) = BACKGROUND_COLOR;
  105. rtgui_dc_fill_rect(dc, &room_rect);
  106. memcpy(&rect, &lattice_rect, sizeof(struct rtgui_rect));
  107. rect.x2 += 1;
  108. rect.y2 += 1;
  109. RTGUI_DC_FC(dc) = WALL_COLOR;
  110. rtgui_dc_draw_rect(dc, &rect);
  111. for(i=1; i<lattice_size_y; i++)
  112. {
  113. memcpy(&rect, &lattice_rect, sizeof(struct rtgui_rect));
  114. rect.x1 += 1;
  115. rect.x2 -= 1;
  116. rtgui_dc_draw_horizontal_line(dc, rect.x1, rect.x2,
  117. rect.y1 + (LATTICE_SIZE * i));
  118. }
  119. for(i=1; i<lattice_size_x; i++)
  120. {
  121. memcpy(&rect, &lattice_rect, sizeof(struct rtgui_rect));
  122. rect.y1 += 1;
  123. rect.y2 -= 1;
  124. rtgui_dc_draw_vertical_line(dc, rect.x1 + (LATTICE_SIZE * i),
  125. rect.y1, rect.y2);
  126. }
  127. /* draw snake. */
  128. {
  129. rt_uint32_t x, y;
  130. rt_bool_t first_node = RT_TRUE;
  131. for (y=0; y<map->height; y++)
  132. {
  133. for (x=0; x<map->width; x++)
  134. {
  135. switch (map->range[y * map->width + x])
  136. {
  137. case NORMAL:
  138. break;
  139. case FOOD:
  140. snake_fill_lattice(dc, x, y, FOOD_COLOR);
  141. break;
  142. case OVER:
  143. if (first_node)
  144. {
  145. first_node = RT_FALSE;
  146. second_node.x = x;
  147. second_node.y = y;
  148. snake_fill_lattice(dc, x, y, SNAKE_HEAD_COLOR);
  149. }
  150. else
  151. {
  152. snake_fill_lattice(dc, x, y, SNAKE_COLOR);
  153. }
  154. break;
  155. }
  156. }
  157. }
  158. }
  159. rtgui_dc_end_drawing(dc);
  160. return;
  161. }
  162. static void snake_update(struct rtgui_widget *widget)
  163. {
  164. struct rtgui_dc *dc;
  165. rt_int32_t x, y;
  166. rt_uint32_t i;
  167. dc = rtgui_dc_begin_drawing(widget);
  168. if (dc == RT_NULL)
  169. {
  170. rt_kprintf("dc == RT_NULL\r\n");
  171. return;
  172. }
  173. snake_fill_lattice(dc, second_node.x, second_node.y, SNAKE_COLOR);
  174. second_node = map->snake_flush[0];
  175. for(i=0; i<3; i++)
  176. {
  177. if(i < 2)
  178. {
  179. x = map->snake_flush[i].x;
  180. y = map->snake_flush[i].y;
  181. }
  182. else
  183. {
  184. x = map->food_flush[0].x;
  185. y = map->food_flush[0].y;
  186. }
  187. if((x >= 0) && (y >= 0))
  188. {
  189. switch (map->range[(map->width * y) + x])
  190. {
  191. case NORMAL:
  192. snake_fill_lattice(dc, x, y, BACKGROUND_COLOR);
  193. break;
  194. case FOOD:
  195. snake_fill_lattice(dc, x, y, FOOD_COLOR);
  196. break;
  197. case OVER:
  198. if (0 == i)
  199. snake_fill_lattice(dc, x, y, SNAKE_HEAD_COLOR);
  200. else
  201. snake_fill_lattice(dc, x, y, SNAKE_COLOR);
  202. break;
  203. }
  204. }
  205. }
  206. rtgui_dc_end_drawing(dc);
  207. return;
  208. }
  209. static void snake_handler(struct rtgui_widget *widget, rtgui_event_t *event)
  210. {
  211. struct rtgui_event_kbd* ekbd;
  212. ekbd = (struct rtgui_event_kbd*) event;
  213. if (ekbd->type == RTGUI_KEYDOWN)
  214. {
  215. switch (ekbd->key)
  216. {
  217. case RTGUIK_UP:
  218. rt_kprintf("RTGUIK_UP\r\n");
  219. run_state = SNAKE_DIR_UP;
  220. break;
  221. case RTGUIK_DOWN:
  222. rt_kprintf("RTGUIK_DOWN\r\n");
  223. run_state = SNAKE_DIR_DOWN;
  224. break;
  225. case RTGUIK_LEFT:
  226. rt_kprintf("RTGUIK_LEFT\r\n");
  227. run_state = SNAKE_DIR_LEFT;
  228. break;
  229. case RTGUIK_RIGHT:
  230. rt_kprintf("RTGUIK_RIGHT\r\n");
  231. run_state = SNAKE_DIR_RIGHT;
  232. break;
  233. default:
  234. break;
  235. }
  236. }
  237. }
  238. static rt_bool_t event_handler(struct rtgui_object *object, rtgui_event_t *event)
  239. {
  240. struct rtgui_widget *widget = RTGUI_WIDGET(object);
  241. rt_kprintf("event_handler\r\n");
  242. if (event->type == RTGUI_EVENT_PAINT)
  243. {
  244. rt_kprintf("RTGUI_EVENT_PAINT\r\n");
  245. rtgui_win_event_handler((struct rtgui_object*)object, event);
  246. snake_draw(widget);
  247. rtgui_timer_start(timer);
  248. }
  249. else if (event->type == RTGUI_EVENT_SHOW)
  250. {
  251. rt_kprintf("RTGUI_EVENT_SHOW\r\n");
  252. rtgui_win_event_handler((struct rtgui_object*)object, event);
  253. snake_draw(widget);
  254. rtgui_timer_start(timer);
  255. }
  256. else if (event->type == RTGUI_EVENT_HIDE)
  257. {
  258. rt_kprintf("RTGUI_EVENT_HIDE\r\n");
  259. rtgui_win_event_handler((struct rtgui_object*)object, event);
  260. rtgui_timer_stop(timer);
  261. }
  262. else if (event->type == RTGUI_EVENT_WIN_DEACTIVATE)
  263. {
  264. rt_kprintf("RTGUI_EVENT_WIN_DEACTIVATE\r\n");
  265. rtgui_win_event_handler((struct rtgui_object*)object, event);
  266. rtgui_timer_stop(timer);
  267. }
  268. else if (event->type == RTGUI_EVENT_KBD)
  269. {
  270. rtgui_win_event_handler((struct rtgui_object*)object, event);
  271. snake_handler(widget, event);
  272. }
  273. else
  274. {
  275. rt_kprintf("event->type:%d\r\n", event->type);
  276. return rtgui_win_event_handler((struct rtgui_object*)object, event);
  277. }
  278. return RT_FALSE;
  279. }
  280. static void timeout(struct rtgui_timer *timer, void *parameter)
  281. {
  282. struct rtgui_widget *widget;
  283. SYS_STE ret;
  284. if (!map)
  285. return;
  286. ret = snake_step(run_state, map);
  287. if (OVER == ret)
  288. return;
  289. if (FOOD == ret)
  290. {
  291. snake_len++;
  292. if (snake_len >= (map->width * map->height) / 3)
  293. {
  294. point_t start;
  295. start.x = snake_init_pointx;
  296. start.y = snake_init_pointy;
  297. run_state = SNAKE_DIR_DOWN;
  298. snake_len = snake_length_init;
  299. if (!snake_restart(&start, snake_len, run_state, map))
  300. {
  301. map_deinit(map);
  302. snake_deinit();
  303. map = RT_NULL;
  304. }
  305. }
  306. food_init(map, 1);
  307. }
  308. widget = RTGUI_WIDGET(parameter);
  309. snake_update(widget);
  310. }
  311. void snake_main(void)
  312. {
  313. struct rtgui_app* application;
  314. struct rtgui_win* win;
  315. application = rtgui_app_create(rt_thread_self(), "sanke_app");
  316. if (application != RT_NULL)
  317. {
  318. win = rtgui_mainwin_create(RT_NULL,
  319. "sanke_win",
  320. RTGUI_WIN_STYLE_MAINWIN | RTGUI_WIN_STYLE_DESTROY_ON_CLOSE);
  321. if(win == RT_NULL)
  322. {
  323. rt_kprintf("sanke_win create fail!\r\n");
  324. return;
  325. }
  326. rtgui_object_set_event_handler(RTGUI_OBJECT(win), event_handler);
  327. timer = rtgui_timer_create(RT_TICK_PER_SECOND / 2,
  328. RT_TIMER_FLAG_PERIODIC,
  329. timeout,
  330. (void *)win);
  331. rtgui_win_show(win, RT_TRUE);
  332. //Í˳öºó²Å·µ»Ø
  333. map_deinit(map);
  334. snake_deinit();
  335. food_deinit();
  336. rtgui_app_destroy(application);
  337. }
  338. }
  339. #include <finsh.h>
  340. FINSH_FUNCTION_EXPORT(snake_main, snake run)