用记事本自学HTML+JS-canvas版本方块打飞机基础内容

本文展示了一个使用HTML5的canvas标签开发的简单打飞机游戏。开发者通过定义Obstercal和Me类来创建障碍物和玩家对象,实现了基础的动画、敌方子弹和玩家操作。游戏使用性能.now()来控制随机时间间隔生成障碍物,并通过keydown事件监听玩家移动。目前功能包括障碍物移动、碰撞检测以及游戏结束的初步判断,但缺少重置和分数记录功能,且未处理键盘长按时的延迟问题。
摘要由CSDN通过智能技术生成

学习HTML、JS、CSS一段时间了。

作为一个男人,还是练习了经典动作:打飞机。

没有使用HTML的<div>标签这些内容,使用了canvas。

目前状态仅完成了基础的动画、敌方子弹、本体操作移动。先做个记录分享。

代码里面有些是调试时的冗余内容,没有删。

<!DOCTYPE html>
<html lang="zh-CN">
	<head>
        		<meta charset="utf-8" />
        		<title>横向移动</title>
  
	<style>
		#x3{
			background-color: yellow;
		}
		.container{
			position: relative;
			background-color:  rgba(80,255,80,1);
		}
		.container canvas {
			position: absolute;
			left: 0;
			top: 0;
			border: 1px solid black;
		}
	</style>

	</head>
	<body>
		<h1>Test for Horizon Scroll</h1>
		<p><input type="button" id="startBtn" value="点击开始"></p>
		<div class="container">
			<canvas id="canvas1" width="600px" height="300px"></canvas>
			<canvas id="canvas2" width="600px" height="300px" tabindex="1"></canvas>
		</div>
		<div id="x3">
			<p id="test"></p>
			
		</div>

		
	</body>
	<script>
		//类定义区域
		//定义障碍物类
		class Obstercal{
			name; x; y; vx; vy;sizex;sizey;out;
			draw(){
				ctx.fillStyle="rgba(255,0,0,1)";
				ctx.fillRect(this.x,this.y,this.sizex,this.sizey);
			};
			move2Left(){
				ctx.clearRect(this.x,this.y,this.sizex,this.sizey);
				this.x=this.x-this.vx;
				if(this.x>0){
					this.draw();
				}else{
					this.out=true;
				}
			};
		};

		//定义控制的对象类。
		class Me{
			name; x; y; vx; vy;sizex;sizey;out;
			draw(){
				ctx2.fillStyle="rgba(0,0,255,1)";
				ctx2.fillRect(this.x,this.y,this.sizex,this.sizey);
			};
			move2Left(){
				ctx2.clearRect(this.x,this.y,this.sizex,this.sizey);
				this.x=this.x-this.vx;
				if(this.x>0){
					this.draw();
				}else{
					this.x=0
					this.draw();
				}
			};

			move2Right(){
				ctx2.clearRect(this.x,this.y,this.sizex,this.sizey);
				this.x=this.x+this.vx;
				if(this.x<=canvas2.width-this.sizex){
					this.draw();
				}else{
					this.x=canvas2.width-this.sizex;
					this.draw();
				}		

			};

			move2Up(){
				ctx2.clearRect(this.x,this.y,this.sizex,this.sizey);
				this.y=this.y-this.vy;
				if(this.y>=0){
					this.draw();
				}else{
					this.y=0;
					this.draw();
				}		
			};

			move2Down(){
				ctx2.clearRect(this.x,this.y,this.sizex,this.sizey);
				this.y=this.y+this.vy;
				if(this.y<=canvas2.height-this.sizey){
					this.draw();
				}else{
					this.y=canvas2.height-this.sizey;
					this.draw();
				}		
			};
		};

		//脚本主体运行区域
		//全局变量及初始化定义
		//获取Canvas对象
		let canvas=document.getElementById("canvas1");
		let canvas2=document.getElementById("canvas2");
		//获取Canvas的2D context
		let ctx=canvas.getContext("2d");
		let ctx2=canvas2.getContext("2d");
		//获取开始按钮对象
		let startbtn=document.getElementById("startBtn");
		//设置运行状态标志
		let running=false;
		//设置时间变量,用于做随机间隔计算使用
		let lastTime=performance.now();
		let currentTime=lastTime;
		//设置障碍对象生成的随机下限、上限时间
		let laserTriggerLow=200;
		let laserTriggerHigh=1000;
		//生成随机的间隔时间
		let delay=getRandomIntInclusive(laserTriggerLow,laserTriggerHigh);

		//创建一个数组用来存放障碍物对象
		let obs=[];
		let me=getMe();	//创建操作对象
		//给画布添加按键监听、给按钮添加点击动作的函数
		canvas2.addEventListener("keydown",moveMe);
		startbtn.addEventListener("click",startGame);


		//函数定义区域
		//启动按钮响应函数
		function startGame(){
			running=true;	//运行状态标记为true。
			run();
		}
		
		//生成操作对象me的函数
		function getMe(){
			let me=new Me();
			me.name="me";
			me.x=canvas2.width/2;
			me.y=canvas2.height/2;
			me.vx=4;
			me.vy=4;
			me.sizex=10;
			me.sizey=10;
			me.draw();
			return me;
		}

		//响应键盘的移动函数
		function moveMe(e){
			switch (e.key){
				case "ArrowUp":
					me.move2Up();
					break;
				case "ArrowDown":
					me.move2Down();
					break;
				case "ArrowLeft":
					me.move2Left();
					break;
				case "ArrowRight":
					me.move2Right();
					break;
			};
		}


		//动画运行的主体函数		
		function run(){
			canvas2.focus();	//将页面焦点到canvas2,用于用户控制me。
			
			//如果运行标志为true。
			if (running){
				let anid=requestAnimationFrame(run);
				currentTime = performance.now();	//将当前函数运行时间记录为当前时间。
				//按一个间隔时间,生成障碍物,将障碍物压到数组中
				if (currentTime - lastTime >= delay) {
    					getObs();
  				}
				//对数组中的内容进行移动
				for (let i=0;i<obs.length;i++){
					//对于已经跑出画面的对象进行删除
					if(obs[i].out){
						obs.splice(i,1);
					}else{
						//未出画面的,进行移动
						obs[i].move2Left();
					}
					//判断与操控的对象的冲突
					let crashMark=crash(obs[i],me);
					if(crashMark){
						running=false;
						break;
					}
				}
			}else{
				alert("Over");
			}
		}
		
		
		//检查两个方块碰撞的函数
		function crash(rect1, rect2){
			if (rect1.x>rect2.x+rect2.sizex || rect1.y>rect2.y+rect2.sizey || rect1.x+rect1.sizex<rect2.x || rect1.y+rect1.sizey<rect2.y){
				return false; //未碰撞
			}
			return true; //碰撞
		}
		

		//创建生成障碍物的对象函数
		function getObs(){
			let newObs=new Obstercal();
			newObs.name="laser";
			newObs.x=canvas.width;
			newObs.y=getRandomIntInclusive(0,canvas.height);
			newObs.vx=getRandomIntInclusive(1,4);
			newObs.vy=0;
			newObs.sizex=getRandomIntInclusive(10,40);
			newObs.sizey=getRandomIntInclusive(2,5);
			newObs.out=false;
			newObs.draw();
			obs.push(newObs);
			lastTime=performance.now();
			delay=getRandomIntInclusive(laserTriggerLow,laserTriggerHigh);
			setTimeout(getObs,delay);
			test.textContent=Date();
		}

		//在某个区间的随机数生成函数
		function getRandomIntInclusive(min, max){
			min = Math.ceil(min);
			max = Math.floor(max);
			return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
		}
		

		
		//canvas整个页面清除的函数
		function clear(){
			ctx.clearRect(0,0,canvas.width,canvas.height);
		}


    </script>

</html>

记录下过程中的几个自学到的知识点:

  1. 按照一定随机时间间隔,执行某个动作,需要使用performance.now()做函数运行的时间记录,用于和间隔时间的比对使用。
  2. canvas的多层,使用css格式,对canvas进行位置重叠设置。
  3. break命令,进行结束循环的跳出。
  4. 自定义class,可以帮助简单复用生成对象。
  5. 使用单独的函数声明,然后和keydown事件绑定。

剩余的问题、功能:

  1. 结束后的reset还没做。
  2. 分数还没记录。
  3. 键盘响应长按时,默认有延迟的效果,还没做处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值