HTML5 2D 游戏开发: 实现 Sprite 行为

[复制链接]
查看11 | 回复5 | 2007-1-24 12:56:49 | 显示全部楼层 |阅读模式
优秀的故事离不开优秀的人物角色。就像图书和电影一样,视频游戏也需要具有有趣行为的人物角色。例如,Braid(一直是最畅销的平台游戏)中的主角可操纵时间。精巧的行为使该游戏脱颖而出。
行为是任何视频游戏的灵魂,将行为添加到 前一期文章 中为 Snail Bait 实现的惰性 sprite 中,就会立刻使该游戏变得更加有趣,如图 1 所示:
图 1. 完成本文后 Snail Bait 的状态

回想一下前一篇文章中的 Sprite 对象 一节,Snail Bait 的 sprite 没有实现自己的活动,比如跑、跳或发怒。相反,sprite 依靠其他对象(称为行为)来控制操作。
图 1 显示了蜗牛射出蜗牛炸弹的行为。其他无法在 图 1 的静态图像中看到的行为包括:
跑步小人跑动
纽扣在平台上来回移动
红宝石和蓝宝石闪耀光芒
表 1 总结了这些行为:
表 1. 本文中讨论的行为
Sprite
行为
说明
纽扣和蜗牛
paceBehavior 在一个平台中来回移动
跑步小人
runBehavior 循环跑步小人的图像,看起来像是跑步小人正在跑动
蜗牛
snailShootBehavior 从蜗牛的口中射出一个蜗牛炸弹
蜗牛
cycleBehavior 循环显示一个 sprite 的图像
蜗牛炸弹
snailBombMoveBehavior 在画布显示范围中水平地将蜗牛炸弹向左移动
操作时间
在 Braid 中,主角 Tim 可以操纵时间,但每个视频游戏都擅长操纵时间。在本文中,您会看到潜在的时间流动行为。在本系列接下来的两篇文章中,我将介绍如何通过让时间弯曲来实现非线性运动,这是跑动和跳跃等真实运动的基本特征。
表 1 中列出的行为不足该游戏行为的一半,在本系列第一篇文章中的 Snail Bait 的 sprite 和行为 表中,可以看到全部行为。它们也是 sprite 的行为基础;举例而言,跳跃要复杂得多,您将在以后的文章中看到。尽管如此,对于本文中的简单行为的实现,仍有许多要学习的地方,包括如何:
实现行为并将它们分配给 sprite
循环显示一个 sprite 的一系列图像
创建轻量级行为以节省内存消耗
组合行为
使用行为发射炮弹
回复

使用道具 举报

千问 | 2007-1-24 12:56:49 | 显示全部楼层
行为基础
Replica Island 的行为
行为的概念来自一个流行的开源 Android 游戏 Replica Island。Snail Bait 的许多图形也来自 Replica Island。请参阅 参考资料,获得该游戏以及该游戏的创建者探讨行为的博客帖子的链接。
任何对象都可以是一个行为,只要它拥有一个 execute() 方法。该方法接受 3 个参数:sprite、时间和游戏动画的帧率。行为的 execute() 方法依据时间和动画帧率来修改 sprite 的状态。
行为很强大,因为:
它们将 sprite 与其行为分离开来。
可在运行时更改 sprite 行为。
可实现用于任何 sprite 的行为。
无状态行为可用作 轻量级行为。
在讨论 表 1 中列出的行为在实现之前,我将通过跑步小人的总体行为大致概括一下 — 如何实现它们并将它们与 sprite 相关联。
回复

使用道具 举报

千问 | 2007-1-24 12:56:49 | 显示全部楼层
[size=0.76em]跑步小人行为[size=0.76em]Snail Bait 的跑步小人有 4 种行为,如表 2 所示:
表 2. 跑步小人的行为
行为
回复

使用道具 举报

千问 | 2007-1-24 12:56:49 | 显示全部楼层
[size=0.76em]轻量型行为[size=0.76em]前一节中讨论的跑步小人的跑动行为需要维持状态,也就是说,行为持续的时间会推动 sprite 的图像移动。这种状态将跑步状态与行为紧密联系在一起。所以,如果您希望让另一个 sprite 跑动,则需要拥有另一个跑动行为。[size=0.76em]不需要维持状态的行为更加灵活;例如,可将这些行为用作轻量型行为。轻量型行为是对象的一个实例,可供其他许多对象同时使用。图 3 演示了一种无状态的移动行为,它让 sprite 在一个平台上来回移动。该行为一个实例被用于游戏的纽扣和蜗牛,所有这些对象都在平台上来回移动,如图 3 所示:
图 3. 纽扣移动顺序

[size=0.76em]清单 6 给出了 Snail Bait 的 createButtonSprites() 方法,它将单独的移动行为添加到每个纽扣:
清单 6. 创建移动纽扣

