stm32f103ZET6实现2048小游戏(LVGL)保姆级教程(三)(代码实现)
·
代码实现
详细文件已上传资源
下面先是2048.c文件
#include "2048.h"
uint8_t p=0,flag=0,cnt=2;
uint8_t sz[WIDTH][WIDTH] = { 0 };
lv_obj_t* sz_del[WIDTH][WIDTH]={0};
lv_obj_t* p_score = NULL;
uint16_t score=0;
lv_obj_t* end_main = NULL;
void game_main() {
lv_obj_t* bg = lv_obj_create(lv_scr_act());
lv_obj_set_style_bg_color(lv_scr_act(),lv_color_hex(0xf8f8f0), LV_STATE_DEFAULT);
lv_obj_set_size(bg, 200, 200);
lv_obj_align(bg, LV_ALIGN_CENTER,0,25);
lv_obj_set_style_bg_color(bg, lv_color_hex(0xb2a296), LV_STATE_DEFAULT);
lv_obj_clear_flag(bg, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_add_event_cb(lv_scr_act(), event_cb, LV_EVENT_GESTURE, bg);
static lv_style_t font_style;
lv_style_init(&font_style);
lv_style_set_text_font(&font_style, &lv_font_montserrat_16);
lv_obj_t* label_2048 = lv_label_create(lv_scr_act());
lv_obj_set_size(label_2048,80, 50);
lv_label_set_recolor(label_2048, true);
lv_label_set_text(label_2048, "#655949 2048#");
lv_obj_add_style(label_2048, &font_style, LV_STATE_DEFAULT);
lv_obj_align(label_2048, LV_ALIGN_TOP_LEFT,20,22);
lv_obj_t* btn = lv_obj_create(lv_scr_act());
lv_obj_t* label1 = lv_label_create(btn);
lv_obj_set_size(btn, 50, 50);
lv_obj_set_style_bg_color(btn, lv_color_hex(0xb8afa0), LV_STATE_DEFAULT);
//lv_obj_set_style_radius(btn, 3, LV_STATE_DEFAULT);
//lv_obj_set_style_opa(btn, LV_OPA_0, LV_STATE_DEFAULT);
lv_obj_set_style_outline_width(btn,0, LV_STATE_DEFAULT);
lv_label_set_recolor(label1, true);
lv_label_set_text(label1, "#f0e4d8 New\n#f0e4d8 Game#");
lv_obj_align(label1, LV_ALIGN_TOP_LEFT, -10, -10);
lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, bg);
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, 160, 10);
lv_obj_clear_flag(btn, LV_OBJ_FLAG_SCROLLABLE);
rands(2, 1);
show_mb(bg);
}
bool detect_end() {
const short a[4][2] = { 0,1,0,-1,1,0,-1,0 };
for (short i = 0; i < WIDTH; i++) {
for (short j = 0; j < WIDTH; j++) {
for (short z = 0; z < 4; z++) {
if (i + a[z][0] < WIDTH && j + a[z][1] < WIDTH && i + a[z][0] >= 0 && j + a[z][1] >= 0) {
if (sz[i][j] == sz[i + a[z][0]][j + a[z][1]]) {
return 0;
}
}
}
}
}
return 1;
}
void event_cb(lv_event_t* e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t* bg = (lv_obj_t*)e->user_data;
if (code == LV_EVENT_GESTURE) {
lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act());
if (dir == LV_DIR_TOP) {
bg_hd(UP, bg);
}
else if (dir == LV_DIR_BOTTOM) {
bg_hd(DOWN, bg);
}
else if (dir == LV_DIR_LEFT) {
bg_hd(LEFT, bg);
}
else if (dir == LV_DIR_RIGHT) {
bg_hd(RIGHT, bg);
}
}
if (code == LV_EVENT_CLICKED) {
game_init(bg);
if(end_main!=NULL){
lv_obj_del(end_main);
end_main=NULL;
lv_obj_clear_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE); // 清除标志
lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_TRANSP, 0); // 设置透明度
}
}
}
void game_init(lv_obj_t* bg) {
for (uint8_t i = 0; i < WIDTH; i++) {
for (uint8_t j = 0; j < WIDTH; j++) {
sz[i][j] = 0;
}
}
score = 0;
rands(2, score);
cnt = 2;
show_mb(bg);
}
void show_mb(lv_obj_t* bg) {
uint8_t margin_x = 0, margin_y = 0;
for (uint8_t i = 0; i < WIDTH; i++) {
margin_x = 0;
for (uint8_t j = 0; j < WIDTH; j++) {
//printf("%d ", sz[i][j]);
show_color_block(sz[i][j], margin_x + j * BLOCKH, margin_y + i * BLOCKH, bg, i, j);
margin_x += 5;
}
margin_y += 5;
//printf("\n");
}
}
void show_color_block(uint8_t n, uint16_t px, uint16_t py, lv_obj_t* bg, uint8_t i, uint8_t j) {
if (sz_del[i][j] != NULL)lv_obj_del(sz_del[i][j]);
if(p_score!=NULL)lv_obj_del(p_score);
lv_obj_t* block = lv_obj_create(bg);
sz_del[i][j] = block;
lv_obj_clear_flag(bg, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_size(block, 40, 40);
lv_obj_set_style_border_width(block, LV_BORDER_SIDE_NONE, LV_STATE_DEFAULT);
lv_obj_t* score_block = lv_obj_create(lv_scr_act());
lv_obj_set_size(score_block, 50, 50);
lv_obj_align(score_block,LV_ALIGN_TOP_LEFT,90,10);
lv_obj_set_style_bg_color(score_block,lv_color_hex(0xb8afa0), LV_STATE_DEFAULT);
lv_obj_t* score_l = lv_label_create(score_block);
static lv_style_t font_style;
lv_style_init(&font_style);
lv_style_set_text_font(&font_style, &lv_font_montserrat_12);
lv_obj_add_style(score_l, &font_style, LV_STATE_DEFAULT);
p_score = score_block;
lv_label_set_recolor(score_l, true);
lv_label_set_text(score_l, "#f0e4d8 SCORE#");
lv_obj_clear_flag(score_block, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_align(score_l, LV_ALIGN_TOP_MID, 0, -10);
lv_obj_t* score_s = lv_label_create(score_block);
static lv_style_t font_style1;
lv_style_init(&font_style1);
lv_style_set_text_font(&font_style1, &lv_font_montserrat_16);
lv_label_set_recolor(score_s, true);
lv_label_set_text_fmt(score_s, "#ffffff %d#",score);
lv_obj_add_style(score_s, &font_style1, LV_STATE_DEFAULT);
lv_obj_align(score_s, LV_ALIGN_BOTTOM_MID, 0, 5);
if (n != 0) {
lv_obj_t* num_l = lv_label_create(block);
lv_obj_clear_flag(block, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_style_border_width(num_l, LV_BORDER_SIDE_NONE, LV_STATE_DEFAULT);
lv_label_set_text_fmt(num_l, "%d", (uint16_t)pow(2, n));
lv_obj_center(num_l);
}
switch (n) {
case 0:
lv_obj_set_style_bg_color(block, lv_color_hex(0xc6b8ab), LV_STATE_DEFAULT); break;
case 1:
lv_obj_set_style_bg_color(block, lv_color_hex(0xece2d8), LV_STATE_DEFAULT); break;
case 2:
lv_obj_set_style_bg_color(block, lv_color_hex(0xeadec6), LV_STATE_DEFAULT); break;
case 3:
lv_obj_set_style_bg_color(block, lv_color_hex(0xf0af76), LV_STATE_DEFAULT); break;
case 4:
lv_obj_set_style_bg_color(block, lv_color_hex(0xec8d54), LV_STATE_DEFAULT); break;
case 5:
lv_obj_set_style_bg_color(block, lv_color_hex(0xf67c5f), LV_STATE_DEFAULT); break;
case 6:
lv_obj_set_style_bg_color(block, lv_color_hex(0xea5937), LV_STATE_DEFAULT); break;
case 7:
lv_obj_set_style_bg_color(block, lv_color_hex(0xf2d76b), LV_STATE_DEFAULT); break;
case 8:
lv_obj_set_style_bg_color(block, lv_color_hex(0xf1d04b), LV_STATE_DEFAULT); break;
case 9:
lv_obj_set_style_bg_color(block, lv_color_hex(0xe4c02a), LV_STATE_DEFAULT); break;
case 10:
lv_obj_set_style_bg_color(block, lv_color_hex(0xdcb82a), LV_STATE_DEFAULT); break;
case 11:
lv_obj_set_style_bg_color(block, lv_color_hex(0xd4b02a), LV_STATE_DEFAULT); break;
}
lv_obj_align(block, LV_ALIGN_TOP_LEFT, px, py);
}
void rands(int n, uint16_t s) {
uint8_t x, y;
while (n > 0) {
srand(ms);
x = rand() % WIDTH;
srand(ms);
y = rand() % WIDTH;
if (sz[x][y] == 0) {
if (s < LIMIT1) {
sz[x][y] = 1;
}
else if (s >= LIMIT1 && s < LIMIT2) {
srand(ms);
uint8_t c = rand() % 4;
if (c == 0) {
sz[x][y] = 1;
}
else{
sz[x][y] = 2;
}
}
else if (s >= LIMIT2 && s < LIMIT3) {
srand(ms);
uint8_t c = rand() % 3;
if (c == 0) {
sz[x][y] = 1;
}
else {
sz[x][y] = 2;
}
}
else if (s >= LIMIT3) {
srand(ms);
uint8_t c = rand() % 2;
if (c == 0) {
sz[x][y] = 1;
}
else {
sz[x][y] = 2;
}
}
}
n -= 1;
}
}
void bg_hd(uint8_t toward, lv_obj_t* bg) {
uint8_t flag, flag_t = 0; //不连续合并
if (toward == UP) {
for (short j = 0; j < WIDTH; j++) {
flag = 1;
for (short i = 1; i < WIDTH; i++) {
for (short z = i; z > 0; z--) {
if (sz[z - 1][j] == sz[z][j] && sz[z][j] != 0 && flag) {
sz[z - 1][j] += 1;
cnt--;
score += (uint16_t)pow(2, sz[z - 1][j]);
sz[z][j] = 0;
flag = 0;
flag_t = 1;
if (flag_t != 1)flag_t = 1;
}
else if (sz[z - 1][j] == 0 && sz[z][j] != 0) {
sz[z - 1][j] = sz[z][j];
sz[z][j] = 0;
if (flag_t != 1)flag_t = 1;
}
}
}
}
}
if (toward == DOWN) {
for (short j = 0; j < WIDTH; j++) {
flag = 1;
for (short i = WIDTH - 2; i >= 0; i--) {
for (short z = i; z < WIDTH - 1; z++) {
if (sz[z + 1][j] == sz[z][j] && sz[z][j] != 0 && flag) {
sz[z + 1][j] += 1;
cnt--;
score += (uint16_t)pow(2, sz[z + 1][j]);
sz[z][j] = 0;
flag = 0;
if (flag_t != 1)flag_t = 1;
}
else if (sz[z + 1][j] == 0 && sz[z][j] != 0) {
sz[z + 1][j] = sz[z][j];
sz[z][j] = 0;
if (flag_t != 1)flag_t = 1;
}
}
}
}
}
if (toward == LEFT) {
for (short j = 0; j < WIDTH; j++) {
flag = 1;
for (short i = 1; i < WIDTH; i++) {
for (short z = i; z > 0; z--) {
if (sz[j][z - 1] == sz[j][z] && sz[j][z] != 0 && flag) {
sz[j][z - 1] += 1;
cnt--;
score += (uint16_t)pow(2, sz[j][z - 1]);
sz[j][z] = 0;
flag = 0;
if (flag_t != 1)flag_t = 1;
}
else if (sz[j][z - 1] == 0 && sz[j][z] != 0) {
sz[j][z - 1] = sz[j][z];
sz[j][z] = 0;
if (flag_t != 1)flag_t = 1;
}
}
}
}
}
if (toward == RIGHT) {
for (short j = 0; j < WIDTH; j++) {
flag = 1;
for (short i = WIDTH - 2; i >= 0; i--) {
for (short z = i; z < WIDTH - 1; z++) {
if (sz[j][z + 1] == sz[j][z] && sz[j][z] != 0 && flag) {
sz[j][z + 1] += 1;
cnt--;
score += (uint16_t)pow(2, sz[j][z + 1]);
sz[j][z] = 0;
flag = 0;
if (flag_t != 1)flag_t = 1;
}
else if (sz[j][z + 1] == 0 && sz[j][z] != 0) {
sz[j][z + 1] = sz[j][z];
sz[j][z] = 0;
if (flag_t != 1)flag_t = 1;
}
}
}
}
}
if (flag_t == 1) {
rands(N, score);
cnt += N;
show_mb(bg);
}
if (cnt == WIDTH * WIDTH) {
if (detect_end()) {
end_ami(bg);
}
}
}
void end_ami(lv_obj_t* bg) {
lv_obj_add_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE);
end_main = lv_obj_create(lv_layer_top());
lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_50, 0); // 设置对象透明度
lv_obj_set_style_bg_color(lv_layer_top(), lv_palette_main(LV_PALETTE_GREY), 0); //灰色背景
lv_obj_set_style_bg_color(end_main, lv_color_hex(0xb2a296), LV_STATE_DEFAULT);
lv_obj_set_size(end_main, 140, 150);
lv_obj_clear_flag(end_main, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_align(end_main, LV_ALIGN_CENTER);
lv_obj_t* score_l = lv_label_create(end_main);
lv_label_set_recolor(score_l, true);
lv_label_set_text(score_l, "#000000 SCORE#");
lv_obj_align(score_l, LV_ALIGN_TOP_MID, 0, 10);
lv_obj_t* score_s = lv_label_create(end_main);
static lv_style_t font_style1;
lv_style_init(&font_style1);
lv_label_set_recolor(score_s, true);
lv_label_set_text_fmt(score_s, "#000000 %d#",score);
lv_obj_add_style(score_s, &font_style1, LV_STATE_DEFAULT);
lv_obj_align(score_s, LV_ALIGN_BOTTOM_MID, 0, -70);
lv_obj_t* regame = lv_obj_create(end_main);
lv_obj_set_size(regame, 100, 40);
lv_obj_set_style_bg_color(regame,lv_color_hex(0x1E90FF), LV_STATE_DEFAULT);
lv_obj_align(regame,LV_ALIGN_BOTTOM_MID, 0, -10);
lv_obj_t* retry = lv_label_create(regame);
lv_label_set_recolor(retry, true);
lv_label_set_text(retry, "#000000 RETRY#");
lv_obj_clear_flag(regame, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_align(retry, LV_ALIGN_CENTER,0,0);
lv_obj_add_event_cb(regame, event_cb, LV_EVENT_CLICKED, bg);
}
2048.h文件
#ifndef __2048_H
#define __2048_H
#include "main.h"
#include "tim.h"
#include "math.h"
#include "lcd.h"
#include "lvgl.h"
#include "lv_port_disp_template.h"
#include "lv_port_indev_template.h"
#include <stdio.h>
#include <stdlib.h>
#define LIMIT1 3000
#define LIMIT2 6000
#define LIMIT3 10000
#define BLOCKH 40
#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
#define WIDTH 4
#define N 1
void event_cb(lv_event_t* e);
void show_color_block(uint8_t n,uint16_t px,uint16_t py,lv_obj_t* bg,uint8_t i,uint8_t j);
void show_mb(lv_obj_t* bg);
void bg_hd(uint8_t toward,lv_obj_t* bg);
void rands(int n, uint16_t s);
void game_init(lv_obj_t* bg);
_Bool detect_end();
void game_main();
void end_ami();
#endif
最后在main.c中调用game_main()即可。
更多推荐

所有评论(0)