用HTML5的<canvas>元素实现刮刮乐游戏

用HTML5的<canvas>元素实现刮刮乐游戏

用HTML5的<canvas>元素实现刮刮乐,要求:将上面的“图层”的图像可用鼠标刮去,露出下面的“图层”的图像。

示例从简单到复杂。

简单示例

准备两张图像,我这里上面的图像top_image.png,下面的图像bottom_image.png,如下图:

 

我这里为方便 ,经图片和源码文件放在同一个文件夹中。

先看用一个canvas元素实现刮刮乐,源码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>刮刮乐(Scratch Card)</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: #f0f0f0; /* 背景色 */
        }
        canvas {
            background-image: url('bottom_image.png'); /* 底层图片 */
            background-size: cover;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="356" height="358"></canvas>
    <script>
        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext("2d");

        // 加载上层图片(可被刮去的图层)
        var img = new Image();
        img.src = "top_image.png"; // 上层图片路径
        img.onload = function() {
            ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
        };

        // 标记是否按下鼠标(开始刮卡)
        var isDown = false;

        // 鼠标按下事件
        canvas.addEventListener('mousedown', function() {
            isDown = true;
            // 切换到“擦除”模式
            ctx.globalCompositeOperation = 'destination-out';
        });

        // 鼠标松开事件
        canvas.addEventListener('mouseup', function() {
            isDown = false;
        });

        // 鼠标移动事件
        canvas.addEventListener('mousemove', function(event) {
            if (isDown) {
                let x = event.offsetX;
                let y = event.offsetY;
                // 绘制擦除效果
                ctx.beginPath();
                ctx.arc(x, y, 20, 0, Math.PI * 2, false); // 使用圆形笔触
                ctx.fill();
                ctx.closePath();
            }
        });
    </script>
</body>
</html>

下面用两个canvas元素实现刮刮乐,底层图片和上层图片各用一个canvas元素,效果和上面的一样。实现的源码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>刮刮乐(Scratch Card)2</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: #f0f0f0;
        }
        #container {
            position: relative;
            width: 356px;
            height: 358px;
        }
        canvas {
            position: absolute;
            top: 0;
            left: 0;
        }
    </style>
</head>
<body>
    <div id="container">
        <canvas id="bottomCanvas" width="356" height="358"></canvas> <!-- 底层Canvas -->
        <canvas id="topCanvas" width="356" height="358"></canvas> <!-- 上层Canvas -->
    </div>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            var bottomCanvas = document.getElementById('bottomCanvas');
            var topCanvas = document.getElementById('topCanvas');
            var bottomCtx = bottomCanvas.getContext('2d');
            var topCtx = topCanvas.getContext('2d');

            // 加载底层图片
            var bottomImage = new Image();
            bottomImage.src = 'bottom_image.png'; // 底层图片路径
            bottomImage.onload = function() {
                bottomCtx.drawImage(bottomImage, 0, 0, bottomCanvas.width, bottomCanvas.height);
            };

            // 加载上层图片
            var topImage = new Image();
            topImage.src = 'top_image.png'; // 上层图片路径
            topImage.onload = function() {
                topCtx.drawImage(topImage, 0, 0, topCanvas.width, topCanvas.height);
            };

            var isDown = false;

            // 鼠标按下事件
            topCanvas.addEventListener('mousedown', function() {
                isDown = true;
                topCtx.globalCompositeOperation = 'destination-out';
            });

            // 鼠标松开事件
            topCanvas.addEventListener('mouseup', function() {
                isDown = false;
            });

            // 鼠标移动事件
            topCanvas.addEventListener('mousemove', function(event) {
                if (!isDown) return;
                var x = event.offsetX;
                var y = event.offsetY;
                // 绘制擦除效果
                topCtx.beginPath();
                topCtx.arc(x, y, 20, 0, Math.PI * 2, false); // 使用圆形笔触
                topCtx.fill();
                topCtx.closePath();
            });
        });

    </script>
