Day11 - Bmo 眼睛嘴巴动起来

https://ithelp.ithome.com.tw/upload/images/20210926/20140513sgBHkEVjD5.png
设定 BMO 初始化、更新要更新什麽、画出 BMO 的方法

class Bmo {
  constructor(ctx, time) {
    // 希望画布与时间跟游戏舞台同步
    this.ctxBmo = ctx;
    this.time = time;

    // Bmo 眼睛参数
    this.eyes = {
      right: {
        pos: {x:230, y:130},
        size: 7,
      },
      left: {
        pos: {x:130, y:130},
        size: 7,
      },
    }

    // Bmo 笑容弧度参数
    this.mouth = {
      beginArc: 1/4*Math.PI,
      endArc: 3/4*Math.PI
    }
    this.update();
    this.render();
  };
  
  // 资料更新
  update() {
    // 眼睛随着滑鼠移动而飘移
    // 滑鼠监听事件晚点会绑定在游戏舞台画布上
    // mouse 的 x y 移动范围晚点会定义为游戏舞台画布 offsetX offsetY
    // 所以 mouse 的 x y 移动范围将介於 0~游戏舞台画布长宽之间
    this.eyes = {
      right: {
        pos: {
          x: 230+mouse.x*0.1,
          y: 130+mouse.y*0.05,
        },
        size: 7,
      },
      left: {
        pos: {
          x: 130+mouse.x*0.1,
          y: 130+mouse.y*0.05
        },
        size: 7,
      },
    };

    // 嘴巴随着滑鼠移动而歪嘴笑
    this.mouth = {
      beginArc: 1/4*Math.PI+0.001*mouse.x,
      endArc: 3/5*Math.PI+0.001*mouse.x
    };
  };
  
  // 画面呈现
  render() {
    // 画 Bmo 身体
    this.ctxBmo.fillStyle = 'hsl(138, 39%, 64%)';
    this.ctxBmo.beginPath();
        this.ctxBmo.fillRect(50,50,300,300);
    this.ctxBmo.closePath();

    // 身体个区块描边颜色
    this.ctxBmo.strokeStyle = "rgba(0,50,0,1)";

    // Bmo 脸
    this.ctxBmo.beginPath();
        this.ctxBmo.rect(100,100,200,100);
        this.ctxBmo.fillStyle = 'hsl(108, 48%, 87%)';
        this.ctxBmo.fill();
        this.ctxBmo.stroke();
    this.ctxBmo.closePath();

    // Bmo 左眼
    this.ctxBmo.beginPath();
        this.ctxBmo.arc(this.eyes.left.pos.x,this.eyes.left.pos.y,7,0,2*Math.PI);
        this.ctxBmo.fillStyle = 'hsl(108, 20%, 22%)';
        this.ctxBmo.fill();
        this.ctxBmo.stroke();
    this.ctxBmo.closePath();
        
    // Bmo 右眼
    this.ctxBmo.beginPath();
        this.ctxBmo.arc(this.eyes.right.pos.x,this.eyes.right.pos.y,7,0,2*Math.PI);
        this.ctxBmo.fillStyle = 'hsl(108, 20%, 22%)';
        this.ctxBmo.fill();
        this.ctxBmo.stroke();
    this.ctxBmo.closePath();

    // Bmo mouth
    this.ctxBmo.beginPath();
        this.ctxBmo.arc(200,100,75,this.mouth.beginArc,this.mouth.endArc);
        this.ctxBmo.stroke();
    this.ctxBmo.closePath();

    // bmo btn 左上空白键
    this.ctxBmo.beginPath();
        this.ctxBmo.strokeRect(100,225,100,20);
        this.ctxBmo.stroke();
    this.ctxBmo.closePath();

    // bmo btn 左中十字
    // 颜色随时间改变而变更,并设定改变范围介於 0~359
    this.ctxBmo.fillStyle = `hsl(${this.time%360},50%,50%)`;
    this.ctxBmo.beginPath();
        this.ctxBmo.fillRect(105,270,40,10);
        this.ctxBmo.fillRect(120,255,10,40);
        this.ctxBmo.fill();
        this.ctxBmo.stroke();
    this.ctxBmo.closePath();

    // bmo btn 左下一一
    this.ctxBmo.beginPath();
        this.ctxBmo.strokeRect(100,310,40,15);
        this.ctxBmo.strokeRect(160,310,40,15);
        this.ctxBmo.stroke();
    this.ctxBmo.closePath();

    // bmo btn 右中三角形
    this.ctxBmo.beginPath();
        this.ctxBmo.moveTo(250,245);
        this.ctxBmo.lineTo(275,270);
        this.ctxBmo.lineTo(225,270);
        this.ctxBmo.closePath();
        this.ctxBmo.stroke();
    this.ctxBmo.closePath();

    // bmo btn 右上圆
    this.ctxBmo.beginPath();
        this.ctxBmo.arc(275,235,10,0,2*Math.PI);
        this.ctxBmo.stroke();
    this.ctxBmo.closePath();

    // bmo btn 右下圆
    this.ctxBmo.beginPath();
        this.ctxBmo.arc(250,305,25,0,2*Math.PI);
        this.ctxBmo.fillStyle = 'hsl(354, 84%, 49%)';
        this.ctxBmo.fill();
        this.ctxBmo.stroke();
    this.ctxBmo.closePath();

    // bmo btn 右右中圆
    this.ctxBmo.beginPath();
        this.ctxBmo.arc(295,280,6,0,2*Math.PI);
        this.ctxBmo.stroke();
    this.ctxBmo.closePath();
  }
};

