Canvas动画之豌豆射手

🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄

🌹简历模板、学习资料、面试题库、技术互助

🌹文末获取联系方式 📝

在这里插入图片描述


往期热门专栏回顾

专栏描述
Java项目实战介绍Java组件安装、使用;手写框架等
Aws服务器实战Aws Linux服务器上操作nginx、git、JDK、Vue
Java微服务实战Java 微服务实战,Spring Cloud Netflix套件、Spring Cloud Alibaba套件、Seata、gateway、shadingjdbc等实战操作
Java基础篇Java基础闲聊,已出HashMap、String、StringBuffer等源码分析,JVM分析,持续更新中
Springboot篇从创建Springboot项目,到加载数据库、静态资源、输出RestFul接口、跨越问题解决到统一返回、全局异常处理、Swagger文档
Spring MVC篇从创建Spring MVC项目,到加载数据库、静态资源、输出RestFul接口、跨越问题解决到统一返回
华为云服务器实战华为云Linux服务器上操作nginx、git、JDK、Vue等,以及使用宝塔运维操作添加Html网页、部署Springboot项目/Vue项目等
Java爬虫通过Java+Selenium+GoogleWebDriver 模拟真人网页操作爬取花瓣网图片、bing搜索图片等
Vue实战讲解Vue3的安装、环境配置,基本语法、循环语句、生命周期、路由设置、组件、axios交互、Element-ui的使用等
Spring讲解Spring(Bean)概念、IOC、AOP、集成jdbcTemplate/redis/事务等

前端小游戏专栏回顾

专栏导航描述
前端小游戏- -Canvas魔法之黑客帝国特效
前端小游戏- -Canvas动画之豌豆射手

前言

今天我们实现豌豆射手自动发射豌豆的效果。
使用工具:Chrome浏览器(或其他支持H5的浏览器)
使用语言:HTML + JavaScript + Canvas + requestAnimationFrame
效果如下:
请添加图片描述


相关知识点介绍

HTML 、 JavaScript 、 Canvas 、 requestAnimationFrame
相关知识点介绍,详见 Canvas魔法之黑客帝国特效

豌豆射手自动发射豌豆效果实战

实现豌豆射手自动发射豌豆效果可以通过创建一个Canvas元素,并在上面使用JavaScript来绘制豌豆射手,豌豆从豌豆射手那里自动往前射击,到画布外之后子弹消失。并为整个画面设置一张草坪背景,意味着豌豆射手是在草坪上战斗。

分为2部分,Html画布(Canvas元素容器,设置草坪背景)、JavaScript脚本控制豌豆从豌豆射手那里自动往前射击。

Html画布

首先是HTML代码,你需要在HTML文件中添加一个Canvas元素:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Peashooter Animation</title>
<style>
  body {
    margin: 0;
    overflow: hidden;
    height: 100%;
  }
  canvas {
    background: #f4f4f4;
  }
</style>
</head>
<body onload="init()">
<canvas id="gameCanvas"></canvas>
<script src="script.js"></script>
</body>
</html>


动画控制

然后,是JavaScript代码,你可以将这部分代码保存为script.js文件:

const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

canvas.width = window.innerWidth / 2;
canvas.height = window.innerHeight / 3;

const bullets = []; // 存储子弹
const bulletSpeed = 10; // 子弹的速度
const peashooterImg = new Image(); // 创建豌豆射手图片对象
peashooterImg.src = 'mutpea.png'; // 设置图片源文件路径

const peashooter = {
  x: 50,
  y: canvas.height / 3,
  width: 80, // 根据实际图片大小调整
  height: 80 // 根据实际图片大小调整
};

function drawPeashooter() {
  ctx.drawImage(peashooterImg, peashooter.x, peashooter.y, peashooter.width, peashooter.height);
}

function drawBullets() {
  ctx.fillStyle = 'green';
  for (let i = 0; i < bullets.length; i++) {
    const bullet = bullets[i];
    ctx.beginPath();
    ctx.arc(bullet.x, bullet.y, 10, 0, Math.PI * 2);
    ctx.fill();

    // 更新子弹的位置
    bullet.x += bulletSpeed;

    // 如果子弹超出画布范围,则移除
    if (bullet.x >= canvas.width) {
      bullets.splice(i, 1);  // 也可使用其他JavaScript 数组删除元素函数
      i--; // 修正数组长度变化后的索引
    }
  }
}

function shoot() {
  // 添加一个子弹到数组中
  const bulletY = peashooter.y + peashooter.height / 2; // 子弹从豌豆射手中间发射
  bullets.push({ x: peashooter.x + peashooter.width, y: bulletY });
}

// 定时发射子弹
setInterval(shoot, 500);

