canvas 小游戏吃豆人

Ⅰ . 吃豆人小游戏

在这里插入图片描述

  1. Canvas API(画布)是在 HTML5 中新增的标签用于在网页实时生成图像;
  2. 是一个非常适合,做一些有趣的小游戏 和 动画;
  3. 下面我们来简单的写一下 这个小例子 👇

    在这里插入图片描述

Ⅱ. 实现步骤

① 让吃豆人嘴巴,动起来
  1. 先画一个扇形 , 然后让扇形有一个的开口
<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>
  1. 然后我们需要,吧吃豆人的嘴动起来
  2. 这时我们就要用到定时器 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>
② 监听 上下左右 让吃豆人动起来
  1. 我们先要找到 上下左右按键 对应的 keyCode 分别是 37~39;
  2. 针对每个反向 改变下 “嘴” 的方向 [修改弧度];
  3. 在走到区域的末端,在反方向重新出现 👇
 // ....... 省略之前代码
  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; }
}
 // ....... 省略之前代码
③ 绘制随机出现的糖豆
  1. 设置 糖豆初始位置 ,通过 Math.random() 随机出现;
  2. 当糖豆在,移动的吃豆人的范围类的时候(40px) ,就初始化 糖豆;
  3. 在每次绘制 吃豆人之后 ,确认之间的距离是否在范围里 👇
    请添加图片描述
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()
    }
}
④ 添加积分器
  1. 在每次糖豆被吃掉时 (糖豆位置初始化时), 增加分数
  2. 绘制一个记录分数的盒子 👇
    请添加图片描述
<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>

在这里插入图片描述
在这里插入图片描述

  • 33
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 34
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野生切图仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值