写在前面
这是一个类贪吃蛇的小游戏,因为最近又翻到了canvas,想着写一些东西来巩固下,刚好就看到博主写的demo,不过我在其基础上进行了一定的规则限制,下面附上链接:博主原文
设计初衷
此次这个游戏加入了
1、积分规则,
2、碰壁死亡规则,
3、调用requestAnimationFrame方法实现循环。
游戏的截图效果如下:
死亡效果截图如下:
设计步骤
1、在HTML文档中创建canvas的节点,以便DOM操作。
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>使用canvas和js来实现一个小游戏</title>
<script type="text/javascript" src = "canvas.js"></script>
</head>
<body>
<canvas id = "drawing" width = "512" height = "480" style="border: 1px solid lightblue;">
</canvas>
</body>
</html>
2、获取对canvas元素以及canvas上下文的引用。
var drawing = document.getElementById("drawing");
var context = drawing.getContext("2d");
3、将游戏人物、怪物、背景图加载进去
因为图片是异步加载的,所以我使用了onload加载函数,并且设置了标记量,以免图片加载的过程中出现错误,显示不了画布上。
//在画布上获取对背景的引用
var bgReady = false; //布尔值用于确保何时可以正确的引用图片
var bgImage = new Image();
bgImage.onload = function () //图片的加载是异步加载
{
bgReady = true;
};
bgImage.src = "image/bg.png";
//在画布上获取对英雄的引用
var heroReady = false;
var heroImage = new Image();
heroImage.onload = function ()
{
heroReady = true;
};
heroImage.src = "image/hero.png";
//在画布上获取对怪兽的引用
var monsterReady = false;
var monsterImage = new Image();
monsterImage.onload = function ()
{
monsterReady = true;
};
monsterImage.src = "image/monster.png";
4、定义游戏对象,定义分数变量
在这个游戏里面,怪物是静止不动且随机出现的,当键盘上控制人物移动时,需要一个速度,即:speed,创建对象来保存他们的变量。
//定义游戏对象(英雄和怪兽的画布座标)
var hero = {
speed : 256,
x : 0,
y : 0
};
var monster = {
x : 0,
y : 0
};
var score = 0;
5、当游戏失败后重置网页或得分后怪物的位置随机出现
在这个函数中使用了随机数来确保怪物位置出现的随机性,确保了游戏的可玩性。
var reset = function ()
{
if(over == true)
{
hero.x = drawing.width/2;
hero.y = drawing.height/2;
over = false;
}
monster.x = 32 + Math.floor((Math.random() * (drawing.width - 64)));
monster.y = 32 + Math.floor((Math.random() * (drawing.height - 64)));
};
6、采用键盘事件的监听,保持稍后存储用户输入
这个部分我们旨在用addEventListener()方法、采用“keydown”、“keyup”来对键盘设置事件的监听,以此来获取用户键盘的输入。addEventListener()方法接受三个参数,即:
1)event,必选,注意: 不要使用 “on” 前缀。 例如,使用 “click” ,而不是使用 “onclick”。
2)必选。指定要事件触发时执行的函数, 当事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。
3) 可选。布尔值,指定事件是否在捕获或冒泡阶段执行。
var keyDown = {};
addEventListener("keydown", function(e){
keyDown[e.keyCode] = true;
},false);
addEventListener("keyup", function(e){
delete keyDown[e.keyCode];
},false);
7、游戏的更新
在这部分的函数中,前四个if语句说明了,当四个方向键被按下的时候,游戏人物会朝着相应的方向移动;第五个if语句用来判断怪兽和游戏人物是否相撞,相撞的话则得一分,因为游戏人物和怪兽都是32 * 32 像素的,所以判断语句才这么写的。
//Dom操作实现英雄和怪兽碰撞加分
var update = function (modifier)
{
if(38 in keyDown)
{
hero.y -= hero.speed * modifier;
}
if (40 in keyDown)
{
hero.y += hero.speed * modifier;
}
if (37 in keyDown)
{
hero.x -= hero.speed * modifier;
}
if (39 in keyDown)
{
hero.x += hero.speed * modifier;
}
if(
hero.x <= (monster.x + 32) &&
hero.y <= (monster.y + 32) &&
monster.x <= (hero.x + 32) &&
monster.y <= (hero.y + 32)
)
{
score = score + 1;
reset();
}
};
8、绘制图像
在这个部分中,我们就用到了之前的标志量,使得可以确保图片在加载时候可以正常的显示在画布中,因为图片是异步加载的;并且将得分情况写在了左上角。
//绘制图像(英雄、怪兽、背景、分数)
var render = function ()
{
if(bgReady)
{
context.drawImage(bgImage,0,0);
}
if(heroReady)
{
context.drawImage(heroImage,hero.x,hero.y);
}
if(monsterReady)
{
context.drawImage(monsterImage,monster.x,monster.y);
}
context.fillStyle = "#fff";
context.font = "24px Helvetica";
context.textAlign = "left";
context.textBaseline = "top";
context.fillText("你的得分: " + score, 32,32);
};
9、设置当英雄碰撞到画布上的边界时,游戏结束或者重置游戏
var over = false;
var gameOver = function ()
{
if(
hero.x <= 0 ||
hero.x >= drawing.width ||
hero.y <= 0 ||
hero.y >=drawing.height
)
{
over = true;
score = 0;
alert("很遗憾,你不小心结束了比赛!");
reset();
}
};
Tips
1、图片的加载方式是异步,必须使用onload加载函数才能够正确的显示
2、我们获取canvas是通过getElementById获取的,其所返回对象的宽和高就是我们所要获取的canvas的宽和高。
3、在设置游戏结束函数时,over必须是提前声明的,且在reset中要有判断over布尔值的语句。
如果大家获取源码的话,请点击这里:游戏源码地址
如果有什么问题还要深究的话,欢迎大家提问。