在上一篇文章中,我演示了如何使用最大堆有效跟踪最远的敌人。在本文中,我们将了解如何将其集成到游戏机制中。
事件驱动方法
现有的实现使用事件驱动的架构。在本文中,我们将重点关注敌人事件。这些事件将触发衍生行动。
每个敌人都会经历各种事件。以下是敌人可能经历的生命周期的示例:
对于这篇文章,我对两个事件感兴趣:
- 敌人移动:当敌人位置改变时触发。
- 敌人移除*:当敌人从游戏中移除(例如被击败)时触发。
(*我计划在未来调整事件名称,因为敌人可能会因为不同的原因而被移除。)
计划
我创建了一个事件模型图来可视化不同事件如何交互。这有助于理解事物如何连接。
对于每个事件,我都有一个触发它的命令。 (因此,事件是命令的结果。)在某些情况下,由于事件的结果,我们需要更新数据(绿色便签描述了这一点)。三者的组合是一个垂直切片。
我的注意力将集中在绿色便签“塔范围内的敌人”上。
执行
我们的目标是每当敌人在塔的范围内时就更新可用的敌人,如果不在则将其移除。
我们将与塔类合作。在这个类中,我们有一个变量来存储敌人。
export class Tower implements ITower { public enemies = new MaxHeap() constructor(id: number, coords: Coordinate) { this.id = id this.coords = coords // listeners will go here... }
将事件监听器放置在 Tower 类中可以集中逻辑,减少维护塔和敌人之间映射的需要。虽然这给类增加了一些复杂性,但它确保了更好的封装并简化了调试,这是目前更容易采取的方向。
行动:添加范围内的敌人
测试:添加敌人
首先,我们将编写一个测试来验证范围内的敌人是否已添加到塔的敌人堆中:
it('should add an enemy to the tower when enemy is within range', () => { const tower = new Tower(1, { col: 0, row: 1 }); const enemy = new TinyEnemy(); enemy.currentPosition = { col: 0, row: 1 }; triggerEnemyMovedEvent(enemy); expect(tower.enemies.length()).toBe(1); });
实施:添加敌人
下面是相应的实现:
window.addEventListener("enemyMoved", event => { const enemy: Enemy = event.detail.enemy; if (enemyWithinRange(this, enemy)) { this.enemies.insertOrUpdate(enemy.id, enemy.distanceTraveled); } });
每当敌人移动被触发时,我们都会检查是否应该将敌人添加到堆中。我已经有enemyWithinRange函数,只需添加insertOrUpdate调用即可。
行动:防止添加超出范围的敌人
测试:忽略范围外的敌人
接下来,我们确保不会添加塔范围之外的敌人:
export class Tower implements ITower { public enemies = new MaxHeap() constructor(id: number, coords: Coordinate) { this.id = id this.coords = coords // listeners will go here... }
实施:忽略范围外的敌人
我们之前使用enemyWithinRange进行的检查已经涵盖了这种情况,因此不需要额外的代码。
行动:将敌人移出范围
测试:消灭超出范围的敌人
现在我们测试离开范围的敌人是否会从塔的可见范围中移除:
it('should add an enemy to the tower when enemy is within range', () => { const tower = new Tower(1, { col: 0, row: 1 }); const enemy = new TinyEnemy(); enemy.currentPosition = { col: 0, row: 1 }; triggerEnemyMovedEvent(enemy); expect(tower.enemies.length()).toBe(1); });
实施:消灭超出范围的敌人
window.addEventListener("enemyMoved", event => { const enemy: Enemy = event.detail.enemy; if (enemyWithinRange(this, enemy)) { this.enemies.insertOrUpdate(enemy.id, enemy.distanceTraveled); } });
如果敌人曾经在范围内,那么我们可以将其移除。
行动:从游戏中移除敌人
测试:处理敌人移除事件
最后,我们确保从游戏中移除的敌人也会从塔堆中移除:
it('should not add an enemy to the tower if enemy is out of range', () => { const tower = new Tower(1, { col: 0, row: 1 }); const enemy = new TinyEnemy(); enemy.currentPosition = { col: 0, row: 99 }; triggerEnemyMovedEvent(enemy); expect(tower.enemies.length()).toBe(0); });
实施:处理敌人删除
it('should remove an enemy from the tower when it moves out of range', () => { const tower = new Tower(1, { col: 0, row: 1 }); const enemy = new TinyEnemy(); enemy.currentPosition = { col: 0, row: 1 }; // enemy within range triggerEnemyMovedEvent(enemy); expect(tower.enemies.length()).toBe(1); // enemy outside of the range enemy.currentPosition = { col: 0, row: 99 }; triggerEnemyMovedEvent(enemy); expect(tower.enemies.length()).toBe(0); });
每当触发事件时,如果敌人在范围内,我们就可以将其移除。
结论
通过将事件驱动方法与最大堆相结合,我们实现了塔楼动态优先处理敌人的有效方法。该实施与游戏的事件系统无缝连接,确保实时更新和响应能力。
此外,在测试时,使用事件驱动方法无需将内部代码与测试联系起来。因此使测试不那么脆弱。我们可以以任何我们想要的方式重构行为背后的代码,只要事件/侦听器设置正确,测试仍然应该通过。
此实施现在可以为以下目标铺平道路:
- 添加攻击功能(现在我们知道要攻击谁了)
- 交换敌人数据的存储方式
请随意将这种方法应用于您自己的塔防游戏。
以上是攻击射程最远的敌人(塔防)的详细内容。更多信息请关注PHP中文网其他相关文章!

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

10款趣味横生的jQuery游戏插件,让您的网站更具吸引力,提升用户粘性!虽然Flash仍然是开发休闲网页游戏的最佳软件,但jQuery也能创造出令人惊喜的效果,虽然无法与纯动作Flash游戏媲美,但在某些情况下,您也能在浏览器中获得意想不到的乐趣。 jQuery井字棋游戏 游戏编程的“Hello world”,现在有了jQuery版本。 源码 jQuery疯狂填词游戏 这是一个填空游戏,由于不知道单词的上下文,可能会产生一些古怪的结果。 源码 jQuery扫雷游戏

本教程演示了如何使用jQuery创建迷人的视差背景效果。 我们将构建一个带有分层图像的标题横幅,从而创造出令人惊叹的视觉深度。 更新的插件可与JQuery 1.6.4及更高版本一起使用。 下载

本文演示了如何使用jQuery和ajax自动每5秒自动刷新DIV的内容。 该示例从RSS提要中获取并显示了最新的博客文章以及最后的刷新时间戳。 加载图像是选择

Matter.js是一个用JavaScript编写的2D刚体物理引擎。此库可以帮助您轻松地在浏览器中模拟2D物理。它提供了许多功能,例如创建刚体并为其分配质量、面积或密度等物理属性的能力。您还可以模拟不同类型的碰撞和力,例如重力摩擦力。 Matter.js支持所有主流浏览器。此外,它也适用于移动设备,因为它可以检测触摸并具有响应能力。所有这些功能都使其值得您投入时间学习如何使用该引擎,因为这样您就可以轻松创建基于物理的2D游戏或模拟。在本教程中,我将介绍此库的基础知识,包括其安装和用法,并提供一

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3汉化版
中文版,非常好用

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

记事本++7.3.1
好用且免费的代码编辑器

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。