坦克大战小游戏关键技术总结
生活随笔
收集整理的這篇文章主要介紹了
坦克大战小游戏关键技术总结
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? ? ? 這兩天參照韓順平的坦克大戰游戲并在其基礎上初步完善成一個小的頁面游戲,最終js代碼大約570行,html代碼200多行,具體可參見https://github.com/Mrkaiyang/Art/tree/gh-pages/tank。主要實現了以下功能:
? ? ? ?現對其主要編程思想做下總結:1、使用html5的<canvas>元素繪制坦克,
主要用到了以下技術:
1、JavaScript面向對象的編程(包括三類對象:坦克、子彈、墻);
//利用構造函數構建坦克類,屬性包括:坦克的橫縱坐標、坦克的方向、坦克移動速度、坦克的類型(英雄坦克/敵人坦克)、坦克生存狀態判斷屬性;方法實現了坦克上下左右移動
function Tank(x,y,direct,speed,type) {this.x=x;this.y=y;this.speed=speed;this.direct=direct;this.isLive=true;this.type=type;this.moveUp=function () {this.direct=0;this.y-=this.speed;}this.moveDown=function () {this.direct=2;this.y+=this.speed;}this.moveRight=function () {this.direct=1;this.x+=this.speed;}this.moveLeft=function () {this.direct=3;this.x-=this.speed;} } //構造子彈類,屬性包括:子彈橫縱坐標,子彈的方向,子彈的移動速度,子彈的類型(英雄子彈/敵人子彈),子彈存在判斷屬性,所屬坦克等;方法實現了子彈的移動的條件及位置移動 function Bullet(x,y,direct,speed,type,tank) {this.x=x;this.y=y;this.isLive=true;this.timer=timer;this.direct=direct;this.speed=speed;this.type=type;this.tank=tank;this.run=function() {if(this.x<0||this.x>500||this.y<10||this.y>600||this.isLive==false){clearInterval(this.timer);this.isLive=false;if(this.type=="enemy"){this.tank.bulletIsLive=false;}}else {switch (this.direct) {case 0:this.y -= this.speed;break;case 1:this.x += this.speed;break;case 2:this.y += this.speed;break;case 3:this.x -= this.speed;break;}}}}//利用構造函數構造墻體類,屬性包括:墻的橫縱坐標、墻的存在判斷屬性; function Wall(x,y){this.x=x;this.y=y;this.isLive=true; }//利用對象冒充繼承方法構造英雄坦克類,英雄坦克自帶射擊方法 var heroBullets=new Array(); function Hero(x,y,direct,speed,type) {//通過對象冒充達到繼承的的效果 this.tank=Tank;this.tank(x,y,direct,speed,type);this.shotEnermy=function () {switch (this.direct){case 0:heroBullet=new Bullet(this.x+9,this.y,this.direct,10);//全局變量 break;case 1:heroBullet=new Bullet(this.x+30,this.y+9,this.direct,10);//全局變量 break;case 2:heroBullet=new Bullet(this.x+9,this.y+30,this.direct,10);//全局變量 break;case 3:heroBullet=new Bullet(this.x,this.y+9,this.direct,10);//全局變量 break;}heroBullets.push(heroBullet);heroBullet.timer=timer//面向對象引用傳遞; var timer=window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50);}} //利用對象冒充繼承方法構造敵人坦克類 function EnemyTank(x,y,direct,speed,type) {this.tank=Tank;//繼承實現this.isLive=true;this.bulletIsLive=true;//this.enermy(x,y,direct,speed,type); this.count=0;this.bulletIsLive=true;this.tank(x,y,direct,speed,type);this.run=function () {var flag = null;switch (this.direct) {case 0:for (var i = 0; i < wall.length; i++) {//實現遇到墻體換向if ((this.y > 0) && ((this.y - this.speed) >= wall[i].y) &&((this.y - this.speed) < wall[i] + 40) && (this.x >= wall[i].x) &&( this.x < wall[i].x + 40)&&(wall[i].isLive==true)) {flag = 1;}}if (this.y > 0 && flag != 1) {this.y -= this.speed;} else {this.direct = Math.round(Math.random() * 3);}break;case 1:for (var i = 0; i < wall.length; i++) {if ((this.x+20 <500) && (this.y+30 > wall[i].y) && (this.y < (wall[i].y + 40)) && ((this.x+30 + this.speed) >= wall[i].x) && ((this.x + this.speed) < (wall[i].x + 40))&&(wall[i].isLive==true)){flag = 1;}}if (this.x + 30 < 500 && flag != 1) {this.x += this.speed;} else {this.direct = Math.round(Math.random() * 3);}break;case 2:for(var i=0;i<wall.length;i++){if ((this.y+30<600) && ((this.y+30 + this.speed)>= wall[i].y) &&(this.y+30 + this.speed) < (wall[i].y + 40) && (this.x+20 >= wall[i].x) &&( this.x < wall[i].x + 40)&&(wall[i].isLive==true)){flag = 1;}}if (this.y+30<600&& flag != 1) {this.y += this.speed;} else {this.direct = Math.round(Math.random() *3);}break;case 3:for (var i = 0; i < wall.length; i++) {if ((this.x-20 > 0) && (this.y+30 > wall[i].y) && (this.y < (wall[i].y + 40)) && ((this.x - this.speed) >= wall[i].x) && ((this.x - this.speed) < (wall[i].x + 40))&&(wall[i].isLive==true)){flag = 1;}}if (this.x > 0 && flag != 1) {this.x -= this.speed;} else {this.direct = Math.round(Math.random() * 3);}break;}if (this.count > 30) {this.direct = Math.round(Math.random() * 3);//隨機生成 0,1,2,3 this.count = 0;}this.count++; } }
2、繪圖技術;利用html5<canvas>元素繪制作戰區域,坦克及子彈
<canvas id="tankMap1" width="500px" height="600px" style="background-color:black" ></canvas> <script type="text/javascript">var drawing=document.getElementById("tankMap1");var cxt=drawing.getContext('2d'); var hero=new Hero(150,420,0,5,"hero");//繪制坦克 function drawTank(tank) {if (tank.isLive==true){switch (tank.direct){case 0:case 2:if(tank.type=="hero"){cxt.fillStyle="#DED284";}else if(tank.type=="enemy"){cxt.fillStyle="yellow";}cxt.fillRect(tank.x,tank.y,5,30); cxt.fillRect(tank.x+15,tank.y,5,30);cxt.fillRect(tank.x+6,tank.y+5,8,20);if(tank.type=="hero"){cxt.fillStyle="#FFD972";}else if(tank.type=="enemy"){cxt.fillStyle="red";}cxt.arc(tank.x+10,tank.y+15,4,0,2*Math.PI,true);cxt.fill();//������? //cxt.strokeStyle="#FFD972"; if(tank.type=="hero"){cxt.strokeStyle="#FFD972";}else if(tank.type=="enemy"){cxt.strokeStyle="red";}cxt.lineWidth=2;cxt.beginPath();cxt.moveTo(tank.x+10,tank.y+15);if(tank.direct==0){cxt.lineTo(tank.x+10,tank.y);}else if(tank.direct==2){cxt.lineTo(tank.x+10,tank.y+30)}cxt.closePath();cxt.stroke();break;case 1:case 3:if(tank.type=="hero"){cxt.fillStyle="#DED284";}else if(tank.type=="enemy"){cxt.fillStyle="yellow";}cxt.fillRect(tank.x,tank.y,30,5); cxt.fillRect(tank.x,tank.y+15,30,5);cxt.fillRect(tank.x+5,tank.y+6,20,8);if(tank.type=="hero"){cxt.fillStyle="#FFD972";}else if(tank.type=="enemy"){cxt.fillStyle="red";}cxt.arc(tank.x+15,tank.y+10,4,0,2*Math.PI,true);cxt.fill();//������? /* cxt.strokeStyle="#FFD972"; cxt.lineWidth=2;*/ if(tank.type=="hero"){cxt.strokeStyle="#FFD972";}else if(tank.type=="enemy"){cxt.strokeStyle="red";}cxt.lineWidth=2;cxt.beginPath();cxt.moveTo(tank.x+15,tank.y+10);if(tank.direct==1){cxt.lineTo(tank.x+30,tank.y+10);}else if(tank.direct==3){cxt.lineTo(tank.x,tank.y+10)}cxt.closePath();cxt.stroke();break;}}} </script>//繪制英雄子彈
function drawHeroBullet(){for(var i=0;i<heroBullets.length;i++){var heroBullet=heroBullets[i];if(heroBullet!=null&&heroBullet.isLive){cxt2.fillStyle="yellow";cxt2.fillRect(heroBullet.x,heroBullet.y,2,2);}} } //繪制敵人子彈 function drawEnemyBullet(tank,i,bullet){ var etBullet = bullet; if (etBullet.isLive == true&&tank.bulletIsLive==true&&tank.isLive==true) {cxt.fillStyle = "#00FEFE";cxt.fillRect(etBullet.x, etBullet.y, 2, 2);} } //繪制墻體 function drawWall() {var wall=new Array(wall1,wall2,wall3,wall4,wall5,wall6,wall7,wall8,wall9,wall10,wall11,wall12,wall13,wall14);for (var i = 0; i < wall.length; i++) {if(wall[i].isLive==true){var img = new Image()img.src = "wall_1.png" cxt.drawImage(img, wall[i].x, wall[i].y);}} }3、界面編程;
4、多個獨立的定時器系統工作;
//啟動這個敵人的坦克 window.setInterval("enemyTanks["+i+"].run()",50); //不停地刷新畫圖,實現坦克移動;var timer1=setInterval("flashTanMap()",100);//不停地刷新畫圖,實現英雄子彈移動;var timer=setInterval("flashBullet()",100);5、網頁游戲的編程思想;
難點所在:
1、如何實現坦克爆炸后產生爆炸動畫效果?
//定義一個炸彈類 function Bomb(x,y){this.x=x;this.y=y;this.isLive=true; //炸彈是否活的,默認true; //炸彈有一個生命值 this.blood=9;//減生命值 this.bloodDown=function(){if(this.blood>0){this.blood--;}else{//說明炸彈死亡 this.isLive=false;}} } //編寫一個函數,專門用于判斷我的子彈,是否擊中了某個敵人坦克 function isHitEnemyTank(){//取出每顆子彈 for(var i=0;i<heroBullets.length;i++){//取出一顆子彈 var heroBullet=heroBullets[i];/* alert(heroBullet.islive);*/ if(heroBullet.isLive===true){ //子彈是活的,才去判斷 //讓這顆子彈去和遍歷每個墻判斷 for(var i=0;i<wall.length;i++){var walls=wall[i];if(walls.isLive==true){if(heroBullet.x>=wall[i].x&&heroBullet.x<=wall[i].x+40 &&heroBullet.y>=wall[i].y&&heroBullet.y<=wall[i].y+40){wall[i].isLive=false;heroBullet.isLive=false;}}}//讓這顆子彈去和遍歷每個敵人坦克判斷 for(var j=0;j<enemyTanks.length;j++){var enemyTank=enemyTanks[j];if(enemyTank.isLive===true){//子彈擊中敵人坦克的條件是什么? 很多思路 , 韓老師的思想是 //(看看這顆子彈,是否進入坦克所在矩形) //根據當時敵人坦克的方向來決定 switch(enemyTank.direct){case 0: //敵人坦克向上 case 2://敵人坦克向下 if(heroBullet.x>=enemyTank.x&&heroBullet.x<=enemyTank.x+20 &&heroBullet.y>=enemyTank.y&&heroBullet.y<=enemyTank.y+30){;//把坦克isLive 設為false ,表示死亡 enemyTank.isLive=false;//該子彈也死亡 heroBullet.isLive=false;//創建一顆炸彈 var bomb=new Bomb(enemyTank.x,enemyTank.y);//在坦克確認被擊中后,增加一個爆炸實例,然后將其畫出//然后把該炸彈放入到bombs數組中 bombs.push(bomb);}break;case 1: //敵人坦克向右 case 3://敵人坦克向左 if(heroBullet.x>=enemyTank.x&&heroBullet.x<=enemyTank.x+30 &&heroBullet.y>=enemyTank.y&&heroBullet.y<=enemyTank.y+20){//把坦克isLive 設為false ,表示死亡 enemyTank.isLive=false;heroBullet.isLive=false;//創建一顆炸彈 var bomb=new Bomb(enemyTank.x,enemyTank.y);//然后把該炸彈放入到bombs數組中 bombs.push(bomb);}break;}}}//for }} }
總結
以上是生活随笔為你收集整理的坦克大战小游戏关键技术总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信息技术计算机说课,信息技术说课稿范文
- 下一篇: python支持向量机回归_用Pytho