javascript面向对象编程(精灵大战)

来源:互联网 发布:ocr表格识别软件 编辑:程序博客网 时间:2024/06/10 05:00


//this是Javascript语言的一个关键字。它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。
//随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用本函数的那个对象。
//.prototype 属性使您有能力向对象添加属性和方法。
//.push(element…) 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
//.appendChild(DOM对象)
//.removeChild(DOM对象)
//.setInterval(function(){}); //创建定时器
//clearInterval(a.timer) //清除掉a的定时器timer
//.parentNode标签父结点
//Math.random()方法可返回介于 0 ~ 1 之间的一个随机数。
//parseInt(实数)方法返回一个整型数字
//setTimeout(function(){}); //只执行一次里面的代码
//.innerHTML = “得分:” + score ; //设置标签对象的内容
//类方法EnemyMonster.timer与类对象方法this.timer是不一样的。
效果图如下

创建公共变量

var score = 0 ; //得分var song ; //游戏背景音乐var bgTimer ; //背景移动定时器

扩展了javascript的内置对象Array

 Array.prototype.remove=function(element){             for(i=0;i<this.length;i++){//遍历数组对象的元素                if(this[i]==element){  //当相等时                   //调用javascript的内置方法splice(规定要删除的项目的位置,要删除的项目数量),返回删除后的this                   this.splice(i,1);                   }             }             return this;   //返回调用remove方法的对象        }

自定义(射手-射箭)类 MyShooter的构造函数function MyShooter(x,y,container){}

function MyShooter(x,y,container){    this.arrows = []; //自定义一个弓箭集合    this.x = x; //射手的坐标初始化    this.y = y;     this.container = container; //引入游戏面板    this.init(); }

扩展init()方法

MyShooter.prototype={   init : function(){        this.Shooter();        this.ShooterMove();        var that = this ; //此处的this指的是MyShooter        MyShooter.timer = setInterval(function(){ //为MyShooter对象定义一个弓箭发射定时器 //此处的this指的是timer             that.Arrow(); //每隔0.4秒执行一次        },400);   },   //自定义射手对象   Shooter : function(){        this.shooter = document.createElement("img"); //创建一个img标签        this.shooter.src = "images/shooter.gif" ; //设置src        this.shooter.style.cssText = "position:absolute; left:" + this.x + "px; top:" + this.y + "px;"; //设置坐标        this.container.appendChild(this.shooter); //添加到游戏面板中   },   //射手随鼠标移动事件   ShooterMove : function(){        var that = this; //此处的this指的是MyShooter对象,其DOM父结点为container        //鼠标监听器        this.container.mousemove = function(e){ //此处的this指的是container,其DOM父结点为body               //在此处的that和this代表的对象不同               e = e||event;               //根据鼠标的坐标确定射手的坐标               var sx = e.clientX - this.offsetLeft - that.shooter.offsetWidth/2 ;                var sy = e.clientY - this.offsetTop -that.shooter.offsetHeight/2 ;               that.shooter.style.left = sx + "px" ;               that.shooter.style.top = sy + "px" ;               //如果射手走出游戏面板的右边界限               if(that.shooter.offsetLeft + that.shooter.offsetWidth >= this.offsetWidth){                     that.shooter.style.left = this.offsetWidth - that.shooter.offsetWidth +"px" ;               }               //左边界限               if(that.shooter.offsetLeft <= 0){                     that.shooter.style.left = "0px" ;               }               //顶边界限               if(that.shooter.offsetTop <= 0){                     that.shooter.style.top = "0px" ;               }               //底边界限               if(that.shooter.offsetTop + that.shooter.offsetHeight >= this.offsetHeight){                     that.shooter.style.top = this.offsetHeight - that.shooter.offsetHeight + "px" ;               }        }   },   //自定义弓箭对象   Arrow : function(){        this.arrow = document.createElement("img");        this.arrow.src = "images/arrow.png";        //根据射手的位置确定弓箭的初始坐标        var ax = this.shooter.offsetLeft + this.shooter.offsetWidth/2 - 1 ;        var ay = this.shooter.offsetTop - 10 ;        this.arrow.style.cssText = "position:absolute; left:" + ax + "px; top:" + ay +"px;" ;        this.container.appendChild(this.arrow); //添加到游戏面板        this.arrows.push(this.arrow); //添加到弓箭集合中        var a = this.arrow; //此处的this指的是MyShooter        var aArr = this.arrows;        a.timer=setInterval(function(){ //弓箭的控制移动/清除 的定时器 //此处的this指的是定时器timer              a.style.top = a.offsetTop- 8 + "px" ; //每隔0.2秒弓箭向上移动8个像素              if(a.offsetTop == -60){ //60像素是弓箭图片的高度                  aArr.remove(a); //从弓箭集合中移除弓箭对象a                  a.parentNode.removeChild(a); //从弓箭的DOM父结点(游戏面板)中移除                  clearInterval(a.timer); //清除掉弓箭的定时器              }        },200);   }}

自定义(怪兽-创建、碰撞)类EnemyMonster的构造函数function EnemyMonster(shooter,arrows,container){}

图1

function EnemyMonster(shooter,arrows,container){    this.enemyList = [] ; //怪兽集合 初始化    this.shooter = shooter ; //射手    this.arrows = arrows ; //弓箭    this.container = container ; //游戏面板,即DOM父结点    this.probability = 0 ; //出发的怪兽数量,这里约定最大为20,最小为0    this.num = 0 ; //出发的怪兽数量,这里约定最大为10,最小为0    this.sWidth = 34; //怪兽图片的宽度    this.mWidth = 46;    this.bWidth = 110;    this.smallURL = "images/smallLive.png";    //图片URL初始化    this.middURL = "images/middleLive.gif";    this.bigURL = "images/bigLive.gif";    this.blastSmallURL = "images/smallDied.png";    this.blastMiddURL = "images/middleDied.png";    this.blastBigURL = "images/bigDied.png";    this.init();}

扩展init()方法

EnemyMonster.prototype={     init : function(){            var that = this;            //只能是EnemyMonster.timer不能是this.timer,因为这里的this指的是EnemyMonster类的一个enemy对象,但是EnemyMonster类可以有多个enemy对象,EnemyMonster.timer指的是timer是属于所有enemy对象的监听器,是类方法,而不是只属于一个enemy对象。            EnemyMonster.timer = setInterval(function(){ //每隔0.8秒创建一只怪兽                  that.probability ++ ; //出发怪兽数量加一                  if(that.probability = 20){ //出发怪兽数量为20时                        var bx = parseInt(Math.random() * (that.container.offsetWidth-that.bWidth));                        that.BigMonster(bx); //创建一只大型怪兽                        that.probability = 0 ; //将probability清零                  }                  else if(that.probability % 5 == 0){ //出发怪兽数量为5的倍数时                        var mx = parseInt(Math.random() * (that.container.offsetWidth-that.mWidth));                        that.MiddMonster(mx);                  }                  else { //每隔0.8秒出发一只小型怪兽                        var sx = parseInt(Math.random() * (that.container.offsetWidth-that.sWidth));                        that.SmallMonster(sx);                  }            },800);     },     //自定义小型怪兽对象     SmallMonster : function(x){ //x指的是怪兽的左边距            this.small = document.createElement("img") ;            this.small.src = this.smallURL ;            //小型怪兽图片的高度为34像素            this.small.style.cssText = "position:absolute; left:" + x + "px; top:-34px;" ;             this.container.appendChild(this.small) ; //加入游戏面板            this.enemyList.push(this.small) ; //加入怪兽集合            this.RelationListener(this.small,this.arrows,this.blastSmallURL,1);     },     //自定义中型怪兽对象     MiddMonster : function(x){            this.midd = document.createElement("img");            this.midd.src = this.middURL;            //中型怪兽图片的高度为60像素            this.midd.style.cssText = "position:absolute; left:" + x + "px; top:-60px;" ;            this.container.appendChild(this.midd);            this.enemyList.push(this.midd);            this.RelationListener(this.midd,this.arrows,this.blastMiddURL,2);     },     //自定义大型怪兽对象     BigMonster : function(x){            this.big = document.createElement("img");            this.big.src = this.bigURL;            //大型怪兽图片的高度为164像素            this.big.cssText = "position:absolute; left:" + x + "px; top:-164px;" ;            this.container.appendChild(this.big);            this.enemyList.push(this.big);            this.RelationListener(this.big,this.arrows,this.blastBigURL,3);     },     //关系监听器     RelationListener : function(monsterObj,arrows,diedImgUrl,monsterType){           this.num++ ; //出发的怪兽数量加一           var blastedSmall = false; //碰撞标识           var blastedMidd = false;           var blastedBig = false;             var hitMidd = 0; //碰撞次数           var hitBig = 0;           var topIncrement = parseInt(Math.random()*3) ; //topIncrement为顶部随机增量,返回0或1或2或3           topIncrement = topIncrement == 0 ? 1 : topIncrement ; //返回1或2或3           //根据现实世界的法则来看,大型怪兽的速度不能快于中、小型怪兽,故只随机加快中、小型怪兽的行走速度           //当对象为大型怪兽时,topIncrement不变           if(monsterType!=3){ //当对象为中、小型怪兽时                if(this.num == 10)                    this.num = 0 ; //num清零                //根据怪兽的出发数量num的奇偶性,来修改怪兽的顶部随机增量topIncrement                if(this.num % 3 == 0){ //当num为奇数时                    topIncrement = monsterType == 2 ? 3 : 6 ;                 }                //当num为偶数时,topIncrement不变           }           var that = this ;           //监听一只怪兽与所有弓箭的关系、与父结点的关系、与射手的关系           monsterObj.timer = setInterval(function(){                monsterObj.style.top =monsterObj.offsetTop + topIncrement; //每隔0.02秒怪兽的top加topIncrement个像素                for(i=0; i<arrows.length; i++){ //遍历弓箭集合                       //弓箭的头部位置和尾部位置,如图1的左边图                       if(arrows[i].offsetTop < monsterObj.offsetTop + monsterObj.offsetHeight &&                           arrows[i].offsetTop + arrows[i].offsetHeight > monsterObj.offsetTop){                              //弓箭的左边位置和右边位置,如图1的右边图                              if(arrows[i].offsetLeft + arrows[i].offsetWidth > monsterObj.offsetLeft &&                                 arrows[i].offsetLeft < monsterObj.offsetLeft + monsterObj.offsetWidth){                                           if(monsterType == 1){                                                 monsterObj.src = diedImgUrl; //更换死亡图片                                                 that.enemyList.remove(monsterObj); //从怪兽集合中移除该怪兽                                                 clearInterval(monsterObj.timer); //清除该怪兽的定时移动器                                                 blastedSmall = true ; //标记为已碰撞                                                 score += 5; //分数加五                                                 scoretext.innerHTML = "得分:" + score; //修改分数面板内容                                           }                                           if(monsterType == 2){                                                 hitMidd ++ ; //碰撞次数加一                                                 if(hitMidd == 4 ){ //如果与中型怪兽的碰撞次数为4                                                      hitMidd = 0 ; //将hitMidd清零                                                      monsterObj.src = diedImgUrl; //更换死亡图片                                                      that.enemyList.remove(monsterObj); //从怪兽集合中移除该怪兽                                                      clearInterval(monsterObj.timer); //清除该怪兽的定时移动器                                                      blastedMidd = true ; //标记为已碰撞                                                      score += 10; //分数加十                                                      scoretext.innerHTML = "得分:" + score; //修改分数面板内容                                                 }                                           }                                           if(monsterType == 3){                                                 hitBig ++ ; //碰撞次数加一                                                 if(hitBig == 6){ //如果与大型怪兽的碰撞次数为6                                                      hitBig = 0 ; //将hitMidd清零                                                      monsterObj.src = diedImgUrl; //更换死亡图片                                                      that.enemyList.remove(monsterObj); //从怪兽集合中移除该怪兽                                                      clearInterval(monsterObj.timer); //清除该怪兽的定时移动器                                                      blastedBig = true ; //标记为已碰撞                                                      score += 20; //分数加十                                                      scoretext.innerHTML = "得分:" + score; //修改分数面板内容                                                 }                                           }                                           //必须在发生碰撞的那一刹那,就立即销毁掉发生碰撞的弓箭,否则以上判断失效                                           arrows[i].parentNode.removeChild(arrows[i]);                                           arrows.remove(arrows[i]);                                   }                       }                }                //设置不同类型的怪兽在发生碰撞后消失的延迟时间                if(blastedSmall){ //0.4秒后消失                     blastedSmall = false ;                     setTimeout(function(){                          that.container.removeChild(monsterObj);                     },400);                }                if(blastedMidd){ //0.5秒后消失                     blastedMidd = false;                     setTimeout(function(){                          that.container.removeChild(monsterObj);                     },500);                }                if(blastedBig){ //0.6秒后消失                     blastedBig = false;                     setTimeout(function(){                          that.container.removeChild(monsterObj);                     },600);                }                //我的射手被怪兽近了身,则游戏结束                if(that.shooter.offsetTop < monsterObj.offsetTop + monsterObj.offsetHeight &&                    that.shooter.offsetTop + that.shooter.offsetHeight > monsterObj.offsetTop){                      if(that.shooter.offsetLeft + that.shooter.offsetWidth > monsterObj.offsetLeft &&                         that.shooter.offsetLeft < monsterObj.offsetLeft + monsterObj.offsetWidth){                         that.over();                        }                }                //如果怪兽的顶距>=父结点(即游戏面板)的高度,则从怪兽集合、游戏面板中删除该怪兽,并清除其移动定时器                if(monsterObj.offsetTop >= that.container.offsetHeight){                     that.enemyList.remove(monsterObj);                     monsterObj.parentNode.removeChild(monsterObj);                     clearInterval(monsterObj.timer);                }           },20);     },   //游戏结束:善后处理     over : function(){           StopSong(); //销毁音乐           this.MyShooter.src = "images/smallDied.png";           clearInterval(MyShooter.timer); //清除弓箭发射定时器           for(var i=0; i<this.arrows.length; i++){ //清除弓箭移动/清除定时器               clearInterval(this.arrows[i].timer);           }           clearInterval(EnemyMonster.timer); //清除怪兽创建定时器           for(var i=0; i<this.enemyList.length; i++){ //清除怪兽移动/碰撞/清除定时器               clearInterval(this.enemyList[i].timer);           }           clearInterval(bgTimer); //清除游戏背景移动定时器           this.container.onmousemove = null ; //清空鼠标移动事件           enddiv.style.display = "block"; //显示游戏结束面板     }}

移动背景函数

function moveBG(){            var backgroundY = 0;     //初始化backgroundY            bgTimer = setInterval(function(){                backgroundY += 1;       //每隔0.02秒backgroundY加一                //设置container的背景位置background-position: 水平位置 垂直位置。                container.style.backgroundPosition = "0 "+backgroundY + "px";                //当backgroundY与container的高度一样时,将backgroundY清零,以达到循环                if(backgroundY == container.offsetHeight){                    backgroundY = 0;                }            },20);        }

游戏开始时的初始化界面显示

function play(){            //得分归零            score = 0;            scoretext.innerHTML = "分数:0";            //替换游戏背景图            container.style.background = "url(images/bg.png)";            //背景移动            moveBG();            //调用MyPlan()实例化玩家飞机            var myShooter = new MyShooter(0,500,container);            //调用EnemyPlan(我的飞机,我的子弹,游戏场地)实例化敌机            var enemy = new EnemyMonster(myShooter.shooter,myShooter.arrows,container);            //每次点击继续按钮,都会创建出一个新的myShooter对象 和一个新的enemy对象,问题是之前创建的对象都还存在着,并没有消失        }

相当于java中的main()方法,即加载网页后, 加载以下变量和方法

window.onload = function(){            var container = document.getElementById("container"); //为container对应的标签 ,创建container变量。            var startBtn = document.getElementById("startBtn"); //为startBtn对应的标签 ,创建startBtn变量。            //点击开始按钮            startBtn.onclick = function(){                StartSong();                this.style.display = "none"; //隐藏 开始按钮                play();                 }}

点击继续按钮时触发该函数

function restartGame(){            StartSong(); //创建音乐            enddiv.style.display = "none";   //隐藏  结束面板且不占地方。            container.innerHTML = scoretext.outerHTML + enddiv.outerHTML + startBtn.outerHTML;             play();  }

创建音乐

function StartSong(){            //动态添加游戏背景音乐            song=document.createElement("embed");            song.src="song.mp3";            song.style="width:0; height:0; "            document.body.appendChild(song);}

销毁音乐

function StopSong(){            document.body.removeChild(song); }

游戏面板如下

<body>    <!-- <embed id="song" src="song.mp3"  width="0" height="0" autostart="false" enablejavascript="true" /> -->    <div id="container">        <p id="scoretext"></p>        <div id="enddiv">            <p class="plantext">游戏结束</p>            <div><button onclick="restartGame()" id="restart">继续</button></div>        </div>        <input type="button" value="开始游戏" id="startBtn">    </div></body>

游戏面板的css设置如下

<style>        #container{            width:320px;            height:568px;            background: url(images/start.png);            margin:20px auto;   /* 距顶部20px,水平居中 */            position: relative;            overflow: hidden;        }        /* 开始按钮样式 */        #container input{            width:120px;            height: 38px;            background: #ff6600;            border:0;            color:#fff;            font-size:14px;            font-family: 微软雅黑;            position: absolute;            left: 100px;            bottom:50px;        }        /* 结束面板 */        #enddiv{            position: absolute;            top: 400px;            left: 75px;            border: 1px solid gray;            border-radius: 5px;            text-align: center;            background-color:#d7ddde;            display: none;            z-index: 2;        }        /* 结束面板里面的    文本面板 */        .plantext{            width: 160px;            height: 30px;            line-height: 30px;            font-size: 16px;            font-weight: bold;        }        /* 结束面板里面的   继续按钮面板  */        #enddiv div{            width: 160px;            height: 50px;        }        /* 结束面板里面的   继续按钮面板里面的  继续按钮  */        #enddiv div button{            margin-top:10px ;            width: 90px;            height: 30px;            border: 1px solid gray;            border-radius: 30px;        }        /* 分数面板 */        #scoretext{            margin: 0;            font-family: arial;            font-size:12px;            font-weight: bold;            color:#ff6600;            position: absolute;            left: 4px;            top: 4px;            z-index: 100;        }</style>
原创粉丝点击