#include "common.h"
#include "bmp.h"
int g_lcd_width = 0;
int g_lcd_height = 0;
int g_lcd_bpp = 0;
/*
get_bmpfiles_index:根据你要显示的数字(2,4,8,16,...)
返回你对应的文件名的下标
返回值:
返回 x对应的文件名在数组bmpfiles的下标
*/
int get_bmpfiles_index(int x)
{
int exp;
for(exp=0; x!=0; x >>= 1, exp++);
return exp-2;
}
//棋盘矩阵
int matrix[BOARDSIZE][BOARDSIZE] =
{
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0
};
/*
get_zero_num:求棋盘矩阵里面有多少个0
返回值:
返回棋盘矩阵中0的个数
*/
int get_zero_num(void)
{
int z = 0;//棋盘矩阵中元素为0的个数
int i, j;
//BOARDSIZE = 4,整个棋盘大小为BOARDSIZE*BOARDSIZE
for (i = 0; i < BOARDSIZE; i++)
{
for (j = 0; j < BOARDSIZE; j++)
{
if (matrix[i][j] == 0)
{
z++;
}
}
}
return z;
}
/*
set_matrix:给棋盘矩阵第z个0的位置,填充一个
值s
*/
void set_matrix(int z, int s)
{
int i, j;
int k = 0 ;//0的个数
for (i = 0; i < BOARDSIZE ;i++)
{
for (j = 0; j < BOARDSIZE; j++)
{
if (matrix[i][j] == 0)
{
k++;
if (k == z)
{
matrix[i][j] = s;
return ;
}
}
}
}
}
/*
lcd_draw_point:在屏幕坐为(x, y)这个点,填充color
这个颜色值。
@x: x轴坐标
@y: y轴坐标
@color: 要填充的辨色值
返回值:
无返回值。
*/
void lcd_draw_point(int x, int y, int color)
{
int *p = plcd;
if (x >= 0 && x < g_lcd_width && y>=0 && y < g_lcd_height)
{
*(p + g_lcd_width *y + x) = color;
}
}
/*
lcd_draw_dect: 在屏幕上画一个矩形,并且用
color这种颜色填充该矩形。
@x0:该矩形的左上角的那个点x轴坐标
@y0:该矩形的左上角的那个点y轴坐标
@w:该矩形的宽
@h:该矩形的高
@color:该矩形要填充的色值
返回值:
无返回值。
*/
void lcd_draw_dect(int x0, int y0, int w, int h, int color)
{
if (x0 < 0 || y0 < 0 || w < 0 || h <0)
return;
if ((x0 + w > g_lcd_width) || (y0+h) > g_lcd_height)
{
return;
}
int x, y;
for (y = y0; y < y0 + h; y++)
{
for (x = x0; x < x0 + w; x++)
{
lcd_draw_point(x, y, color);
}
}
}
/*
draw_bmp:把一张bmp图片显示在屏幕上特定的位置
@bmpfile:要显示的bmp图片的文件名
@x0: 在屏幕上显示的左上角顶点的x轴坐标
@y0: 在屏幕上显示的左上角顶点的y轴坐标
返回值:
无返回值.
*/
void draw_bmp(const char *bmpfile, int x0, int y0)
{
int fd;
int x, y;
fd = open(bmpfile, O_RDONLY);
if (fd == -1)
{
perror("open bmpfile error:");
return ;
}
struct header head;
struct info info;
read(fd, &head, sizeof(head));
read(fd, &info, sizeof(info));
char *bmpdata = calloc(1, head.size-head.offbytes);
read(fd, bmpdata, info.width * info.height * info.bit_count/8);
close(fd);
int i = 0;
for (y = 0; y < info.height; y++)
{
unsigned char r,g ,b;
int color;
for (x = 0; x < info.width; x++)
{
b = bmpdata[i++];
g = bmpdata[i++];
r = bmpdata[i++];
color = (r << 16) | (g << 8) | b;
lcd_draw_point(x0+ x, y0 + (info.height -1 - y) ,color);
}
}
free(bmpdata);
}
/*
draw_matrix:把棋盘矩阵在屏幕上显示出来
*/
void draw_matrix(void)
{
int i, j;
for (i = 0; i < BOARDSIZE; i++)
{
for (j = 0; j < BOARDSIZE;j++)
{
int x0, y0;
x0 = 185;//棋盘矩阵左上角那个点的x轴坐标
y0 = 25;//棋盘矩阵左上角那个点的y轴坐标
if (matrix[i][j] == 0)
{
lcd_draw_dect(x0+j*110, y0+i*110,
100 , 100,
0xb4eeb4);//如果此处元素的值为0,那么
//就显示
}
else
{
int f_index = get_bmpfiles_index(matrix[i][j]);
draw_bmp(bmpfiles[f_index],
x0+j*110, y0+i*110);
}
}
}
}
/*
init_matrix:初始化棋盘矩阵
在任意x个位置,填充x个数字(2,4,8)
*/
void init_matrix(void)
{
//规则x >= 1,x <= 3
int x = (random() % 3) + 1;
int i;
/*
step1:随机产生x个数字,并填充到棋盘矩阵中去
*/
for(i = 0; i < x; i++)
{
int pos = (random() % get_zero_num()) + 1;
int s[] = {2, 4, 4, 2};
int s_i = (random() % 3);
set_matrix(pos, s[s_i]);
}
/*
step 2: 绘制棋盘矩阵
*/
draw_matrix();
}
/*
rand1_matrix:移动之后随机产生一个数字填充到
任意一个0的位置上
*/
void rand_matrix()
{
int pos = (random() % get_zero_num()) + 1;
int s[] = {2, 4, 8, 2};
int s_i = (random() % 4);
set_matrix(pos, s[s_i]);
draw_matrix();
}
/*
get_finger_direction:获取手指在触摸屏上面的滑动方向
返回值:
MOVE_LEFT:手指向左移动
MOVE_RIGHT:手指向右移动
MOVE_UP:手指向上移动
MOVE_DOWN:手指向下移动
*/
int get_finger_direction()
{
int ret;
int fd = open("/dev/input/event0", O_RDONLY);
if (fd == -1)
{
perror("open event failed:");
return -1;
}
struct input_event ev;
int x1 = -1; //在滑动过程中第一个点的x轴坐标
int x2; //在滑动过程中最后一个点的x轴坐标
int y1 = -1;//在滑动过程中第一个点的y轴坐标
int y2;//在滑动过程中最后一个点的y轴坐标
while (1)
{
ret = read(fd, &ev, sizeof(ev));
if(ret != sizeof(ev))
{
continue;
}
if (ev.type == EV_ABS && ev.code == ABS_X)//是x轴坐标
{
if (x1 == -1)//x1重来没有赋过值,那么肯定是第一个点
{
x1 = ev.value;
}
x2 = ev.value;
}
if (ev.type == EV_ABS && ev.code == ABS_Y)//是y轴坐标
{
if ( y1 == -1)//y1重来没有赋过值,那么肯定是第一个点
{
y1 = ev.value;
}
y2 = ev.value;
}
if (ev.type == EV_KEY && ev.code == BTN_TOUCH //手指弹起,再计算滑动方向
&& ev.value == 0)//触摸屏压力值为0, press up
{
int x_cz;//x轴的位移
int y_cz;//y轴的位移
int abs_x;
int abs_y;
x_cz = x2 - x1;
y_cz = y2 - y1;
abs_x = abs(x_cz);
abs_y = abs(y_cz);
if((x_cz > 30) && (abs_x > 2 * abs_y))
{
close(fd);
return MOVE_RIGHT;
}
else if((x_cz < -30) && (abs_x > 2 * abs_y))
{
close(fd);
return MOVE_LEFT;
}
else if((y_cz > 30) && (abs_y > 2 * abs_x))
{
close(fd);
return MOVE_UP;
}
else if((y_cz < -30) && (abs_y > 2 * abs_x))
{
close(fd);
return MOVE_DOWN;
}
else
{
x1 = y1 = -1;
continue;
}
}
}
close(fd);
}
/*
fin_left:手指左划后棋子移动及合并的方式
*/
void fin_left()
{
int i, j;//i为矩阵行下标,j为矩阵列下标
int value, save_zero;
for(i = 0; i < BOARDSIZE; i++)
{
value = 0;
save_zero= 0;
for(j = 0; j < BOARDSIZE ; j++)
{
if (matrix[i][j] == 0)
continue;
if (value == 0)
value = matrix[i][j];
else
{
if (value == matrix[i][j])
{
matrix[i][save_zero++] = value * 2;
value = 0;
} else {
matrix[i][save_zero++] = value;
value = matrix[i][j];
}
}
matrix[i][j] = 0;
}
if (value != 0)
matrix[i][save_zero] = value;
}
}
/*
手指上划后棋子移动及合并的方式
*/
void fin_right()
{
}
/*
fin_up:手指上划后棋子移动及合并的方式
*/
void fin_up()
{
}
//draw_matrix();
/*
fin_down:手指上划后棋子移动及合并的方式
*/
void fin_down()
{
}
/*
判断是否还能移动
*/
bool is_game_over(void)
{
int i, j;
if(get_zero_num() != 0)
{
return false;
}
for(i = 0; i < BOARDSIZE; i++)
{
for(j = 0; j < BOARDSIZE ; j++)
{
if (j != BOARDSIZE -1)
{
if (matrix[i][j] == matrix[i][j+1])
{
return false;
}
}
基于GEC6818的2048小游戏代码

"基于GEC6818的2048小游戏代码"涉及的主要知识点是游戏开发、嵌入式系统以及编程语言的应用。GEC6818是一款微控制器,通常用于嵌入式系统,其在游戏开发中的应用展示了硬件与软件的紧密集成。
"基于GEC6818的2048小游戏代码"表明这是一个使用GEC6818微控制器实现的2048游戏的源代码。2048是一款流行的数字拼图游戏,玩家通过上下左右滑动屏幕来合并数字,目标是达到2048这个数字。游戏的实现涉及到算法设计、用户界面交互以及硬件驱动程序的编写。
"软件/插件"提示我们关注的是软件层面的内容,特别是这个项目可能包含的软件开发过程、编程技巧和可能存在的软件优化策略。
【文件名称列表】"2048-master"通常表示这是项目的主分支或者源码仓库,可能包含了项目的所有源文件、编译脚本、配置文件等。在这样的代码库中,我们可以期待找到游戏逻辑的实现、界面布局、用户输入处理、得分计算、游戏状态管理等相关代码。
详细说明:
1. **GEC6818微控制器**:这是一种低功耗、高性能的微处理器,通常用于嵌入式设备,具有处理能力和内存资源,适合运行小型游戏。
2. **游戏开发**:2048的实现需要理解游戏规则,设计合适的算法来处理数字的合并、生成和消除,同时还需要设计游戏逻辑,如游戏结束条件、得分计算等。
3. **编程语言**:GEC6818可能支持C或汇编语言进行编程,因此开发者需要熟悉这些语言,并能有效地利用它们实现游戏功能。
4. **用户界面**:在嵌入式系统上构建用户界面可能需要利用LCD屏幕和触摸输入,开发者需要编写驱动程序来处理这些输入和显示。
5. **内存管理**:在有限的硬件资源下,优化内存使用是关键。开发者需要合理地分配和释放内存,避免内存泄漏,确保游戏流畅运行。
6. **编译和调试**:在GEC6818这样的嵌入式平台上,代码编译和调试可能需要专用的工具链,如交叉编译器和JTAG调试器。
7. **性能优化**:为了在有限的硬件资源上提供良好的游戏体验,可能需要对算法和代码进行优化,减少计算量,提高响应速度。
8. **版本控制**:"master"分支可能意味着使用了Git进行版本控制,这有助于团队协作和代码维护。
9. **软件工程实践**:项目可能包含了README文件、Makefile等,这些都是软件开发中常见的文档和构建工具,帮助理解项目结构和构建流程。
整体来看,这个项目提供了学习嵌入式系统编程、微控制器应用开发以及2048游戏逻辑实现的实例,对于希望深入理解这些领域的开发者来说,是一个宝贵的资源。

我是刘在野
- 粉丝: 37
- 资源: 1
最新资源
- 基于Comsol三次谐波的物理现象,大子刊NC复现报告:手性BIC超表面下的远场偏振与手性透射图示分析-电场、二维能带图解读及Q因子图展现所见即所得的光学效应 ,平面手征超表面研究:连续介质中的三次
- 人工智能&深度学习:LSTM 文本分类实战 - 基于 THUCNews 数据集的 Python 源码资源(源码+数据集+说明)
- MATLAB程序专为非全向移动机器人设计的扩展卡尔曼滤波(EKF)数据处理工具箱,精准融合ADS-B与GPS数据,高效状态估计解决方案,MATLAB程序优化:非全向移动机器人EKF状态估计与飞行数据处
- 简易图像处理软件,与PS工具类似
- iOS swift工具类使用
- AR.js 完整资源包,可以完整的引用
- 西门子PLC与三台欧姆龙温控器通讯程序:实现温度控制及监控,支持轮询通讯与故障恢复功能,PLC与触摸屏集成设置温度,支持扩展及详细注释 ,西门子PLC与三台欧姆龙温控器通讯程序:实现温度控制及监控,支
- 这份文档的内容并非技术性文章,而是一段歌词片段,无法按照技术文档的要求生成标准标题 若需要总结,该文档包含了一段歌词,表达了关于期待与未知相遇的主题 但由于内容不足以及非技术性质,无法提供更详细总
- .safetensors转换成.GGUF所需工具cmake
- 三相光伏并网逆变器仿真:PV升压逆变并网系统中的电压电流双环控制与SVPWM策略研究,三相光伏并网逆变器仿真研究:PV光伏boost升压逆变并网系统之电压外环与电流内环SVPWM控制机制探讨,三相光伏
- 《基于信捷PLC的7轴伺服插补联动设备的设计与实现-喷涂机程序与牵引示教功能》,信捷PLC驱动7轴伺服插补联动设备-XD5-48T6-E牵引示教功能与喷涂机程序解析,信捷PLC7轴伺服插补联动XD
- MPC模型预测控制:从原理到代码实现,涵盖双积分、倒立摆、车辆运动学与动力学跟踪控制系统的详细文档与编程实践,MPC模型预测控制原理到代码实现:双积分、倒立摆、车辆运动学与动力学跟踪控制案例详解,mp
- 车路协同C-V2X港口应用分析
- gradle-6.1.1.zip资源下载
- 用dockerfile打包带有nginx-monitor-vts模块的nginx镜像
- .safetensors转换成.GGUF所需工具ccache