0020-wasm-康威生命游戏

环境

  • Time 2022-05-17
  • Rust 1.60.0
  • Node 12.22.5
  • wasm-pack 0.10.2

前言

说明

参考:https://rustwasm.github.io/docs/book/game-of-life/interactivity.html

目标

在上一节的基础上进行。给游戏增加暂停和继续功能。

index.html

<!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="utf-8">
  <title>康威生命游戏</title>
  <style>
    body {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
    }
  </style>
</head>


<body>
  <button id="play-pause"></button>
  <hr>
  <canvas id="game"></canvas>
  <script src="./bootstrap.js"></script>
</body>

</html>

animationId

const universe = Universe.new(WIDTH, HEIGHT);
let animationId = null;
const renderLoop = () => {
    drawGrid();
    drawCells();
    universe.tick();
    animationId = requestAnimationFrame(renderLoop);
};

增加点击事件

const playPauseButton = document.getElementById("play-pause");
const play = () => {
    playPauseButton.textContent = "暂停";
    renderLoop();
};

const pause = () => {
    playPauseButton.textContent = "继续";
    cancelAnimationFrame(animationId);
    animationId = null;
};

playPauseButton.addEventListener("click", _ => {
    animationId === null ? play() : pause();
});

play()

效果

暂停和继续

总结

实现了游戏的暂停和继续功能。

附录

源码

import { Universe } from "game";
import { memory } from "game/game_bg";

const CELL_SIZE = 10;
const GRID_COLOR = "#CCCCCC";
const DEAD_COLOR = "#FFFFFF";
const ALIVE_COLOR = "#000000";
const WIDTH = 64;
const HEIGHT = 64;


const canvas = document.getElementById("game");
canvas.height = (CELL_SIZE + 1) * HEIGHT + 1;
canvas.width = (CELL_SIZE + 1) * WIDTH + 1;
const ctx = canvas.getContext('2d');

const universe = Universe.new(WIDTH, HEIGHT);
let animationId = null;
const renderLoop = () => {
    drawGrid();
    drawCells();
    universe.tick();
    animationId = requestAnimationFrame(renderLoop);
};

const drawGrid = () => {
    ctx.beginPath();
    ctx.strokeStyle = GRID_COLOR;

    for (let i = 0; i <= WIDTH; i++) {
        ctx.moveTo(i * (CELL_SIZE + 1) + 1, 0);
        ctx.lineTo(i * (CELL_SIZE + 1) + 1, (CELL_SIZE + 1) * HEIGHT + 1);
    }

    for (let j = 0; j <= HEIGHT; j++) {
        ctx.moveTo(0, j * (CELL_SIZE + 1) + 1);
        ctx.lineTo((CELL_SIZE + 1) * WIDTH + 1, j * (CELL_SIZE + 1) + 1);
    }

    ctx.stroke();
};

const bitIsSet = (n, arr) => {
    const byte = Math.floor(n / 8);
    const mask = 1 << (n % 8);
    return (arr[byte] & mask) === mask;
};

const drawCells = () => {
    const cellsPtr = universe.cells();
    const cells = new Uint8Array(memory.buffer, cellsPtr, WIDTH * HEIGHT / 8);

    ctx.beginPath();
    for (let row = 0; row < HEIGHT; row++) {
        for (let col = 0; col < WIDTH; col++) {
            const idx = row * WIDTH + col;
            ctx.fillStyle = bitIsSet(idx, cells) ? ALIVE_COLOR : DEAD_COLOR;
            ctx.fillRect(col * (CELL_SIZE + 1) + 1,
                row * (CELL_SIZE + 1) + 1, CELL_SIZE, CELL_SIZE);
        }
    }
    ctx.stroke();
};

const playPauseButton = document.getElementById("play-pause");
const play = () => {
    playPauseButton.textContent = "暂停";
    renderLoop();
};

const pause = () => {
    playPauseButton.textContent = "继续";
    cancelAnimationFrame(animationId);
    animationId = null;
};

playPauseButton.addEventListener("click", _ => {
    animationId === null ? play() : pause();
});

play()
posted @   jiangbo4444  阅读(53)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示