</body>
</html>

复杂示例

下面是改进,从列表框(下拉框)选择图片刮刮乐,增加了游戏的趣味性。

先给出效果

项目(project)的目录结构如下:

我这里游戏图片:

源码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>刮刮乐(Scratch Card)3</title>
    <style>
        div{ 
            margin:20px;
            text-align:center;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: #f0f0f0;
        }
        #container {
            position: relative;
            width: 356px;
            height: 358px;
        }
        canvas {
            position: absolute;
            top: 0;
            left: 0;
        }
    </style>
</head>
<body>
    <div> 
        选择游戏图片
        <select id="mySelect" onchange="loadImages()"> <!-- 添加 onchange 事件 -->
            <option value="1">1</option> <!-- 更改 value 以匹配图像名称 -->
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
    <div>

    <div id="container">
        <canvas id="bottomCanvas" width="356" height="358"></canvas> <!-- 底层Canvas -->
        <canvas id="topCanvas" width="356" height="358"></canvas> <!-- 上层Canvas -->
    </div>

    <script>
        function loadImages() {
            var selectElement = document.getElementById('mySelect');
            var selectedValue = selectElement.options[selectElement.selectedIndex].value;

            var bottomCanvas = document.getElementById('bottomCanvas');
            var topCanvas = document.getElementById('topCanvas');
            var bottomCtx = bottomCanvas.getContext('2d');
            var topCtx = topCanvas.getContext('2d');

            // 清除画布
            bottomCtx.clearRect(0, 0, bottomCanvas.width, bottomCanvas.height);
            topCtx.clearRect(0, 0, topCanvas.width, topCanvas.height);

            // 加载底层图片
            var bottomImage = new Image();
            bottomImage.src = 'img/bottom' + selectedValue + '.png';
            bottomImage.onload = function() {
                bottomCtx.drawImage(bottomImage, 0, 0, bottomCanvas.width, bottomCanvas.height);
            };

            // 重新加载并绘制上层图片
            var topImage = new Image();
            topImage.src = 'img/top' + selectedValue + '.png'; // 确保这里的路径正确匹配你的图片路径和命名
            topImage.onload = function() {
                topCtx.globalCompositeOperation = 'source-over'; // 重置合成操作为默认值
                topCtx.drawImage(topImage, 0, 0, topCanvas.width, topCanvas.height);
                // 确保刮刮效果重新应用
                addScratchEffect(topCanvas, topCtx);
            };
        }

        function addScratchEffect(canvas, ctx) {
            var isDown = false;
            // 移除之前可能添加的事件监听器
            canvas.onmousedown = null;
            canvas.onmouseup = null;
            canvas.onmousemove = null;

            // 鼠标按下事件
            canvas.onmousedown = function() {
                isDown = true;
                ctx.globalCompositeOperation = 'destination-out'; // 设置合成操作以实现刮效果
            };

            // 鼠标松开事件
            canvas.onmouseup = function() {
                isDown = false;
            };

            // 鼠标移动事件
            canvas.onmousemove = function(event) {
                if (!isDown) return;
                var x = event.offsetX;
                var y = event.offsetY;
                // 绘制擦除效果
                ctx.beginPath();
                ctx.arc(x, y, 20, 0, Math.PI * 2); // 使用圆形笔触
                ctx.fill();
            };
        }

        // 页面加载完毕后初始化画布
        document.addEventListener('DOMContentLoaded', function() {
            loadImages(); // 页面加载时也加载图片
        });

    </script>
</body>
</html>

本文是对https://blog.csdn.net/cnds123/article/details/112392014 例子的补充

关于HTML5中,使用<select>元素创建一个列表框(下拉框),并使用JavaScript来操作,可参见https://blog.csdn.net/cnds123/article/details/128353007

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

学习&实践爱好者

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

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

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

打赏作者

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

抵扣说明:

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

余额充值