本文通过JavaScript原生代码完整实现《飞机大战坦克》游戏。详细解析了背景滚动、子弹发射、敌人随机生成及碰撞检测等核心逻辑。重点介绍了如何利用定时器管理屏幕外元素,以及通过坐标判断实现子弹击中敌人和飞机碰撞死亡的判定机制,为前端游戏开发提供参考。
游戏界面与实现思路
首先展示游戏的初始界面截图。

实现思路如下:
1. 页面加载后,背景图片开始持续移动。
2. 用户点击“开始”按钮后,飞机开始持续发射子弹,敌人随机从屏幕上方出现。
3. 当子弹击中敌人时,敌人消失。
4. 当敌人撞击到飞机时,飞机被摧毁,游戏结束。
HTML与CSS基础结构
HTML页面结构如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>飞机大战</title>
<link rel="stylesheet" type="text/css" href="飞机大战.css">
</head>
<body>
<div id="mainScreen">
<!-- 背景图片 -->
<div id="bgImg1" class="bg"></div>
<div id="bgImg2" class="bg"></div>
<!-- 飞机 -->
<div id="airplane"></div>
<!-- 开始按钮 -->
<div id="startMenu">
<a href="#" id="start">Start</a>
</div>
<!-- 重新开始按钮 -->
<div id="restartMenu">
<a href="#" id="restart">Game Over!<br/>重新开始</a>
</div>
<!-- 敌人 -->
<div class="enemy"></div>
<div class="enemy"></div>
<div class="enemy"></div>
<div class="enemy"></div>
<div class="enemy"></div>
<!-- 子弹 -->
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
</div>
<script type="text/javascript" src="sunckBase.js"></script>
<script type="text/javascript" src="飞机大战.js"></script>
</body>
</html>
CSS样式定义如下:
*{
margin: 0;
padding: 0;
font-family: "微软雅黑";
}
#mainScreen{
width: 512px;
height: 768px;
margin:0 auto;
position: relative;
overflow: hidden;
}
.bg{
width: 512px;
height:768px;
position: absolute;
background: url(bg.jpg);
}
#bgImg2{
top:-768px;
}
#airplane{
width: 109px;
height: 82px;
position: absolute;
background: url(hero.png);
left: 215px;
top: 668px;
}
.enemy{
position: absolute;
width: 30px;
height: 30px;
left: -100px;
top: 0px;
background: url(enemy.png);
background-size: 30px 30px;
}
.bullet{
position: absolute;
width: 5px;
height: 10px;
left: -100px;
top: -100px;
background: url(bullet.png);
background-size: 5px 10px;
}
#startMenu, #restartMenu{
position: absolute;
width: 512px;
text-align: center;
left: 0;
top: 300px;
}
#start, #restart{
line-height:50px;
font-size:30px;
font-weight:bold;
color:#F00;
display:block;
text-decoration:none;
}
#restartMenu{
display: none;
}
背景滚动与游戏启动
页面加载时,通过定时器使背景图片持续移动,营造动态效果。
//给背景设置定时器,让背景不停的动,形成动感
var bgTimer = setInterval(bgRun, 10);
function bgRun() {
jsBg1.style.top = jsBg1.offsetTop + 1 + "px";
jsBg2.style.top = jsBg2.offsetTop + 1 + "px";
if (jsBg1.offsetTop >= 768) {
jsBg1.style.top = "-768px";
} else {
if (jsBg2.offsetTop >= 768) {
jsBg2.style.top = "-768px";
}
}
}
点击“开始”按钮后,正式进入游戏状态。
游戏进行中。
注意:虽然屏幕上的子弹和敌人DOM元素数量不多,但我们在游戏开始前利用定时器将它们全部放置在屏幕外。当游戏需要时,再修改这些元素的位置,将其显示在页面中。
var jsStartBox=document.getElementById("startMenu")
jsStart.onclick = function startGame(){
jsStartBox.style.display="none";
var baseX = 0;
var baseY = 0;
var moveX = 0;
var moveY = 0;
jsAirplane.onmousedown = function(e) {
var evt = e || window.event;
baseX = evt.pageX;
baseY = evt.pageY;
jsDivBox.onmousemove = function(v) {
var vt = v || window.event;
moveX = vt.pageX - baseX;
baseX = vt.pageX;
moveY = vt.pageY - baseY;
baseY = vt.pageY;
jsAirplane.style.left = jsAirplane.offsetLeft + moveX + "px";
jsAirplane.style.top = jsAirplane.offsetTop + moveY + "px";
};
};
jsAirplane.onmouseup = function() {
mainScreen.onmousemove = null;
}
//找到可用的子弹
var findBulletTimer = setInterval(findBullet, 300);
function findBullet() {
for (var i = 0; i < jsBullets.length; i++) {
if (jsBullets[i]["isShow"] == false) {
jsBullets[i]["isShow"] = true;
//将子弹移动到飞机头
jsBullets[i].style.left = jsAirplane.offsetLeft + jsAirplane.offsetWidth / 2 + "px";
jsBullets[i].style.top = jsAirplane.offsetTop + "px";
break;
}
}
}
// //让子弹飞
var bulletFlyTimer = setInterval(bulletFlay, 100);
function bulletFlay() {
for (var j = 0; j < jsBullets.length; j++) {
if (jsBullets[j]["isShow"] == true) {
if (jsBullets[j].offsetTop > -20) {
jsBullets[j].style.top = jsBullets[j].offsetTop - 20 + "px";
} else {
jsBullets[j].style.left = "-100px";
jsBullets[j].style.top = "-100px";
jsBullets[j]["isShow"] = false;
}
}
}
}
//找到可用敌人
var findEnemyTimer = setInterval(findEnemy, 500);
function findEnemy(){
//找到一个没有在屏幕中的敌人
for (var i = 0; i < jsEnemys.length; i++) {
if (jsEnemys[i]["isShow"] == false) {
//标记敌人已经使用
jsEnemys[i]["isShow"] = true;
//将敌人移动到屏幕
var left = randomNum(0, 482);
jsEnemys[i].style.left = left + "px";
jsEnemys[i].style.top = 0 + "px";
break;
}
}
}
// //让敌人下落
var enemyLandTimer = setInterval(enemyLand, 100);
function enemyLand() {
for (var j = 0; j < jsEnemys.length; j++) {
if (jsEnemys[j]["isShow"] == true) {
var a = randomNum(4, 20);
if (jsEnemys[j].offsetTop <= 768) {
jsEnemys[j].style.top = jsEnemys[j].offsetTop + a + "px";
} else {
jsEnemys[j].style.left = "-100px";
jsEnemys[j].style.top = "0px";
jsEnemys[j]["isShow"] = false;
}
}
}
}
}
子弹击中与敌人销毁逻辑
击中敌人逻辑。
通过遍历页面上所有存在的敌人和子弹的定位坐标进行判断,如果发生碰撞,则使敌人消失。
var perishEnemyTimer = setInterval(perishEnemy, 50);
function perishEnemy() {
for (var i = 0; i < jsBullets.length; i++) {
if (jsBullets[i]["isShow"] == true) {
for (var j = 0; j < jsEnemys.length; j++) {
if (jsEnemys[j]["isShow"] == true) {
var ret = pzjcFunc(jsBullets[i], jsEnemys[j]);
if (ret) {
jsBullets[i].style.left = "-100px";
jsBullets[i].style.top = "-100px";
jsBullets[i]["isShow"] = false;
jsEnemys[j].style.left = "-100px";
jsEnemys[j].style.top = "-100px";
jsEnemys[j]["isShow"] = false;
}
}
}
}
}
}
碰撞检测与游戏结束判定
死亡检测逻辑。
游戏结束状态。
通过遍历页面上所有存在的敌人和飞机的定位坐标进行检测,如果两者相遇,则判定游戏结束。
注意:在检测时采用取反逻辑。如果坦克位于飞机的上方、下方、左侧或右侧,则视为未碰撞;取反后即为两者已相遇的情况。
//死亡检测
var dieTimer = setInterval(die, 50);
var jsStop = document.getElementById("restartMenu")
function die() {
for (var i = 0; i < jsEnemys.length; i++) {
if (jsEnemys[i]["isShow"] == true) {
var isDie = pzjcFunc(jsAirplane, jsEnemys[i]);
if (isDie) {
jsStop.style.display="block";
jsAirplane.onmouseup = function() {
mainScreen.onmousemove = null;
}
}
}
}
}
上述两步中用于检测两者是否碰撞的函数实现如下:
//死亡检测的函数
function pzjcFunc(obj1, obj2){
var obj1Left = obj1.offsetLeft;
var obj1Width = obj1Left + obj1.offsetWidth;
var obj1Top = obj1.offsetTop;
var obj1Height = obj1Top + obj1.offsetHeight;
var obj2Left = obj2.offsetLeft;
var obj2Width = obj2Left + obj2.offsetWidth;
var obj2Top = obj2.offsetTop;
var obj2Height = obj2Top + obj2.offsetHeight;
if ( !(obj1Left > obj2Width || obj1Width < obj2Left || obj1Top > obj2Height || obj1Height < obj2Top) ) {
return true;
}
return false;
}
重新开始与总结
点击“重新开始”按钮后,刷新页面以重置游戏状态。
var jsRestart=document.getElementById("restart");
jsRestart.onclick=function(){
jsStop.style.display="none";
window.location.reload();//刷新页面
}
现在,我们的游戏已经可以运行。这个游戏中的一些编写思想,例如利用屏幕外空间以及碰撞检测机制,可以在未来的项目中借鉴学习。
总结。
以上就是本文的全部内容,希望本文的内容对大家学习或使用JavaScript能带来一定的帮助。如果有疑问,欢迎大家留言交流。