HTML5 游戏开发指南

2023-02-23 0 593

因此您想采用 Canvas 和 HTML5 制做格斗游戏吗? 依照本讲义展开操作方式,您迅速就会后路。

本讲义假设您最少具备中等的 JavaScript 科学知识。

您能先玩格斗游戏 或间接重定向到该文查阅格斗游戏源码

建立画笔

为的是画小东西,她们须要建立两个画笔。 即使这是两本 No Tears 手册,因此她们将采用 jQuery。

var CANVAS_WIDTH = 480;var CANVAS_HEIGHT = 320;var canvasElement = $(“<canvas width=” + CANVAS_WIDTH + ” height=” + CANVAS_HEIGHT + “></canvas>”);var canvas = canvasElement.get(0).getContext(“2d”);canvasElement.appendTo(body);

格斗游戏循环式

为的是演示简洁和已连续的格斗游戏外形,她们期望预览格斗游戏和重画萤幕的速率慢于人类文明观念和双眼所能交互的速率。

var FPS = 30;setInterval(function() { update(); draw();}, 1000/FPS);

那时她们能将预览和绘出方式昂格吕尔县。 关键的是要晓得 setInterval()负责管理不定期给她们发短信。

function update() { … }function draw() { … }

你好世界

那时她们有两个格斗游戏循环式,让她们预览她们的 draw 方式以在萤幕上实际绘出一些文本。

