一、效果图
二、代码
html和js放一起了,看着代码量有点多
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/drawing_utils/drawing_utils.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/hands/hands.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- 1.游戏背景 -->
<div class="scene">
<!-- UI层,显示分数 -->
<!-- 3.战斗层 -->
<div class="war-layer">
<!-- 添加小飞机 -->
<img src="img/hero.png" id="hero" />
</div>
<!-- 地图背景层 -->
<div class="map-layer"></div>
</div>
<video class="input_video"></video>
<canvas class="output_canvas" width="1280px" height="720px"></canvas>
</body>
<script>
function LoadAudio() {
var mp3 = "audio/bgm_zhandou2.mp3";
var mp3 = new Audio(mp3);
mp3.setAttribute('muted', 'muted')
console.log(mp3)
// mp3.play(); //播放 mp3这个音频对象
var promise = mp3.play();
if (promise !== undefined) {
promise.then(_ => {
// Autoplay started!
}).catch(error => {
// Autoplay was prevented.
// Show a "Play" button so that user can start playback.
});
}
}
window.onload = LoadAudio;
//获得游戏背景
var scene = document.getElementsByClassName('scene')[0]
//获取战斗层
var warlay = document.getElementsByClassName('war-layer')[0]
//一,生成本机
var hero = document.getElementById('hero')
//使用鼠标移动小飞机
scene.addEventListener("mousemove", function(event) {
var x = event.clientX;
var y = event.clientY;
console.log(x, '----', y)
//把鼠标的坐标赋值给飞机,(飞机是以左上角定位的)
hero.style.top = y - hero.offsetHeight / 2 + 'px';
hero.style.left = x - hero.offsetWidth / 2 + 'px';
})
//二,生成敌机
function makeEnemy() {
//生成敌机
var enemy = document.createElement('img')
enemy.src = "./img/enemy1.png";
//敌机样式
enemy.setAttribute('class', 'enemy')
//敌机位置
enemy.style.left = Math.random() * scene.offsetWidth - 100 + 'px'
enemy.style.top = '0px'
//把子弹放在页面上
warlay.appendChild(enemy)
}
//使用定时器生成敌机
var timer = setInterval(function() {
makeEnemy();
}, 500)
//三,生成子弹
function makeBullet() {
//生成子弹图片元素
var bullet = document.createElement('img')
//设置子弹图片
bullet.src = "./img/bullet1.png"
//添加子弹样式
bullet.setAttribute('class', 'bullet');
//设置子弹发射的位置
console.log(hero.offsetLeft)
console.log(hero.offsetWidth / 2)
bullet.style.left = hero.offsetLeft + hero.offsetWidth / 2 - 5 + 'px';
bullet.style.top = hero.offsetTop - 20 + 'px';
//把子弹添加到战斗层页面上
warlay.appendChild(bullet)
}
//使用定时器生成子弹
var timer = setInterval(function() {
makeBullet()
}, 200)
//四,让子弹和敌机飞
var speeed = 10; //本机子弹的移动速度
var espeed = 5; //敌机的飞行速度,()
setInterval(function() {
//获取所有子弹
var bullets = document.getElementsByClassName('bullet'); //获取所有子弹
var enemies = document.getElementsByClassName('enemy'); //获取所有敌机
//子弹开始飞
for (var i = 0; i < bullets.length; i++) {
var bullet = bullets[i];
bullet.style.top = bullet.offsetTop - speeed + 'px';
//回收炮弹
if (bullet.offsetTop < -100) {
warlay.removeChild(bullet)
}
//碰撞检测(遍历所有子弹的同时遍历所有敌机)
for (var j = 0; j < enemies.length; j++) {
var enemy = enemies[j]
//如果满足碰撞条件,则碰撞,移除敌机和子弹
if (collision(bullet, enemy)) {
playBomb();
makeBomb(bullet, enemy)
warlay.removeChild(bullet)
warlay.removeChild(enemy)
}
}
}
//敌机开始飞
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
enemy.style.top = enemy.offsetTop + espeed + 'px';
//当敌机超出屏幕时,移除敌机
if (enemy.offsetTop > scene.offsetHeight) {
warlay.removeChild(enemy)
}
}
function collision(a, b) {
//敌机的坐标位置
var x1 = b.offsetLeft; //距离左侧边栏的偏移量
var y1 = b.offsetTop; //距离上侧边栏的偏移量
var x2 = x1 + b.offsetWidth //敌机的偏移量+敌机的宽度
var y2 = y1 + b.offsetHeight //敌机的上偏移量+敌机的高度
//子弹的坐标位置
var x3 = a.offsetLeft + a.offsetWidth
var y3 = a.offsetTop + a.offsetHeight
//判断是否撞击
if (((x3 > x1) && (x3 < x2)) && ((y3 > y1) && (y3 < y2))) {
return true
}
}
function playBomb() {
var mp3 = "audio/bomb.wav";
var mp3 = new Audio(mp3);
mp3.setAttribute('muted', 'muted')
console.log(mp3)
// mp3.play(); //播放 mp3这个音频对象
var promise = mp3.play();
if (promise !== undefined) {
promise.then(_ => {
// Autoplay started!
}).catch(error => {
// Autoplay was prevented.
// Show a "Play" button so that user can start playback.
});
}
}
}, 16)
//制造爆炸场面
function makeBomb(bullet, enemy) {
//生成爆炸图片元素
var Bomb = document.createElement('img')
//设置爆炸图片
Bomb.src = "./img/bomb.png"
//添加爆炸样式
Bomb.setAttribute('class', 'Bomb');
//设置爆炸的位置
Bomb.style.top = hero.offsetTop - enemy.offsetTop + enemy.offsetHeight + 'px'
Bomb.style.left = enemy.offsetLeft + 'px'
//把爆炸图片添加到战斗层页面上
warlay.appendChild(Bomb)
setTimeout(function() {
warlay.removeChild(Bomb)
}, 100)
}
// 6. 使用鼠标移动小飞机
// 鼠标移动事件
scene.addEventListener("mousemove", function(event) {
// 获得鼠标的位置坐标
var x = event.clientX;
var y = event.clientY;
// 把鼠标的坐标赋值给飞机
hero.style.top = y - hero.offsetHeight / 2 + 'px'
hero.style.left = x - hero.offsetWidth / 2 + 'px'
})
// 使用手势移动飞机
function movePlaneByHand(x, y) {
var x = x * 1920;
var y = y * scene.offsetHeight;
// 把鼠标的坐标赋值给飞机
hero.style.top = y - hero.offsetHeight / 2 + 'px'
hero.style.left = x - hero.offsetWidth / 2 + 'px'
}
</script>
<script src="./hand.js"></script>
</html>
*{
margin: 0;
padding: 0;
}
html,body{
width: 100%;
height: 100%;
}
body{
overflow: hidden;
}
.scene{
width: 100%;
height: 100%;
margin: 0 auto;
border: solid 1px red;
position: relative;
}
.game-scene{
width: 100%;
height: 100%;
}
/* 背景层 */
.map-layer{
width: 100%;
height: 100%;
background-image: url(./img/img_bg_level_1.jpg);
background-repeat: repeat-y;
background-size: 100%;
background-position-y: 300px;
}
/* 主角飞机 */
#hero{
width: 150px;
position: absolute;
z-index: 100;
top: 100px;
left: 50px;
}
.bullet{
width: 10px;
position: absolute;
z-index: 100;
}
.enemy{
width: 100px;
position: absolute;
z-index: 100;
}
.Bomb{
width: 100px;
position: absolute;
z-index: 100;
}
结束语
项目中用到的音频、图片等资源我都放在【我的资源】里面了,大家可以下载。