在ARM开发板上实现2048小游戏

 event.h

屏幕点击事件.h文件:获取屏幕的xy坐标,获取手指滑动的方向,获取点击事件。

#ifndef __EVENT_H_
#define __EVENT_H_


#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <linux/input.h>

#define BIN_TOUCH 0x14a

#define up 1
#define down 2
#define left 3
#define right 4



void get_event_xy(int *x,int *y);
int get_event_dirention();
void photo();
int get_event_button();

#endif

event.c 

屏幕点击事件.c文件:实现屏幕的xy坐标,获取手指滑动的方向,获取点击事件函数。

#include "event.h"
#include "lcd.h"
void get_event_xy(int *x,int *y)//获取像素的坐标
{
    int fd_ev = open("/dev/input/event0",O_RDONLY);//打开屏幕()
    if(fd_ev ==-1)
    {
        perror("open error");
        exit(1);
    }
    printf("open duccess\n");

    struct input_event ev;
    while(1)
    {
        int ret =read(fd_ev,&ev,sizeof(ev));
        if(ret ==-1)
        {
            perror("read ev error");
            exit(1);
        }

        if(ev.type == EV_ABS && ev.code ==ABS_X)
        {
            *x = ev.value;
        }
        if(ev.type == EV_ABS && ev.code ==ABS_Y)
        {
            *y = ev.value;
        }
        if(ev.type == EV_KEY &&ev.code ==BIN_TOUCH && ev.value == 0)
        {
            break;
        }

    }
    close(fd_ev);
}

int get_event_dirention()
{//按键方向的判断
    int fd_ev = open("/dev/input/event0",O_RDONLY);
    if(fd_ev ==-1)
    {
        perror("open error");
        exit(1);
    }
    printf("open duccess\n");

    struct input_event ev;
    int x0 =-1,y0=-1;
    int x1=-1,y1 =-1;

    while(1)
    {
        int ret =read(fd_ev,&ev,sizeof(ev));
        if(ret ==-1)
        {
            perror("read ev error");
            exit(1);
        }

        if(ev.type == EV_ABS && ev.code ==ABS_X)
        {
            if(x0==-1)
            {
                x0=ev.value;
            }else{
                x1=ev.value;
            }
        }
        if(ev.type == EV_ABS && ev.code ==ABS_Y)
        {
            if(y0==-1)
            {
                y0=ev.value;
            }else{
                y1=ev.value;
            }
        }
        if(ev.type == EV_KEY &&ev.code ==BIN_TOUCH && ev.value == 0)
        {
            int x_d =x1-x0;
            int y_d=y1-y0;
            printf("x0=%d,y0=%d,x1=%d,y1=%d\n",x0,x1,y0,y1);
            printf("x_d=%d,y_d=%d\n",x_d,y_d);
            if(abs(x_d)>abs(y_d))
            {
                if(x_d>100)
                {
                    close(fd_ev);
                    return right;
                }else if(x_d<-100)
                {
                    close(fd_ev);
                    return left;
                }
            }else{
                if(y_d>100)
                {
                    close(fd_ev);
                    return down;
                }else if(y_d<-100)
                {
                    close(fd_ev);
                    return up;
                }
            }
        }

    }
    close(fd_ev);
}

int get_event_button()
{//对按键的监听
    int x2 = -1, y2 = -1;
    get_event_xy(&x2, &y2);
    // 转换成像素点的坐标
    int x0 = x2 /1.28;
    int y0 = y2 /1.25;
    int w=150 ,h=80;
    //符合区间就返回那个值
    if((x0 > 480 && x0 < 480 + w) && (y0 > 250 && y0 < h + 250)) // 重启
    {
        return 1;
    }
    else if ((x0 > 480 && x0 < 480 + w) && (y0 > 340 && y0 < h + 340)) // 退出
    {
        return 2;
    }
    else
    {
        return -1;
    }
}

lcd.h

系统IO操作LCD,内存映射操作显示屏。

#ifndef __LCD_H_
#define __LCD_H_

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <sys/ioctl.h>

