Uefi Application小游戏开发之贪吃蛇
这段代码是一个 UEFI 应用程序,它实现了一个简单的贪吃蛇游戏。
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/ShellCEntryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <stdio.h>
#include <Library/TimerLib.h>
#include <Library/DebugLib.h>
#define A 1664525
#define C 1013904223
#define M 4294967296UL
static unsigned seed = 1;
BOOLEAN GameoverFlag=FALSE;
#define N 48
#define L 24
char Map[N][L];
typedef struct Position {
int x, y;
} Position;
Position snake[4000000], food, next;
int head,tail,lenght,speed,grade;
char dirction,dirbef;
int score=0;
int order,wall,order_type;
int rank[5]={0};
char first[20]={"1."};
char second[20]={"2."};
char thirst[20]={"3."};
char forth[20]={"4."};
char fifth[20]={"5."};
void SetFood(){
food.x=my_rand()%20 ;
food.y=my_rand()%42 ;
food.x= my_abs(food.x)+2;
food.y=my_abs(food.y)+2;
Map[food.x][food.y]='*';
DEBUG((DEBUG_INFO, "food.x:%d ,food.y: %d\n", food.x , food.y));
xy(food.x,food.y);
Print(L"*");
}
// void xy(int y,int x)
// {
// gST->ConOut->SetCursorPosition ( gST->ConOut, x, y);
// }
ShowSnake()
{
int index=0;
xy( snake[head].x, snake[head].y);
Print(L"@");
for(index=0;index < 2; index++)
{
xy( snake[index].x, snake[index].y);
Print(L"+");
}
}
void Hello(){
Print(L"\n\n\n\t\t\t\t\t\t 1.New Game\n");
Print(L"\n\t\t\t\t\t\t 2.Continue\n");
Print(L"\n\t\t\t\t\t\t 3.Exit\n");
}
void SetMap(){
// for(int i=0;i<N;i++){
// for(int j=0;j<N;j++){
// Map[i][j]=' ';
// }
// }
// for(int k=0;k<N;k++){ //set map
// Map[0][k]=Map[N-1][k]=Map[k][0]=Map[k][N-1]='+';
// }
// SetFood();
Hello();
head=2;
tail=0;
dirction='d'; //default left
dirbef='d';
snake[0].x=5; //snake
snake[0].y=4;
snake[2].x=5;
snake[2].y=6;
snake[1].x=5;
snake[1].y=5;
// Map[1][3]='O';
// Map[1][2]='O';
// Map[1][1]='O';
lenght=3;
speed=500;
score=0;
grade=0;
order=1;
if(order==1){
//cls();
Print(L"\n\n\n\t\t\t\t\t\t 1.Normal Mode\n");
Print(L"\n\t\t\t\t\t\t 2.No Wall Mode\n");
order_type=2;
if(order_type==1) wall=1;
else wall=0;
}
if(order==3) return ;
for(int time=3;time>0;time--) {
cls();
Print(L"\n\t\t\t\tready to game %d\n", time);
Sleep (1000);
cls();
}
food.x =5;
food.y =18;
xy(food.x,food.y);
Print(L"*");
}
void ShowKK(){
int i,j;
//CpuBreakpoint();
for (int i = 1; i < L; i++) {
for (int j = 1; j < N; j++) {
if (i == 1 || i == L-1 || j == 1|| j == N-1) {
Map[i][j]='+';
xy(i,j);
Print(L"+");
}
}
}
}
void ShowMap(){
int i,j;
for (i = 1; i < N-1; i++) {
for (j = 1; j < N-1; j++) {
Print(L"%c ", Map[i][j]);
}
// if (i == 2) {
// Print(L"\t\tScore=%d", score);
// }
// if (i == 4) {
// Print(L"\t\tLenght=%d", lenght);
// }
// if (i == 6) {
// Print(L"\t\tSpeed=%d", 600 - speed);
// }
Print(L"\n");
}
}
int Gameover(){
if(dirction=='p'){
cls();
Print(L"\n\n\t\t\t\tGame Over\n\n\n");
return 0;
}
if(wall){
if(Map[next.y][next.x] == 'O' ||Map[next.y][next.x]=='+') {
Map[next.y][next.x] = '@' ;
Map[snake[head].y][snake[head].x]='O';
Map[snake[tail].y][snake[tail].x]=' ';
ShowMap();
return 0;
}
}
else{
if(Map[next.y][next.x] == 'O') {
Map[next.y][next.x] = '@' ;
Map[snake[head].y][snake[head].x]='O';
Map[snake[tail].y][snake[tail].x]=' ';
return 0;
}
}
return 1;
}
int SnakeMove(){//move
if(score%100==0&&score!=0) speed=500-score; //speed
BOOLEAN timeover = TRUE;
EFI_EVENT WaitList[2];
EFI_EVENT TimeOutEvent;
UINTN EventIndex;
EFI_STATUS Status;
EFI_INPUT_KEY Key;
gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimeOutEvent);
gBS->SetTimer (TimeOutEvent, TimerRelative, 10 * 1000 * 1000);
WaitList[0] = TimeOutEvent;
WaitList[1] = gST->ConIn->WaitForKey;
while (1) {
gBS->WaitForEvent (2, WaitList, &EventIndex);
if (EventIndex == 1) {
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
if (Status == EFI_SUCCESS) {
//Print(L"GetKey %d",Key.UnicodeChar);
DEBUG((DEBUG_INFO, "Key.UnicodeChar:%d\n",Key.UnicodeChar ));
if( Key.UnicodeChar== 'w' ||Key.UnicodeChar== 'a'|| Key.UnicodeChar== 's' || Key.UnicodeChar== 'd')
{
dirction=Key.UnicodeChar;
break;
}
dirction=Key.UnicodeChar;
break;
}
}else
{ Status = EFI_TIMEOUT;
// Print(L"Status %r",Status);
break;
}
}
//getchar
dirbef=dirction;
DEBUG((DEBUG_INFO, "dirction:%d ,dirbef: \n",dirction ,dirbef));
if(dirction!='w'&&dirction!='a'&&dirction!='s'&&dirction!='d'||((dirction=='w'&&dirbef=='s')||(dirction=='a'&&dirbef=='d')||(dirction=='s'&&dirbef=='w')||(dirction=='d'&&dirbef=='a')))
dirction=dirbef;
switch(dirction){
case 'a':
next.y = snake[head].y-1;
next.x = snake[head].x;
break;
case 'd':
next.y = snake[head].y+1;
next.x = snake[head].x;
break;
case 'w':
next.y = snake[head].y;
next.x = snake[head].x-1;
break;
case 's':
next.y = snake[head].y;
next.x = snake[head].x+1;
break;
case 'p':
break;
//Gameover();
}
if((next.y==1)||(next.y==N-1)|| (next.x==1)||(next.x==L-1))
{
cls();
Print(L"\n\n\t\t\t\tGame Over\n\n\n");
GameoverFlag=TRUE;
MicroSecondDelay(3*1000*1000);
return Status;
}
// if(next.y==0) next.y=N-2;
// if(next.y==N-1) next.y=1;
// if(next.x==0) next.x=M-2;
// if(next.x==M-1) next.x=1;
}
void Eat(){//is eat food
if(next.x==food.x&&next.y==food.y){//eat
score+=10;
xy(next.x,next.y );
Print(L"@");
xy(snake[head].x,snake[head].y);
Print(L"+");
head++;
snake[head].x=next.x;
snake[head].y=next.y;
Map[snake[head].x][snake[head].y]='@';
lenght++;
SetFood();
}
else{//no eat
xy(next.x,next.y );
Print(L"@");
xy(snake[head].x,snake[head].y);
Print(L"+");
head++;
snake[head].x=next.x;
snake[head].y=next.y;
xy(snake[head-lenght].x,snake[head-lenght].y);
Print(L" ");
}
xy(5,60);
Print(L"Score:%d",score);
}
EFI_STATUS
EFIAPI
TanchisheInit(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
my_srand(11);
gST->ConOut->EnableCursor (gST->ConOut, FALSE);
while(1){
SetMap();
if(order==3){
}
else{
ShowKK();
ShowSnake();
while(1){
SnakeMove();
if(GameoverFlag)
{
return EFI_SUCCESS;
}
if(!Gameover()) {
if(dirction!='p')
break;
}
Eat();
}
}
Print(L"\n....................press any key continue\n");
order=0;
dirction=dirbef;
}
}
游戏界面:
简单介绍下模块
while (1) {
gBS->WaitForEvent (2, WaitList, &EventIndex);
if (EventIndex == 1) {
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
if (Status == EFI_SUCCESS) {
//Print(L"GetKey %d",Key.UnicodeChar);
DEBUG((DEBUG_INFO, "Key.UnicodeChar:%d\n",Key.UnicodeChar ));
if( Key.UnicodeChar== 'w' ||Key.UnicodeChar== 'a'|| Key.UnicodeChar== 's' || Key.UnicodeChar== 'd')
{
dirction=Key.UnicodeChar;
break;
}
dirction=Key.UnicodeChar;
break;
}
}else
{ Status = EFI_TIMEOUT;
// Print(L"Status %r",Status);
break;
}
}
gBS->WaitForEvent (2, WaitList, &EventIndex);
这行代码是在等待两个事件中的任何一个发生。这两个事件分别是定时器事件和键盘输入事件。
如果 EventIndex == 1
,那么发生的事件是键盘输入事件。在这种情况下,程序会调用 gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
来读取用户输入的键值。
如果读取成功,即 Status == EFI_SUCCESS
,那么程序会检查用户输入的键值。如果键值是 'w'、'a'、's' 或 'd',那么程序会将这些值赋给 dirction
变量,并退出循环。
如果等待的事件不是键盘输入事件,那么程序会设置 Status = EFI_TIMEOUT;
并退出循环。
总的来说,这段代码的作用是等待用户输入方向键,并根据用户的输入来改变蛇的移动方向
原文地址:https://blog.csdn.net/qq_43561214/article/details/143603333
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!