[作品提交] 【双人格斗游戏机】+基于自定义GUI的格斗游戏

北方   2022-9-13 12:21 楼主

作品名称:双人格斗游戏机

作者:   北方    

 

 

一、作品简介

   原计划使用lvgl制作一个双人格斗游戏机,实现双人对战的格斗模式。控制格斗采用光学ToF传感器阵列进行手势识别,输出上下左右的控制动作。但是经过测试,lvgl的动态性能表现不足,比较适合静态图像。如果提高动态效果,一般可以使用animation功能,或者占用过多的内存,或者动作很慢。所以最终采用自定义Simple Game Engine的方式使用STM32F70独有的LTDC新型双页面刷新。

    制作两个动态形态,互相格斗,当接近有重叠后,就是击中,根据主动性判读胜负,积分。

二、系统框图

en.bd_stm32f750_64k.jpg

 

三、各部分功能说明

3.1 显示内存定义,使用两个数组指针,分别为38400和12800,接收两个图层的数据,使用lcd_config定义为RGB565格式并且设定交叠后的透明度。

/* Layer1 Configuration ------------------------------------------------------*/
  
  /* Windowing configuration */ 
  pLayerCfg.WindowX0 = 0;
  pLayerCfg.WindowX1 = 320;
  pLayerCfg.WindowY0 = 0;
  pLayerCfg.WindowY1 = 80;
  
  /* Pixel Format configuration*/ 
  pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
  
  /* Start Address configuration : frame buffer is located at FLASH memory */
  pLayerCfg.FBStartAdress = (uint32_t)&Image_background;
  
  /* Alpha constant (255 totally opaque) */
  pLayerCfg.Alpha = 200;
  
  /* Default Color configuration (configure A,R,G,B component values) */
  pLayerCfg.Alpha0 = 0;
  pLayerCfg.Backcolor.Blue = 0;
  pLayerCfg.Backcolor.Green = 0;
  pLayerCfg.Backcolor.Red = 0;
  
  /* Configure blending factors */
  pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
  pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
  
  /* Configure the number of lines and number of pixels per line */
  pLayerCfg.ImageWidth = 320;
  pLayerCfg.ImageHeight = 240;

/* Layer2 Configuration ------------------------------------------------------*/
  
  /* Windowing configuration */ 
  pLayerCfg1.WindowX0 = 0;
  pLayerCfg1.WindowX1 = 320;
  pLayerCfg1.WindowY0 = 0;
  pLayerCfg1.WindowY1 = 80;
  
  /* Pixel Format configuration*/ 
  pLayerCfg1.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
  
  /* Start Address configuration : frame buffer is located at FLASH memory */
  pLayerCfg1.FBStartAdress = (uint32_t)&Image_combat_320x80;
  
  /* Alpha constant (255 totally opaque) */
  pLayerCfg1.Alpha = 128;
  
  /* Default Color configuration (configure A,R,G,B component values) */
  pLayerCfg1.Alpha0 = 0;
  pLayerCfg1.Backcolor.Blue = 0;
  pLayerCfg1.Backcolor.Green = 0;
  pLayerCfg1.Backcolor.Red = 0;
  
  /* Configure blending factors */
  pLayerCfg1.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
  pLayerCfg1.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
  
  /* Configure the number of lines and number of pixels per line */
  pLayerCfg1.ImageWidth = 320;
  pLayerCfg1.ImageHeight = 80;  

3.2 运行逻辑

初始化文件后,启动图册,两个avatar分别移动,一个受机器随机函数控制,另一个受板载user button控制。

当碰撞后,执行碰撞监测的响应程序。

非常精简地在while loop中完成。

  HAL_LTDC_ProgramLineEvent(&LtdcHandle, 0);    
	HAL_LTDC_SetWindowPosition_NoReload(&LtdcHandle, 80, 32, 0);
  /* Infinite loop */
  while (1)
  { 
		//y1_ctl = 10 ;		y1_ctl++;		//Image_combat_320x80[y1_ctl]=0x00000000;
	
		cnt = Render(x1_ctl , y1_ctl,  x2_ctl,  y2_ctl);
		Collision(cnt);
		
		//Show the Data
       HAL_LTDC_SetWindowPosition_NoReload(&LtdcHandle, 80, 180, 1);
       ReloadFlag = 0;
       HAL_LTDC_Reload(&LtdcHandle,LTDC_RELOAD_VERTICAL_BLANKING);
       while(ReloadFlag == 0)  {      }
    HAL_Delay(200);

  }

 

