自学内容网 自学内容网

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)!