news 2026/6/22 17:18:01

Flutter for OpenHarmony 实战_吃豆人游戏迷宫生成与渲染系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flutter for OpenHarmony 实战_吃豆人游戏迷宫生成与渲染系统

Flutter for OpenHarmony 实战:吃豆人游戏迷宫生成与渲染系统

欢迎加入开源鸿蒙跨平台社区:开源鸿蒙跨平台开发者社区

文章目录

  • Flutter for OpenHarmony 实战:吃豆人游戏迷宫生成与渲染系统
    • 前言
    • 一、迷宫数据结构设计
      • 1.1 迷宫布局表示
      • 1.2 豆子状态管理
    • 二、CustomPainter渲染系统
      • 2.1 画布坐标系设置
      • 2.2 墙壁绘制
      • 2.3 豆子绘制
    • 三、吃豆人角色绘制
      • 3.1 弧形绘制技术
      • 3.2 方向控制实现
      • 3.3 嘴巴动画系统
      • 3.4 眼睛细节绘制
    • 四、游戏循环与定时器
      • 4.1 双定时器系统
      • 4.2 定时器生命周期管理
    • 五、重绘优化策略
      • 5.1 精确的重绘控制
    • 六、UI界面设计
      • 6.1 状态栏设计
      • 6.2 游戏容器样式
    • 总结

前言

吃豆人游戏是经典的街机游戏,玩家需要在迷宫中控制角色吃掉所有豆子,同时躲避幽灵的追逐。本文将详细介绍如何使用Flutter for OpenHarmony实现吃豆人游戏的迷宫生成和渲染系统,包括迷宫数据结构设计、CustomPainter绘制技术、角色动画实现等核心技术点。

一、迷宫数据结构设计

1.1 迷宫布局表示

代码中使用15x15的二维数组表示迷宫布局:

staticconstint rows=15;staticconstint cols=15;// 0 = 空地, 1 = 墙, 2 = 豆子finalList<List<int>>initialMaze=[[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,2,2,2,2,2,2,1,2,2,2,2,2,2,1],[1,2,1,1,2,1,2,2,2,1,2,1,1,2,1],[1,2,2,2,2,1,2,1,2,1,2,2,2,2,1],[1,2,1,1,2,1,2,1,2,1,2,1,1,2,1],[1,2,2,2,2,2,2,2,2,2,2,2,2,2,1],[1,2,1,1,2,1,1,1,1,1,2,1,1,2,1],[1,2,2,2,2,1,0,0,0,1,2,2,2,2,1],[1,2,1,1,2,1,1,1,1,1,2,1,1,2,1],[1,2,2,2,2,2,2,2,2,2,2,2,2,2,1],[1,2,1,1,2,1,2,1,2,1,2,1,1,2,1],[1,2,2,2,2,1,2,1,2,1,2,2,2,2,1],[1,2,1,1,2,1,2,2,2,1,2,1,1,2,1],[1,2,2,2,2,2,2,1,2,2,2,2,2,2,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],];

这种设计将迷宫的每个单元格用整数表示,数字0、1、2分别对应空地、墙壁和豆子,简洁明了地表达了游戏场景的完整信息。

1.2 豆子状态管理

代码使用布尔二维数组单独管理豆子状态:

lateList<List<bool>>dots;dots=List.generate(rows,(i)=>List.generate(cols,(j)=>maze[i][j]==2));

通过遍历迷宫数组,将所有值为2的位置标记为true,这样可以独立控制每个位置的豆子是否被吃掉,而不影响原始迷宫布局。

二、CustomPainter渲染系统

2.1 画布坐标系设置

staticconstdouble cellSize=20.0;@overridevoidpaint(Canvascanvas,Sizesize){finalcellWidth=size.width/cols;finalcellHeight=size.height/rows;}

将画布动态划分为15x15的网格,每个单元格的尺寸根据画布总尺寸计算,确保在不同屏幕尺寸下都能正确显示。

2.2 墙壁绘制

if(maze[y][x]==1){finalrect=Rect.fromLTWH(x*cellWidth,y*cellHeight,cellWidth,cellHeight,);finalpaint=Paint()..color=Colors.blue.shade700..style=PaintingStyle.fill;canvas.drawRect(rect,paint);}