//BMP图片信息结构体
typedef struct bmp_info
{
    int size;       //图片的大小
    int width;      //图片的宽度
    int height;     //图片的高度
    short depth;    //图片的色深
    char* data;     //保存像素数组首地址
}BMP;


//系统IO操作显示屏
void open_lcd();
void close_lcd();
void write_lcd(unsigned int color);
void rgbrun();

//内存映射操作显示屏
void lcd_init();
void lcd_uninit();
void lcd_draw_point(int i, int j, unsigned int color);
void lcd_draw_background(unsigned int color);
void lcd_draw_word(int x0,int y0,int w, int h,unsigned int color,char *lcd_draw_word);
void lcd_draw_bmp(int x, int y, char* bmpname);
BMP get_bmp_info(char *bmpname);



#endif

lcd.c

系统IO完成:打开LCD函数,关闭LCD函数,写入像素点颜色函数,刷屏函数。

#include "lcd.h"

int fd_lcd = -1; //显示屏的文件描述符
int* plcd = NULL; //内存映射区域的首地址
struct fb_var_screeninfo fbinfo; //屏幕属性信息结构体

/********************系统IO操作显示屏************************/
/**
 * @brief 打开LCD显示屏
 * 
 */
void open_lcd()
{
    fd_lcd = open("/dev/fb0", O_WRONLY);
    if(fd_lcd == -1)
    {
        perror("open error");
        exit(1);
    }
    printf("open /dev/fb0 success\n");
}

/**
 * @brief 关闭显示屏
 * 
 */
void close_lcd()
{
    close(fd_lcd);
}

/**
 * @brief 往屏幕文件中写入数据
 * 
 * @param color 需要显示的颜色
 */
void write_lcd(unsigned int color)
{
    int array[480][800] = {0}; //二维数组  对应显示屏上的像素点

    for(int i = 0; i < 480; i++) //行
    {
        for(int j = 0; j < 800; j++) //列
        {
            array[i][j] = color;
        }
    }

    //把颜色数据写入到显示屏文件中
    write(fd_lcd, array, 800*480*4);
}
/**
 * @brief 实现显示屏的刷屏
 * 
 */
void change_lcd()
{
    unsigned int color[3] = {0xFF0000, 0x00FF00, 0x0000FF};

    int i = 0;
    while(1)
    {
        write_lcd(color[i]);
        sleep(3); //延时3秒
        i++;

        if(i > 2)
            i = 0;

        //把光标偏移到文件开头
        lseek(fd_lcd, 0, SEEK_SET);
    }

}

屏幕的初始化:打开屏幕,内存映射。

/*********************内存映射操作显示屏********************/

/**
 * @brief 屏幕初始化:打开显示屏,内存映射
 * 
 */
void lcd_init()
{
    //可读可写方式打开显示屏
    fd_lcd = open("/dev/fb0", O_RDWR);
    if(fd_lcd == -1)
    {
        perror("open error");
        exit(1);
    }
    printf("open /dev/fb0 success\n");

    //使用ioctl获取屏幕的属性信息
    int ret = ioctl(fd_lcd, FBIOGET_VSCREENINFO, &fbinfo);
    if(ret == 0)
    {
        printf("LCD: %d, %d, %d\n", fbinfo.xres, fbinfo.yres, fbinfo.bits_per_pixel);
    }

    //进行内存映射
    plcd = mmap(
            NULL,               //映射区域的地址由系统自行分配
            //800*480*4,         //映射区域的大小
            fbinfo.xres * fbinfo.yres * fbinfo.bits_per_pixel / 8, //映射区域的大小
            PROT_READ | PROT_WRITE, //可读可写
            MAP_SHARED,         //共享映射,操作立马响应
            fd_lcd,             //文件描述符
            0                   //文件映射偏移量,为0,表示从文件开头进行映射
    );
    if(plcd == MAP_FAILED)
    {
        perror("mmap error");
        exit(1);
    }
    printf("mmap  success\n");
}

关闭屏幕,解除映射。 

/**
 * @brief 接触显示屏初始化: 解除映射,关闭显示屏
 * 
 */