function animate() {
  // 创建垂直渐变
  var gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
  // 添加颜色断点
  gradient.addColorStop(0, '#00b4d8'); // 天空的颜色
  gradient.addColorStop(1, '#48c78e'); // 草地的颜色

  // 设置渐变为填充样式并绘制背景
  ctx.fillStyle = gradient;
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  drawPeashooter(); // 绘制豌豆射手
  drawBullets(); // 绘制子弹
  requestAnimationFrame(animate); // 循环调用animate函数
}

// 确保图片加载后开始动画
peashooterImg.onload = animate;


讲解

在上述代码中,我们创建了一个Image对象来加载豌豆射手的图片。然后,我们定义了一个peashooter对象来存储豌豆射手的位置和大小。drawPeashooter函数使用drawImage方法将豌豆射手绘制到Canvas上。

drawBullets函数负责绘制和更新所有子弹的位置。shoot函数每隔一段时间被调用,以模拟豌豆射手发射子弹的动作(这里可以修改控制发射子弹的频率,现在的500毫秒,相当于0.5秒)。

最后,animate函数是动画的主循环,负责清除Canvas、绘制豌豆射手和子弹,并通过requestAnimationFrame递归调用自己。

注意,我们使用peashooterImg.onload来确保在图片加载完成后才开始动画循环,以避免在图片未加载完成时绘制。

将上述代码保存到相应的HTML和JavaScript文件中,并确保图片文件peashooter.png在项目目录中。打开HTML文件后,你应该能看到豌豆射手图片,并且它会定期发射子弹。

目录结构

  • index.html : html代码区域
  • mutpea.png、pea.png: 豌豆射手的图片,一张是多重豌豆射手、另一张是普通的豌豆射手
  • script.js:JavaScript脚本,控制豌豆发射
    在这里插入图片描述

资料获取,更多粉丝福利,关注下方公众号获取

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣1290. 二进制链表转整数

Problem: 1290. 二进制链表转整数 文章目录 题目描述思路复杂度Code 题目描述 思路 1.记录一个变量res初始化为0&#xff0c;指针p指向链表头&#xff1b; 2.循环每次res res * 2 p -> val;p p -> next;&#xff08;充分利用二进制数的特性&#xff1b;其中利用指针先…

Spring的生命周期

文章目录 第一章 对象的生命周期1.1 什么是对象的生命周期1.2 为什么要学习对象的生命周期1.3 生命周期的 3 个阶段1.3.1 创建阶段1.3.2 初始化阶段1.3.3 销毁阶段 1.4 总结 第二章 后置处理Bean2.1 后置处理Bean的运⾏原理分析2.2 BeanPostProcessor的开发步骤 第一章 对象的生…

哪个牌子的电视盒子好用?2024超强电视盒子排名

最近很多朋友问我电视盒子的相关问题&#xff0c;就目前来说&#xff0c;电视盒子的地位依然是不可取代的。我近来要发布的测评内容是哪个牌子的电视盒子好用&#xff0c;耗时两周进行对比后整理了电视盒子排名&#xff0c;看看哪些电视盒子是最值得入手的吧。 NO.1——泰捷新品…

有效涨点,增强型 YOLOV8 与多尺度注意力特征融合,附代码,详细步骤

目录 摘要 结构图 原理 代码实现 添加ymal文件 实验结果 可接论文指导----------> v jiabei-545 完整代码&#xff08;失效 -----------&#x1f446; &#xff09; 执行程序流程 摘要 在本实验中&#xff0c;我们通过将双层路由注意&#xff08;BRA&#xff09;…

[云原生] 二进制安装K8S(上)搭建单机matser、etcd集群和node节点

一、单机matser预部署设计 目前Kubernetes最新版本是v1.25&#xff0c;但大部分公司一般不会使用最新版本。 目前公司使用比较多的&#xff1a;老版本是v1.15&#xff0c;因为v1.16改变了很多API接口版本&#xff0c;国内目前使用比较多的是v1.18、v1.20。 组件部署&#xff…

Stable Diffusion 绘画入门教程(webui)-ControlNet(Inpaint)

上篇文章介绍了语义分割Tile/Blur&#xff0c;这篇文章介绍下Inpaint&#xff08;重绘&#xff09; Inpaint类似于图生图的局部重绘&#xff0c;但是Inpain效果要更好一点&#xff0c;和原图融合会更加融洽&#xff0c;下面是案例&#xff0c;可以看下效果&#xff08;左侧原图…

“美元是吸血鬼”!“这资产”成为最强避风港,兑14个国家货币创下历史新高!

随着比特币站稳5万美元大关&#xff0c;比特币兑土耳其、阿根廷、埃及、巴基斯坦、尼日利亚、日本和黎巴嫩等14个国家货币已创下历史新高。在价格尚未达到峰值69000美元前&#xff0c;多国货币的贬值造就了这一盛况&#xff0c;比特币正成为强大的避风港。 这种情况突显了14个国…

解决若依的分页失效问题

