游戏 保卫萝卜
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>bwlb</title> <meta name="author" content="Administrator" /> <script src="jquery-1.11.1.js"></script> <!-- Date: 2015-04-20 --> <style> #div1{ margin:20px auto; position:relative;} .box1{ width:50px; height:50px; background:black; float:left;} .box2{ width:50px; height:50px; background:white; float:left;} .box3{ width:50px; height:50px; background:yellow; float:left; text-align:center; line-height:50px;} .box4{ width:50px; height:50px; background:blue; float:left; text-align:center; line-height:50px;} .gw1{ width:50px; height:50px; background:url(gw1.jpg) no-repeat; position:absolute;} .active{ background:red;} .pt1{ width:50px; height:50px; background:url(pt1.jpg) no-repeat; float:left;} .bullet1{ width:5px; height:5px; background:blue; position:absolute;} </style> <script> $(function(){ var Game={ arrMap : [ //地图 表现的路线跟地图一样 1代表黑色方块,3代表起始方块,2代表白色方块,4代表结束方块 1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1, 1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,1, 1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,1,1 ], arrRoute : [ //方向 0代表不能走的区域 B T L R 代表方向 数字代表行走先后顺序 0,0,'1B',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,'2R',0,0,0,0,0,0,'3B',0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,'4R',0,0,0,0,0,0,'5B',0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,'7B',0,0,0,0,0,0,0,0,0,'6L',0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,'8B',0,0,0,0,0,0,0,0,0,0,0,0,0 ], bBtn : true, //参考走口字 三个数组初始化为空 需要根据路线来找 各数组的内容 rootDir:[],//运动的方向的数组 rootSpeed:[],//运动的速度的数组 rootTarget:[],//运动的目标点的数组 colNum:20, //每行的网格个数 因为数组是一个整体 不会换行 gridWidth:50, //网格的宽度 gwStyle:'gw1',//敌人的样式 小怪物 gwSpeed:5,//敌人运动的速度 gwBlood:100, gwMoney:10, ptStyle:'pt1',//炮塔样式 ptMoney:50,//炮塔价格 bulletRange:100,//子弹的攻击范围 bulletPower:10, //子弹攻击力 bulletSpeed:10,//子弹速度 bulletStyle:'bullet1',//子弹样式 $startElement:null,//起始元素 $endElement:null,//结束元素 init:function(){ //初始化游戏 this.elements(); this.createMap(); this.bindEvent(); this.listens(); }, elements:function(){ //收集所有的元素 降低内存 this.$parent = $('#div1'); this.$startBtn = $('#start1'); this.$money = $('#money1') }, createMap:function(){ //创建地图 var This=this; This.$parent.css('width',this.colNum*this.gridWidth); //设置div的宽 限制范围 $.each(this.arrMap ,function(i,value){ var $div = $('<div class="box'+value+'"></div>'); //value指的就是数组中的每一项 //添加 起始 结束 文字 if( value == 3 ){ $div.html('起始'); This.$startElement = $div; //起始元素 }else if( value==4 ){ $div.html('结束'); This.$endElement = $div;//结束元素 } This.$parent.append($div) }) this.rootes() }, bindEvent:function(){ //事件操作的集合 var This = this; //点击开始按钮 this.$startBtn.on('click', function(){ if( This.bBtn ){ This.bBtn = false; This.createGWList(); //点击开始按钮创建小怪物 不管起始位置在哪里 小怪物在起始位置动态生成 } }) this.$parent.delegate('.box1','mouseover',function(){ $(this).addClass('active') }) this.$parent.delegate('.box1','mouseout',function(){ $(this).removeClass('active') }) //点击黑色部分 .box1 创建炮塔 this.$parent.delegate('.box1','click',function(){ This.createPt(this) }) }, createGWList:function(){ var num=10;//创建10个小怪物 var This=this; var timer=setInterval(function(){ if( num==0 ){ clearInterval(timer) }else{ This.createGW(); num-- } },500) }, //创建小怪物 createGW:function(){ var $gw = $('<div class="'+this.gwStyle+'"></div>'); var x = this.$startElement.position().left; //position().left 相对有定位的父级 var y = this.$startElement.position().top; $gw.css({'left':x,'top':y}); //给怪物挂载血量 和 金币 $gw.get(0).blood = this.gwBlood; $gw.get(0).money = this.gwMoney; this.$parent.append($gw); this.runGW($gw);//创建完怪物后让怪物运动起来 }, runGW:function($gw){ //敌人的运动 var iNow=0; var nowVal=0; var This=this; $gw.get(0).timer=setInterval(function(){ //根据三个数组来计算 rootDir rootSpeed rootTarget nowVal = $gw.position()[This.rootDir[iNow]] + This.rootSpeed[iNow]; $gw.css( This.rootDir[iNow], nowVal ); if( Math.abs(nowVal - This.rootTarget[iNow] )<=1){ if( iNow==This.rootTarget.length-1 ){ alert('游戏结束'); $gw.remove() }else{ iNow++ } } },30) }, rootes:function(){ //收集路线 var arr=[]; var This = this; var $aDiv = this.$parent.find('div'); $.each( this.arrRoute ,function(i,value){ if( this!=0 ){//将方向和位置存起来 还有坐标i arr.push({ dir:value, xy:i }) } }) //调整顺序 按照数字排序 arr.sort(function(dir1,dir2){ //要比较前面的数字 return dir1.dir.substring(0,dir1.dir.length-1) - dir2.dir.substring(0,dir2.dir.length-1) }) //console.dir(arr) //[{dir:1B,xy:2},{dir:2R,xy:42},{dir:3B,xy:49},{dir:4R,xy:109},{dir:5B,xy:116},{dir:6L,xy:156}... ] $.each(arr,function(i,value){ var dir = value.dir.substring(value.dir.length-1);//截取字母 决定方向的 B T L R if( i==arr.length-1 ){ return false } switch(dir){ case 'B': This.rootDir.push('top'); This.rootSpeed.push(This.gwSpeed); This.rootTarget.push( $aDiv.eq( arr[i+1].xy ).position().top ) //arr[i+1].xy是下一个目标点的坐标 目标点 是下一个坐标xy的开始的 元素 break case 'T': This.rootDir.push('top'); This.rootSpeed.push(-This.gwSpeed); This.rootTarget.push( $aDiv.eq( arr[i+1].xy ).position().top );//xy 是坐标 break case 'L': This.rootDir.push('left'); This.rootSpeed.push(-This.gwSpeed); This.rootTarget.push( $aDiv.eq( arr[i+1].xy ).position().left ) break case 'R': This.rootDir.push('left'); This.rootSpeed.push(This.gwSpeed); This.rootTarget.push( $aDiv.eq( arr[i+1].xy ).position().left ) break } }) }, createPt:function(elem){ //创建炮塔 //把当前点击区域的样式改成炮塔的样式 每个炮塔金额50 因为不能无限生成炮塔 限制创建炮塔的个数 用金额来限制 当当前的金额>=50的时候可以创建炮塔 if( parseInt( this.$money.val() )>= this.ptMoney ){ $(elem).attr('class',this.ptStyle); //当前点击处的样式切换 改个class 创建炮塔样式 this.changeMoney(-this.ptMoney) //创建一个炮塔 减去50元 } }, changeMoney:function(num){ //num 就是炮塔所需要的金额 var val = parseInt( this.$money.val() ) + num +"¥"; this.$money.val(val) }, disRange:function( $elem1, $elem2 ){ //攻击范围 //炮塔与怪物的距离 var a=$elem1.offset().left - $elem2.offset().left; var b=$elem1.offset().top - $elem2.offset().top; var c= Math.sqrt(a*a + b*b) return c }, //监听怪物是否进入攻击范围 点击开始按钮之后就可以监听 listens:function(){ var This = this; //找到所有炮塔 var $aPt = this.$parent.find('.'+this.ptStyle); //对所有炮塔进行遍历 $aPt.each(function(){ This.listensGW(this) //监听每一个敌人gw 并把每个炮塔传进去 }) setTimeout(function(){ This.listens() //每隔100ms 自调用 就会一直去监听 不用setInterval是因为setTimeout性能好些 },100) }, //每个炮塔跟所有怪物的检测 listensGW:function(pt){ var This = this; //找到所有怪物 var $aGw = this.$parent.find('.'+this.gwStyle); //需要将进入攻击范围的怪物存进数组中 数组是针对每一个炮塔的 pt.arr=[]; $aGw.each(function(i,elem){ //将进入攻击范围的怪物存到一个数组中 pt相当于一个变量,需要使用 $(pt) 来调用 因为传进来的是jquery的元素对象 if(This.disRange($(pt),$(elem)) <= This.bulletRange){ pt.arr.push(elem) } }) //什么时候攻击? 当数组里有值的时候攻击 if(pt.arr.length){ this.createBullet(pt) //子弹是炮塔发出的 } }, createBullet:function(pt){ //创建子弹 var $bu = $('<span class="'+this.bulletStyle+'"></span>'); //子弹的初始位置位于炮塔的中心点 $bu.css({ 'left': $(pt).position().left + $(pt).width()/2 , 'top': $(pt).position().top + $(pt).height()/2 }) $(pt).append($bu); this.runBullet(pt,$bu) }, runBullet:function(pt,$bu){ var This = this; $bu.get(0).timer=setInterval(function(){ if( !pt.arr.length ){ clearInterval($bu.get(0).timer); pt.innerHTML = ''; return false; } //跟踪算法 运动的是子弹 相对静止的是敌人 从最后一个怪物开始攻击 怪物存在数组中 var curGw =pt.arr[pt.arr.length-1];//当前怪物 从最后一个计算 var a = $(curGw).offset().left + $(curGw).width()/2 -$bu.offset().left; var b = $(curGw).offset().top + $(curGw).height()/2 -$bu.offset().top; var c = Math.sqrt( a*a + b*b ); //怪物与 子弹的距离 // This.bulletSpeed斜边的速度 求 X轴速度 和 Y轴速度 var speedX = This.bulletSpeed * a/c; var speedY = This.bulletSpeed * b/c; $bu.css({ 'left':$bu.position().left + speedX, 'top':$bu.position().top + speedY, }) //如果子弹击中了怪物 if( This.pz( $bu , $(curGw) ) ){ $bu.remove(); curGw.blood = curGw.blood - This.bulletPower; if( !curGw.blood ){ clearInterval( $bu.get(0).timer ); //敌人消灭后 关掉子弹的定时器 clearInterval( curGw.timer );//敌人消灭后 关掉敌人的定时器 $(curGw).remove(); This.changeMoney(curGw.money) //打死一个敌人 增加敌人的金币 } } },30) }, pz : function($obj1,$obj2){ //碰撞检测 var T1 = $obj1.offset().top; var B1 = $obj1.offset().top + $obj1.height(); var L1 = $obj1.offset().left; var R1 = $obj1.offset().left + $obj1.width(); var T2 = $obj2.offset().top; var B2 = $obj2.offset().top + $obj2.height(); var L2 = $obj2.offset().left; var R2 = $obj2.offset().left + $obj2.width(); if(T1>B2 || B1<T2 || L1>R2 || R1<L2){ return false; } else{ return true; } } } Game.init(); }) </script> </head> <body> <input type="button" id="start1" value="开始"> <input type="button" value="200¥" id="money1" /> <div id="div1"></div> </body> </html>