查看: 1918|回复: 5

[Blazar β-Board开发4] 2048游戏的实现•ᴗ•

[复制链接]
  • TA的每日心情
    开心
    2022-8-16 09:50
  • 签到天数: 16 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    发表于 2017-1-10 17:36:36 | 显示全部楼层 |阅读模式
    分享到:
    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);            }         }      }   }}
    回复

    使用道具 举报

    该用户从未签到

    发表于 2019-6-3 22:03:32 | 显示全部楼层
    楼主,连接失效了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    2019-7-30 16:59
  • 签到天数: 10 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2020-4-7 09:37:04 | 显示全部楼层

    楼主,连接失效了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    2019-7-30 16:59
  • 签到天数: 10 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2020-4-7 09:37:47 | 显示全部楼层
    现在还可以买到。。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    2019-7-30 16:59
  • 签到天数: 10 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2021-7-19 14:07:30 | 显示全部楼层
    这个板现在没有了?新的板好像更适合,淘宝搜索:blazar a
    https://item.taobao.com/item.htm ... p;abbucket=2#detail
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-12-18 22:22 , Processed in 0.170239 second(s), 27 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.