四、作品源码

Fighting.202209.zip (9.45 MB)
(下载次数: 3, 2022-9-14 13:27 上传)

部分核心代码如下

int main(void)
{
	x1_ctl =0; y1_ctl =0;  x2_ctl =120;  y2_ctl =0; 
  RCC_PeriphCLKInitTypeDef  PeriphClkInitStruct;
  //uint32_t index = 0;

  /* Enable the CPU Cache */
  CPU_CACHE_Enable();
	
  /* STM32F7xx HAL library initialization:
       - Configure the Flash ART accelerator on ITCM interface
       - Systick timer is configured by default as source of time base, but user 
         can eventually implement his proper time base source (a general purpose 
         timer for example or other time source), keeping in mind that Time base 
         duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
         handled in milliseconds basis.
       - Set NVIC Group Priority to 4
  - Low Level Initialization
  */
  HAL_Init();
  
  /* Configure the system clock to 216 MHz */
  SystemClock_Config();
  
  /*## LTDC Clock Configuration ###########################################*/  
  /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
  /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 Mhz */
  /* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/5 = 38.4 Mhz */
  /* LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_4 = 38.4/4 = 9.6Mhz */
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
  PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
  PeriphClkInitStruct.PLLSAI.PLLSAIR = 5;
  PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_4;
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);  
  
  /* Configure LED1 */
  BSP_LED_Init(LED1);   	
  BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO);

  /*##-1- LCD Configuration ##################################################*/ 
  /* Configure 2 layers w/ Blending and CLUT loading for layer 1 */
  LCD_Config(); 
  
  /*##-2- CLUT Configuration #################################################*/
  //HAL_LTDC_ConfigCLUT(&LtdcHandle, (uint32_t *)L8_320x240_CLUT, 256, 0); 
  
  /*##-3- Enable CLUT For Layer 1 ############################################*/
  //HAL_LTDC_EnableCLUT(&LtdcHandle, 0);   
  
  /*##-4- Configure line event ###############################################*/
  HAL_LTDC_ProgramLineEvent(&LtdcHandle, 0);    
	HAL_LTDC_SetWindowPosition_NoReload(&LtdcHandle, 80, 32, 0);
  /* Infinite loop */
  while (1)
  { 
		//y1_ctl = 10 ;		y1_ctl++;		//Image_combat_320x80[y1_ctl]=0x00000000;
	
		cnt = Render(x1_ctl , y1_ctl,  x2_ctl,  y2_ctl);
		Collision(cnt);
		
		//Show the Data
       HAL_LTDC_SetWindowPosition_NoReload(&LtdcHandle, 80, 180, 1);
       ReloadFlag = 0;
       HAL_LTDC_Reload(&LtdcHandle,LTDC_RELOAD_VERTICAL_BLANKING);
       while(ReloadFlag == 0)  {      }
    HAL_Delay(200);

  }
}

/**
  * @brief   calculate pictures position.
  * @param  x1:    picture1 x position
  * @param  y1:    picture1 y position
  * @param  x2:    picture2 x position
  * @param  y2:    picture2 y position
  * @param  index: 
  * @retval None
  */

static int Render(uint32_t x1,   uint32_t y1,   uint32_t x2,   uint32_t y2)
{
	uint32_t cnt_collision=0;
	uint32_t ix,iy;	

	for (iy = 0; iy < 80; iy++)
    {
			for (ix = 0; ix < 160; ix++)
			{
				Image_combat_320x80[160*iy + ix]=0xFFFFFFFF;
				
			}		
			for (ix = 0; ix < 30; ix++)
			{
				Image_combat_320x80[ix + x1 + 160*iy] = Image02_60x80[ix+30*iy];
				if ( Image_combat_320x80[ix + x2 + 160*iy] != 0xFFFFFFFF)	{
						cnt_collision = cnt_collision + 1;
					}
				Image_combat_320x80[ix + x2 + 160*iy] = Image01_60x80[ix+30*iy];
				
			}			
    }
    //BSP_LED_On(LED1);
	return cnt_collision;
}

