Ⅰ . 吃豆人小游戏
Canvas API
(画布)是在HTML5
中新增的标签用于在网页实时生成图像;- 是一个非常适合,做一些有趣的小游戏 和 动画;
- 下面我们来简单的写一下 这个小例子 👇
文章目录
- Ⅰ . 吃豆人小游戏
- Ⅱ. 实现步骤
- ① 让吃豆人嘴巴,动起来
- ③ 监听 上下左右 让吃豆人动起来
- ② 绘制随机出现的糖豆
- ④ 添加积分器
- Ⅱ. 整合最终代码
Ⅱ. 实现步骤
① 让吃豆人嘴巴,动起来
- 先画一个扇形 , 然后让扇形有一个的开口
<body>
<canvas id="cvs" width="1000" height="500"></canvas>
</body>
<script>
const canvas = document.getElementById("cvs");
const ctx = canvas.getContext('2d');
let x = 500, y = 200; // 扇形的初始位置
let start = Math.PI*1.95, end = Math.PI*0.1; //扇形的开口弧度
draw()
function draw(){
ctx.clearRect(0,0,1000,500);
ctx.beginPath();
ctx.fillStyle = "orange";
ctx.arc(x,y,50,start,end,0);
ctx.lineTo(x,y);
ctx.fill();
ctx.stroke();
}
</script>
- 然后我们需要,吧吃豆人的嘴动起来
- 这时我们就要用到定时器
setInterval
,每改变 嘴(扇形弧度
), 重新绘制一遍
<body>
<canvas id="cvs" width="1000" height="500"></canvas>
</body>
<script>
const canvas = document.getElementById("cvs");
const ctx = canvas.getContext('2d');
let x = 500, y = 200; // 扇形的初始位置
let start = Math.PI*1.95, end = Math.PI*0.1; //扇形的开口弧度
let isMax = true; // 弧度是否张开最大
let num = 0; // 弧度改变的次数
setInterval(()=>{ setAngle(); draw(); },30);
function setAngle() { // 修改圆的开口
angle = isMax ? Math.PI*0.01:(-Math.PI*0.01)
start = start - angle
end = end + angle
num++;
if(num==10){
isMax=!isMax;
num = 0
}
}
function draw(){ // 绘制圆
ctx.clearRect(0,0,1000,500);
ctx.beginPath();
ctx.fillStyle = "orange";
ctx.arc(x,y,50,start,end,0);
ctx.lineTo(x,y);
ctx.fill();
ctx.stroke();
}
</script>
③ 监听 上下左右 让吃豆人动起来
- 我们先要找到 上下左右按键 对应的
keyCode
分别是 37~39; - 针对每个反向 改变下 “嘴” 的方向 [
修改弧度
]; - 在走到区域的末端,在反方向重新出现 👇
// ....... 省略之前代码
document.onkeydown = function(e){
switch(e.keyCode){
case 37: start = Math.PI*0.8, end = Math.PI*1.1; move('←'); reset(); break;
case 38: start = Math.PI*1.45, end = Math.PI*1.7; move('↑'); reset(); break;
case 39: start = Math.PI*1.95, end = Math.PI*0.1; move('→'); reset(); break;
case 40: start = Math.PI*0.4, end = Math.PI*0.7; move('↓'); reset(); break;
}
}
function move(direction){
switch(direction){
case '←': x-=5; draw(); break;
case '↑': y-=5; draw(); break;
case '→': x+=5; draw(); break;
case '↓': y+=5; draw(); break;
}
}
function reset(){
if(x > 1050) { x = 0; }
if(x < 0) { x = 1050; }
if(y > 550) { y =0; }
if(y < 0) { y =550; }
}
// ....... 省略之前代码
② 绘制随机出现的糖豆
- 设置 糖豆初始位置 ,通过
Math.random()
随机出现; - 当糖豆在,移动的吃豆人的范围类的时候(
40px
) ,就初始化
糖豆; - 在每次绘制 吃豆人之后 ,确认之间的距离是否在范围里 👇
let t_x = Math.round(Math.random() * 900) ,t_y = Math.round(Math.random() * 450);
function draw() {
// ...省略之前代码
t_draw()
}
function t_draw(){
ctx.beginPath();
ctx.arc(t_x,t_y,10,0,Math.PI*2,0);
ctx.stroke();
if(
t_x > x - 40
&& t_x < x + 40
&& t_y > y - 40
&& t_y < y + 40
){
t_x=Math.round(Math.random()*900);
t_y=Math.round(Math.random()*450);
t_draw()
}
}
④ 添加积分器
- 在每次糖豆被吃掉时 (
糖豆位置初始化时
), 增加分数 - 绘制一个记录分数的盒子 👇
<style>
.box{
width: 150px;
height: 60px;
background-color: yellow;
font-size: 20px;
text-align: center;
line-height: 60px;
border: 2px solid coral;
border-radius: 20px;
position: relative;
top: -500px;
left: 840px;
}
</style>
<body>
<div class="box">分数为:<span id="score">0</span></div>
</body>
<script>
// ...省略其他代码
addScore() { //重新改变糖豆位置时执行
const score = document.getElementById('score')
score.innerHTML = Number(score.innerHTML) + 5
}
</script>
Ⅱ. 整合最终代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
#cvs {
background-color: paleturquoise;
}
.box {
width: 150px;
height: 60px;
color: chocolate;
background-color: yellow;
font-size: 20px;
text-align: center;
line-height: 60px;
border: 2px solid coral;
border-radius: 20px;
position: relative;
top: -500px;
left: 840px;
}
</style>
<body>
<canvas id="cvs" width="1000" height="500"></canvas>
<div class="box">分数为:<span id="score">0</span></div>
</body>
<script>
const canvas = document.getElementById("cvs");
const ctx = canvas.getContext('2d');
let start = Math.PI * 1.95, end = Math.PI * 0.1;
let x = 100, y = 200;
let t_x = Math.round(Math.random() * 900);
let t_y = Math.round(Math.random() * 450);
let isMax = true;
let num = 0;
setInterval(setAngle, 30);
document.onkeydown = function (e) {
switch (e.keyCode) {
case 37: start = Math.PI * 0.8, end = Math.PI * 1.1; move('←'); reset(); break;
case 38: start = Math.PI * 1.45, end = Math.PI * 1.7; move('↑'); reset(); break;
case 39: start = Math.PI * 1.95, end = Math.PI * 0.1; move('→'); reset(); break;
case 40: start = Math.PI * 0.4, end = Math.PI * 0.7; move('↓'); reset(); break;
}
}
function move(direction) {
switch (direction) {
case '←': x -= 5; draw(); break;
case '↑': y -= 5; draw(); break;
case '→': x += 5; draw(); break;
case '↓': y += 5; draw(); break;
}
}
function setAngle() {
angle = isMax ? Math.PI * 0.01 : (-Math.PI * 0.01)
start = start - angle
end = end + angle
num++;
if (num == 10) {
isMax = !isMax;
num = 0
}
draw();
}
function draw() {
ctx.clearRect(0, 0, 1000, 500);
ctx.beginPath();
ctx.fillStyle = "orange";
ctx.arc(x, y, 50, end, start, 0);
ctx.lineTo(x, y);
ctx.fill();
ctx.stroke();
t_draw();
}
function t_draw() {
ctx.beginPath();
ctx.arc(t_x, t_y, 10, 0, Math.PI * 2, 0);
ctx.stroke();
if (
t_x > x - 40
&& t_x < x + 40
&& t_y > y - 40
&& t_y < y + 40
) {
t_x = Math.round(Math.random() * 900);
t_y = Math.round(Math.random() * 450);
t_draw()
addScore()
}
}
function addScore() { //重新改变糖豆位置时执行
const score = document.getElementById('score')
score.innerHTML = Number(score.innerHTML) + 5
}
function reset() {
if (x > 1050) {
x = 0
}
if (x < 0) {
x = 1050
}
if (y > 550) {
y = 0;
}
if (y < 0) {
y = 550;
}
}
</script>
</html>