function draw() { canvas.fillStyle = “#000”; // Set color to black canvas.fillText(“Sup Bro!”, 50, 50);}

专业提示:确保在展开更改后运行您的应用程序。 如果有什么小东西坏了,当只有几行变化要看时,追踪起来会容易得多。

这对于固定文本来说非常酷,但是即使她们已经设置了两个格斗游戏循环式,因此她们应该能够很容易地让它移动。

var textX = 50;var textY = 50;function update() { textX += 1; textY += 1;}function draw() { canvas.fillStyle = “#000”; canvas.fillText(“Sup Bro!”, textX, textY);}

那时试一试。 如果你跟着走,它应该在移动,但也会离开之前在萤幕上绘出的时间。 花点时间猜猜为什么会这样。 这是即使她们没有清除萤幕。 因此让她们在 draw 方式中添加一些萤幕清除代码。

function draw() { canvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); canvas.fillStyle = “#000”; canvas.fillText(“Sup Bro!”, textX, textY);}

那时您已经在萤幕上移动了一些文本,您已经完成了两个真正的格斗游戏。 只需加强控制、改进格斗游戏玩法、修饰图形……好吧,这可能是真正格斗游戏的 1/7,但好消息是讲义还有更多内容。

建立播放器

建立两个对象来保存播放器数据并负责管理绘图之类的事情。 在这里,她们采用两个简单的对象字面量来建立两个播放器对象来保存所有信息。

var player = { color: “#00A”, x: 220, y: 270, width: 32, height: 32, draw: function() { canvas.fillStyle = this.color; canvas.fillRect(this.x, this.y, this.width, this.height); }};

她们那时采用两个简单的彩色矩形来代表玩家。 当她们绘出格斗游戏时,她们将清除画笔并绘出玩家。

function draw() { canvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); player.draw();}

键盘控制

采用 jQuery 热键

使跨浏览器的jQuery Hotkeys 插件 按键处理变得更加容易。 而不是为无法辨认的跨浏览器哭泣keyCode和charCode问题,她们能像这样绑定事件:

$(document).bind(“keydown”, “left”, function() { … });

不必担心哪些键具备哪些代码的细节是两个巨大的胜利。 她们只是期望能够说出诸如“当玩家按下向上按钮时,做某事”之类的话。 jQuery Hotkeys 能很好地做到这一点。

球员运动

JavaScript 处理键盘事件的方式完全是事件驱动的。 这意味着没有用于检查键是否关闭的内置查询,因此她们必须采用自己的查询。

您可能会问,“为什么不采用事件驱动的方式来处理键呢?” 好吧,这是即使键盘重复率因系统而异,并且不受格斗游戏循环式时间的限制,因此格斗游戏玩法可能因系统而异。 要建立一致的体验,将键盘事件检测与格斗游戏循环式紧密集成非常关键。

好消息是我已经包含了两个 16 行的 JS 包装器,它将使事件查询可用。 它称为 key_status.js ,您能随时通过检查来查询密钥的状态 keydown.left, ETC。

那时她们能查询按键是否按下,她们能采用这个简单的预览方式来移动播放器。

function update() { if (keydown.left) { player.x -= 2; } if (keydown.right) { player.x += 2; }}

来吧,试一试。

您可能会注意到播放器能移出萤幕。 让她们限制玩家的位置,让她们保持在边界内。 此外,播放器似乎有点慢,因此让她们也提高速率。

function update() { if (keydown.left) { player.x -= 5; } if (keydown.right) { player.x += 5; } player.x = player.x.clamp(0, CANVAS_WIDTH – player.width);}

添加更多输入也同样容易,因此让她们添加一些射弹。

function update() { if (keydown.space) { player.shoot(); } if (keydown.left) { player.x -= 5; } if (keydown.right) { player.x += 5; } player.x = player.x.clamp(0, CANVAS_WIDTH – player.width);}player.shoot = function() { console.log(“Pew pew”); // 🙂 Well at least adding the key binding was easy…};

添加更多格斗游戏对象

炮弹

那时让她们真正添加射弹。 首先,她们须要两个集合来将它们全部存储在:

var playerBullets = [];

接下来,她们须要两个构造函数来建立项目符号实例。

function Bullet(I) { I.active = true; I.xVelocity = 0; I.yVelocity = -I.speed; I.width = 3; I.height = 3; I.color = “#000”; I.inBounds = function() { return I.x >= 0 && I.x <= CANVAS_WIDTH && I.y >= 0 && I.y <= CANVAS_HEIGHT; }; I.draw = function() { canvas.fillStyle = this.color; canvas.fillRect(this.x, this.y, this.width, this.height); }; I.update = function() { I.x += I.xVelocity; I.y += I.yVelocity; I.active = I.active && I.inBounds(); }; return I;}

当玩家射击时,她们应该建立两个子弹实例并将其添加到子弹集合中。

player.shoot = function() { var bulletPosition = this.midpoint(); playerBullets.push(Bullet({ speed: 5, x: bulletPosition.x, y: bulletPosition.y }));};player.midpoint = function() { return { x: this.x + this.width/2, y: this.y + this.height/2 };};

她们那时须要将项目符号的预览添加到预览步骤函数中。 为的是防止项目符号集合无限期地填满,她们过滤项目符号列表以仅包含活动项目符号。 这也使她们能够移除与敌人相撞的子弹。

function update() { … playerBullets.forEach(function(bullet) { bullet.update(); }); playerBullets = playerBullets.filter(function(bullet) { return bullet.active; });}

最后一步是绘出子弹:

function draw() { … playerBullets.forEach(function(bullet) { bullet.draw(); });}
敌人

那时是时候像添加子弹一样添加敌人了。

enemies = [];function Enemy(I) { I = I || {}; I.active = true; I.age = Math.floor(Math.random() * 128); I.color = “#A2B”; I.x = CANVAS_WIDTH / 4 + Math.random() * CANVAS_WIDTH / 2; I.y = 0; I.xVelocity = 0 I.yVelocity = 2; I.width = 32; I.height = 32; I.inBounds = function() { return I.x >= 0 && I.x <= CANVAS_WIDTH && I.y >= 0 && I.y <= CANVAS_HEIGHT; }; I.draw = function() { canvas.fillStyle = this.color; canvas.fillRect(this.x, this.y, this.width, this.height); }; I.update = function() { I.x += I.xVelocity; I.y += I.yVelocity; I.xVelocity = 3 * Math.sin(I.age * Math.PI / 64); I.age++; I.active = I.active && I.inBounds(); }; return I;};function update() { … enemies.forEach(function(enemy) { enemy.update(); }); enemies = enemies.filter(function(enemy) { return enemy.active; }); if(Math.random() < 0.1) { enemies.push(Enemy()); }};function draw() { … enemies.forEach(function(enemy) { enemy.draw(); });}

加载和绘出图像

看着所有这些盒子飞来飞去很酷,但是为它们制做图像会更酷。 在画笔上加载和绘出图像通常是一种令人泪流满面的体验。 为的是避免这种痛苦和痛苦,她们能采用两个简单的实用程序类。

player.sprite = Sprite(“player”);player.draw = function() { this.sprite.draw(canvas, this.x, this.y);};function Enemy(I) { … I.sprite = Sprite(“enemy”); I.draw = function() { this.sprite.draw(canvas, this.x, this.y); }; …}

碰撞检测

她们让所有这些交易在萤幕上飞来飞去,但它们并没有相互影响。 为的是让一切都晓得什么时候爆炸,她们须要添加某种碰撞检测。

让她们采用两个简单的矩形碰撞检测算法:

function collides(a, b) { return a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y;}

她们要检查几个碰撞:

Player Bullets => 敌舰玩家 => 敌舰

让她们建立两个方式来处理她们能从预览方式调用的冲突。

function handleCollisions() { playerBullets.forEach(function(bullet) { enemies.forEach(function(enemy) { if (collides(bullet, enemy)) { enemy.explode(); bullet.active = false; } }); }); enemies.forEach(function(enemy) { if (collides(enemy, player)) { enemy.explode(); player.explode(); } });}function update() { … handleCollisions();}

那时她们须要为玩家和敌人添加爆炸方式。 这会将它们标记为移除并添加爆炸。

function Enemy(I) { … I.explode = function() { this.active = false; // Extra Credit: Add an explosion graphic }; return I;};player.explode = function() { this.active = false; // Extra Credit: Add an explosion graphic and then end the game};

声音

为的是完善体验,她们将添加一些甜美的音效。 声音,就像图像一样,在 HTML5 中采用起来可能有些痛苦,但是由于她们神奇的无泪公式 sound.js,声音能变得超级简单。

player.shoot = function() { Sound.play(“shoot”); …}function Enemy(I) { … I.explode = function() { Sound.play(“explode”); … }}

虽然 API 那时是无撕裂的,但添加声音是目前使您的应用程序崩溃的最快方式。 声音中断或关闭整个浏览器选项卡的情况并不少见,因此请准备好您的纸巾。

告别

同样,这里是完整的格斗游戏演示 。 您也能下载zip 格式的源码

好吧,我期望你喜欢学习用 JavaScript 和 HTML5 制做简单格斗游戏的基础科学知识。 通过在正确的抽象级别展开编程,她们能将自己与 API 中较困难的部分隔离开来,并在面对未来的变化时保持弹性。

参考

HTML5 Canvas 备忘单 HTML5 格斗游戏引擎

举报/反馈

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务