void lcd_uninit()
{
    //解除内存映射
    munmap(plcd, 800*480*4);
    //关闭显示屏
    close(fd_lcd);
}
/**
 * @brief 画背景色(让整个屏幕显示某种颜色)
 * 
 * @param color 颜色
 */
void lcd_draw_background(unsigned int color)
{
    for(int i = 0; i < 480; i++) //行
    {
        for(int j = 0; j < 800; j++) //列
        {
            lcd_draw_point(i, j, color);
        }
    }
}
/**
 * @brief 显示一个字符
 * 
 * @param x0 
 * @param y0 第y行的第x个像素点为字符的最左上角的坐标
 * @param w 宽
 * @param h 高
 * @param color 颜色 
 * @param word 需要显示的字符的字模数据
 */
void lcd_draw_word(int x0, int y0, int w, int h, unsigned int color, char* word)
{
    int x, y; //表示需要进行显示的像素点的下标 第y行的第x个像素点

    for(int i = 0; i < w*h/8; i++) //对点阵数组进行遍历
    {
        for(int j = 0; j < 8; j++) //对点阵矩阵中的元素一个一个bit进行分析
        {
            //word[i]对应有8bit, 一个一个bit来分析,从左往右,高字节到子字节
            if(word[i] & (1<<(7-j)))
            {
                y = i/(w/8); //第几行  w/8一行有多少字节
                x = i % (w/8) * 8 + j;
                //i%(w/8) 当前元素在这一行前面有多少个字节的元素
                //i%(w/8)*8 当前元素在这一行前面有多少个像素点
                lcd_draw_point(y+y0, x+x0, color);
            }
        }
    }
}
/**
 * @brief Get the bmp info object
 * 
 * @param bmpname 需要进行属性信息获取的bmp图片路径
 * @return BMP 返回获取到的属性信息
 */
BMP get_bmp_info(char* bmpname)
{
    //打开图片
    int fd_bmp = open(bmpname, O_RDONLY);
    if(fd_bmp == -1)
    {
        perror("open bmp error");
        exit(1);
    }

    //判断该文件是否为bmp文件
    char bm[2] = {0};
    read(fd_bmp, bm, 2);
    if(!(bm[0] == 'B' && bm[1] == 'M'))
    {
        printf("%s is not BMP file\n", bmpname);
        exit(1);
    }

    //获取BMP图片数据
    BMP bmpinfo;

    //文件大小
    lseek(fd_bmp, 0x02, SEEK_SET);
    read(fd_bmp, &bmpinfo.size, 4);

    //宽度和高度
    lseek(fd_bmp, 0x12, SEEK_SET);
    read(fd_bmp, &bmpinfo.width, 4);
    read(fd_bmp, &bmpinfo.height, 4);

    //色深 
    lseek(fd_bmp, 0x1C, SEEK_SET);
    read(fd_bmp, &bmpinfo.depth, 2);

    //像素数组
    char* p = malloc(bmpinfo.size - 54); //图片的总大小-文件头大小
    lseek(fd_bmp, 0x36, SEEK_SET); //偏移到像素数组的位置
    read(fd_bmp, p, bmpinfo.size-54);
    bmpinfo.data = p;

    //关闭文件
    close(fd_bmp);

    return bmpinfo;
}

/**
 * @brief 显示一张bmp图片
 * 
 * @param x 
 * @param y 第y行的第x个像素点为图片最左上角的坐标
 * @param bmpname 图片的路径
 */
