TA的每日心情 | 开心 2022-8-16 09:50 |
---|
签到天数: 16 天 连续签到: 1 天 [LV.4]偶尔看看III
|
Blazar β-Board板子是边学边玩的开发版,板子设计也是游戏机的样子,怎么能没有游戏呢,搞了好几天终于把2048的游戏搞上来了^_^
先上程序链接https://share.weiyun.com/4814054857023e73b17a0b85b...第一次用qq微云,不知道多会失效,如果失效联系我就好Q308229423
图形菜单包括gui的在我之前的经验中https://jingyan.eeboard.com/article/75711
单独2048的程序在下边
首先2048游戏要实现那必须先要有16个格子中有数据,各个数据会变化,所以我们就先定义一个16大小的数组int box[16];
当然为了方便观察也可以定义成4*4的数组,这项更形象一些。
程序的主函数是game();主函数调用game即可实现功能,我们来看这个函数都干了什么,game开始到第48行就是画线 写一些说明,因为OLED分辨率为128*64的,然后2048当然方正点好看了,所以用64*64加上画线占用的一个格子里最多显示两个数字了,要实现2048还要显示1024,512,128的数据,都想放弃的时候看到 了键盘上的小符号!@#¥%^&*(),可以用他们来代替这些显示不了的,在右边标注出来。
[img]file:///C:UserslenovoAppDataRoamingTencentQQTempJIGK}$D[F2HV%AGXD2W)CH4.png[/img] 之后就进入了一个死循环while(1)从50行到107行,这个循环中就是重新打印数据因为数据是随着上下左右按键变化的,
key=key_return();这个在之前的经验分享中有介绍,是个阻塞的函数,没有按键一直等,有按键的话就返回按键的值,然后就进入了核心
update_box(box,key);这个是更新box【16】数组中的数据的,就是在这里把数据更新的然后在函数内部有个全局变量用来表示游戏的分数和完成或失败的标志。这个函数之后就进行退出按键的判断和ok键的判断,然后返回回去刷新屏幕,更新16个的数据的值。
我们知道在2048中每次按下按键后比如说像→,每一行相同的会叠加,不同的依次按顺序移动到最右边,这里为方便理解变成4*4的矩阵
int box[4][4] = {0};
int i, j;
int deep;
int mline = 0;
for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
{
box[j] = oned_box[i*4+j];
}
}
if(dir == KEY_DOWN){
for(i=0; i<4; i++){ // row
deep = 3;
mline = 0;
for(j=3; j>=0; j--){
if(box[j] != 0){
box[deep] = box[j]; // move to right
if(deep != j)
box[j] = 0;
if(deep < 3 && mline == 0 && box[deep] == box[deep+1]){
point += box[deep+1];
box[deep+1] *= 2;
box[deep] = 0;
mline = 1;
}
这里我只举例向→的程序的实现,其它的依次类推,dir就是读取的按键的值,box代表四行四列的数据
第一层for循环4遍就是四行的,每一行都要往→移动,然后就是遍历数组,deep就是下标
遍历数组从数组的的当前位置的下一个开始遍历,找不是0的位置() 如果没找到什么也不做
如果当前位置是0,那么像当前位置与下一个进行互换(当前位置获得下一个位置的数据,并且将下一个位置数据置为0,将下标减一) 如果当前位置和下一个位置相等,将当前位置数据*2,下个位置数据置0
其他←↑↓也是一样的。
最后怎么判断游戏结束呢,刚看了下代码好像写的不全,应该是1没有空位,这个很简单找数组中有没有零就好了。2,相邻的两个没有相同的,这个我好像忘了搞了(写好之后玩了一下能玩就没管了,没玩到最后),有兴趣可以加上。现在板子交回去了,没东西调了,所以发挥你们的聪明才智自己加吧。
最后2048的代码奉上,整个工程的链接https://share.weiyun.com/4814054857023e73b17a0b85b0095315
//#include "delay.h"//#include "oled.h"#include "key.h"#include "app.h"#include "config.h"#include "stdlib.h"#include "menulx.h"//#include "stm32f10x.h"//#include "menulx.h"//#include "message.h"#include "delay.h"void update_box(int box[],int dir); void merge(int oned_box[],int dir);u8 gameover_flag=0;uint32 point,step;extern WINDOWS windows[]; extern void DrawMainWindow(void);extern u8 exit_flag;int box[16]={0,0,0,0,0,2,0,0,0,2};void game(){ int i=0,j=0,key; GUI_WindowsClr(windows) ; GUI_WindowsHide(windows) ; step=0; point=0; GUI_Exec(); exit_flag=0; GUI_LineWith(0,0,64,0,3,1); GUI_LineWith(0,0,0,64,3,1); GUI_LineWith(64,0,64,64,3,1); GUI_LineWith(0,62,62,62,3,1); GUI_LineWith(0,17,64,17,1,1); //横线 GUI_LineWith(0,32,64,32,1,1); GUI_LineWith(0,47,64,47,1,1); GUI_LineWith(17,0,17,64,1,1); GUI_LineWith(32,0,32,64,1,1); GUI_LineWith(47,0,47,64,1,1); GUI_PutString8_8(90,0,"2048"); GUI_PutString(70,10," 128-> * "); GUI_PutString(70,19," 512-> $ "); GUI_PutString(70,28,"1024-> @ "); GUI_PutString(70,38,"STEP"); GUI_PutString(90,48,"MARK :"); while(1) {LED_PrintValueC8_8(99,38,step); LED_PrintValueC8_8(82,56,point);//LED_PrintValueC(90,48,point); for(j=0;j<4;j++) {if(j==0) for(i=0;i<4;i++) { LED_PrintValueC1(3,6+i*15,box[i+j*4]); } else for(i=0;i<4;i++) { LED_PrintValueC1(5+15*j,6+i*15,box[i+j*4]); } } GUI_Exec(); key=key_return();update_box(box,key); if(gameover_flag==1) {gameover_flag=0; GUI_PutString8_8(90,30,"GAME OVER"); GUI_Exec(); delay_ms(800); GUI_PutString8_8(90,30," "); GUI_Exec(); for(i=0;i<16;i++) { box=0; } box[10]=2; box[12]=0; } if(key==KEY_OK){ step=0; point=0; for(i=0;i<16;i++) { box=0; } box[10]=2; box[12]=2; } if(exit_flag==1){ ///* 显示窗口 */DrawMainWindow(); GUI_Exec();break;}}} int random_2or4(void) { int val=rand()%5; return val>3?4:2;}int empty[16]={0};int findPos() //查找空位{int i,count=0,pos; for(i=0;i<16;i++) { if(box==0) empty[count++]=i; } if(count==0) return -1;//游戏结束 pos=empty[rand()%count]; return pos;}void update_box(int box[],int dir) { int newpos; switch(dir) { case KEY_UP: case KEY_DOWN: case KEY_LEFT: case KEY_RIGHT: merge(box,dir); newpos=findPos(); if(newpos<0) { return; } box[newpos]=random_2or4(); // } break; // case QUIT:exit(0); // break; // case INVALID: // break; } } void merge(int oned_box[],int dir){ int box[4][4] = {0}; int i, j; int deep; int mline = 0; for(i=0; i<4; i++) { for(j=0; j<4; j++) { box[j] = oned_box[i*4+j]; } } if(dir == KEY_DOWN){ for(i=0; i<4; i++){ // row deep = 3; mline = 0; for(j=3; j>=0; j--){ if(box[j] != 0){ box[deep] = box[j]; // move to right if(deep != j) box[j] = 0; if(deep < 3 && mline == 0 && box[deep] == box[deep+1]){ point += box[deep+1]; box[deep+1] *= 2; box[deep] = 0; mline = 1; } else deep--; } } } } if(dir == KEY_UP){ for(i=0; i<4; i++){ // row deep = 0; mline = 0; for(j=0; j<4; j++){ if(box[j] != 0){ box[deep] = box[j]; // move to left if(deep != j) box[j] = 0; if(deep > 0 && mline == 0 && box[deep] == box[deep-1]){ point += box[deep-1]; box[deep-1] *= 2; box[deep] = 0; mline = 1; } else deep++; } } } } if(dir == KEY_LEFT){ for(j=0; j<4; j++){ // col deep = 0; mline = 0; for(i=0; i<4; i++){ if(box[j] != 0){ box[deep][j] = box[j]; // move to up if(deep != i) box[j] = 0; if(deep > 0 && mline == 0 && box[deep][j] == box[deep-1][j]){ point += box[deep-1][j]; box[deep-1][j] *= 2; box[deep][j] = 0; mline = 1; } else deep++; } } } } if(dir == KEY_RIGHT){ for(j=0; j<4; j++){ // row deep = 3; mline = 0; for(i=3; i>=0; i--){ if(box[j] != 0){ box[deep][j] = box[j]; // move to down if(deep != i) box[j] = 0; if(deep < 3 && mline == 0 && box[deep][j] == box[deep+1][j]){ point += box[deep+1][j]; box[deep+1][j] *= 2; box[deep][j] = 0; mline = 1; } else deep--; } } } } for(i=0; i<4; i++) { for(j=0; j<4; j++) { if(oned_box[i*4+j] != box[j]) { oned_box[i*4+j] = box[j]; step++; if(oned_box[i*4+j] == 64) { gameover_flag=1; // printf("恭喜完成\n"); // exit(0); } } } }} |
|