javascript
JavaScript制作简易的《飞机大战》
老規(guī)矩,我們先上最終效果圖:
飛機(jī)大戰(zhàn) - Google Chrome 2022-05-09 18-27-36
接下來我們開始這個(gè)項(xiàng)目案例的書寫;
1.項(xiàng)目準(zhǔn)備
項(xiàng)目分析,
基本準(zhǔn)備。
我們首先分析這個(gè) 項(xiàng)目分析,
我們需要 背景。飛機(jī)。子彈。敵機(jī) 這四個(gè)元素
然后所有的元素都是動(dòng)態(tài)的出現(xiàn)的,其中飛機(jī)是被用戶可以操作的。
有撞擊事件彈出失敗彈窗
基本準(zhǔn)備
首先創(chuàng)立一個(gè)html文件,及其需要的img文件和js文件。
并且在html文件中調(diào)用js文件(當(dāng)然各位也可以邊寫邊調(diào)用)
圖片的查詢可以參考 作者的 JavaScript 利用內(nèi)置對象Mach的一個(gè)方法制作滿天星 (點(diǎn)擊這個(gè)標(biāo)題跳轉(zhuǎn)到這篇文章)
如何利用 阿里的 iconfont 矢量圖庫來獲取我們所需要的資源,這里直接下載png文件就可以了。
接下來我們開始正式項(xiàng)目的書寫:
2.背景圖的運(yùn)動(dòng)
添加一個(gè)div標(biāo)簽作為項(xiàng)目界面:
對界面進(jìn)行一些簡單的樣式設(shè)置
#container {width: 320px;height: 560px;background-image: url(img/bg.jpg);background-size: 100% 100%;position: relative;margin: 0 auto;}進(jìn)行js操作:
我們先獲取元素var dContainer = document.getElementById("container"); 分別設(shè)置界面的寬和高var sw = 320;var sh = 560;我們用背景圖的方式插入圖片,這里注意一點(diǎn)要進(jìn)行position定位,因?yàn)橹笃渌麕讉€(gè)元素的運(yùn)動(dòng)都要根據(jù)背景圖來進(jìn)行絕對定位。
然后開始書寫背景圖的js部分:
js/bg.js部分
我們在這里再寫一個(gè)公用方法,用于存放我們需要調(diào)用的方法
這里寫一個(gè)隨機(jī)函數(shù),(想了解的可以看這個(gè) JavaScript 利用內(nèi)置對象Mach的一個(gè)方法制作滿天星):
js/public.js部分
在這個(gè)js文件里在寫一個(gè)判斷函數(shù)用于媒體查詢
判斷是否是移動(dòng)端 function isPhone() {var arr = ["iPhone","iPad","Android"];var is = false;for(var i=0; i<arr.length; i++){if (navigator.userAgent.includes(arr[i])){is = true;break;}} return is; }相對應(yīng)的js操作再添加移動(dòng)端的部分:
var dContainer = document.getElementById("container");var sw = 320;var sh = 560;添加的移動(dòng)端判斷if(isPhone()){sw = window.innerWidth;sh = window.innerHeight;}2.飛機(jī)的移動(dòng)及其操作控制
我們先添加一個(gè)div,用于飛機(jī)的添加
如法炮制css:
#hero {width: 66px;height: 82px;background-image: url(img/hero.png);background-size: 100% 100%;position: absolute; 這里注意絕對定位,相對于父級定位,接下來的兩行操作才得以執(zhí)行left: 127px;top: 476px;}接下來是飛機(jī)的移動(dòng)操作部分js/hero.js:
先獲取元素 var dHero = document.getElementById("hero"); 添加狀態(tài),用于移動(dòng)的判斷 var isLeft = false; var isTop = false; var isRight = false; var isBottom = false; 按下事件 window.onkeydown = function(e) {// console.log(e.keyCode); 這里可以獲取我們鍵盤按鍵的值,在操作臺可以看到if(e.keyCode === 37){isLeft = true;}else if(e.keyCode === 38){isTop = true;}else if(e.keyCode === 39){isRight = true;}else if(e.keyCode === 40){isBottom = true;} } 抬起事件 window.onkeyup = function(e) {if(e.keyCode === 37){isLeft = false;}else if(e.keyCode === 38){isTop = false;}else if(e.keyCode === 39){isRight = false;}else if(e.keyCode === 40){isBottom = false;} }我們通過布爾值來進(jìn)行狀態(tài)判斷,在移動(dòng)的操作中只需要看是flase還是true就可以進(jìn)行移動(dòng)
function heroMove() { 先獲取飛機(jī)元素的偏移量var left = dHero.offsetLeft;var top = dHero.offsetTop; 這里就直接進(jìn)行判斷 因?yàn)槭峭瑫r(shí)進(jìn)行的所以我們使用四個(gè)同級的if語句if (isLeft) {left -= 8; 每次移動(dòng)的距離left= left<-10 ? -10 : left; 三目運(yùn)算符 當(dāng)移動(dòng)的距離大于界面的時(shí)候就為0否則就為原來的}if (isTop) {top -= 8;top = top<0 ? 0 : top;}if (isRight) {left += 8;left= left>sw-56 ? sw-56 : left;}if (isBottom) {top += 8;top = top>sh-82 ? sh-82 : top;}最后將得到的值賦給飛機(jī)的樣式dHero.style.left = left + 'px';dHero.style.top = top + 'px'; }接下來我們再寫一個(gè)移動(dòng)端的移動(dòng)操作
觸屏事件 dHero.ontouchstart = function(e) {e.preventDefault(); 消除默認(rèn)的操作if (e.touches.length > 1){return ;}var touch = e.touches[0];var x = touch.pageX;var y = touch.pageY;var l = dHero.offsetLeft;var t = dHero.offsetTop;window.ontouchmove = function(e) {var touch2 = e.touches[0];dHero.style.left = touch2.pageX - x + l +'px';dHero.style.top = touch2.pageY - y + t +'px';} }3.敵機(jī)的創(chuàng)建與移動(dòng)
在html中添加div標(biāo)簽
添加相應(yīng)的css
.enemy {width: 38px;height: 34px;background-image: url(img/enemy.png);position: absolute;background-size: 100% 100%;}接下來是js/enemy.js部分:
獲取元素 var dEnemy = document.getElementById("enemy"); 創(chuàng)建敵機(jī) function creatEnemy() {dom操作創(chuàng)建div標(biāo)簽var enemy = document.createElement('div');enemy.className = 'enemy';enemy.style.left = rand(0,sw-38) +'px'; 調(diào)用隨機(jī)函數(shù)(我們之前在公用方法里面寫過,這里直接調(diào)用)enemy.speed = rand(3,8);dEnemy.appendChild(enemy);將創(chuàng)建的敵機(jī)存儲在父級里 } 這里是一個(gè)拓展的操作,由于之前創(chuàng)建會使每次出現(xiàn)的敵機(jī)數(shù)量一致(且計(jì)時(shí)器的速度是30毫秒 使敵機(jī)數(shù)量過于龐大) 我們這里使用一個(gè)操作 概率 var diff = 200; 定義一個(gè)變量并且使隨機(jī)數(shù)在 0~diff 中這樣使它小于 10,這樣只要改變diff的值就可以使小于10的數(shù)有一個(gè)范圍, diff越大 小于10出現(xiàn)的數(shù)的可能性就更小,反之更大 function enemyMove() {if (rand(0,diff) <= 10){ //概率creatEnemy();}var es = dEnemy.children; 所有敵機(jī)for(var i=0; i<es.length; i++) { 遍歷所有敵機(jī)var e = es[i]; 每一個(gè)敵機(jī)if(e.offsetTop > sh-40){ 當(dāng)敵機(jī)的位置大于界面高度使它消失dEnemy.removeChild(e); 刪除敵機(jī) 使其消失i--; //防止漏元素continue; 退出此次循環(huán)進(jìn)入下次循環(huán)}e.style.top = e.offsetTop + e.speed + 'px'; 更新每個(gè)敵機(jī)的位置} }4.子彈的創(chuàng)建及其移動(dòng)
在html中添加div標(biāo)簽
子彈的移動(dòng)js/bullet.js部分:
獲取元素 var dBullet = document.getElementById("bullet"); 創(chuàng)建子彈 function creatBullet() {var bullet = document.createElement('div');bullet.className = 'bullet'; 子彈的出現(xiàn)是從飛機(jī)的頭部出現(xiàn) 所以位置應(yīng)該從獲取飛機(jī)的距離bullet.style.left = dHero.offsetLeft + 33 - 8 + 'px'; bullet.style.top = dHero.offsetTop + 'px';dBullet.appendChild(bullet); } 子彈的移動(dòng) function bulletMove() {creatBullet();var bs = dBullet.children;遍歷每個(gè)子彈for(var i=0; i<bs.length; i++){var top = bs[i].offsetTop;if(top <= -14){dBullet.removeChild(bs[i]);i--;continue;}bs[i].style.top = top - 20 + 'px';} }其實(shí) 寫到這里我們會發(fā)現(xiàn)子彈和敵機(jī)的操作幾乎是相同的,只不過,子彈是從一個(gè)地方出現(xiàn),敵機(jī)的多個(gè)地方出現(xiàn)
再補(bǔ)上css部分
5。碰撞檢測
這就是最重要的部分了,我們將飛機(jī),子彈 分別與敵機(jī)的碰撞 觸發(fā)不同的事件
關(guān)于碰撞檢測 我們有下面這張圖
當(dāng)r2<l1 , b2<t1 ,r1<l2,b1<t2 時(shí)便不會發(fā)生碰撞
接下來我們把碰撞檢測函數(shù)在調(diào)用一下 并且觸發(fā)相應(yīng)的事件
function check() {var bs = dBullet.children; 所有的子彈var es = dEnemy.children; 所有的敵機(jī)for(var i=0; i<es.length; i++){ 遍歷所有敵機(jī)var e = es[i]; 每一個(gè)敵機(jī)if(isCrash(dHero,e)){ 進(jìn)行判斷alert("失敗"); 彈窗}//子彈和敵機(jī)的碰撞檢測for(var j=0; j<bs.length; j++){var b = bs[j];if(isCrash(e,b)){dBullet.removeChild(b); 刪除該子彈dEnemy.removeChild(e); 刪除該敵機(jī)}}} }6,最后,我們將所有函數(shù)在計(jì)時(shí)器里調(diào)用
function start() {timer = setInterval(function() {bgMove();heroMove();enemyMove();bulletMove();check();},30)}start();以上就是利用js制作的一個(gè)簡易的飛機(jī)大戰(zhàn),喜歡的小伙伴可以一件三連哦🤑🤑🤑
總結(jié)
以上是生活随笔為你收集整理的JavaScript制作简易的《飞机大战》的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 静态路由(一)
- 下一篇: html读取在线文件,javascrip