基于51单片机的跳一跳游戏程序设计(C语言)

一、题目简述

选题灵感来源于微信小程序“跳一跳”,在游戏中,一个棋子站在跳板上,用户触摸手机屏幕时棋子蓄力,松手时棋子弹跳至下一个跳板,弹力大小由触摸时长来控制,游戏至棋子跌落跳板时结束。跳得越精准(正中板心)、踩过的跳板越多,得分越高,游戏结束时可以查看本局得分以及历史最高得分。

二、题目设计思想

我们通过TFT彩屏显示游戏画面、通过蜂鸣器输出声音,并通过触摸彩屏或者按下按键实现输入。

主函数中,游戏的初始界面显示游戏名称,提示用户按下并开始游戏。同时定时器1打开,按照音乐码表填充不同的TH1、TL1值,使蜂鸣器按不同频率振动,进而播放出音乐。

用户按下后,显示设计人员姓名,延时一段时间后,主函数调用Startgame()函数,游戏进入到主界面。游戏主界面中,屏幕显示两条红色线段分别作为起点平台和目的平台,在起点平台上的黄色小方块作为棋子,初始位置位于起点平台中央。屏幕右上角显示本局得分和最高得分。

之后,进入到while循环中等待玩家按下。玩家按下后,设置标志变量pushing=1,并且打开定时器0中断,使得每过50ms,定时器0中断服务程序使timeover=1。同时,函数进入到嵌套的while(pushing==1)循环,循环中判断如果timeover==1,调用AddTime函数,以记录时间。

AddTime()函数中,当用户按下时,变量time0=time0+50,表示按下的时间增加50ms。同时,屏幕上显示进度条表示蓄力时间,蜂鸣器振动的频率也随着蓄力时间增加而升高。

当用户松开手指时,设置pushing=0,定时结束,Startgame()跳出循环,令TR0=0,关闭定时器0。

之后,Startgame()调用JUMP()函数,函数根据蓄力时间的长短,判断棋子跳跃的轨迹,使得棋子按抛物线轨迹向上跳跃,同时屏幕上的平台向左移动。通过Delay()函数,调整移动的速度。根据棋子落点的位置,分为掉落平台、命中平台和精确命中三种情况,分别对应不同的提示语、不同的提示音以及不同的得分。当棋子掉落平台时,设置标志变量fail=1。

本轮结束之后,如果没有掉落平台,程序根据玩家此轮按下的时间,屏幕显示新的平台。

如果掉落,Startgame()调用Endgame()函数,游戏结束,显示最高得分和本轮得分,等待用户按下后开始新的一局。

三、主要代码

void Endgame()
{
    music_mode=3;music_bit=0;time_count=0; //切换为fail的音乐
    TFT_ClearScreen(BLACK);
	if(score>topscore)
	   topscore=score;
	music_on=1;
	GUI_WriteASCII(80, 100, "FAILED", RED, BLACK);
	GUI_Write32CnChar(65,220, "再来一局", WHITE, BLACK);
	GUI_WriteASCII(60, 170, "score:", GREEN, BLACK);
	Num2Char(score);
	GUI_WriteASCII(160, 170, num2char, GREEN, BLACK);
	GUI_WriteASCII(11, 145, "topscore:", GREEN, BLACK);
	Num2Char(topscore);
	GUI_WriteASCII(160, 145, num2char, GREEN, BLACK);
	while(ReadKey()==0&&ReadTouch()==0);
	GUI_WriteASCII(80, 100, "FAILED", BLACK, BLACK);
	GUI_Write32CnChar(65,220, "再来一局", BLACK,BLACK);
	GUI_WriteASCII(60, 170, "score:", BLACK, BLACK);
	Num2Char(score);
	GUI_WriteASCII(160, 170, num2char, BLACK, BLACK);
	GUI_WriteASCII(11, 145, "topscore:", BLACK, BLACK);
	Num2Char(topscore);
	GUI_WriteASCII(160, 145, num2char, BLACK, BLACK);
	x1=30,x2=70;
	x0=(x1+x2)/2;
	Startgame();
}


