成品效果

在这里插入图片描述
前往玩一下?

代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>飞机大战</title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<style>
			html,
			body {
				margin: 0;
				background-color: beige;
			}

			button {
				width: 70px;
				height: 30px;
				border: 0;
				border-radius: 5px;
				background-color: #f5d325;
				color: white;
				font-weight: bold;
				cursor: pointer;
				box-shadow: 0px 5px 2px 2px rgb(209, 209, 209);
			}

			button:active {
				transform: translateY(3px) translateX(3px);
				box-shadow: 2px 2px 2px 2px rgb(190, 225, 255);
			}

			#root {
				height: 100vh;
				display: flex;
				align-items: center;
				justify-content: center;
				flex-direction: column;
			}

			#content {
				width: 350px;
				display: flex;
				flex-direction: column;
				height: 650px;
				background-color: #55aaff;
				border-radius: 5px;
			}

			#game {
				display: flex;
				align-items: center;
				justify-content: center;
				flex: 1;
			}

			#key {
				height: 100px;
				display: flex;
				justify-content: center;
				align-items: center;
			}
		</style>
	</head>
	<body>
		<div id="root">
			<div id="content">
				<div id="game">
					<canvas id="gameCanvas" width="300" height="500"></canvas>
				</div>
				<div id="key">
					<div style="width: 300px;display: flex;">
						<div style="display: flex;gap: 10px;">
							<button onclick="mainRole.moveTo(1)">左(A)</button>
							<button onclick="mainRole.moveTo(2)">右(D)</button>
						</div>
						<div style="flex: 1;display: flex;justify-content: flex-end;align-items: flex-start;">
							<button onclick="mainRole.attack()">开火(J)</button>
						</div>
					</div>
				</div>
			</div>
		</div>
		<script>
			var c = document.getElementById("gameCanvas");
			var context = c.getContext("2d");
			var width = c.width;
			var height = c.height;
			// 星星数组
			var stars = [];
			// 星星添加
			for (var i = 0; i < 30; i++) {
				let star = {
					x: Math.floor(Math.random() * width),
					y: Math.floor(Math.random() * height),
					r: Math.floor(Math.random() * 3) + 1,
					lastRefreshTime: new Date().getTime(),
					draw(ctx) {
						let time = new Date().getTime();
						this.y += (time - this.lastRefreshTime) / 10.0;
						if (this.y > height) {
							this.y = 0;
							this.x = Math.floor(Math.random() * width);
						}
						this.lastRefreshTime = time;
						ctx.beginPath();
						ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, true);
						ctx.fill();
					}
				}
				stars.push(star)
			}
			// 主角对象
			var mainRole = {
				x: width / 2,
				y: height - 50,
				wh: 30,
				hp: 3,
				score: 0,
				weapon: 1,
				// 绘制
				draw(ctx) {
					ctx.beginPath();
					ctx.moveTo(this.x, this.y - this.wh / 2);
					ctx.lineTo(this.x + this.wh / 2, this.y + this.wh / 2);
					ctx.lineTo(this.x - this.wh / 2, this.y + this.wh / 2);
					ctx.fill();
				},
				// 移动
				moveTo(direction) {
					if (direction == 1) {
						this.x -= this.wh
						if (this.x < 0) {
							this.x = width;
						}
					}
					if (direction == 2) {
						this.x += this.wh
						if (this.x > width) {
							this.x = 0;
						}
					}
				},
				// 攻击
				attack() {
					var bullet = {
						bx: this.x,
						by: this.y - this.wh / 2,
						bw: 4,
						bh: 12,
						bhp: this.hp * 10,
						lastRefreshTime: new Date().getTime(),
						draw(ctx) {
							let time = new Date().getTime();
							this.by -= (time - this.lastRefreshTime) / 5.0;
							if (this.by < 0) {
								return true;
							}
							this.lastRefreshTime = time;
							context.fillRect(this.bx - this.bw / 2, this.by - this.bh / 2, this.bw, this.bh);
							for (var i = 0; i < roles.length; i++) {
								let role = roles[i];
								let distance = Math.sqrt((this.bx - role.x) * (this.bx - role.x) + (this.by - role.y) * (
									this.by - role.y))
								if (distance < role.wh / 2) {
									role.hp -= 10;
									this.bhp -= 10;
									this.bh -= 3;
								}
							}
							return this.hp <= 10;
						}
					}
					bullets.push(bullet)
				}
			};
			// 子弹
			var bullets = []
			// 敌机
			var roles = []

			// 敌机上一次添加的时间
			var roleLastAddTime = new Date().getTime()
			// 上次主角生命添加的分数
			var lastMainRoleHpAddScore = 0;
			// 游戏启动时间
			var gameStartTime = new Date().getTime()
			// 计时器
			var intervalId = setInterval(function() {
				// 刷新画面
				draw();
				// 添加敌机
				let addTime = 3000 - (new Date().getTime() - gameStartTime) / 100;
				let time = addTime > 500 ? addTime : 500;
				if (new Date().getTime() - roleLastAddTime > time) {
					let role = {
						x: Math.floor(Math.random() * 10) * 30,
						y: 0,
						wh: 30,
						hp: 10,
						lastRefreshTime: new Date().getTime(),
						draw(ctx) {
							let time = new Date().getTime();
							this.y += (time - this.lastRefreshTime) / 20.0;
							if (this.y > height) {
								mainRole.hp -= 1;
								return true;
							}
							this.lastRefreshTime = time;
							ctx.beginPath();
							ctx.moveTo(this.x, this.y + this.wh / 2);
							ctx.lineTo(this.x + this.wh / 2, this.y - this.wh / 2);
							ctx.lineTo(this.x - this.wh / 2, this.y - this.wh / 2);
							ctx.fill();
							if (this.hp <= 0) {
								mainRole.score += 10;
								if ((mainRole.score - lastMainRoleHpAddScore) >= 100) {
									mainRole.hp += 1;
									lastMainRoleHpAddScore = mainRole.score
								}
							}
							return this.hp <= 0;
						},
					}
					roles.push(role)
					roleLastAddTime = new Date().getTime();
				}
			}, 16);
			/**
			 * 游戏绘制
			 */
			function draw() {
				// 背景
				context.fillStyle = "black";
				context.fillRect(0, 0, width, height);
				context.fillStyle = "#c8c8c8";
				for (var i = 0; i < stars.length; i++) {
					stars[i].draw(context)
				}
				// 角色
				context.fillStyle = "#00aaff";
				mainRole.draw(context)
				// 子弹
				context.fillStyle = "#ff5500";
				for (var i = bullets.length - 1; i >= 0; i--) {
					if (bullets[i].draw(context)) {
						bullets.splice(i, 1);
					}
				}
				// 敌机
				context.fillStyle = "#aa55ff";
				for (var i = roles.length - 1; i >= 0; i--) {
					if (roles[i].draw(context)) {
						roles.splice(i, 1);
					}
				}
				// 游戏信息
				context.fillStyle = "#ffffff";
				context.fillText("剩余次数:" + mainRole.hp, 10, 20)
				context.fillText("分数:" + mainRole.score, 10, 40)
			}
			// 键盘监听
			window.onload = function() {
				document.onkeydown = function(event) {
					if (event.keyCode == 65) {
						mainRole.moveTo(1)
					} else if (event.keyCode == 68) {
						mainRole.moveTo(2)
					} else if (event.keyCode == 74) {
						mainRole.attack()
					}
				};
			};
		</script>
	</body>
</html>
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