遍历迷宫数组,遇到值为1的位置时,使用Rect.fromLTWH创建矩形区域,然后用深蓝色填充,形成迷宫的墙壁效果。

2.3 豆子绘制

if(dots[y][x]){finalcenter=Offset(x*cellWidth+cellWidth/2,y*cellHeight+cellHeight/2,);finalpaint=Paint()..color=Colors.yellow..style=PaintingStyle.fill;canvas.drawCircle(center,cellWidth/8,paint);}

豆子使用黄色圆形表示,圆心位于单元格中心,半径为单元格宽度的1/8,这个比例保证了豆子大小适中,既清晰可见又不会过大。

三、吃豆人角色绘制

3.1 弧形绘制技术

吃豆人角色的核心是一个带有张嘴动画的扇形:

finalpacmanCenter=Offset(pacmanX*cellWidth+cellWidth/2,pacmanY*cellHeight+cellHeight/2,);finalpacmanPaint=Paint()..color=Colors.yellow..style=PaintingStyle.fill;finalstartAngle=_getPacmanStartAngle();finalsweepAngle=_getPacmanSweepAngle();canvas.drawArc(Rect.fromCircle(center:pacmanCenter,radius:cellWidth/2.2),startAngle,sweepAngle,true,pacmanPaint,);

使用drawArc方法绘制扇形,第一个参数是扇形的外接圆,第二个参数是起始角度,第三个参数是扫过的角度,第四个参数true表示使用圆心形成扇形。

3.2 方向控制实现

根据移动方向计算扇形的起始角度:

double_getPacmanStartAngle(){finalbaseAngle=pacmanDirection*pi/2;returnbaseAngle+mouthOpen*pi/180;}

四个方向分别对应不同的baseAngle值:0对应向上(0弧度),1对应向右(π/2弧度),2对应向下(π弧度),3对应向左(3π/2弧度)。加上mouthOpen角度后,嘴巴就会朝向移动方向。

3.3 嘴巴动画系统

嘴巴的张合动画通过定时器实现:

int mouthOpen=0;int mouthDirection=1;voidupdateMouth(){setState((){mouthOpen+=mouthDirection;if(mouthOpen>=45||mouthOpen<=0){mouthDirection*=-1;}});}

mouthOpen在0到45度之间往复变化,每次增加或减少mouthDirection,当达到边界值时将direction乘以-1实现反转。这个定时器每200毫秒执行一次,形成流畅的张嘴动画效果。

3.4 眼睛细节绘制

finaleyeOffset=Offset(pacmanCenter.dx+cellWidth/6*cos(_getPacmanEyeAngle()),pacmanCenter.dy+cellWidth/6*sin(_getPacmanEyeAngle()),);finaleyePaint=Paint()..color=Colors.black..style=PaintingStyle.fill;canvas.drawCircle(eyeOffset,cellWidth/15,eyePaint);double_getPacmanEyeAngle(){returnpacmanDirection*pi/2-pi/2;}

眼睛的位置使用三角函数计算,距离圆心为cellWidth/6,角度比移动方向少π/2(90度),使眼睛始终位于扇形开口方向,增强角色的方向感。

四、游戏循环与定时器

4.1 双定时器系统

代码使用两个独立的定时器分别控制吃豆人和幽灵:

Timer?gameTimer;Timer?ghostTimer;gameTimer=Timer.periodic(constDuration(milliseconds:200),(timer){if(!gameOver&&!won){movePacman();updateMouth();}});ghostTimer=Timer.periodic(constDuration(milliseconds:300),(timer){if(!gameOver&&!won){moveGhosts();checkCollisions();}});

吃豆人每200毫秒移动一次,幽灵每300毫秒移动一次,这种时间差异让玩家的速度略快于幽灵,增加了游戏的公平性和可玩性。

4.2 定时器生命周期管理

@overridevoiddispose(){gameTimer?.cancel();ghostTimer?.cancel();super.dispose();}

在组件销毁时取消所有定时器,避免内存泄漏和资源浪费。

五、重绘优化策略

5.1 精确的重绘控制

@overrideboolshouldRepaint(PacManPainteroldDelegate){returnoldDelegate.pacmanX!=pacmanX||oldDelegate.pacmanY!=pacmanY||oldDelegate.pacmanDirection!=pacmanDirection||oldDelegate.mouthOpen!=mouthOpen||oldDelegate.ghosts!=ghosts;}

