一、簡介
還記得許多年前的春天,你我一起“打飛機”。
那就一起寫個打飛機游戲吧:

二、HTML內容
HTML內容把需要的圖片資源以相應標簽格式寫出即可,分為以下幾部分:
-
- 背景圖片
- 自己戰機的圖片
- 子彈的圖片
- 敵機的圖片
- 敵機掛了的圖片
- 計算分數的位置預留
<base href="http://images.cnblogs.com/cnblogs_com/suoning/860380/" /> <div class="bg"> <div class="me-plan"></div> <div id="play_num"></div> <div class="bullet"> <img src="o_cartridge.png"> </div> <div class="x"> <img class="lift" src="o_plain1.png"> <img class="die" src="o_die1.png"> </div> <div class="x2"> <img class="lift" src="o_plain2.png"> <img class="die" src="o_die2.png"> </div> </div>
三、CSS布局
CSS代碼塊只需把HTML代碼塊的圖片進程簡單布局,分以下幾部分:
-
- 背景圖片的寬與高、居中、邊框、超出邊界隱藏、relative相對定位
- 自己戰機的寬與高、absolute相對父級定位與z-index優先級最高
- 自己戰機默認隱藏,游戲開始則滑出
- 子彈、敵機的absolute相對父級定位
- 子彈、敵機的默認隱藏,游戲開始則通過克隆展示
- 敵機死亡的圖片定位與隱藏
- 分數的字體大小設置及定位
<base href="http://images.cnblogs.com/cnblogs_com/suoning/860380/" /> <style> .bg { background-image: url("o_bg.jpg"); height: 500px; width: 300px; position: relative; margin-left: 40%; margin-top: 5%; overflow: hidden; border: 1px; } .me-plan { width: 99px; height: 112px; background-image: url("o_me.png"); position: absolute; top: 80%; left: 35%; display: none; z-index: 666; } .bullet { position: absolute; display: none; left: -10px; } .x, .x2 { position: absolute; display: none; } .lift { position: absolute; top: -110px; } .die { display: none; } #play_num { font-size: 30px; } </style>
四、jQuery 代碼塊
JavaScript基礎知識戳這,DOM相關戳這,jQuery全套戳這
jQuery代碼塊是程序的主要實現部分:
-
- 自己戰機得需要跟着鼠標移動
- 自己戰機移動的同時子彈也需要同時做相對定位的移動
- 敵機隨機從上到下移動
- 敵機若與子彈相碰,則炸毀,相應分數增加
1、程序所需值與預定義
程序在一開始就必須獲取相應的值,以便之后調用:
背景的寬與高 :判斷自己戰機是否超出邊界,如果超出則固定在邊界內某一塊;
自己戰機的寬與高:也做超出邊界固定的作用,加上這個值更精確;
背景圖片相對父元素的距離:這個值也可以說背景圖片相對body的距離,因為需要不斷獲取鼠標的坐標,來確定自己戰機的位置,鼠標的坐標減去這個值即是元素相對父級元素的距離;
還需要預定義一些值:
play_num:游戲的得分,默認定位0;
FD = {}:定義一個"字典",存放每個敵機的對象與對於標簽,用於判斷碰撞。
var dwidth = $('.bg').width(); // 背景的寬與高 var dheight = $('.bg').height(); var fwidth = $('.me-plan').width(); // 自己戰機的寬與高 var fheight = $('.me-plan').height(); var zwidth = $('.bullet').width(); // 子彈的寬與高 var zheight = $('.bullet').height(); var t = $('.bg').offset().top; // 背景相對父元素的距離 var l = $('.bg').offset().left; var FD = {}; // 存放敵的的對象,封裝坐標及標簽 var play_num = 0; // 計算分數
2、鼠標移動事件
自己戰機需要不斷跟着鼠標走,所有必須定義鼠標移動事件;
event.clientX與event.clientY分別為鼠標的x和y軸距離;
判斷如果超出邊界,則戰機固定位置;
鼠標位置坐相應處理就是戰機的位置(實時)。
$(".me-plan").mousemove(function m(event) {
/*
鼠標移動事件
*/
var x = event.clientX - fwidth / 2;
var y = event.clientY - fheight / 2;
MovePlanM(x - l, y - t);
})
function MovePlanM(x, y) {
/*
戰機隨鼠標移動
*/
if (x >= dwidth) {
x = dwidth - fwidth;
} else if (y >= dheight) {
y = dheight - fheight;
}
$('.me-plan').css({
"top": y + "px",
"left": x + "px",
});
}
3、隨機值
每次敵機出現的x軸位置是不同的,所有需要寫一個隨機數函數;
可以以做為出現敵機的類型,小飛機與大飛機。
function Randmon() { /* 用於隨機生成x軸與敵機型號 */ var num_one = Math.random(); var num_two = num_one * 100; if (num_two < 80) { num_two += 100; } num_stree = Math.round(Math.abs(num_two)); return num_stree }
4、敵機類
一次可以出現一個以上敵機,而敵機屬性都類似,所有需要寫一個類;
三個參數,分別為x軸,y軸,還有敵機的類型;
通過克隆再插入對應標簽實現多個敵機;
通過定時器使y軸自加,使敵機不斷向下移動;
判斷如果超出背景,則停止定時器,刪除對應標簽;
把對象都加入FD字典中;
注意:定時器為單獨函數,不屬於類,所以需要用到繼承。
function FoePlan(x, y, BB) { /* 克隆及移動敵機 */ this.x = x; this.y = y; this.BB = BB; this.Clone = function () { var objj = $(this.BB).first().clone(true).appendTo(".bg").css("display", "block"); var s2 = setInterval(MovePlanFirst, 100); function MovePlanFirst() { FoePlan.call(this, x, y, BB); // 類的繼承 var dic = [this.x, this.y, objj]; FD[this] = dic; RemovePlan(this.y, s2, objj); y += 20; objj.css({ "top": this.y + "px", "left": this.x + "px", }) } } } function RemovePlan(y, s2, objj) { /* 用於刪除出鏡的敵機 */ if (y > 600) { clearInterval(s2); $(objj).remove(); } }
5、子彈相關
兩個參數,分別為自己戰機x軸與y軸坐標,用於跟着戰機相對移動;
定時器讓y軸坐標自減,對應的子彈會一直上升;
子彈超出邊界則刪除定時器與對應標簽;
循環讀取FD字典,得到每個敵機的坐標,判斷碰撞則爆炸效果,並淡出;
如果擊落敵機對應分數增加;
擊落敵機刪除對應標簽與FD中的值。
function MoveBullet(x, y) { /* 克隆及移動子彈、判斷子彈是否射到敵機 */ var obj = $('.bullet').first().clone(true).appendTo(".bg").css("display", "block"); var s1 = setInterval(function () { for (var item in FD) { // 判斷子彈是否射到敵機 var xx = FD[item][0]; var yy = FD[item][1]; var objj = FD[item][2]; var flag = false; if ((xx < x) && (x < (xx + 60)) && (yy < y) && ( y < (yy + 60))) { $(objj).children().first().css("display", "none"); $(objj).children().last().css("display", "block").fadeOut("1600").fadeTo("slow", 0); play_num += 10; $('#play_num').text(play_num); } if (flag) { $(objj).remove(); flag = false; } } RemoveBullet(y, s1, obj); y -= 20; obj.css({ "top": (y) + "px", "left": x + "px", }) }, 100); } function RemoveBullet(y, s1, obj) { /* 刪除超出邊界的子彈 */ if (y < 0) { clearInterval(s1); $(obj).remove(); } }
6、運行程序
頁面加載完成則開始運行游戲;
定時器獲取自己戰機的坐標,並傳給子彈,讓子彈不斷開炮;
定時器獲取隨機值,並傳給敵機類,讓敵機不斷涌現。
$(function () { /* 頁面加載完成初始化開始游戲 */ $(".me-plan").slideDown("900"); setInterval(function () { var x = $(".me-plan").position().left + fwidth / 2; var y = $(".me-plan").position().top; MoveBullet(x, y); }, 200); setInterval(function () { var n = Randmon(); if (n > 130) { var shape = '.x'; } else { var shape = '.x2'; } var obj = new FoePlan(n, 0, shape); obj.Clone(); }, 1500); });
五、完整代碼
注:訪問代碼里圖片路徑需加前綴:
http://images.cnblogs.com/cnblogs_com/suoning/860380/ + 圖片名字
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>外掛版打飛機 Nick Suo</title>
<base href="http://images.cnblogs.com/cnblogs_com/suoning/860380/"/>
<style>
.bg {
background-image: url("o_bg.jpg");
height: 500px;
width: 300px;
position: relative;
margin-left: 40%;
margin-top: 5%;
overflow: hidden;
border: 1px;
}
.me-plan {
width: 99px;
height: 112px;
background-image: url("o_me.png");
position: absolute;
top: 80%;
left: 35%;
display: none;
z-index: 666;
}
.bullet {
position: absolute;
display: none;
left: -10px;
}
.x, .x2 {
position: absolute;
display: none;
}
.lift {
position: absolute;
top: -110px;
}
.die {
display: none;
}
#play_num {
font-size: 30px;
}
</style>
</head>
<body>
<div class="bg">
<div class="me-plan"></div>
<div id="play_num"></div>
<div class="bullet">
<img src="o_cartridge.png">
</div>
<div class="x">
<img class="lift" src="o_plain1.png">
<img class="die" src="o_die1.png">
</div>
<div class="x2">
<img class="lift" src="o_plain2.png">
<img class="die" src="o_die2.png">
</div>
</div>
<script src="../jquery-1.12.4.js"></script>
<script>
/*
build time: Jul 28,2016 23:59
author: Nick Suo
email: 630571017@qq.com
*/
var dwidth = $('.bg').width(); // 背景的寬與高
var dheight = $('.bg').height();
var fwidth = $('.me-plan').width(); // 自己戰機的寬與高
var fheight = $('.me-plan').height();
var zwidth = $('.bullet').width(); // 子彈的寬與高
var zheight = $('.bullet').height();
var t = $('.bg').offset().top; // 背景相對父元素的距離
var l = $('.bg').offset().left;
var FD = {}; // 存放敵的的對象,封裝坐標及標簽
var play_num = 0; // 計算分數
$(".me-plan").mousemove(function m(event) {
/*
鼠標移動事件
*/
var x = event.clientX - fwidth / 2;
var y = event.clientY - fheight / 2;
MovePlanM(x - l, y - t);
})
function MovePlanM(x, y) {
/*
戰機隨鼠標移動
*/
if (x >= dwidth) {
x = dwidth - fwidth;
} else if (y >= dheight) {
y = dheight - fheight;
}
$('.me-plan').css({
"top": y + "px",
"left": x + "px",
});
}
$(function () {
/*
頁面加載完成初始化開始游戲
*/
$(".me-plan").slideDown("900");
setInterval(function () {
var x = $(".me-plan").position().left + fwidth / 2;
var y = $(".me-plan").position().top;
MoveBullet(x, y);
}, 200);
setInterval(function () {
var n = Randmon();
if (n > 130) {
var shape = '.x';
} else {
var shape = '.x2';
}
var obj = new FoePlan(n, 0, shape);
obj.Clone();
}, 1500);
});
function MoveBullet(x, y) {
/*
克隆及移動子彈、判斷子彈是否射到敵機
*/
var obj = $('.bullet').first().clone(true).appendTo(".bg").css("display", "block");
var s1 = setInterval(function () {
for (var item in FD) { // 判斷子彈是否射到敵機
var xx = FD[item][0];
var yy = FD[item][1];
var objj = FD[item][2];
var flag = false;
if ((xx < x) && (x < (xx + 60)) && (yy < y) && ( y < (yy + 60))) {
$(objj).children().first().css("display", "none");
$(objj).children().last().css("display", "block").fadeOut("1600").fadeTo("slow", 0);
play_num += 10;
$('#play_num').text(play_num);
}
if (flag) {
$(objj).remove();
flag = false;
}
}
RemoveBullet(y, s1, obj);
y -= 20;
obj.css({
"top": (y) + "px",
"left": x + "px",
})
}, 100);
}
function RemoveBullet(y, s1, obj) {
/*
刪除超出邊界的子彈
*/
if (y < 0) {
clearInterval(s1);
$(obj).remove();
}
}
function FoePlan(x, y, BB) {
/*
克隆及移動敵機
*/
this.x = x;
this.y = y;
this.BB = BB;
this.Clone = function () {
var objj = $(this.BB).first().clone(true).appendTo(".bg").css("display", "block");
var s2 = setInterval(MovePlanFirst, 100);
function MovePlanFirst() {
FoePlan.call(this, x, y, BB); // 類的繼承
var dic = [this.x, this.y, objj];
FD[this] = dic;
RemovePlan(this.y, s2, objj);
y += 20;
objj.css({
"top": this.y + "px",
"left": this.x + "px",
})
}
}
}
function RemovePlan(y, s2, objj) {
/*
用於刪除出鏡的敵機
*/
if (y > 600) {
clearInterval(s2);
$(objj).remove();
}
}
function Randmon() {
/*
用於隨機生成x軸與敵機型號
*/
var num_one = Math.random();
var num_two = num_one * 100;
if (num_two < 80) {
num_two += 100;
}
num_stree = Math.round(Math.abs(num_two));
return num_stree
}
</script>
</body>
</html>
持續更新中...