void lcd_draw_bmp(int x, int y, char* bmpname)
{
    //获取bmp图片信息
    BMP bmp = get_bmp_info(bmpname);
    printf("bmpname = %s, size = %d, width = %d, height = %d, depth = %d\n", 
            bmpname, bmp.size, bmp.width, bmp.height, bmp.depth);

    //一行的有效字节数
    int line_bytes = bmp.width * bmp.depth / 8;
    
    //一行的填充字节数
    int pad_bytes = (line_bytes % 4 == 0) ? 0 : (4 - line_bytes%4);

    //解析像素数组中的数据
    unsigned int color = 0; //像素点的颜色
    unsigned char a, r, g, b; //颜色分量

    //开始进行解析
    char* p = bmp.data;

    for(int h = 0; h < abs(bmp.height); h++)
    {
        for(int w = 0; w < abs(bmp.width); w++)
        {
            //获取颜色分量
            b = *(p++);
            g = *(p++);
            r = *(p++);
            //只考虑24位和32位图片
            a = (bmp.depth == 24) ? 0 : *(p++);
            //颜色分量合成颜色数据
            color = a<<24 | r<<16 | g<<8 | b;
            //描点
            // width > 0 : 每一行的像素点从左往右存放
            // width < 0 : 每一行的像素点从右往左存放
            // height > 0 : 每一行像素点从下往上存放
            // height < 0 : 每一行像素点从上往下存放
            int m = x + w;//横坐标  一行中的第几个像素点
            int n = y+bmp.height-1 - h; //纵坐标  第几行
            lcd_draw_point(n, m, color);
        }
        //跳过填充字节数
        p += pad_bytes;
    }
    free(bmp.data); //把申请的空间释放
}

2048.h

#ifndef __2048_H_
#define __2048_H_

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <pthread.h>
char *pic_bmp(int n);

void menu();//主页面
int Rander();//随机数
void InitNode();//初始化节点
int UP();//上下左右
int RIGHT();
int LEFT();
int DOWN();
void move();//移动方向判断
int over();//判断结束条件
void start();//开始函数
void Init_menu();//初始化页面
void *Botton(void *arg);//线程按键


#endif

2048.c


#include "2048.h"
#include "event.h"
#include "lcd.h"
int map[4][4] = {0};//存放数组
int score = 0;//分数
char input;//判断屏幕上下左右接收的数据
int gameover = 1;//判断游戏是否继续
int flag = 1;//判断数组是否移动

//==初始化函数用在重新开始和结束按钮=====
void Init_menu()
{
	lcd_draw_background(0xFFFFFF);
	int i = 0;
	int j = 0;
	score = 0;
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 4; j++)
		{
			map[i][j] = 0;
		}
	}

	InitNode();
	menu();
}

//=====上下左右移动的函数=====
int UP()
{ // 向上
    int now, next; // 定义当前和下一个元素的变量
    int i, j, k;
    for (j = 0; j < 4; j++) // 外层循环遍历列(竖直方向)
    {
        for (i = 0; i < 4; i++) // 内层循环遍历行(从上到下)
        {
            now = map[i][j]; // 获取当前位置的元素值
            if (now != 0) // 如果当前元素不为0(即非空)
            {
                k = i + 1;
                while (k < 4) // 从当前行的下一行开始向下查找
                {
                    next = map[k][j]; // 获取下一个位置的元素值
                    if (next != 0) // 如果下一个位置不为0(即非空)
                    {
                        if (now == next) // 如果当前元素与下一个元素相等
                        {
                            flag = 1; // 设置标志位为1,表示发生了合并操作
                            score += map[k][j]; // 更新分数,加上合并后的值
                            map[i][j] = 2 * map[k][j]; // 当前位置更新为两者之和
                            map[k][j] = 0; // 下一个位置清零(合并后该位置为空)
                        }
                        k = 4; // 跳出循环
                    }
                    k++; // 继续向下查找
                }
            }
        }
    }
    for (j = 0; j < 4; j++) // 第二个for语句是把当前控制方向的非零元素移动当前方向的前面
    {
        for (i = 0; i < 4; i++)
        {
            now = map[i][j];
            if (now == 0) // 如果当前位置为空(值为0)
            {
                k = 1 + i;
                while (k < 4) // 从当前位置的下一行开始向下查找
                {
                    next = map[k][j]; // 获取下一个位置的元素值
                    if (next != 0) // 如果下一个位置不为空
                    {
                        flag = 1; // 设置标志位为1,表示发生了移动操作
                        map[i][j] = next; // 当前位置更新为下一个位置的值
                        map[k][j] = 0; // 下一个位置清零
                        k = 4; // 跳出循环
                    }
                    k++; // 继续向下查找
                }
            }
        }
    }
    // 返回注释代码
return flag;
}

向上移动代码中注释很清楚,其他方向同理,暂不例出了。

