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


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

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

    示例从简单到复杂。

    简单示例

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

     

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

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

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>刮刮乐(Scratch Card)title>
    6. <style>
    7. * {
    8. margin: 0;
    9. padding: 0;
    10. box-sizing: border-box;
    11. }
    12. body {
    13. height: 100vh;
    14. display: flex;
    15. justify-content: center;
    16. align-items: center;
    17. background-color: #f0f0f0; /* 背景色 */
    18. }
    19. canvas {
    20. background-image: url('bottom_image.png'); /* 底层图片 */
    21. background-size: cover;
    22. }
    23. style>
    24. head>
    25. <body>
    26. <canvas id="canvas" width="356" height="358">canvas>
    27. <script>
    28. var canvas = document.getElementById("canvas");
    29. var ctx = canvas.getContext("2d");
    30. // 加载上层图片(可被刮去的图层)
    31. var img = new Image();
    32. img.src = "top_image.png"; // 上层图片路径
    33. img.onload = function() {
    34. ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
    35. };
    36. // 标记是否按下鼠标(开始刮卡)
    37. var isDown = false;
    38. // 鼠标按下事件
    39. canvas.addEventListener('mousedown', function() {
    40. isDown = true;
    41. // 切换到“擦除”模式
    42. ctx.globalCompositeOperation = 'destination-out';
    43. });
    44. // 鼠标松开事件
    45. canvas.addEventListener('mouseup', function() {
    46. isDown = false;
    47. });
    48. // 鼠标移动事件
    49. canvas.addEventListener('mousemove', function(event) {
    50. if (isDown) {
    51. let x = event.offsetX;
    52. let y = event.offsetY;
    53. // 绘制擦除效果
    54. ctx.beginPath();
    55. ctx.arc(x, y, 20, 0, Math.PI * 2, false); // 使用圆形笔触
    56. ctx.fill();
    57. ctx.closePath();
    58. }
    59. });
    60. script>
    61. body>
    62. html>

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

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>刮刮乐(Scratch Card)2title>
    6. <style>
    7. * {
    8. margin: 0;
    9. padding: 0;
    10. box-sizing: border-box;
    11. }
    12. body {
    13. height: 100vh;
    14. display: flex;
    15. justify-content: center;
    16. align-items: center;
    17. background-color: #f0f0f0;
    18. }
    19. #container {
    20. position: relative;
    21. width: 356px;
    22. height: 358px;
    23. }
    24. canvas {
    25. position: absolute;
    26. top: 0;
    27. left: 0;
    28. }
    29. style>
    30. head>
    31. <body>
    32. <div id="container">
    33. <canvas id="bottomCanvas" width="356" height="358">canvas>
    34. <canvas id="topCanvas" width="356" height="358">canvas>
    35. div>
    36. <script>
    37. document.addEventListener('DOMContentLoaded', function() {
    38. var bottomCanvas = document.getElementById('bottomCanvas');
    39. var topCanvas = document.getElementById('topCanvas');
    40. var bottomCtx = bottomCanvas.getContext('2d');
    41. var topCtx = topCanvas.getContext('2d');
    42. // 加载底层图片
    43. var bottomImage = new Image();
    44. bottomImage.src = 'bottom_image.png'; // 底层图片路径
    45. bottomImage.onload = function() {
    46. bottomCtx.drawImage(bottomImage, 0, 0, bottomCanvas.width, bottomCanvas.height);
    47. };
    48. // 加载上层图片
    49. var topImage = new Image();
    50. topImage.src = 'top_image.png'; // 上层图片路径
    51. topImage.onload = function() {
    52. topCtx.drawImage(topImage, 0, 0, topCanvas.width, topCanvas.height);
    53. };
    54. var isDown = false;
    55. // 鼠标按下事件
    56. topCanvas.addEventListener('mousedown', function() {
    57. isDown = true;
    58. topCtx.globalCompositeOperation = 'destination-out';
    59. });
    60. // 鼠标松开事件
    61. topCanvas.addEventListener('mouseup', function() {
    62. isDown = false;
    63. });
    64. // 鼠标移动事件
    65. topCanvas.addEventListener('mousemove', function(event) {
    66. if (!isDown) return;
    67. var x = event.offsetX;
    68. var y = event.offsetY;
    69. // 绘制擦除效果
    70. topCtx.beginPath();
    71. topCtx.arc(x, y, 20, 0, Math.PI * 2, false); // 使用圆形笔触
    72. topCtx.fill();
    73. topCtx.closePath();
    74. });
    75. });
    76. script>
    77. body>
    78. html>

    复杂示例

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

    先给出效果

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

    我这里游戏图片:

    源码如下:

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>刮刮乐(Scratch Card)3title>
    6. <style>
    7. div{
    8. margin:20px;
    9. text-align:center;
    10. }
    11. * {
    12. margin: 0;
    13. padding: 0;
    14. box-sizing: border-box;
    15. }
    16. body {
    17. height: 100vh;
    18. display: flex;
    19. justify-content: center;
    20. align-items: center;
    21. background-color: #f0f0f0;
    22. }
    23. #container {
    24. position: relative;
    25. width: 356px;
    26. height: 358px;
    27. }
    28. canvas {
    29. position: absolute;
    30. top: 0;
    31. left: 0;
    32. }
    33. style>
    34. head>
    35. <body>
    36. <div>
    37. 选择游戏图片
    38. <select id="mySelect" onchange="loadImages()">
    39. <option value="1">1option>
    40. <option value="2">2option>
    41. <option value="3">3option>
    42. select>
    43. <div>
    44. <div id="container">
    45. <canvas id="bottomCanvas" width="356" height="358">canvas>
    46. <canvas id="topCanvas" width="356" height="358">canvas>
    47. div>
    48. <script>
    49. function loadImages() {
    50. var selectElement = document.getElementById('mySelect');
    51. var selectedValue = selectElement.options[selectElement.selectedIndex].value;
    52. var bottomCanvas = document.getElementById('bottomCanvas');
    53. var topCanvas = document.getElementById('topCanvas');
    54. var bottomCtx = bottomCanvas.getContext('2d');
    55. var topCtx = topCanvas.getContext('2d');
    56. // 清除画布
    57. bottomCtx.clearRect(0, 0, bottomCanvas.width, bottomCanvas.height);
    58. topCtx.clearRect(0, 0, topCanvas.width, topCanvas.height);
    59. // 加载底层图片
    60. var bottomImage = new Image();
    61. bottomImage.src = 'img/bottom' + selectedValue + '.png';
    62. bottomImage.onload = function() {
    63. bottomCtx.drawImage(bottomImage, 0, 0, bottomCanvas.width, bottomCanvas.height);
    64. };
    65. // 重新加载并绘制上层图片
    66. var topImage = new Image();
    67. topImage.src = 'img/top' + selectedValue + '.png'; // 确保这里的路径正确匹配你的图片路径和命名
    68. topImage.onload = function() {
    69. topCtx.globalCompositeOperation = 'source-over'; // 重置合成操作为默认值
    70. topCtx.drawImage(topImage, 0, 0, topCanvas.width, topCanvas.height);
    71. // 确保刮刮效果重新应用
    72. addScratchEffect(topCanvas, topCtx);
    73. };
    74. }
    75. function addScratchEffect(canvas, ctx) {
    76. var isDown = false;
    77. // 移除之前可能添加的事件监听器
    78. canvas.onmousedown = null;
    79. canvas.onmouseup = null;
    80. canvas.onmousemove = null;
    81. // 鼠标按下事件
    82. canvas.onmousedown = function() {
    83. isDown = true;
    84. ctx.globalCompositeOperation = 'destination-out'; // 设置合成操作以实现刮效果
    85. };
    86. // 鼠标松开事件
    87. canvas.onmouseup = function() {
    88. isDown = false;
    89. };
    90. // 鼠标移动事件
    91. canvas.onmousemove = function(event) {
    92. if (!isDown) return;
    93. var x = event.offsetX;
    94. var y = event.offsetY;
    95. // 绘制擦除效果
    96. ctx.beginPath();
    97. ctx.arc(x, y, 20, 0, Math.PI * 2); // 使用圆形笔触
    98. ctx.fill();
    99. };
    100. }
    101. // 页面加载完毕后初始化画布
    102. document.addEventListener('DOMContentLoaded', function() {
    103. loadImages(); // 页面加载时也加载图片
    104. });
    105. script>
    106. body>
    107. html>

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

    关于HTML5中,使用