嵌入式系統 Team2
Transcript of 嵌入式系統 Team2
嵌入式專題-貪食蛇 組別:第 2組 組員:楊職銓(0010745)、王盛弘(0010841)、鄭孟原(0010834)
遊戲特色:
蛇在畫面中行進,碰到邊界會死亡(不可穿透),吃到藍色點點,蛇的身體會加長。另外,有選單提供單人模式,以及雙人模式。以及死亡後的通知。
主要程式說明:/***************************************************************************
Include files
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "app_platform_routing.h"
#include "platform\platform_board.h"
#include "joystick\module_joystick.h"
#include "buzzer\module_buzzer.h"
#include "lcd\module_gui.h"
#include "uart\module_uart.h"
/***************************************************************************
Constant define
***************************************************************************/
#define TIMECONST 500;
/***************************************************************************
Function Prototype (External)
***************************************************************************/
/***************************************************************************
Function Prototype (Local)
***************************************************************************/
/***************************************************************************
Variable Define (External)
***************************************************************************/
/***************************************************************************
Variable Define (Global)
***************************************************************************/
int gameMode=0,mode=0;
int head[2],tail[2],point[20][3],pointcount=0;
int direction=2,length=5,t_direction=2,target[2];
int head_2[2],tail_2[2],point_2[20][3],pointcount_2=0;
int direction_2=2,length_2=5,t_direction_2=2;
int crossBoard_1=0,crossBoard_2=0,gameOver=0;
/***************************************************************************
Variable Define (Local)
***************************************************************************/
/***************************************************************************
* Purpose ....: Read value of the joystick then show to LCD.
* Input ....:
* @param ....: None.
* Output ....:
* @param ....: None
* @Return ....: None.
* Note ....: None
***************************************************************************/
static void app_display (void)
{
uint16_t gADCValue[4];
int i;
for (i=0; i < 4; i++) //取得 joystick1,joystick2座標(鄭孟原){
module_joystick_get_value(APP_ADC_JOYSTK1_X+i, &gADCValue[i]);
gADCValue[i]=gADCValue[i]>>8; //right shift 8位 }
//snake_1's joystick
//判定 joystick1的方向(楊職銓、王盛弘、鄭孟原共同討論) if(gADCValue[0]==0&&(direction==0||direction==1)) //Joy1 LEFT
{
direction=2; //2=向左 point[pointcount][0]=head[0]; //pointcount為 snake_1的幾個轉折點 point[pointcount][1]=head[1]; // point[][0]放"x座標"
point[pointcount][2]=direction; // point[][1]放"y座標"
pointcount++; // point[][2]放"方向" }
else if(gADCValue[0]==15&&(direction==0||direction==1)) //Joy1 RIGHT
{
direction=3; //3=向右 point[pointcount][0]=head[0];
point[pointcount][1]=head[1];
point[pointcount][2]=direction;
pointcount++;
}
else if(gADCValue[1]==0&&(direction==2||direction==3)) //Joy1 DOWN
{
direction=1; //1=向下 point[pointcount][0]=head[0];
point[pointcount][1]=head[1];
point[pointcount][2]=direction;
pointcount++;
}
else if(gADCValue[1]==15&&(direction==2||direction==3)) //Joy1 UP
{
direction=0; //0=向上 point[pointcount][0]=head[0];
point[pointcount][1]=head[1];
point[pointcount][2]=direction;
pointcount++;
}
if(gameMode==2)
{
//snake_2's joystick
//判定 joystick2的方向(楊職銓、王盛弘、鄭孟原共同討論)
if(gADCValue[2]==0&&(direction_2==0||direction_2==1)) //Joy2 LEFT
{
direction_2=2;
//pointcount_2=snake_2的幾個轉折點point_2[pointcount_2][0]=head_2[0]; //point_2[][0]放"x座標"
point_2[pointcount_2][1]=head_2[1]; // point_2[][1]放"y座標"
point_2[pointcount_2][2]=direction_2; // point_2[][2]放"方向"pointcount_2++;
}
else if(gADCValue[2]==15&&(direction_2==0||direction_2==1))//Joy2
RIGHT
{
direction_2=3;
point_2[pointcount_2][0]=head_2[0];
point_2[pointcount_2][1]=head_2[1];
point_2[pointcount_2][2]=direction_2;
pointcount_2++;
}
else if(gADCValue[3]==0&&(direction_2==2||direction_2==3)) //Joy2
DOWN
{
direction_2=1;
point_2[pointcount_2][0]=head_2[0];
point_2[pointcount_2][1]=head_2[1];
point_2[pointcount_2][2]=direction_2;
pointcount_2++;
}
else if(gADCValue[3]==15&&(direction_2==2||direction_2==3)) //Joy2
UP
{
direction_2=0;
point_2[pointcount_2][0]=head_2[0];
point_2[pointcount_2][1]=head_2[1];
point_2[pointcount_2][2]=direction_2;
pointcount_2++;
}
}
//snake_1 tail block 畫出 snake_1尾巴(tail)的方塊 module_gui_draw_rect_fill_color (tail[0],tail[1],10,10,GUI_BLACK);
//snake_2 tail block 畫出 snake_2尾巴(tail_2)的方塊
if(gameMode==2)
{ module_gui_draw_rect_fill_color(tail_2[0],tail_2[1],10,10,GUI_BLACK);}
//snake_1頭(head)的座標移動,head[0]表示 x座標,head[1]表示 y座標//(楊職銓、王盛弘共同討論)
switch(direction)
{
case 0:
head[1]-=10;
break;
case 1:
head[1]+=10;
break;
case 2:
head[0]-=10;
break;
case 3:
head[0]+=10;
break;
}
//crossBoard_1=0表示 snake_1未超界,crossBoard_1=1表示 snake_1超界//(楊職銓)
if(head[0]<0) crossBoard_1=1;
if(head[0]>310) crossBoard_1=1;
if(head[1]<0) crossBoard_1=1;
if(head[1]>230) crossBoard_1=1;
//snake_2頭(head_2)的座標移動,head_2[0]表示 x座標,head_2[1]表示 y座標//(楊職銓、王盛弘共同討論)
if(gameMode==2)
{
switch(direction_2)
{
case 0:
head_2[1]-=10;
break;
case 1:
head_2[1]+=10;
break;
case 2:
head_2[0]-=10;
break;
case 3:
head_2[0]+=10;
break;
}
//crossBoard_2=0表示 snake_2未超界,crossBoard_2=1表示 snake_2超界
//(楊職銓)if(head_2[0]<0) crossBoard_2=1;
if(head_2[0]>310) crossBoard_2=1;
if(head_2[1]<0) crossBoard_2=1;
if(head_2[1]>230) crossBoard_2=1;
}
//snake_1 suicide 自殺,自己撞到自己//若 snake_1有 n個轉折點//(楊職銓、王盛弘、鄭孟原共同討論)
for(int j=0;j<pointcount;j++)
{
if(j==0)
{
if(point[j][2]==0 || point[j][2]==1)
{
if((head[0]<=tail[0] && head[0]>=point[j][0]) ||
(head[0]>=tail[0] && head[0]<=point[j][0]))
{
if(head[1]==point[j][1])
gameOver=1;
}
if(gameMode==2)
{
if((head_2[0]<=tail[0] && head_2[0]>=point[j][0]) ||
(head_2[0]>=tail[0] && head_2[0]<=point[j][0]))
{
if(head_2[1]==point[j][1])
gameOver=2;
}
}
}
if(point[j][2]==2 || point[j][2]==3)
{
if((head[1]<=tail[1] && head[1]>=point[j][1]) ||
(head[1]>=tail[1] && head[1]<=point[j][1]))
{
if(head[0]==point[j][0])
gameOver=1;
}
if(gameMode==2)
{
if((head_2[1]<=tail[1] && head_2[1]>=point[j][1]) ||
(head_2[1]>=tail[1] && head_2[1]<=point[j][1]))
{
if(head_2[0]==point[j][0])
gameOver=2;
}
}
}
}else
{
if(point[j][2]==0 || point[j][2]==1)
{
if((head[0]<=point[j-1][0] && head[0]>=point[j][0]) ||
(head[0]>=point[j-1][0] && head[0]<=point[j][0]))
{
if(head[1]==point[j][1])
gameOver=1;
}
if(gameMode==2)
{
if((head_2[0]<=point[j-1][0] && head_2[0]>=point[j][0]) ||
(head_2[0]>=point[j-1][0] && head_2[0]<=point[j][0]))
{
if(head_2[1]==point[j][1])
gameOver=2;
}
}
}
if(point[j][2]==2 || point[j][2]==3)
{
if((head[1]<=point[j-1][1] && head[1]>=point[j][1]) ||
(head[1]>=point[j-1][1] && head[1]<=point[j][1]))
{
if(head[0]==point[j][0])
gameOver=1;
}
if(gameMode==2)
{
if((head_2[1]<=point[j-1][1] && head_2[1]>=point[j][1]) ||
(head_2[1]>=point[j-1][1] && head_2[1]<=point[j][1]))
{
if(head_2[0]==point[j][0])
gameOver=2;
}
}
}
}
}
//若 snake_1沒有轉折點,自己撞到自己//(楊職銓、王盛弘、鄭孟原共同討論)
if(pointcount==0)
{
if(direction==0 || direction==1)
{
if((head_2[1]<=tail[1] && head_2[1]>=head[1]) ||
(head_2[1]>=tail[1] && head_2[1]<=head[1]))
{
if(head_2[0]==head[0])
gameOver=2;
}
}
if(direction==2 || direction==3)
{
if((head_2[0]<=tail[0] && head_2[0]>=head[0]) ||
(head_2[0]>=tail[0] && head_2[0]<=head[0]))
{
if(head_2[1]==head[1])
gameOver=2;
}
}
if(head[0]==tail[0] && head[1]==tail[1])
gameOver=1;
}
//snake_2 suicide 自殺,自己撞到自己//若 snake_2有 n個轉折點//(楊職銓、王盛弘、鄭孟原共同討論)
if(gameMode==2)
{
for(int j=0;j<pointcount_2;j++)
{
if(j==0)
{
if(point_2[j][2]==0 || point_2[j][2]==1)
{
if((head_2[0]<=tail_2[0] && head_2[0]>=point_2[j][0]) ||
(head_2[0]>=tail_2[0] && head_2[0]<=point_2[j][0]))
{
if(head_2[1]==point_2[j][1])
gameOver=2;
}
if((head[0]<=tail_2[0] && head[0]>=point_2[j][0]) ||
(head[0]>=tail_2[0] && head[0]<=point_2[j][0]))
{
if(head[1]==point_2[j][1])
gameOver=1;
}
}
if(point_2[j][2]==2 || point_2[j][2]==3)
{
if((head_2[1]<=tail_2[1] && head_2[1]>=point_2[j][1]) ||
(head_2[1]>=tail_2[1] && head_2[1]<=point_2[j][1]))
{
if(head_2[0]==point_2[j][0])
gameOver=2;
}
if((head[1]<=tail_2[1] && head[1]>=point_2[j][1]) ||
(head[1]>=tail_2[1] && head[1]<=point_2[j][1]))
{
if(head[0]==point_2[j][0])
gameOver=1;
}
}
}else
{
if(point_2[j][2]==0 || point_2[j][2]==1)
{
if((head_2[0]<=point_2[j-1][0] && head_2[0]>=point_2[j]
[0]) || (head_2[0]>=point_2[j-1][0] && head_2[0]<=point_2[j][0]))
{
if(head_2[1]==point_2[j][1])
gameOver=2;
}
if((head[0]<=point_2[j-1][0] && head[0]>=point_2[j][0]) ||
(head[0]>=point_2[j-1][0] && head[0]<=point_2[j][0]))
{
if(head[1]==point_2[j][1])
gameOver=1;
}
}
if(point_2[j][2]==2 || point_2[j][2]==3)
{
if((head_2[1]<=point_2[j-1][1] && head_2[1]>=point_2[j]
[1]) || (head_2[1]>=point_2[j-1][1] && head_2[1]<=point_2[j][1]))
{
if(head_2[0]==point_2[j][0])
gameOver=2;
}
if((head[1]<=point_2[j-1][1] && head[1]>=point_2[j][1]) ||
(head[1]>=point_2[j-1][1] && head[1]<=point_2[j][1]))
{
if(head[0]==point_2[j][0])
gameOver=1;
}
}
}
}
//若 snake_2沒有轉折點,自己撞到自己//(楊職銓、王盛弘、鄭孟原共同討論)
if(pointcount_2==0)
{
if(direction_2==0 || direction_2==1)
{
if((head[1]<=tail_2[1] && head[1]>=head_2[1]) ||
(head[1]>=tail_2[1] && head[1]<=head_2[1]))
{
if(head[0]==head_2[0])
gameOver=1;
}
}
if(direction_2==2 || direction_2==3)
{
if((head[0]<=tail_2[0] && head[0]>=head_2[0]) ||
(head[0]>=tail_2[0] && head[0]<=head_2[0]))
{
if(head[1]==head_2[1])
gameOver=1;
}
}
if(head_2[0]==tail_2[0] && head_2[1]==tail_2[1])
gameOver=2;
}
}
//snake_1===========================================
==============
//判斷尾巴到轉折點,若到了要換方向//(楊職銓、王盛弘、鄭孟原共同討論)
if(pointcount>0)
{
if(t_direction==0||t_direction==1)
{
if(tail[1]==point[0][1])
{
t_direction=point[0][2];
for(int n=0;n<pointcount;n++)
{
point[n][0]=point[n+1][0];
point[n][1]=point[n+1][1];
point[n][2]=point[n+1][2];
}
pointcount--;
}
}
if(t_direction==2||t_direction==3)
{
if(tail[0]==point[0][0])
{
t_direction=point[0][2];
for(int n=0;n<pointcount;n++)
{
point[n][0]=point[n+1][0];
point[n][1]=point[n+1][1];
point[n][2]=point[n+1][2];
}
pointcount--;
}
}
}
switch(t_direction)
{
case 0:
tail[1]-=10;
break;
case 1:
tail[1]+=10;
break;
case 2:
tail[0]-=10;
break;
case 3:
tail[0]+=10;
break;
}
if(tail[0]<0) tail[0]=310;
if(tail[0]>310) tail[0]=0;
if(tail[1]<0) tail[1]=230;
if(tail[1]>230) tail[1]=0;
if(head[0]==target[0]&&head[1]==target[1])
{
length++;
target[0]=(rand()%32)*10;
target[1]=(rand()%24)*10;
module_gui_draw_rect_fill_color(target[0],target[1],10,10,GUI_BLUE);
switch(t_direction)
{
case 0:
tail[1]+=10;
break;
case 1:
tail[1]-=10;
break;
case 2:
tail[0]+=10;
break;
case 3:
tail[0]-=10;
break;
}
if(tail[0]<0) tail[0]=310;
if(tail[0]>310) tail[0]=0;
if(tail[1]<0) tail[1]=230;
if(tail[1]>230) tail[1]=0;
module_gui_draw_rect_fill_color(tail[0],tail[1],10,10,GUI_WHITE);
}
//snake_1===========================================
==============
//snake_2===========================================
==============
//判斷尾巴到轉折點,若到了要換方向//(楊職銓、王盛弘共同討論)
if(gameMode==2)
{
if(pointcount_2>0)
{
if(t_direction_2==0||t_direction_2==1)
{
if(tail_2[1]==point_2[0][1])
{
t_direction_2=point_2[0][2];
for(int n=0;n<pointcount_2;n++)
{
point_2[n][0]=point_2[n+1][0];
point_2[n][1]=point_2[n+1][1];
point_2[n][2]=point_2[n+1][2];
}
pointcount_2--;
}
}
if(t_direction_2==2||t_direction_2==3)
{
if(tail_2[0]==point_2[0][0])
{
t_direction_2=point_2[0][2];
for(int n=0;n<pointcount_2;n++)
{
point_2[n][0]=point_2[n+1][0];
point_2[n][1]=point_2[n+1][1];
point_2[n][2]=point_2[n+1][2];
}
pointcount_2--;
}
}
}
switch(t_direction_2)
{
case 0:
tail_2[1]-=10;
break;
case 1:
tail_2[1]+=10;
break;
case 2:
tail_2[0]-=10;
break;
case 3:
tail_2[0]+=10;
break;
}
if(tail_2[0]<0) tail_2[0]=310;
if(tail_2[0]>310) tail_2[0]=0;
if(tail_2[1]<0) tail_2[1]=230;
if(tail_2[1]>230) tail_2[1]=0;
if(head_2[0]==target[0]&&head_2[1]==target[1])
{
length_2++;
target[0]=(rand()%32)*10;
target[1]=(rand()%24)*10;
module_gui_draw_rect_fill_color (target[0], target[1], 10, 10,
GUI_BLUE);
switch(t_direction_2)
{
case 0:
tail_2[1]+=10;
break;
case 1:
tail_2[1]-=10;
break;
case 2:
tail_2[0]+=10;
break;
case 3:
tail_2[0]-=10;
break;
}
if(tail_2[0]<0) tail_2[0]=310;
if(tail_2[0]>310) tail_2[0]=0;
if(tail_2[1]<0) tail_2[1]=230;
if(tail_2[1]>230) tail_2[1]=0;
module_gui_draw_rect_fill_color (tail_2[0], tail_2[1], 10, 10,
GUI_GREEN);
}
}
//snake_2===========================================
==============
//cross board
if(crossBoard_1==1 && crossBoard_2==1) gameOver=3;
else if(crossBoard_1==1) gameOver=1;
else if(crossBoard_2==1) gameOver=2;
//snake_1的畫圖,文字,顏色 module_gui_draw_rect_fill_color(target[0],target[1],10,10,GUI_BLUE);
module_gui_set_text_color(GUI_WHITE);
module_gui_text_printf_line (1,"P1 Length %d",length);
module_gui_draw_rect_fill_color (head[0], head[1], 10, 10, GUI_WHITE);
//snake_2的畫圖,文字,顏色 if(gameMode==2)
{
module_gui_set_text_color (GUI_GREEN);
module_gui_text_printf_line (2,"P2 Length %d",length_2);
module_gui_draw_rect_fill_color (head_2[0], head_2[1], 10, 10,
GUI_GREEN);
}
}
//game lobby 遊戲進入畫面選單//(楊職銓、王盛弘、鄭孟原共同討論)static void game_lobby (void)
{
uint16_t gADCValue[4];
int i;
//取 joystick座標值 for (i=0; i < 4; i++)
{
module_joystick_get_value(APP_ADC_JOYSTK1_X+i, &gADCValue[i]);
gADCValue[i]=gADCValue[i]>>8;
}
//joystick1 選單,上下選擇與向右進入//(王盛弘)if(gADCValue[1]==0) //Joy1 DOWN
{
mode++;
if(mode>1) mode=0; //mode=0表示第一個 }
else if(gADCValue[1]==15) //Joy1 UP
{
mode--;
if(mode<0) mode=1; //mode=2表示第二個 }
else if(gADCValue[0]==15) //Joy1 RIGHT
{
gameMode=mode+1;
}
switch(mode)
{
case 0:
module_gui_text_printf_line (15," *Single");
module_gui_text_printf_line (18," Double");
break;
case 1:
module_gui_text_printf_line (15," Single");
module_gui_text_printf_line (18," *Double");
break;
}
}
/***************************************************************************
* Purpose ....: read value of the Joystick.
* Input ....:
* @param ....: None
* Output ....:
* @param ....: None
* @Return ....: None
* Note ....: None
***************************************************************************/
void main (void)
{
platform_board_init(SystemCoreClock);
module_gui_init();
module_gui_set_color(GUI_WHITE, GUI_BLACK);
module_joystick_init();
module_joystick_start();
//選單預設畫面//(楊職銓)
module_gui_clear (GUI_RED);
module_font_scale_set(4);
module_gui_set_text_color (GUI_WHITE);
module_gui_text_printf_line (0,"Greedy");
module_gui_text_printf_line (4," Snakes");
module_font_scale_set(3);
module_gui_text_printf_line (15," *Single");
module_gui_text_printf_line (18," Double");
//game lobby 遊戲選單 while(1)
{
if(!gameMode)
{
game_lobby();
VK_DELAY_MS(200);
}else
{
break;
}
}
//clear background
module_gui_clear (GUI_BLACK);
module_font_scale_set(1);
//亂數產生食物方塊(藍色)
//(楊職銓) srand(time(NULL));
target[0]=(rand()%32)*10;
target[1]=(rand()%24)*10;
module_gui_draw_rect_fill_color (target[0], target[1], 10, 10, GUI_BLUE);
module_gui_set_text_color (GUI_WHITE);
module_gui_text_printf_line (1,"P1 Length %d",length);
module_gui_set_text_color (GUI_GREEN);
//snake 1 initial position
head[0]=160;head[1]=120;
tail[0]=160+(length-1)*10;tail[1]=120;
module_gui_draw_rect_fill_color (head[0], head[1], 10, 10*length,
GUI_WHITE);
//snake 2 initial position
if(gameMode==2)
{
head_2[0]=160;head_2[1]=160;
tail_2[0]=160+(length_2-1)*10;tail_2[1]=160;
module_gui_draw_rect_fill_color (head_2[0], head_2[1], 10,
10*length_2, GUI_GREEN);
module_gui_text_printf_line (2,"P2 Length %d",length_2);
}
//結束遊戲判斷 while (1)
{
if(!gameOver)
{
app_display();
VK_DELAY_MS(200-length*5-length_2*5);
}else
{
module_gui_set_text_color (GUI_WHITE);
if(gameOver==1)
{
module_font_scale_set(3);
module_gui_set_text_color (GUI_WHITE);
module_gui_text_printf_line (10,"Player 1 lose");
}
if(gameOver==2)
{
module_font_scale_set(3);
module_gui_set_text_color (GUI_GREEN);
module_gui_text_printf_line (10,"Player 2 lose");
}
if(gameOver==3)
{
module_font_scale_set(3);
module_gui_set_text_color (GUI_BLUE);
module_gui_text_printf_line (10," Ties");
}
}
}
}
工作分配:
已在上面程式碼中用顏色標示。 影片連結
http://www.youtube.com/watch?v=e-NROQvU2c4&feature=youtu.be
http://www.youtube.com/watch?v=wO5ge1-vmNQ&feature=youtu.be
參考資料上課講義、網路。