用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>

复杂示例

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

先给出效果

我这里游戏图片:

源码如下:

<!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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/712167.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

7、Redis-事务、持久化、内存淘汰机制和过期key处理

目录 一、事务 二、持久化 三、内存淘汰机制 四、过期key处理 一、事务 Redis的事务本质上就是一个批量执行命令的操作。分为三个步骤&#xff1a; 开始事务&#xff1a;multi命令入队&#xff1a;正常输入命令即可执行事务&#xff08;依次执行命令&#xff09;&#xf…

不是我吹,这8道HashMap面试题让你面试时对答如流

前言 又到了一年一度的金三银四面试季&#xff0c;我们拿着自己的面试秘籍去面试&#xff0c;但是面试官的问题五花八门&#xff0c;让我们摸不清他们的套路。今天我就总结了面试时必问的hashmap面试题&#xff0c;无论面试官怎么问&#xff0c;我们都对答如流。 另外本人整理了…

java小记(2)

IS-A&#xff1a;类的父子继承关系。 default&#xff1a;关键字&#xff0c;与Java中的public&#xff0c;private等关键字一样&#xff0c;都属于修饰符关键字&#xff0c;可以用来修饰属性、方法以及类&#xff0c;但是default一般用来修饰接口中的方法。 接口与抽象类的区…

马斯克正式起诉OpenAI和奥特曼!

就在刚刚&#xff0c;马斯克闹出来一件大事——正式起诉OpenAI和Sam Altman&#xff0c;并要求OpenAI 恢复开源GPT-4等模型&#xff01; 众所周知&#xff0c;马斯克这两年一只在推特上指责 OpenAI是CloseAI(不开源)&#xff0c;但都只是停留在口头上。 而这次马斯克动了真格。…

从0开始python学习-53.python中flask创建简单接口

目录 1. 创建一个简单的请求,没有写方法时默认为get 2. 创建一个get请求 3. 创建一个post请求&#xff0c;默认可以使用params和表单传参 4. 带有参数的post请求 1. 创建一个简单的请求,没有写方法时默认为get from flask import Flask, request# 初始化一个flask的对象 ap…

USB - Battery Charing

Getting to the bottom of USB Battery Charging (了解 USB 电池充电的真相) 如今&#xff0c;几乎所有带电池的产品都被期望支持 BC1.2 USB 充电标准。 Today, almost every product with a battery is expected to support the BC1.2 standard for USB charging. 这对消费者来…

详解字符串函数<string.h>(上)

1. strlen函数的使用和模拟实现 size_t strlen(const char* str); 1.1 函数功能以及用法 字符串长度 strlen函数的功能是计算字符串的长度。在使用时&#xff0c;要求用户传入需要计算长度的字符串的起始位置&#xff0c;并返回字符串的长度。 #include <stdio.h> #…

基于SSM医院电子病历管理系统的设计与实现(源代码+数据库脚本+万字文档+PPT)

系统介绍 医院电子病历管理系统主要是借助计算机&#xff0c;通过对医院电子病历管理系统所需的信息管理&#xff0c;增加用户的选择&#xff0c;同时也方便对广大用户信息的及时查询、修改以及对用户信息的及时了解。医院电子病历管理系统 对用户带来了更多的便利&#xff0c…

一文读懂ZKFair PFP-CyberArmy的参与价值与潜力

3月2日&#xff0c;ZKFair PFP-CyberArmy 将在 Element 上正式开始Public Sale。

文件基础和文件fd

文章目录 预备知识C语言的文件接口系统调用文件fd 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转到网站。 预备知识 我们平时说文件就是说文件里…

大模型量化技术原理-SmoothQuant

近年来&#xff0c;随着Transformer、MOE架构的提出&#xff0c;使得深度学习模型轻松突破上万亿规模参数&#xff0c;从而导致模型变得越来越大&#xff0c;因此&#xff0c;我们需要一些大模型压缩技术来降低模型部署的成本&#xff0c;并提升模型的推理性能。 模型压缩主要分…

强化学习(六)时序差分

时序差分&#xff08;TD&#xff09;是强化学习的核心&#xff0c;其是蒙特卡罗&#xff08;MC&#xff09;和动态规划&#xff08;DP&#xff09;的结合。 1、TD 预测 TD 和 MC 都是利用经验来解决预测问题。一种非平稳环境的一般访问蒙特卡罗方法是 V ( S t ) ← V ( S t …

Python GUI开发库之nicegui使用详解

概要 在 Python 中,创建图形用户界面(GUI)应用程序通常需要大量的代码和时间。然而,随着 Python 生态系统的不断发展,出现了一些简化 GUI 开发过程的工具和库。其中之一就是 NiceGUI 库。本文将深入探讨 NiceGUI 库的功能、用法以及如何利用它来创建漂亮而功能丰富的 GUI…

List 集合遍历过程中删除元素避坑指南。

文章目录 1. 遍历2. 遍历过程中删除元素2.1 for 简单循环正向遍历方式2.2 for 简单循环反向遍历方式2.3 foreach 方式遍历删除2.4 Iterator的remove()方法2.5 <font color green> removeIf() &#xff08;推荐&#xff09;<green>2.6 Strem 方式 作为一名后端开发…

nginx使用详解--动静分离

什么是动静分离&#xff1f; 为了提高网站的响应速度&#xff0c;减轻程序服务器&#xff08;Tomcat&#xff0c;Jboss等&#xff09;的负载&#xff0c;对于静态资源&#xff0c;如图片、js、css等文件&#xff0c;可以在反向代理服务器中进行缓存&#xff0c;这样浏览器在请…

如何利用HubSpot海外获客系统实现海外市场扩张?

在当今全球化的时代&#xff0c;企业面临着越来越激烈的竞争&#xff0c;而海外市场则被视为获取更多增长机会的重要途径之一。针对这一挑战&#xff0c;企业需要建立一个完整的海外获客系统&#xff0c;而HubSpot软件的应用则成为了关键。作为HubSpot的合作伙伴&#xff0c;我…

librtmp源码分析

阅读了librtmp的源码&#xff0c;简单记录下。 首先补充下AMF格式基本知识 1 AMF格式 AMF是Action Message Format(动作消息格式)的简写&#xff0c;它是一种二进制的数据格式。它的设计是为了把actionscript里面的数据(包括Object, Array, Boolean, Number等)序列化成二进制…

oracle11安装及使用

安装oracle11 官网下载地址 Oracle Database 11g Release 2 for Microsoft Windows (x64) 官网下载慢可访问我的资源 也可以网盘获取 链接&#xff1a;https://pan.baidu.com/s/1RDrGkqDA7tfKRnpJXUBMDw 提取码&#xff1a;z3na 上传安装包到服务器 在指定目录下创建文件…

adb命令

1. 常用命令&#xff1a; adb devices #查看连接设备adb -s cf27456f shell # 指定连接设备使用命令adb install test.apk # 安装应用adb install -r demo.apk #安装apk 到sd 卡&#xff1a;adb uninstall cn.com.test.mobile #卸载应用&#xff0c;需要指定包adb uninstall -…

Windows系统x86机器安装龙芯(loongarch64)3A5000虚拟机系统详细教程

本次介绍在window系统x86机器上安装loongarch64系统的详细教程。 1.安装环境准备。 首先&#xff0c;你得有台电脑。 配置别太差&#xff0c;至少4核8G内存&#xff0c;安装window10或者11都行&#xff08;为啥不能是Window7&#xff0c;你要用也不是不行&#xff0c;你先解决…