想作這個遊戲已久,今天終於初步完成,先解釋下,這是一個模擬機場塔臺管制指揮的遊戲,飛機從不一樣的方向飛入管制空域,有不一樣的目的地,飛機名稱最後一個字母表示飛機要到達的目的地,分ABCD和R。A-D表示四個方向,R表示到本場的跑道降落。飛機有H,M,S三種速度,離場必須不能是最快的速度(H),降落必須是S的速度這樣才能得分。默認設置是20架飛機,最多容量默認是10架飛機。固然實際的指揮比這個要複雜。html
整個遊戲是基於canvas的,純JavaScript,四種朝向的飛機是用四張圖片實現的,全部要不斷渲染的對象都在airspace這個數組裏面。有Plane,Runway和Exit三個對象。正確指揮一架飛機到目的地有5分。前端
function Plane(id,sx,sy,heading,url){ this.x=sx; this.y=sy; this.flightId=id; this.h=heading||"down";//up down left right this.img=url||"down.png"; this.draw=drawPlane this.move=movePlane this.speed=airspeed[getRandom(3)]; this.D=destination[getRandom(5)]; this.state="cruise"; this.width=size; this.height=size; this.getCenter=getCenter; }
function Runway(name,x,y,w,h){ this.name=name; this.x=y; this.y=y; this.width=w; this.height=h; this.draw=drawRunway; this.getCenter=getCenter; }
到canvas上選中一架飛機以後會用紅色邊框,表示當前正在指揮的飛機。canvas自己沒有提供對象的click事件git
因此要根據鼠標的位置來判斷是否選中了目標:github
function eventDispature(canvas){ canvas.onclick=function(e){ console.log(e.offsetX,e.offsetY,e.type) detectEvent(e.offsetX,e.offsetY,e.type) } } function detectEvent(x,y,type){ //判斷是否擊中 airspace.forEach(function(p){ //範圍 x,x+size y,y+size var maX=p.x+p.width; var maY=p.y+p.height; if(x>=p.x&&x<=maX&&y>=p.y&&y<=maY){ p.selected=true; taget=p; console.log("選中",p.flightId,p.x,p.y) airspace.filter(n=>n.flightId!=p.flightId).forEach(n=>n.selected=false); } }) }
根據e.offsetX和e.offsetY得到事件的位置,判斷是否在某個飛機的座標範圍裏,而後標記選中,並去除其餘被標記selected的飛機。固然這個地方還能夠完善成一個事件系統,並支持其餘的事件。算法
碰撞有四種狀況,首先是飛機與飛機相撞,飛機飛出邊界(是否正確飛向入口),飛機飛入跑道(是否對準入口進入)。錯誤操做的飛機將會被移除airspace數組。canvas
function isIntersect(p1,p2){ var center=p1.getCenter(); var c1=p2.getCenter(); var dx=Math.abs(center.x-c1.x); var dy=Math.abs(center.y-c1.y); return dx<(p1.width/2+p2.width/2)&&dy<(p1.height/2+p2.height/2) }
三種狀況的判斷主要依靠上面這個方法,而後再有區分,飛機飛入跑道,首先是座標矩形會與跑道矩形相交,而後y1,y2在跑道的y軸範圍以內便可。數組
if(isIntersect(plane,runway)&&plane.state==states.cruise){ console.warn(plane.flightId+"進入跑道"); //進入跑道的條件是 左邊的兩個點 和右邊的兩個點 var y1=plane.y; var y2=plane.y+plane.height; //速度最慢,方向是跑道才能得分 if(y1>runway.y&&y1<runway.y+runway.height&&y2>runway.y&&y2<runway.y+runway.height &&plane.D==destination[4]&&plane.speed==airspeed[2]) { plane.state=states.landing; score+=5; info(plane.flightId+"正確降落跑道"); showPlaneNum(); plane.state=states.stop; removePlane(plane.flightId); }else{ plane.state=states.crash; info(plane.flightId+"墜毀,航向"+plane.h+",速度"+plane.speed); removePlane(plane.flightId); }
判斷進入入口的道理同樣。右下角幾個按鈕分別表示四個方向和三種速度。dom
1.飛機用了四張圖片仍是有點笨,由於當初旋轉移動沒有搞定,後續繼續研究。測試
2.飛機碰撞的算法還不夠準確,離場的判斷只判斷了一個點。這裏是考慮到離場判斷和入場飛機有衝突,這裏須要再優化下。優化
3.還能夠增長一些效果。
PS:這實際上是當時入學時一個測試程序,當時就記住了,今天用前端實現一回。來玩一玩吧,喜歡就給個贊,歡迎拍磚。