只在关键状态变化时才重绘,避免每帧都重绘带来的性能开销。这种细粒度的重绘控制是游戏性能优化的关键。

六、UI界面设计

6.1 状态栏设计

AppBar(backgroundColor:Colors.blue.shade900,title:constText('吃豆人游戏',style:TextStyle(color:Colors.yellow,fontWeight:FontWeight.bold)),actions:[Center(child:Padding(padding:constEdgeInsets.only(right:16),child:Text('得分:$score生命:$lives',style:constTextStyle(color:Colors.white,fontSize:16,fontWeight:FontWeight.bold,),),),),],)

使用深蓝色背景和黄色标题营造街机风格,右侧实时显示得分和生命值,让玩家随时了解游戏状态。

6.2 游戏容器样式

Container(decoration:BoxDecoration(border:Border.all(color:Colors.blue.shade700,width:3),borderRadius:BorderRadius.circular(8),),child:CustomPaint(size:constSize(cols*cellSize,rows*cellSize),painter:PacManPainter(maze:maze,dots:dots,pacmanX:pacmanX,pacmanY:pacmanY,pacmanDirection:pacmanDirection,mouthOpen:mouthOpen,ghosts:ghosts,),),)

游戏区域使用3像素的蓝色边框和8像素圆角,与整体设计风格保持一致。

总结

本文详细介绍了吃豆人游戏的迷宫生成和渲染系统,从数据结构设计到CustomPainter绘制,从角色动画到游戏循环,完整展示了使用Flutter for OpenHarmony开发经典游戏的完整技术路径。通过这些技术实现,我们能够创建出视觉效果出色、运行流畅的游戏体验。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/13 16:03:27

制药业CRM系统需求激增,预测未来六年将以7.8%的CAGR稳健增长

2025 - 2032全球制药行业CRM软件市场洞察&#xff1a;规模增长与竞争格局剖析据恒州诚思调研统计&#xff0c;2025年全球制药行业CRM软件市场规模约达14.06亿元&#xff0c;预计未来将持续保持平稳增长态势&#xff0c;至2032年市场规模将接近23.71亿元&#xff0c;未来六年复合…

作者头像 李华
网站建设 2026/6/13 11:36:20

Leetcode—206. 反转链表【简单】

2025每日刷题&#xff08;247&#xff09; Leetcode—206. 反转链表实现代码 /*** Definition for singly-linked list.* type ListNode struct {* Val int* Next *ListNode* }*/ func reverseList(head *ListNode) *ListNode {dummy : new(ListNode)dummy.Next nilpr…

作者头像 李华
网站建设 2026/6/15 15:10:36

「中南林业科技大学和河南大学地理科学与工程学部支持 | E3S Web of Conferences(ISSN:2267-1242)出版」第二届能源工程与污染治理国际学术会议(EEPC 2026)

第二届能源工程与污染治理国际学术会议&#xff08;EEPC 2026&#xff09; 2026 2nd International Conference on Energy Engineering and Pollution Control 2026年3月13日&#xff0c;线上会议 大会官网&#xff1a;www.iceepc.org【参会投稿】 截稿时间&#xff1a;见官…

作者头像 李华
网站建设 2026/6/12 20:34:09

NDW-100000型微机控制重型汽车传动轴静扭试验机

NDW-100000型微机控制重型汽车传动轴静扭试验机一、概述&#xff1a;NDW-100000型微机控制重型汽车传动轴静扭试验机采用平台式结构&#xff0c;试样安装方便&#xff0c;可用于重型传动轴、半轴、汽车扭杆、转向柱的等轴类、杆类的扭转疲劳试验与静态特性试验&#xff08;扭转…

作者头像 李华
网站建设 2026/6/13 20:27:23

PLS-25-7电液伺服七通道汽车悬架疲劳试验系统

PLS-25-7电液伺服七通道汽车悬架疲劳试验系统汽车悬架系统是汽车底盘系统关键的一部分&#xff0c;汽车悬架系统有几个大部分&#xff08;弹性元件&#xff0c;导向机构&#xff0c;减震器&#xff0c;横向稳定杆&#xff09;组成。这部分的试验一般采用多通道的构件疲劳试验机…

作者头像 李华