编译无问题,但存在段错误,检测并修改错误函数,将修改后的完整函数写出来:
#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "game.h"
// 定义颜色常量
#define PRIMARY_COLOR lv_color_hex(0x1a1a2e)
#define SECONDARY_COLOR lv_color_hex(0x16213e)
#define ACCENT_COLOR lv_color_hex(0x0f3460)
#define HIGHLIGHT_COLOR lv_color_hex(0xe94560)
#define TEXT_COLOR lv_color_hex(0xffffff)
// 用户结构体
typedef struct {
char username[20];
char password[20];
int high_score;
} User;
// 游戏结构体
typedef struct {
int x[100];
int y[100];
int length;
int direction;
int food_x;
int food_y;
int score;
int speed;
int game_over;
} SnakeGame;
// 全局变量
static lv_obj_t *login_scr;
static lv_obj_t *register_scr;
static lv_obj_t *main_menu_scr;
static lv_obj_t *game_scr;
static lv_obj_t *scoreboard_scr;
static SnakeGame game;
static User current_user;
static User users[10];
static int user_count = 0;
static lv_timer_t *game_timer;
static void game_timer_cb(lv_timer_t *timer);
static lv_obj_t *game_container = NULL;
static lv_obj_t *overlay = NULL;
static lv_obj_t *score_label_game = NULL;
// 函数原型声明
void save_users();
void load_users();
int find_user(const char *username);
void register_user(const char *username, const char *password);
int login_user(const char *username, const char *password);
void update_user_score(int score);
void init_game();
void generate_food();
void move_snake();
void check_collision();
void create_login_screen();
void create_register_screen();
void create_main_menu();
void create_game_screen();
void create_scoreboard_screen();
void switch_screen(lv_obj_t *new_screen);
// 用户管理函数
void save_users() {
FILE *file = fopen("users.dat", "wb");
if (file) {
fwrite(&user_count, sizeof(int), 1, file);
fwrite(users, sizeof(User), user_count, file);
fclose(file);
}
}
void load_users() {
FILE *file = fopen("users.dat", "rb");
if (file) {
size_t read_count = fread(&user_count, sizeof(int), 1, file);
if (read_count == 1 && user_count > 0 && user_count <= 10) {
fread(users, sizeof(User), user_count, file);
} else {
user_count = 0;
}
fclose(file);
} else {
user_count = 0; // 初始化用户数量
}
}
int find_user(const char *username) {
for (int i = 0; i < user_count; i++) {
if (strcmp(users[i].username, username) == 0) {
return i;
}
}
return -1;
}
void register_user(const char *username, const char *password) {
if (user_count >= 10) return;
if (find_user(username) != -1) return;
strcpy(users[user_count].username, username);
strcpy(users[user_count].password, password);
users[user_count].high_score = 0;
user_count++;
save_users();
}
int login_user(const char *username, const char *password) {
int idx = find_user(username);
if (idx == -1) return 0;
if (strcmp(users[idx].password, password) != 0) return 0;
current_user = users[idx];
return 1;
}
void update_user_score(int score) {
if (score > current_user.high_score) {
current_user.high_score = score;
}
int idx = find_user(current_user.username);
if (idx != -1) {
users[idx] = current_user;
save_users();
}
}
// 游戏初始化
void init_game() {
srand(time(NULL));
game.length = 3;
game.direction = 2; // 初始向右移动
game.score = 0;
game.speed = 150;
game.game_over = 0;
// 初始化蛇身位置 - 修改这里
for (int i = 0; i < game.length; i++) {
// 蛇头在中间,蛇身向右延伸
game.x[i] = 10 + i; // 初始位置 (10,10), (11,10), (12,10)
game.y[i] = 10;
}
// 生成食物
generate_food();
}
void generate_food() {
int valid = 0; // 修复:声明valid变量
int attempts = 0;
while (!valid && attempts < 100) {
game.food_x = rand() % 20;
game.food_y = rand() % 20;
valid = 1;
for (int i = 0; i < game.length; i++) {
if (game.x[i] == game.food_x && game.y[i] == game.food_y) {
valid = 0;
break;
}
}
attempts++;
}
if (!valid) {
// 设置安全位置作为后备
game.food_x = 10; // 中间位置
game.food_y = 10;
// 确保这个位置没有蛇身
for (int i = 0; i < game.length; i++) {
if (game.x[i] == 10 && game.y[i] == 10) {
game.food_x = 11; // 如果中间有蛇,使用旁边位置
game.food_y = 10;
break;
}
}
}
}
void move_snake() {
if (game.game_over) return;
// 保存蛇尾位置(用于绘制)
int prev_x = game.x[game.length-1];
int prev_y = game.y[game.length-1];
// 移动蛇身
for (int i = game.length-1; i > 0; i--) {
game.x[i] = game.x[i-1];
game.y[i] = game.y[i-1];
}
// 移动蛇头
switch (game.direction) {
case 0: game.y[0]--; break; // 上
case 1: game.y[0]++; break; // 下
case 2: game.x[0]++; break; // 右
case 3: game.x[0]--; break; // 左
}
// 检查是否吃到食物
if (game.x[0] == game.food_x && game.y[0] == game.food_y) {
// 只在吃到食物时才增加长度
if (game.length < 100) { // 检查长度限制
game.length++;
// 增加蛇身
game.x[game.length-1] = prev_x;
game.y[game.length-1] = prev_y;
} else {
// 处理达到最大长度的情况
game.game_over = 1;
}
// 生成新食物
generate_food();
// 增加速度
if (game.speed > 50) {
game.speed -= 5;
lv_timer_set_period(game_timer, game.speed);
}
}
// 检查碰撞
check_collision();
}
void check_collision() {
// 检查墙壁碰撞
if (game.x[0] < 0 || game.x[0] >= 20 || game.y[0] < 0 || game.y[0] >= 20) {
game.game_over = 1;
return;
}
// 检查自身碰撞
for (int i = 1; i < game.length; i++) {
if (game.x[0] == game.x[i] && game.y[0] == game.y[i]) {
game.game_over = 1;
return;
}
}
}
// 修改后的 switch_screen 函数
void switch_screen(lv_obj_t *new_screen) {
lv_disp_t *disp = lv_disp_get_default();
lv_disp_load_scr(new_screen);
}
// 定时器回调辅助函数
static void timer_callback(lv_timer_t *t) {
lv_obj_del(t->user_data);
lv_timer_del(t);
}
// 登录回调函数
static void login_btn_cb(lv_event_t *e) {
lv_obj_t *username_ta = lv_obj_get_child(login_scr, 1);
lv_obj_t *password_ta = lv_obj_get_child(login_scr, 3);
const char *username = lv_textarea_get_text(username_ta);
const char *password = lv_textarea_get_text(password_ta);
if (login_user(username, password)) {
switch_screen(main_menu_scr);
} else {
lv_obj_t *error_label = lv_label_create(login_scr);
lv_label_set_text(error_label, "用户名或密码错误");
lv_obj_set_style_text_color(error_label, lv_color_hex(0xff0000), 0);
lv_obj_align(error_label, LV_ALIGN_BOTTOM_MID, 0, -20);
lv_timer_t *timer = lv_timer_create(timer_callback, 2000, error_label);
}
}
// 注册回调函数
static void register_btn_cb(lv_event_t *e) {
lv_obj_t *username_ta = lv_obj_get_child(register_scr, 1);
lv_obj_t *password_ta = lv_obj_get_child(register_scr, 3);
lv_obj_t *confirm_ta = lv_obj_get_child(register_scr, 5);
const char *username = lv_textarea_get_text(username_ta);
const char *password = lv_textarea_get_text(password_ta);
const char *confirm = lv_textarea_get_text(confirm_ta);
if (strlen(username) < 3) {
lv_obj_t *error_label = lv_label_create(register_scr);
lv_label_set_text(error_label, "用户名至少3个字符");
lv_obj_set_style_text_color(error_label, lv_color_hex(0xff0000), 0);
lv_obj_align(error_label, LV_ALIGN_BOTTOM_MID, 0, -20);
lv_timer_t *timer = lv_timer_create(timer_callback, 2000, error_label);
return;
}
if (strcmp(password, confirm) != 0) {
lv_obj_t *error_label = lv_label_create(register_scr);
lv_label_set_text(error_label, "两次输入的密码不一致");
lv_obj_set_style_text_color(error_label, lv_color_hex(0xff0000), 0);
lv_obj_align(error_label, LV_ALIGN_BOTTOM_MID, 0, -20);
lv_timer_t *timer = lv_timer_create(timer_callback, 2000, error_label);
return;
}
register_user(username, password);
switch_screen(login_scr);
}
// 菜单按钮回调
static void menu_btn_cb(lv_event_t *e) {
if (e->code == LV_EVENT_CLICKED) {
switch_screen(main_menu_scr);
}
}
// 注册按钮回调
static void register_btn_handler(lv_event_t *e) {
if (e->code == LV_EVENT_CLICKED) {
switch_screen(register_scr);
}
}
// 返回登录回调
static void back_to_login_cb(lv_event_t *e) {
if (e->code == LV_EVENT_CLICKED) {
switch_screen(login_scr);
}
}
// 开始游戏回调
static void play_game_cb(lv_event_t *e) {
// 清除之前的定时器
if (game_timer) {
lv_timer_del(game_timer);
game_timer = NULL;
}
// 清除之前的覆盖层
if (overlay) {
lv_obj_del(overlay);
overlay = NULL;
}
init_game();
switch_screen(game_scr);
if (score_label_game) {
lv_label_set_text(score_label_game, "分数: 0");
}
game_timer = lv_timer_create(game_timer_cb, game.speed, NULL);
}
// 排行榜回调
static void show_scoreboard_cb(lv_event_t *e) {
if (e->code == LV_EVENT_CLICKED) {
switch_screen(scoreboard_scr);
}
}
// 退出登录回调
static void logout_cb(lv_event_t *e) {
if (e->code == LV_EVENT_CLICKED) {
switch_screen(login_scr);
}
}
// 返回主菜单回调
static void back_to_menu_cb(lv_event_t *e) {
if (e->code == LV_EVENT_CLICKED) {
switch_screen(main_menu_scr);
}
}
// 游戏控制回调
static void game_timer_cb(lv_timer_t *timer) {
// 检查容器是否有效 - 使用全局变量
if (!game_container) {
return;
}
move_snake();
// 更新UI - 使用全局分数标签
if (score_label_game) {
lv_label_set_text_fmt(score_label_game, "分数: %d", game.score);
}
// 清除之前的绘制
lv_obj_clean(game_container);
// 绘制食物 (添加有效性检查)
if (game.food_x >= 0 && game.food_y >= 0) {
// 修复:移除重复的变量声明
lv_obj_t *food = lv_obj_create(game_container);
lv_obj_set_size(food, 15, 15); // 每个格子15x15像素
lv_obj_set_pos(food, game.food_x * 15, game.food_y * 15);
lv_obj_set_style_bg_color(food, HIGHLIGHT_COLOR, 0);
lv_obj_set_style_radius(food, LV_RADIUS_CIRCLE, 0);
lv_obj_set_style_border_width(food, 0, 0);
}
// 绘制蛇身
for (int i = 0; i < game.length; i++) {
lv_obj_t *snake_part = lv_obj_create(game_container);
lv_obj_set_size(snake_part, 15, 15);
lv_obj_set_pos(snake_part, game.x[i] * 15, game.y[i] * 15);
if (i == 0) {
// 蛇头
lv_obj_set_style_bg_color(snake_part, HIGHLIGHT_COLOR, 0);
} else {
// 蛇身
lv_obj_set_style_bg_color(snake_part, lv_color_hex(0x00ff00), 0);
}
lv_obj_set_style_border_width(snake_part, 0, 0);
}
lv_obj_invalidate(game_scr);
if (game.game_over) {
lv_timer_del(game_timer);
// 显示游戏结束画面
overlay = lv_obj_create(game_scr);
lv_obj_set_size(overlay, lv_pct(100), lv_pct(100));
lv_obj_set_style_bg_color(overlay, lv_color_hex(0x000000), 0);
lv_obj_set_style_bg_opa(overlay, LV_OPA_50, 0);
lv_obj_set_style_radius(overlay, 0, 0);
lv_obj_t *game_over_label = lv_label_create(overlay);
lv_label_set_text(game_over_label, "游戏结束!");
lv_obj_set_style_text_font(game_over_label, &lv_font_montserrat_28, 0);
lv_obj_set_style_text_color(game_over_label, HIGHLIGHT_COLOR, 0);
lv_obj_align(game_over_label, LV_ALIGN_CENTER, 0, -40);
// 修复:使用正确的变量名 final_score_label
lv_obj_t *final_score_label = lv_label_create(overlay);
lv_label_set_text_fmt(final_score_label, "最终分数: %d", game.score);
lv_obj_set_style_text_font(final_score_label, &lv_font_montserrat_24, 0);
lv_obj_set_style_text_color(final_score_label, TEXT_COLOR, 0);
lv_obj_align(final_score_label, LV_ALIGN_CENTER, 0, 0);
update_user_score(game.score);
lv_obj_t *menu_btn = lv_btn_create(overlay);
lv_obj_set_size(menu_btn, 150, 50);
lv_obj_align(menu_btn, LV_ALIGN_CENTER, 0, 60);
lv_obj_set_style_bg_color(menu_btn, HIGHLIGHT_COLOR, 0);
lv_obj_t *btn_label = lv_label_create(menu_btn);
lv_label_set_text(btn_label, "返回主菜单");
lv_obj_center(btn_label);
lv_obj_add_event_cb(menu_btn, menu_btn_cb, LV_EVENT_CLICKED, NULL);
}
}
// 键盘输入回调
static void game_input_cb(lv_event_t *e) {
lv_event_code_t code = lv_event_get_code(e);
if (code == LV_EVENT_KEY) {
uint32_t key = lv_event_get_key(e);
// 防止180度转向
if (key == LV_KEY_UP && game.direction != 1) game.direction = 0;
else if (key == LV_KEY_DOWN && game.direction != 0) game.direction = 1;
else if (key == LV_KEY_RIGHT && game.direction != 3) game.direction = 2;
else if (key == LV_KEY_LEFT && game.direction != 2) game.direction = 3;
}
}
// 创建登录界面
void create_login_screen() {
login_scr = lv_obj_create(NULL);
lv_obj_set_style_bg_color(login_scr, PRIMARY_COLOR, 0);
lv_obj_set_style_pad_all(login_scr, 20, 0);
// 标题
lv_obj_t *title = lv_label_create(login_scr);
lv_label_set_text(title, "贪吃蛇游戏");
lv_obj_set_style_text_font(title, &lv_font_montserrat_36, 0);
lv_obj_set_style_text_color(title, HIGHLIGHT_COLOR, 0);
lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 30);
// 用户名标签
lv_obj_t *user_label = lv_label_create(login_scr);
lv_label_set_text(user_label, "用户名:");
lv_obj_set_style_text_color(user_label, TEXT_COLOR, 0);
lv_obj_align(user_label, LV_ALIGN_TOP_MID, -80, 100);
// 用户名输入框
lv_obj_t *user_ta = lv_textarea_create(login_scr);
lv_obj_set_size(user_ta, 200, 40);
lv_obj_align(user_ta, LV_ALIGN_TOP_MID, 40, 100);
lv_textarea_set_placeholder_text(user_ta, "输入用户名");
lv_obj_set_style_bg_color(user_ta, SECONDARY_COLOR, 0);
// 密码标签
lv_obj_t *pass_label = lv_label_create(login_scr);
lv_label_set_text(pass_label, "密码:");
lv_obj_set_style_text_color(pass_label, TEXT_COLOR, 0);
lv_obj_align(pass_label, LV_ALIGN_TOP_MID, -80, 160);
// 密码输入框
lv_obj_t *pass_ta = lv_textarea_create(login_scr);
lv_obj_set_size(pass_ta, 200, 40);
lv_obj_align(pass_ta, LV_ALIGN_TOP_MID, 40, 160);
lv_textarea_set_placeholder_text(pass_ta, "输入密码");
lv_textarea_set_password_mode(pass_ta, true);
lv_obj_set_style_bg_color(pass_ta, SECONDARY_COLOR, 0);
// 登录按钮
lv_obj_t *login_btn = lv_btn_create(login_scr);
lv_obj_set_size(login_btn, 180, 50);
lv_obj_align(login_btn, LV_ALIGN_TOP_MID, 0, 230);
lv_obj_set_style_bg_color(login_btn, HIGHLIGHT_COLOR, 0);
lv_obj_t *login_label = lv_label_create(login_btn);
lv_label_set_text(login_label, "登录");
lv_obj_center(login_label);
lv_obj_add_event_cb(login_btn, login_btn_cb, LV_EVENT_CLICKED, NULL);
// 注册按钮
lv_obj_t *register_btn = lv_btn_create(login_scr);
lv_obj_set_size(register_btn, 180, 40);
lv_obj_align(register_btn, LV_ALIGN_TOP_MID, 0, 290);
lv_obj_set_style_bg_color(register_btn, ACCENT_COLOR, 0);
lv_obj_t *register_label = lv_label_create(register_btn);
lv_label_set_text(register_label, "没有账号? 注册");
lv_obj_center(register_label);
lv_obj_add_event_cb(register_btn, register_btn_handler, LV_EVENT_CLICKED, NULL);
}
// 创建注册界面
void create_register_screen() {
register_scr = lv_obj_create(NULL);
lv_obj_set_style_bg_color(register_scr, PRIMARY_COLOR, 0);
lv_obj_set_style_pad_all(register_scr, 20, 0);
// 标题
lv_obj_t *title = lv_label_create(register_scr);
lv_label_set_text(title, "注册新账号");
lv_obj_set_style_text_font(title, &lv_font_montserrat_28, 0);
lv_obj_set_style_text_color(title, HIGHLIGHT_COLOR, 0);
lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 30);
// 用户名标签
lv_obj_t *user_label = lv_label_create(register_scr);
lv_label_set_text(user_label, "用户名:");
lv_obj_set_style_text_color(user_label, TEXT_COLOR, 0);
lv_obj_align(user_label, LV_ALIGN_TOP_MID, -80, 100);
// 用户名输入框
lv_obj_t *user_ta = lv_textarea_create(register_scr);
lv_obj_set_size(user_ta, 200, 40);
lv_obj_align(user_ta, LV_ALIGN_TOP_MID, 40, 100);
lv_textarea_set_placeholder_text(user_ta, "输入用户名");
lv_obj_set_style_bg_color(user_ta, SECONDARY_COLOR, 0);
// 密码标签
lv_obj_t *pass_label = lv_label_create(register_scr);
lv_label_set_text(pass_label, "密码:");
lv_obj_set_style_text_color(pass_label, TEXT_COLOR, 0);
lv_obj_align(pass_label, LV_ALIGN_TOP_MID, -80, 160);
// 密码输入框
lv_obj_t *pass_ta = lv_textarea_create(register_scr);
lv_obj_set_size(pass_ta, 200, 40);
lv_obj_align(pass_ta, LV_ALIGN_TOP_MID, 40, 160);
lv_textarea_set_placeholder_text(pass_ta, "输入密码");
lv_textarea_set_password_mode(pass_ta, true);
lv_obj_set_style_bg_color(pass_ta, SECONDARY_COLOR, 0);
// 确认密码标签
lv_obj_t *confirm_label = lv_label_create(register_scr);
lv_label_set_text(confirm_label, "确认密码:");
lv_obj_set_style_text_color(confirm_label, TEXT_COLOR, 0);
lv_obj_align(confirm_label, LV_ALIGN_TOP_MID, -80, 220);
// 确认密码输入框
lv_obj_t *confirm_ta = lv_textarea_create(register_scr);
lv_obj_set_size(confirm_ta, 200, 40);
lv_obj_align(confirm_ta, LV_ALIGN_TOP_MID, 40, 220);
lv_textarea_set_placeholder_text(confirm_ta, "再次输入密码");
lv_textarea_set_password_mode(confirm_ta, true);
lv_obj_set_style_bg_color(confirm_ta, SECONDARY_COLOR, 0);
// 注册按钮
lv_obj_t *register_btn = lv_btn_create(register_scr);
lv_obj_set_size(register_btn, 180, 50);
lv_obj_align(register_btn, LV_ALIGN_TOP_MID, 0, 290);
lv_obj_set_style_bg_color(register_btn, HIGHLIGHT_COLOR, 0);
lv_obj_t *register_label = lv_label_create(register_btn);
lv_label_set_text(register_label, "注册");
lv_obj_center(register_label);
lv_obj_add_event_cb(register_btn, register_btn_cb, LV_EVENT_CLICKED, NULL);
// 返回登录按钮
lv_obj_t *back_btn = lv_btn_create(register_scr);
lv_obj_set_size(back_btn, 180, 40);
lv_obj_align(back_btn, LV_ALIGN_TOP_MID, 0, 350);
lv_obj_set_style_bg_color(back_btn, ACCENT_COLOR, 0);
lv_obj_t *back_label = lv_label_create(back_btn);
lv_label_set_text(back_label, "返回登录");
lv_obj_center(back_label);
lv_obj_add_event_cb(back_btn, back_to_login_cb, LV_EVENT_CLICKED, NULL);
}
// 创建主菜单
void create_main_menu() {
main_menu_scr = lv_obj_create(NULL);
lv_obj_set_style_bg_color(main_menu_scr, PRIMARY_COLOR, 0);
// 欢迎标题
lv_obj_t *welcome_label = lv_label_create(main_menu_scr);
lv_label_set_text_fmt(welcome_label, "欢迎, %s!", current_user.username);
lv_obj_set_style_text_font(welcome_label, &lv_font_montserrat_24, 0);
lv_obj_set_style_text_color(welcome_label, TEXT_COLOR, 0);
lv_obj_align(welcome_label, LV_ALIGN_TOP_MID, 0, 30);
// 最高分
lv_obj_t *score_label = lv_label_create(main_menu_scr);
lv_label_set_text_fmt(score_label, "最高分: %d", current_user.high_score);
lv_obj_set_style_text_color(score_label, HIGHLIGHT_COLOR, 0);
lv_obj_align(score_label, LV_ALIGN_TOP_MID, 0, 70);
// 开始游戏按钮
lv_obj_t *play_btn = lv_btn_create(main_menu_scr);
lv_obj_set_size(play_btn, 220, 60);
lv_obj_align(play_btn, LV_ALIGN_CENTER, 0, -50);
lv_obj_set_style_bg_color(play_btn, HIGHLIGHT_COLOR, 0);
lv_obj_t *play_label = lv_label_create(play_btn);
lv_label_set_text(play_label, "开始游戏");
lv_obj_center(play_label);
lv_obj_set_style_text_font(play_label, &lv_font_montserrat_24, 0);
lv_obj_add_event_cb(play_btn, play_game_cb, LV_EVENT_CLICKED, NULL);
// 排行榜按钮
lv_obj_t *scoreboard_btn = lv_btn_create(main_menu_scr);
lv_obj_set_size(scoreboard_btn, 220, 50);
lv_obj_align(scoreboard_btn, LV_ALIGN_CENTER, 0, 30);
lv_obj_set_style_bg_color(scoreboard_btn, ACCENT_COLOR, 0);
lv_obj_t *scoreboard_label = lv_label_create(scoreboard_btn);
lv_label_set_text(scoreboard_label, "排行榜");
lv_obj_center(scoreboard_label);
lv_obj_add_event_cb(scoreboard_btn, show_scoreboard_cb, LV_EVENT_CLICKED, NULL);
// 退出按钮
lv_obj_t *exit_btn = lv_btn_create(main_menu_scr);
lv_obj_set_size(exit_btn, 220, 50);
lv_obj_align(exit_btn, LV_ALIGN_CENTER, 0, 100);
lv_obj_set_style_bg_color(exit_btn, ACCENT_COLOR, 0);
lv_obj_t *exit_label = lv_label_create(exit_btn);
lv_label_set_text(exit_label, "退出登录");
lv_obj_center(exit_label);
lv_obj_add_event_cb(exit_btn, logout_cb, LV_EVENT_CLICKED, NULL);
}
// 创建游戏界面
void create_game_screen() {
game_scr = lv_obj_create(NULL);
lv_obj_set_style_bg_color(game_scr, PRIMARY_COLOR, 0);
// 分数显示
score_label_game = lv_label_create(game_scr); // 使用全局变量
lv_label_set_text(score_label_game, "分数: 0");
// 修复:全部使用 score_label_game
lv_obj_set_style_text_font(score_label_game, &lv_font_montserrat_20, 0);
lv_obj_set_style_text_color(score_label_game, TEXT_COLOR, 0);
lv_obj_align(score_label_game, LV_ALIGN_TOP_LEFT, 10, 10);
// 游戏区域容器
game_container = lv_obj_create(game_scr); // 赋值给全局变量
lv_obj_set_size(game_container, 300, 300);
lv_obj_align(game_container, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_style_bg_color(game_container, PRIMARY_COLOR, 0);
lv_obj_set_style_border_width(game_container, 0, 0);
// 键盘输入支持
lv_obj_add_flag(game_container, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_flag(game_container, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_add_event_cb(game_container, game_input_cb, LV_EVENT_KEY, NULL);
lv_group_t *group = lv_group_create();
lv_group_add_obj(group, game_container);
lv_group_focus_obj(game_container);
}
// 创建排行榜界面
void create_scoreboard_screen() {
scoreboard_scr = lv_obj_create(NULL);
lv_obj_set_style_bg_color(scoreboard_scr, PRIMARY_COLOR, 0);
// 标题
lv_obj_t *title = lv_label_create(scoreboard_scr);
lv_label_set_text(title, "玩家排行榜");
lv_obj_set_style_text_font(title, &lv_font_montserrat_28, 0);
lv_obj_set_style_text_color(title, HIGHLIGHT_COLOR, 0);
lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 20);
// 排行榜容器
lv_obj_t *container = lv_obj_create(scoreboard_scr);
lv_obj_set_size(container, 300, 350);
lv_obj_align(container, LV_ALIGN_CENTER, 0, 20);
lv_obj_set_style_bg_color(container, SECONDARY_COLOR, 0);
lv_obj_set_style_border_width(container, 0, 0);
lv_obj_set_flex_flow(container, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(container, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
// 表头
lv_obj_t *header = lv_obj_create(container);
lv_obj_set_size(header, lv_pct(100), 40);
lv_obj_set_style_bg_color(header, ACCENT_COLOR, 0);
lv_obj_set_style_border_width(header, 0, 0);
lv_obj_set_flex_flow(header, LV_FLEX_FLOW_ROW);
lv_obj_t *rank_label = lv_label_create(header);
lv_label_set_text(rank_label, "排名");
lv_obj_set_style_text_font(rank_label, &lv_font_montserrat_18, 0);
lv_obj_set_width(rank_label, 60);
lv_obj_set_style_pad_left(rank_label, 10, 0);
lv_obj_t *name_label = lv_label_create(header);
lv_label_set_text(name_label, "玩家");
lv_obj_set_style_text_font(name_label, &lv_font_montserrat_18, 0);
lv_obj_set_width(name_label, 150);
lv_obj_t *score_label = lv_label_create(header);
lv_label_set_text(score_label, "最高分");
lv_obj_set_style_text_font(score_label, &lv_font_montserrat_18, 0);
lv_obj_set_width(score_label, 80);
// 添加玩家分数
for (int i = 0; i < user_count && i < 5; i++) {
lv_obj_t *row = lv_obj_create(container);
lv_obj_set_size(row, lv_pct(100), 50);
lv_obj_set_style_border_width(row, 0, 0);
lv_obj_set_flex_flow(row, LV_FLEX_FLOW_ROW);
lv_obj_t *rank = lv_label_create(row);
lv_label_set_text_fmt(rank, "%d", i+1);
lv_obj_set_style_text_font(rank, &lv_font_montserrat_18, 0);
lv_obj_set_width(rank, 60);
lv_obj_set_style_pad_left(rank, 10, 0);
lv_obj_t *name = lv_label_create(row);
lv_label_set_text(name, users[i].username);
lv_obj_set_style_text_font(name, &lv_font_montserrat_18, 0);
lv_obj_set_width(name, 150);
lv_obj_t *score = lv_label_create(row);
lv_label_set_text_fmt(score, "%d", users[i].high_score);
lv_obj_set_style_text_font(score, &lv_font_montserrat_18, 0);
lv_obj_set_width(score, 80);
// 高亮当前用户
if (strcmp(users[i].username, current_user.username) == 0) {
lv_obj_set_style_bg_color(row, lv_color_hex(0x4a5568), 0);
}
}
// 返回按钮
lv_obj_t *back_btn = lv_btn_create(scoreboard_scr);
lv_obj_set_size(back_btn, 150, 50);
lv_obj_align(back_btn, LV_ALIGN_BOTTOM_MID, 0, -20);
lv_obj_set_style_bg_color(back_btn, HIGHLIGHT_COLOR, 0);
lv_obj_t *back_label = lv_label_create(back_btn);
lv_label_set_text(back_label, "返回");
lv_obj_center(back_label);
lv_obj_add_event_cb(back_btn, back_to_menu_cb, LV_EVENT_CLICKED, NULL);
}
// 主函数
int main(void) {
// 初始化LVGL
lv_init();
// 初始化显示驱动和输入设备
// (根据GEC6818开发板具体实现)
// 加载用户数据
load_users();
// 创建各个界面
create_login_screen();
create_register_screen();
create_main_menu();
create_game_screen();
create_scoreboard_screen();
// 设置初始屏幕
lv_disp_load_scr(login_scr);
// 主循环
while (1) {
lv_timer_handler();
usleep(5000);
}
return 0;
}