H5前端其实很简单!H5前端入门 canvas游戏设计 内附全注释~
sinye56 2024-10-23 14:23 10 浏览 0 评论
前端,对于一个初学者来说,可能有人会觉得很难。
不过呢,前端主要还是靠理解和多练。
一时的不理解与不认识没关系,时间久了就好。
今天小编特意整理前两天一个canvas小游戏。分享给各位。
有兴趣的伙伴们可以尝试看看哦~。
注释齐全,容易理解。
注意:复制进 编码软件里再运行。
游戏完成效果
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
#mc{
background: black;
display:block;
margin: 0 auto;
}
</style>
</head>
<body>
<canvas id="mc" width="800" height="800"></canvas>
</body>
<script>
var mc = document.getElementById('mc'); //获取元素
var ctx = mc.getContext('2d'); //画笔
//全局变量
//鼠标基于canvas画布的x坐标(绘制白色快及子弹)
var mouseX = mc.width / 2 - 20;
//子弹数组
var bulletArr = [];
//掉落快数组
var enemyArr = [];
//爆炸物数组
var boomArr = [];
//分数初始值
var score = 0;
//没被击中,且移出画布的掉落块的数量
var dieNum = 0;
//绘制频率计时器
var eleMoveTimer;
//掉落快计时器
var createEnemyTimer;
//随机数
function sui(x, y) {
return Math.round(Math.random() * (y - x) + x)
}
//游戏开始页面
function drawStartPage() {
ctx.beginPath();
ctx.font = '60px Arial';
ctx.fillStyle = 'white';
ctx.fillText('暴力像素块', 250, 400); //canvas 前一个是内容,后两个是起点
ctx.beginPath();
ctx.font = '30px Arial';
ctx.fillStyle = '#F5F5F5';
ctx.fillText('点击游戏页面任何位置开始游戏', 180, 480); //canvas 前一个是内容,后两个是起点
}
drawStartPage();
//绘制白块
function drawBox() {
//判断盒子x轴的最大值,不让盒子从画布里出去
if(mouseX > mc.width - 20) {
mouseX = mc.width - 20;
}
//判断盒子x轴的最小值,不让盒子从画布里出去(只能用if语句,不能用三目运算符)
if(mouseX < 20) {
mouseX = 20;
}
//绘制白块
ctx.beginPath();
ctx.fillStyle = '#fff';
ctx.fillRect(mouseX - 20, 730, 40, 40);
ctx.fill();
}
//封装子弹类
function Bullet() {
this.x = mouseX - 4; //子弹x的坐标
this.y = 726; //子弹y的坐标
this.spped = 2; //子弹匀速移动速度
}
//绘制子弹方法
Bullet.prototype.move = function() {
this.y -= this.spped;
ctx.beginPath(); //开始一条新路径
ctx.fillStyle = '#fff';
ctx.fillRect(this.x, this.y, 8, 8);
ctx.fill();
//当子弹移出画布的时候,从数组中是喊出,减少不必要的循环,出去的都是数组里第一个元素
if(this.y < 0) {
bulletArr.shift();
}
}
//创建一个子弹
function createBullet() {
var bullet = new Bullet(); //实例化子弹
bulletArr.push(bullet); //塞进子弹数组
//console.log(bulletArr);
}
/*
* Enemy()类:掉落块的类
* x,y 是坐标
* wh:是宽高
* vx,vy:水平方向和竖直方向移动的速度
* bc:背景色
* dis:左右摇摆的范围
*/
//创建
function Enemy(x, wh, vx, vy, bc, dis) {
this.x = x;
this.y = -wh;
this.wh = wh;
this.bc = bc;
this.vx = vx;
this.vy = vy;
this.left = this.x - dis; //摆动的左边边界
this.right = this.x + dis; //摆动右边的边界
}
Enemy.prototype.move = function() {
//当块左右摆动到达边界之后,反弹
if(this.x < this.left || this.x > this.right) {
this.vx *= -1
}
//位置变化
this.x += this.vx;
this.y += this.vy;
//绘制方块
ctx.beginPath();
ctx.fillStyle = this.bc;
ctx.fillRect(this.x, this.y, this.wh, this.wh);
ctx.fill();
}
//封装创建一个方块函数(实例化enemy)
var minWh = 40,
maxWh = 70; //敌方飞机的宽高范围
var MinX = 0,
maxX = mc.width - maxWh; //x坐标范围
var minVx = -2,
maxVx = 3; //x方向速度范围
var minVy = 1,
maxVy = 3; //y方向速度范围
var minDis = 0,
maxDis = 100; //摆动范围
function createEmeny() {
var x = sui(MinX, maxX); //地方位置
var wh = sui(minWh, maxWh); //宽高
var vx = sui(minVx, maxVx); //x方向速度范围
var vy = sui(minVy, maxVy); //
var dis = sui(minDis, maxDis); //摆动范围
var bc = 'rgb('+ sui(30, 255) + ','+ sui(30, 255) + ','+ sui(30, 255) + ')'; //颜色
var enemy = new Enemy(x, wh, vx, vy, bc, dis); //实例化一个敌方飞机
enemyArr.push(enemy); //每实例化一个飞机就push进数组里
}
//判断小块是否移出画布,如果移出则从enemy数组中删除
function judegeEnemy() {
for(var i = 0; i < enemyArr.length; i++) {
if(enemyArr[i].y > mc.height) {
enemyArr.splice(i, 1);
i--; //移除因素之后数组结构否发生变化,为了防止漏判,要让i-1;
dieNum++;
console.log(dieNum);
}
}
}
//封装一个爆炸物类
function Boom(x, y, vx, vy, bc) {
this.x = x; //x坐标
this.y = y; //y坐标
this.vx = vx; //x速度
this.vy = vy; //y速度
this.bc = bc; //背景色
this.times = 0; //爆炸物的绘制次数(move函数每调用一次,time加+)
}
//为爆炸物添加原型方法
Boom.prototype.move = function() {
this.x += this.vx;
this.y += this.vy;
ctx.beginPath();
ctx.fillStyle = this.bc;
ctx.fillRect(this.x, this.y, 8, 8);
ctx.fill();
this.times++;
}
//判断是否击中函数(碰撞检测)
function judgeHit() {
for(var i = 0; i < bulletArr.length; i++) {
for(var j = 0; j < enemyArr.length; j++) {
var a = bulletArr[i]; //当前子弹
var b = enemyArr[j]; //当前掉落块
//a 和 b的碰撞检测
if(a.x + 8 > b.x && a.y + 8 > b.y && a.x < b.x + b.wh && a.y < b.y + b.wh) {
//创建爆炸物,调用碰撞函数。根据被击中块的信息来创建
createBoom(b.x, b.y, b.wh, b.bc);
//两两碰撞
bulletArr.splice(i, 1); //子弹移出
enemyArr.splice(j, 1); //掉落物移出
score++;
//当碰撞上后,两个块都已消失,删除之后,不用多做比较,直接跳出内层循环,让外层循环进行下一次碰撞检测
i--;
break;
}
}
}
}
//产生爆炸物函数
function createBoom(x, y, wh, bc) {
//当前块产生的爆炸物数组
var nowArr = [];
//实例化BOOM
var num = Math.floor(wh / 8); //宽和高可以生成的的小块
//双层循环实例化类(外层控制行(竖),内层控制列(横))
for(var i = 0; i < num; i++) {
//计算每行的y坐标
var thisY = y + 8 * i;
for(var j = 0; j < num; j++) {
var thisX = x + 8 * j; //计算行的x坐标
//速度
var vx = sui(-2, 2);
var vy = sui(-2, 3);
if(vx == 0 && vy == 0) {
vx += -1;
vy = 2
}
//实例化爆炸物
var boom = new Boom(thisX, thisY, vx, vy, bc);
nowArr.push(boom); //将爆炸物push进爆炸物数组
}
}
boomArr.push(nowArr); //将每个爆炸物的数组塞进整体爆炸物的数组
}
//判断爆炸物
function judgeBoom() {
for(var i = 0; i < boomArr.length; i++) {
for(var j = 0; j < boomArr.length; j++) {
//判断一批爆炸物中移动最慢的是否从画布移出
var maxTimes = Math.ceil(Math.sqrt(Math.pow(mc.width, 2) + Math.pow(mc.height, 2)));
if(boomArr[i][j].times > maxTimes) {
boomArr.splice(i, 1); //让整个爆炸物数组移出
i--; //让外层循环减一,重新循环
break; //跳出循环
}
}
}
}
//绘制分数
function drawScore() {
ctx.beginPath();
ctx.font = '20px Arial';
ctx.fillStyle = 'burlywood';
ctx.fillText('分数:'+ score, 20, 20);
}
function kaishi(){
//游戏开关
var gameFlag = true;
//为canvas绑定点击事件
mc.onclick = function() {
//设置开关,第一次点击画布,开始游戏,之后再点击画布,创建子弹。
if(gameFlag) {
//为canvas添加鼠标移动事件
mc.onmousemove = function() {
//计算出鼠标距离canvas的坐标
var e = event || window.event;
mouseX = e.clientX - mc.offsetLeft; //获取鼠标在底部坐标,并设置在中间
drawBox(); //鼠标移动创建白色块
}
gameStart();
gameFlag = false;
drawScore();
} else {
createBullet(); //调用创建子弹函数
}
}
}kaishi();
//封装计时器函数
function gameStart() {
//绘制频率
eleMoveTimer = setInterval(function() {
ctx.clearRect(0, 0, 800, 800);
drawBox(); //调用绘制下方白块函数
//循环绘制所有子弹
for(var i = 0; i < bulletArr.length; i++) {
bulletArr[i].move();
}
//循环绘制掉落物
for(var j = 0; j < enemyArr.length; j++) {
enemyArr[j].move();
}
for(var m = 0; m < boomArr.length; m++) {
for(var n = 0; n < boomArr[m].length; n++) {
boomArr[m][n].move();
}
}
//绘制爆炸物
judegeEnemy(); //判读掉落物是否移出画布
judgeHit(); //碰撞检测
drawScore(); //绘制分数
//判断爆炸物是否移出页面
judgeBoom();
//检测游戏结束
if(dieNum == 5) {
gameOver();
}
}, 10);
//掉落快计时器
createEnemyTimer = setInterval(function() {
createEmeny();
}, 1000);
}
//封装游戏结束函数
function gameOver() {
//清除游戏运行计时器
clearInterval(eleMoveTimer); //清除游戏频率计时器
clearInterval(createEnemyTimer); //清除掉落块计时器
//清除画布的事件
mc.onclick = null;
mc.onmousemove = null;
//绘制最终分数
ctx.clearRect(0, 0, 800, 800); //清空画布
ctx.beginPath();
ctx.font = '50px Arial';
ctx.fillStyle = 'burlywood';
ctx.fillText('游戏结束', 300, 300);
ctx.fill();
ctx.beginPath();
ctx.font = '30px Arial';
ctx.fillStyle = 'burlywood';
ctx.fillText('游戏得分:'+ score, 300, 400);
ctx.fill();
//将分数重置为0
score = 0;
dieNum = 0;
//清空数组
//子弹数组
bulletArr = [];
//掉落快数组
enemyArr = [];
//爆炸物数组
boomArr = [];
//点击canvas回到首页
mc.onclick = function(){
ctx.clearRect(0,0,800,800);
drawStartPage();
kaishi();
}
}
</script>
</html>
————————————————————————————————————————
赋值图片以下 横线以上的代码至编码软件。
另外,各位伙伴如果对前端有兴趣,欢迎关注哦,定期分享趣味前端。小编也是新手。只是喜欢而已~
相关推荐
- 程序员:JDK的安装与配置(完整版)_jdk的安装方法
-
对于Java程序员来说,jdk是必不陌生的一个词。但怎么安装配置jdk,对新手来说确实头疼的一件事情。我这里以jdk10为例,详细的说明讲解了jdk的安装和配置,如果有不明白的小伙伴可以评论区留言哦下...
- Linux中安装jdk并配置环境变量_linux jdk安装教程及环境变量配置
-
一、通过连接工具登录到Linux(我这里使用的Centos7.6版本)服务器连接工具有很多我就不一一介绍了今天使用比较常用的XShell工具登录成功如下:二、上传jdk安装包到Linux服务器jdk...
- 麒麟系统安装JAVA JDK教程_麒麟系统配置jdk
-
检查检查系统是否自带java在麒麟系统桌面空白处,右键“在终端打开”,打开shell对话框输入:java–version查看是否自带java及版本如图所示,系统自带OpenJDK,要先卸载自带JDK...
- 学习笔记-Linux JDK - 安装&配置
-
前提条件#检查是否存在JDKrpm-qa|grepjava#删除现存JDKyum-yremovejava*安装OracleJDK不分系统#进入安装文件目...
- Linux新手入门系列:Linux下jdk安装配置
-
本系列文章是把作者刚接触和学习Linux时候的实操记录分享出来,内容主要包括Linux入门的一些理论概念知识、Web程序、mysql数据库的简单安装部署,希望能够帮到一些初学者,少走一些弯路。注意:L...
- 测试员必备:Linux下安装JDK 1.8你必须知道的那些事
-
1.简介在Oracle收购Sun后,Java的一系列产品就被整合到Oracle官网中,打开官网乍眼一看也不知道去哪里下载,还得一个一个的摸索尝试,而且网上大多数都是一些Oracle收购Sun前,或者就...
- Linux 下安装JDK17_linux 安装jdk1.8 yum
-
一、安装环境操作系统:JDK版本:17二、安装步骤第一步:下载安装包下载Linux环境下的jdk1.8,请去官网(https://www.oracle.com/java/technologies/do...
- 在Ubuntu系统中安装JDK 17并配置环境变量教程
-
在Ubuntu系统上安装JDK17并配置环境变量是Java开发环境搭建的重要步骤。JDK17是Oracle提供的长期支持版本,广泛用于开发Java应用程序。以下是详细的步骤,帮助你在Ubuntu系...
- 如何在 Linux 上安装 Java_linux安装java的步骤
-
在桌面上拥抱Java应用程序,然后在所有桌面上运行它们。--SethKenlon(作者)无论你运行的是哪种操作系统,通常都有几种安装应用程序的方法。有时你可能会在应用程序商店中找到一个应用程序...
- Windows和Linux环境下的JDK安装教程
-
JavaDevelopmentKit(简称JDK),是Java开发的核心工具包,提供了Java应用程序的编译、运行和开发所需的各类工具和类库。它包括了JRE(JavaRuntimeEnviro...
- linux安装jdk_linux安装jdk软连接
-
JDK是啥就不用多介绍了哈,外行的人也不会进来看我的博文。依然记得读大学那会,第一次实验课就是在机房安装jdk,编写HelloWorld程序。时光飞逝啊,一下过了十多年了,挣了不少钱,买了跑车,娶了富...
- linux安装jdk,全局配置,不同用户不同jdk
-
jdk1.8安装包链接:https://pan.baidu.com/s/14qBrh6ZpLK04QS8ogCepwg提取码:09zs上传文件解压tar-zxvfjdk-8u152-linux-...
- 运维大神教你在linux下安装jdk8_linux安装jdk1.7
-
1.到官网下载适合自己机器的版本。楼主下载的是jdk-8u66-linux-i586.tar.gzhttp://www.oracle.com/technetwork/java/javase/downl...
- window和linux安装JDK1.8_linux 安装jdk1.8.tar
-
Windows安装JDK1.8的步骤:步骤1:下载JDK打开浏览器,找到JDK下载页面https://d.injdk.cn/download/oraclejdk/8在页面中找到并点击“下载...
- 最全的linux下安装JavaJDK的教程(图文详解)不会安装你来打我?
-
默认已经有了linux服务器,且有root账号首先检查一下是否已经安装过java的jdk任意位置输入命令:whichjava像我这个已经安装过了,就会提示在哪个位置,你的肯定是找不到。一般我们在...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle忘记用户名密码 (59)
- oracle11gr2安装教程 (55)
- mybatis调用oracle存储过程 (67)
- oracle spool的用法 (57)
- oracle asm 磁盘管理 (67)
- 前端 设计模式 (64)
- 前端面试vue (56)
- linux格式化 (55)
- linux图形界面 (62)
- linux文件压缩 (75)
- Linux设置权限 (53)
- linux服务器配置 (62)
- mysql安装linux (71)
- linux启动命令 (59)
- 查看linux磁盘 (72)
- linux用户组 (74)
- linux多线程 (70)
- linux设备驱动 (53)
- linux自启动 (59)
- linux网络命令 (55)
- linux传文件 (60)
- linux打包文件 (58)
- linux查看数据库 (61)
- linux获取ip (64)
- linux进程通信 (63)