设定游戏舞台初始化(包含铺画布、请 BMO 上台、更新资料、绘制画面)

class GameBoard{
  constructor(){
    this.canvas = document.getElementById('canvasBmoClass');
    this.ctx = this.canvas.getContext('2d');
    this.canvas.width = 400;
    this.canvas.height = 400;
    this.time = 0;

    // Bmo 上台
    this.bmo = new Bmo(this.ctx, this.time);
    this.update();
    this.render();
  };
  update(){
    this.time ++;
    // bmo 时间也同步更新
    this.bmo.time = this.time;
    this.bmo.update();
    setTimeout(()=>this.update());
  };
  render(){
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    this.ctx.beginPath();
    this.ctx.fillStyle = "rgba(0,0,0,0.2)";
    this.ctx.strokeStyle = "rgba(0,0,0,0.2)";
    for(let i=1;i<9;i++){
        let pos = 50*i
        // 画垂直线
        this.ctx.moveTo(pos,0);
        this.ctx.lineTo(pos,400);
        // 画水平线
        this.ctx.moveTo(0,pos);
        this.ctx.lineTo(400,pos);
        // 写轴 x 座标与 y 轴座标
        this.ctx.fillText(pos,pos,10);
        this.ctx.fillText(pos,0,pos);
    }
    this.ctx.stroke();
    this.bmo.render();
    requestAnimationFrame(()=>this.render());
  };
};

// 呼叫游戏舞台出场~
var gameBoard = new GameBoard();

当滑鼠经过游戏舞台时,纪录滑鼠 offset 座标,取得滑鼠在游戏舞台内移动的状态

var mouse = {
    x: 0,
    y: 0
};
gameBoard.canvas.addEventListener('mousemove',function(evt){
    mouse.x = evt.offsetX;
    mouse.y = evt.offsetY;
})

祝大家开开心心河河笑,如果上述理解有误希望能协助提点~感谢大家 ε= ᕕ( ᐛ )ᕗ


<<:  [Day12] 为了摆脱菜鸟C#後端 -到底什麽是Delegate?Func<T, TResult>?

>>:  12 | WordPress 图库区块 Gallery Block

纠正很有用,但鼓励的效果更好。

纠正很有用,但鼓励的效果更好。 Correction does much, but encourag...

[Day23]-用python处理影像档案2

在影像内绘制图案 绘制点、线条 绘制多边形 *在影像内填入文字 小实作-制作Qrcode ...

D23 - 走!去浏览器用 create & append 加餐

前言 恭喜 codepen 复活 \(^∀^)メ(^∀^)ノ 终於可以透过实作来学习如何选取元素、操...

C# 入门之逻辑判断(上)

在讲逻辑判断之前,我们需要了解一下 C# 中的比较运算符,在前面的数据类型和运算符的介绍中,我们有介...

[30天 Vue学好学满 DAY16] slot 插槽

slot 在子元件(内层)中预留空间,由父元件(外层)设定、分配内容。 子元件本身对slot无控制权...