SnailBait.prototype = { ... createButtonSprites: function () {var button,
buttonArtist = new SpriteSheetArtist(this.spritesheet,
this.buttonCells),goldButtonArtist = new SpriteSheetArtist(this.spritesheet,
this.goldButtonCells);for (var i = 0; i < this.buttonData.length; ++i) { if (i === this.buttonData.length - 1) {
button = new Sprite('button',
goldButtonArtist,
[ this.paceBehavior ]); } else {
button = new Sprite('button',
buttonArtist,
[ this.paceBehavior ]); } button.width = this.BUTTON_CELLS_WIDTH; button.height = this.BUTTON_CELLS_HEIGHT; button.velocityX = this.BUTTON_PACE_VELOCITY; button.direction = this.RIGHT; this.buttons.push(button);} }, ...};
回复

使用道具 举报

千问 | 2007-1-24 12:56:49 | 显示全部楼层
[size=0.76em]非游戏独有的行为轻量型行为和状态[size=0.76em][size=0.76em]paceBehavior 可用作一个轻量型行为,因为它是无状态的。它没有状态是因为它将状态(每个 sprite 的位置和方向)存储在 sprite 自身中。
[size=0.76em]我们在本文中讨论的第一个行为( runBehavior )是一种有状态行为,它与一个 sprite 紧密关联。接下来要讨论的 paceBehavior 是一个无状态行为,该行为与各个 sprite 是分离开的,所以一个实例可供多个 sprite 使用。[size=0.76em]行为可进一步一般化:不仅可以将它们与各个 sprite 分离,还可以将它们与游戏本身分离。Snail Bait 使用了 3 种可用在任何游戏中使用的行为:bounceBehaviorcycleBehaviorpulseBehavior
[size=0.76em]弹跳行为上下弹跳一个 sprite,这个周期性的行为循环显示 sprite 的一组图像,心跳行为操纵了 sprite 的不透明度,使它显示为好像是 sprite 正在心跳。[size=0.76em]弹跳和心跳行为都涉及到非线性动画,我将在未来的文章中探讨这一主题。这个周期性行为线性循环显示了一个 sprite 的行为,所以我将使用该行为的实现来演示如何实现可在任何游戏中使用的行为。[size=0.76em]闪耀的红宝石[size=0.76em]Snail Bait 的红宝石和蓝宝石会不停闪耀,如图 4 所示:
图 4. 闪耀的红宝石序列

[size=0.76em]Snail Bait 的 sprite 表单包含红宝石和蓝宝石的图形序列;循环显示这些图像会带来闪耀的效果。[size=0.76em]清单 8 给出了创建红宝石的 Snail Bait 方法。可以采用几乎相同的方法(未给出)创建蓝宝石。createRubySprites() 方法还创建一种每隔 500 毫秒显示红宝石闪耀序列中的下一个图像 100 毫秒的周期性行为。
清单 8. 创建红宝石

SnailBait.prototype = { ... createRubySprites: function () {var ruby,
rubyArtist = new SpriteSheetArtist(this.spritesheet, this.rubyCells); for (var i = 0; i < this.rubyData.length; ++i) { ruby = new Sprite('ruby', rubyArtist,
[ new CycleBehavior(100, // animation duration
500) ]); // interval between animations ...} }, ...};
回复

使用道具 举报

千问 | 2007-1-24 12:56:49 | 显示全部楼层
[size=0.76em]组合行为[size=0.76em]各个行为会封装特定的操作,比如跑步、移动或闪耀。也可组合行为来实现更复杂的效果;例如,在蜗牛在其平台上来回移动时,会定期射出蜗牛炸弹,如图 5 所示:
图 5. 蜗牛射击序列

[size=0.76em]蜗牛射击序列是 3 种行为的组合:paceBehaviorsnailShootBehaviorsnailBombMoveBehavior
[size=0.76em]paceBehavior 和 snailShootBehavior 与蜗牛相关联,snailBombMoveBehavior 与蜗牛炸弹相关联。当 Snail Bait 创建 sprite 时,它在 Sprite 构造函数中指定前两个行为,如清单 10 中所示:
清单 10. 创建蜗牛

SnailBait.prototype = { ... createSnailSprites: function () {var snail,
snailArtist = new SpriteSheetArtist(this.spritesheet, this.snailCells); for (var i = 0; i < this.snailData.length; ++i) { snail = new Sprite('snail',
snailArtist,
[ this.paceBehavior,
this.snailShootBehavior,
new CycleBehavior(300,// 300ms per image
1500) // 1.5 seconds between sequences
]); snail.width= this.SNAIL_CELLS_WIDTH; snail.height = this.SNAIL_CELLS_HEIGHT; snail.velocityX = this.SNAIL_PACE_VELOCITY; snail.direction = this.RIGHT; this.snails.push(snail); // Push snail onto snails array} },};
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行