解决若依的分页失效问题 我的迷茫和胆怯也一直都在&#xff0c;但我告诉自己&#xff0c;就算是万丈深渊&#xff0c;走下去&#xff0c;也是前程万里。——木心《素履之往》 首先&#xff0c;我们根据若依的文档来清楚几个问题&#xff1a; 前端采用基于bootstrap的轻量级表格…

OpenAI视频生成Sora技术简析

基本介绍 Sora是春节期间OpenAI发布的产品&#xff0c;主要是通过文字描述生成视频&#xff0c;通过大规模视频数据训练而成的生成模型&#xff0c;当前还没开放试用。官方发布的技术报告&#xff1a;https://openai.com/research/video-generation-models-as-world-simulators…

【Simulink系列】——动态系统仿真 之 混合系统

声明&#xff1a;本系列博客参考有关专业书籍&#xff0c;截图均为自己实操&#xff0c;仅供交流学习&#xff01; 一、混合系统概述 由不同类型系统共同构成的系统称为混合系统&#xff01;仿真时必须考虑连续信号和离散信号的采样匹配问题&#xff0c;一般使用变步长连续求…

Sora 提示词每日分享 | 中英文对照

每日分享一个 sora 创意视频提示词之《冲浪者在历史大厅的巨浪中展现技艺》 sora提示词视频 prompt: In an ornate, historical hall, a massive tidal wave peaks and begins to crash. Two surfers, seizing the moment, skillfully navigate the face of the wave. 提示词…

成都直播产业园进行时!发挥直播电商优势 赋能优势产业发展

在当今数字化的时代&#xff0c;直播电商已经成为一种新型的商业模式&#xff0c;为优势产业的发展带来了巨大的机遇。通过直播电商&#xff0c;优势产业能够更好地展示自身特色和优势&#xff0c;扩大渠道&#xff0c;提升品牌影响力&#xff0c;从而实现产业的升级和转型。天…

JAVA工程师面试专题-《Redis》篇

目录 一、基础 1、Redis 是什么 2、说一下你对redis的理解 3、Redis 为什么这么快&#xff1f; 4、项目中如何使用缓存&#xff1f; 5、为什么使用缓存&#xff1f; 6、Redis key 和value 可以存储最大值分别多是多少&#xff1f; 7、Redis和memcache有什么区别&#xf…

数字电路设计得力助手——《Design Compiler User Guide》

在当今数字化时代&#xff0c;电子设备和芯片的需求日益增长&#xff0c;这使得数字电路设计变得愈发重要。在数字电路设计过程中&#xff0c;使用先进的工具和技术是至关重要的。Synopsys公司的Design Compiler就是这样一款备受推崇的设计编译器软件&#xff0c;而其详尽的用户…

python(ch2)

可变长编码和不可变长编码 可变长编码是指不同字符使用不同数量的字节进行编码。例如&#xff0c;UTF-8 编码中&#xff0c;ASCII 字符使用 1 个字节编码&#xff0c;而其他语言的字符使用 2 个或更多字节编码。 不可变长编码是指所有字符都使用相同数量的字节进行编码。例如…

代码随想录01 移除元素

移除元素 1.暴力解法2.双指针法 1.暴力解法 暴力解法就是嵌套两次for循环,第一层for循环来寻找数组中的值等于val的, 第二层for循环是往前覆盖,将值等于val的删除. 2.双指针法 双指针法,分为快指针和慢指针 快指针的意义是新的数组中含有的值 慢指针的意义是新的数组中值所在的…

SAP MD81创建客户独立需求简介

正常我们用的最多的计划独立需求都是使用的是MD61 ,今天我们说下SAP的另外的一个标准功能客户独立需求MD81。虽然SAP给这个TCODE的描述是客户独立需求,但是实际是没有地方去关联对应的客户信息的。或者可以理解为是一个关联销售订单的一个计划独立需求。 1、MD81在SAP中的路…

Pyglet综合应用|推箱子游戏之关卡图片载入内存

目录 读取图片 分割图片 综合应用 本篇为之前写的博客《怎样使用Pyglet库给推箱子游戏画关卡地图》的续篇&#xff0c;内容上有相关性&#xff0c;需要阅读的请见链接&#xff1a; https://hannyang.blog.csdn.net/article/details/136209138 「推箱子」是一款风靡全球的益…

Python及Pydev调试程序传递参数方法的实践

在Python中&#xff0c;可以使用sys.argv来获取命令行参数。下面是一个示例的Python脚本&#xff0c;展示了如何通过命令行传递参数并打印输出&#xff1a; import sys# 判断是否有传入参数 if len(sys.argv) > 1:# 获取第二个参数&#xff08;索引为1&#xff09;param s…

spring面试题

文章目录 前言一、面试题1、springIOC是什么&#xff1f;2、springIOC产生的原因&#xff1a;背景3、spring 中Bean的生命周期&#xff1a;4、springAOP&#xff1a;5、Spring框架中的设计模式-太多了1、单例模式&#xff08;Singleton Pattern&#xff09;&#xff1a;2、工厂…