<!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>