static void update_ctl(void)
{
  //BSP_LED_On(LED1);
	int btn =0;
	int cnt_rand;
	//srand(2);
	cnt_rand = -1 + rand () % 3;
	btn = BSP_PB_GetState(BUTTON_KEY);
	y1_ctl =0;
	y2_ctl =0;
	x1_ctl=( x1_ctl + btn ) % 160;	
	x2_ctl=( x2_ctl + cnt_rand ) % 160;	
}

static void Collision(uint32_t cnt)
{
  //BSP_LED_On(LED1);
	if ( cnt > 0 ){
		//beep();	
		x1_ctl = x1_ctl - 10;
	}		
		update_ctl();		
	
}

 

五、作品功能演示视频

VID20220914125743

    项目启动后,第一层加载背景,然后第二层加载格斗平台,两个avatar分别出现,一个是机器自动控制,这里使用随机函数乱动。另一用板载button控制,按键后前进,每次都清零,防止跑得过于高兴撞到墙上,当然,这里取模不让跑得太远,如果撞上了,处理逻辑就是被反弹回来。

 

 

六、项目总结

 

6.1 基本动态制作。

   初始测试,使用inkscape矢量生产动态图片。

boxing01.1.PNG 然后输出两个格斗小人

boxing01.png boxing02.png

使用lcd-image-converter转换成RGB565格式的头文件,

boxing02.PNG 数据格式如下

boxing03.PNG

6.2 基于LTDC的页面加载两个avatar,效果如下

197492278.jpg

6.3 使用这个过程启动代码,生成两个图层,一个是背景,这里使用大赛logo,另一个是战斗平台。作为初始版本,在有限的空间,单轴二维输出,使用320x80的屏幕。

1397806213.jpg
这样基础版本的自定义gameEngine完成。

 

七、其他

    这样基础版本的自定义gameEngine从通常的角度看非常简陋,但是这个完成了完整的GE引擎流程,从定义并建立显示存储控制空间,进行线性和二维转换,分区填充,分层绘图,建模,渲染,碰撞监测,外设驱动的输入和自动的Robot等待被锤(虽然只是用了随机函数,但是切换到AI对战可以无缝衔接),这样的流程大概有10多个步骤。这个步骤的实现,和Epic这样的巨著是没有根本区别的,只是性能,效率和效果差距巨大。

 这样的玩法还不如用lvgl好使,但是有巨大的优势,在这个项目里,刷新的频率是可以自定义的。刷新频率已经可以定义到50ms,使用HAL_delay(50)简单完成任务。

这样的扩展性还有很多体验。本次提交算是基本作业,如果时间可以,可以完善这个项目到比较酷炫的情况。后续继续搞一下。

 

ps,主要函数和流程的代码还是贴出来的好

Capture.PNG

 

开发板的资料

https://www.st.com/en/evaluation-tools/stm32f7508-dk.html#st-also-like

数据特性可以参考一下。

  • STM32F750N8H6 microcontroller featuring 64 Kbytes of Flash memory and 340 Kbytes of RAM, in BGA216 package
  • 4.3-inch 480x272 color LCD-TFT with capacitive touch screen
  • Ethernet connector compliant with IEEE-802.3-2002
  • USB OTG HS FS
  • SAI audio codec
  • 2 ST-MEMS digital microphones
  • 128-Mbit Quad-SPI Flash memory
  • 128-Mbit SDRAM (64 Mbits accessible)

 

回复评论 (1)

这种基础版本的自定义gameEngine,从通常的角度看虽然简陋,但是结果还是挺好

很期待楼主后面的完善这个项目到比较酷炫的测评

点赞  2022-9-15 07:26
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复