//======创建线程对重新开始按钮和游戏结束按钮=======
void *Botton(void *arg)
{
	int button = -1;
	while (1)
	{
		button = get_event_button();
		if (button == 1)
		{
			Init_menu();
		}
		else if (button == 2)
		{
			lcd_draw_bmp(0, 0, "game_over.bmp");
			lcd_draw_bmp(0, 0, "game_over.bmp");
			lcd_draw_bmp(0, 0, "game_over.bmp");
			exit(1);
		}
	}
}

main.c

#include "lcd.h"
#include "event.h"
#include "2048.h"
#include <pthread.h>


int main()
{
    lcd_init();
    lcd_draw_background(0xFFFFFF);
    pthread_t pid;
    int ret=pthread_create(&pid,NULL,Botton,NULL);
    start();
    lcd_uninit();
    return 0;
}

演示图片如下: 初始状态

向下移动 

 

完整项目:

链接:https://pan.baidu.com/s/1vO1ZAuLbndoxoN5Kt02ALg?pwd=ucyl 

提取码:ucyl

好的,以下是基于 SDL 库实现ARM6818 开发板上运行的 2048 小游戏的代码。注意,此代码仅供参考,可能需要根据您的具体情况进行适当的修改。 ``` #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <SDL2/SDL.h> #define SCREEN_WIDTH 480 #define SCREEN_HEIGHT 800 #define BLOCK_SIZE 100 #define BLOCK_PADDING 10 #define BOARD_PADDING 20 #define BOARD_SIZE (BLOCK_SIZE*4+BLOCK_PADDING*3+BOARD_PADDING*2) SDL_Window* window = NULL; SDL_Renderer* renderer = NULL; SDL_Texture* block_texture = NULL; SDL_Texture* bg_texture = NULL; SDL_Texture* gameover_texture = NULL; SDL_Rect block_rect; int board[4][4] = {0}; bool is_gameover = false; void init() { SDL_Init(SDL_INIT_VIDEO); window = SDL_CreateWindow("2048", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); SDL_Surface* surface = SDL_LoadBMP("block.bmp"); block_texture = SDL_CreateTextureFromSurface(renderer, surface); SDL_FreeSurface(surface); surface = SDL_LoadBMP("bg.bmp"); bg_texture = SDL_CreateTextureFromSurface(renderer, surface); SDL_FreeSurface(surface); surface = SDL_LoadBMP("gameover.bmp"); gameover_texture = SDL_CreateTextureFromSurface(renderer, surface); SDL_FreeSurface(surface); } void quit() { SDL_DestroyTexture(block_texture); SDL_DestroyTexture(bg_texture); SDL_DestroyTexture(gameover_texture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); } void draw_block(int row, int col, int value) { block_rect.x = BOARD_PADDING + (BLOCK_SIZE + BLOCK_PADDING) * col; block_rect.y = BOARD_PADDING + (BLOCK_SIZE + BLOCK_PADDING) * row; block_rect.w = BLOCK_SIZE; block_rect.h = BLOCK_SIZE; SDL_RenderCopy(renderer, block_texture, NULL, &block_rect); char str[16]; sprintf(str, "%d", value); SDL_Surface* surface = TTF_RenderText_Solid(font, str, (SDL_Color){255, 255, 255, 255}); SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface); SDL_Rect rect; rect.x = block_rect.x + BLOCK_SIZE / 2 - surface->w / 2; rect.y = block_rect.y + BLOCK_SIZE / 2 - surface->h / 2; rect.w = surface->w; rect.h = surface->h; SDL_RenderCopy(renderer, texture, NULL, &rect); SDL_FreeSurface(surface); SDL_DestroyTexture(texture); } void draw_board() { SDL_RenderCopy(renderer, bg_texture, NULL, NULL); for (int row = 0; row < 4; row++) { for (int col = 0; col < 4; col++) { if (board[row][col] > 0) { draw_block(row, col, board[row][col]); } } } } bool is_full() { for (int row = 0; row < 4; row++) { for (int col = 0; col < 4; col++) { if (board[row][col] == 0) { return false; } } } return true; } bool is_gameover() { if (!is_full()) { return false; } for (int row = 0; row < 4; row++) { for (int col = 0; col < 4; col++) { if (row > 0 && board[row][col] == board[row - 1][col]) { return false; } if (row < 3 && board[row][col] == board[row + 1][col]) { return false; } if (col > 0 && board[row][col] == board[row][col - 1]) { return false; } if (col < 3 && board[row][col] == board[row][col + 1]) { return false; } } } return true; } void add_random_block() { int row, col; do { row = rand() % 4; col = rand() % 4; } while (board[row][col] != 0); board[row][col] = (rand() % 2 + 1) * 2; } void move_left() { bool is_moved = false; for (int row = 0; row < 4; row++) { int i = 0; for (int col = 1; col < 4; col++) { if (board[row][col] > 0) { if (board[row][i] == 0) { board[row][i] = board[row][col]; board[row][col] = 0; is_moved = true; } else if (board[row][i] == board[row][col]) { board[row][i] *= 2; board[row][col] = 0; is_moved = true; } else { i++; if (i != col) { board[row][i] = board[row][col]; board[row][col] = 0; is_moved = true; } } } } } if (is_moved) { add_random_block(); } } void move_right() { bool is_moved = false; for (int row = 0; row < 4; row++) { int i = 3; for (int col = 2; col >= 0; col--) { if (board[row][col] > 0) { if (board[row][i] == 0) { board[row][i] = board[row][col]; board[row][col] = 0; is_moved = true; } else if (board[row][i] == board[row][col]) { board[row][i] *= 2; board[row][col] = 0; is_moved = true; } else { i--; if (i != col) { board[row][i] = board[row][col]; board[row][col] = 0; is_moved = true; } } } } } if (is_moved) { add_random_block(); } } void move_up() { bool is_moved = false; for (int col = 0; col < 4; col++) { int i = 0; for (int row = 1; row < 4; row++) { if (board[row][col] > 0) { if (board[i][col] == 0) { board[i][col] = board[row][col]; board[row][col] = 0; is_moved = true; } else if (board[i][col] == board[row][col]) { board[i][col] *= 2; board[row][col] = 0; is_moved = true; } else { i++; if (i != row) { board[i][col] = board[row][col]; board[row][col] = 0; is_moved = true; } } } } } if (is_moved) { add_random_block(); } } void move_down() { bool is_moved = false; for (int col = 0; col < 4; col++) { int i = 3; for (int row = 2; row >= 0; row--) { if (board[row][col] > 0) { if (board[i][col] == 0) { board[i][col] = board[row][col]; board[row][col] = 0; is_moved = true; } else if (board[i][col] == board[row][col]) { board[i][col] *= 2; board[row][col] = 0; is_moved = true; } else { i--; if (i != row) { board[i][col] = board[row][col]; board[row][col] = 0; is_moved = true; } } } } } if (is_moved) { add_random_block(); } } void handle_event(SDL_Event* event) { switch (event->type) { case SDL_QUIT: is_gameover = true; break; case SDL_KEYDOWN: switch (event->key.keysym.sym) { case SDLK_LEFT: move_left(); break; case SDLK_RIGHT: move_right(); break; case SDLK_UP: move_up(); break; case SDLK_DOWN: move_down(); break; } if (is_gameover()) { is_gameover = true; } break; } } void game_loop() { while (!is_gameover) { SDL_Event event; while (SDL_PollEvent(&event)) { handle_event(&event); } SDL_RenderClear(renderer); draw_board(); SDL_RenderPresent(renderer); SDL_Delay(10); } SDL_RenderCopy(renderer, gameover_texture, NULL, NULL); SDL_RenderPresent(renderer); SDL_Delay(3000); } int main(int argc, char* argv[]) { init(); add_random_block(); add_random_block(); game_loop(); quit(); return 0; } ``` 注意,此代码中涉及到了一些图形界面的操作和事件处理,需要您提前安装好相应的库并进行配置。此外,此代码中使用了 SDL2 的事件循环机制来处理用户输入和游戏逻辑,您可以根据自己的需求进行修改。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值