一、簡介
還記得許多年前的春天,你我一起“打飛機”。
那就一起寫個打飛機游戲吧:
二、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>
持續更新中...