void JUMP(int x0,int y0,int distance)  //distance跳跃的距离
{
  	 int i,x=x0,y=y0;				//x、y点当前位置

	 if(x0+distance>x1+len&&x0+distance<x2+len) fail=0;
	 else fail=1;					   //判断能否跳到平台上

	    for(i=0;;i++)
	    { 
		 GUI_Dot(x0,y,BLACK);
		 x++;
		 y=y0+(x-x0)*(x-x0-distance)/40;	   //抛物线轨迹
		 if(i<x2+1)
		 {
		   GUI_Dot(x1-i-1,200,RED);
		   GUI_Dot(x2-i,200,BLACK);	  //起点平台的移动
		 }
		 GUI_Dot(x1+len-i-1,200,RED);
	   	 GUI_Dot(x2+len-i,200,BLACK); //目的平台的移动

		 GUI_Dot(x0,y,YELLOW);
		 Delay(5);                   //点的移动,Delay控制移动速度
		 if(y==y0&&x>x0+1&&fail==0) break;
		 else if(y>230) 
		        Endgame();
		}  

	   if(x1/2+x2/2+len-x0-distance<5&&x1/2+x2/2+len-x0-distance>-5)	  
	      {
		    music_mode=2;music_bit=0;time_count=0;  //音乐切换为bravo!的音乐
		    score+=4;
			GUI_WriteASCII(70, y-50, "bravo!", YELLOW, BLACK);
			Delay(150);
			GUI_WriteASCII(70, y-50, "bravo!", BLACK, BLACK);
		  }
	   else 
	   {
	      music_mode=1;music_bit=0;time_count=0;  //音乐切换为good的音乐
	      score+=2;
		  GUI_WriteASCII(70, y-50, "good", WHITE, BLACK);
		  Delay(150);
		  GUI_WriteASCII(70, y-50, "good", BLACK, BLACK);
	   }
	   GUI_WriteASCII(190, 40, num2char, BLACK, BLACK);
	   Num2Char(score);
	   GUI_WriteASCII(190, 40, num2char, GREEN, BLACK);
	  
	   x0=x;
	   x1=x1+len-distance-1;
	   x2=x2+len-distance-1;		 //目的平台变成起点平台
	   GUI_Line(0,200,x1-2,200,BLACK);	//清除前面的线   
}
 void AddTime()			 //累计时间函数
{
    if(time0>100051)  //防止总时间过大
	{
	    time0=0;
	}
      if(ReadKey() == 1||ReadTouch()==1)  //读取按键或屏幕,如果被按下
	{
	        time0=time0+50; //定时器刚刚计时完50ms,并且此时仍然按下,那么要为总时间加50毫秒
			if(time0/100<30)					  //防止时间过长,超过码表里的频率上限
			{
	  			frequency=time0/100;              //频率随时间增高,但有上限
			}
			GUI_Dot(x0+time0/35,240,BLUE);	   			
	}
   	else
		{
			if(pushing == 1)                          
			{
				pushing = 0;                         //更新状态为松开
				music_mode=4;music_bit=0;time_count=0;	 //音乐定时器切回到背景音乐模式	
			}		
	    }
}
void Startgame()
{
   		music_on=0;
	    GUI_Line(x1,200,x2,200,RED);	      //起点平台
	    GUI_Line(x1+len,200,x2+len,200,RED);  //目标平台	
	    GUI_Dot(x0,y0,YELLOW);
		GUI_WriteASCII(40, 15, "topscore:", GREEN, BLACK);
		Num2Char(topscore);
	    GUI_WriteASCII(190, 15, num2char, GREEN, BLACK);
		score=0;
		GUI_WriteASCII(90, 40, "score:", GREEN, BLACK);
		Num2Char(score);
	    GUI_WriteASCII(190, 40, num2char, GREEN, BLACK);
	while(1)
	{
		while(ReadKey()==0&&ReadTouch()==0);	 //等待按键被按下
		pushing=1;time0=0;frequency=0;music_mode=0;music_bit=0;time_count=0;//做好准备
	    Timer0Init();		     //打开定时器
		while(pushing == 1)		 //如果处于按下的状态,进入循环
		{
		   if(timeover == 1)	//定时器刚刚定时50ms
		   {
		       timeover = 0;	//timeover标志变量置零
			   AddTime();	    //调用累加时间函数
		   }

		}
	    TR0=0;					 //关闭定时器,(不用定时器时最好关掉,不关掉会影响运行速度和声音质量)
		GUI_Line(x0,240,x0+time0/20,240,BLACK);
	 	distance=time0/15;		//跳跃距离
	    JUMP(x0,y0,distance);   //跳跃函数,x0、y0初始位置
		len=time0/20;			//更改下一平台的位置
		if(len<50)
		   len+=50;
		if(len>200)
		   len-=50;
		GUI_Line(x1+len,200,x2+len,200,RED);	

   }
}

跳一跳界面

 

 

程序源码:

(2条消息) 基于51单片机的跳一跳游戏程序设计(C语言)-C/C++文档类资源-CSDN文库

  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

where_are_u

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值