<style>
#myCanvas{
position:absolute;
z-index:-1;/*确保在遮盖的元素的上方*/
top:0px;
left:0px;
}
#myCanvasbg{
background:rgba(255,255,255,0);/*关键点*/
position:absolute;
z-index:-2;/*确保在遮盖的元素的上方*/
top:0px;
left:0px;
}
</style>
<canvas width=800 height=400 id="myCanvas">
</canvas>
<canvas width=800 height=400 id="myCanvasbg">
</canvas>
<!-- <button onclick="pause()">暂停</button>-->
<script>
var pauseFlag=false;
var colorarr=["black","red","blue"];
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var cbg=document.getElementById("myCanvasbg");
var ctxbg=cbg.getContext("2d");
var player = {x:750,y:350,c:"blue",dir:-1};
var node = [{y:20,f:1},
{y:200,f:1},
{dir:0,ds:-1,f:-1},
{x:200,f:1},
{dir:-90,ds:-1,f:-1},
{y:80,f:-1},
{dir:0,ds:1,f:1},
{x:400,f:1},
{dir:90,ds:1,f:1},
{y:300,f:1}];
var arr =[
{x:20,y:20,c:'black',index:1,dir:90,waittime:0},
{y:0,x:20,c:'black',index:0,dir:90,waittime:0},
{y:-20,x:20,c:'red',index:0,dir:90,waittime:0},
{y:-40,x:20,c:'red',index:0,dir:90,waittime:0},
{y:-60,x:20,c:'blue',index:0,dir:90,waittime:0},
{y:-80,x:20,c:'blue',index:0,dir:90,waittime:0},
{y:-100,x:20,c:'black',index:0,dir:90,waittime:0},
{y:-120,x:20,c:'black',index:0,dir:90,waittime:0},
{y:-140,x:20,c:'blue',index:0,dir:90,waittime:0},
{y:-160,x:20,c:'blue',index:0,dir:90,waittime:0},
{y:-180,x:20,c:'black',index:0,dir:90,waittime:0},
{y:-200,x:20,c:'black',index:0,dir:90,waittime:0},
{y:-220,x:20,c:'red',index:0,dir:90,waittime:0},
{y:-240,x:20,c:'red',index:0,dir:90,waittime:0},
{y:-260,x:20,c:'black',index:0,dir:90,waittime:0},
{y:-280,x:20,c:'black',index:0,dir:90,waittime:0},
{y:-300,x:20,c:'black',index:0,dir:90,waittime:0},
//*/
];
function pause(){
pauseFlag=!pauseFlag;
console.log(arr);
}
window.onclick = function(e){
movePlayer(e.clientX,e.clientY);
}
function movePlayer(x,y){
if(player&&player.dir==-1){
player.dir = calDir(player.x,player.y,x,y);
}
}
function reCreatePlayer(){
player={x:750,y:350,c:colorarr[Math.floor(Math.random()*3)],dir:-1};
}
function movingPlayer(){
if(player.dir!=-1){
var tmp = moveOne(player.x,player.y,player.dir,10);
player.x=tmp.x;
player.y=tmp.y;
if(player.x>800||player.x<0||player.y>400||player.y<0){
player.x=750;
player.y=350;
player.dir=-1;
player.c=colorarr[Math.floor(Math.random()*3)];
}
}
}
function draw(obj,ctx){
drawCircle(ctx,obj.c,obj.x,obj.y);
}
function drawCircle(ctx,color,x,y){
ctx.fillStyle=color;
ctx.beginPath();
ctx.arc(x,y,10,0,2*Math.PI);
ctx.fill();
}
function h2j(a){
return a/Math.PI/2*360;
}
function j2h(a){
return a/360*2*Math.PI;
}
function calDir(x,y,tx,ty){
var o;
if(tx-x!=0){
if(ty-y==0){
if(tx>x){
o=0;
}else{
o=180;
}
}else{
var o =Math.atan((ty-y)/(tx-x));
if(o<0){// 2 4
if(ty<y&&tx>x){//4
o=h2j(o)+360;
}else{//2
o=h2j(o)+180;
}
}else{//1 3
if(ty>y&&tx>x){//1
o=h2j(o);
}else{//3
o=h2j(o)+180;
}
}
}
}else{
if(ty>y){
o=90;
}else{
o=270;
}
}
return o;
}
function addj(dir){
if(dir+1>=360){
return dir+1-360;
}else{
return dir+1;
}
}
function delj(dir){
if(dir-1<=0){
return dir-1+360;
}else{
return dir-1;
}
}
function move(x,y,tx,ty,dir){
var tdir = calDir(x,y,tx,ty);
if(tdir>dir){
if(tdir-dir>180){
dir=delj(dir);
}else{
dir=addj(dir);
}
}else if(tdir<dir){
if(dir-tdir>180){
dir=addj(dir);
}else{
dir=delj(dir);
}
}
return moveOne(x,y,dir,1);
}
function moveOne(x,y,dir,speed){
var o = j2h(dir);
var sx = Math.cos(o)*speed,sy = Math.sin(o)*speed;
return {x:x+sx,y:y+sy,dir:dir};
}
function boom(tnode,index,bof){//bof 1--front 2--behind
var start=(bof==1)?index-1:index,end=(bof==1)?index:index+1;
var nmb1=0;
for(var i=start;i>=0;i--){
if(arr[i].c==player.c){
nmb1++;
start=i;
}else{
break;
}
}
var nmb2=0;
for(var i=end;i<arr.length;i++){
if(arr[i].c==player.c){
nmb2++;
end=i;
}else{
break;
}
}
var toEnd = end<arr.length-1?1:0;
var nmb=nmb1+nmb2;
if(nmb>=2){
var tmp=[];
for(var i=0;i<arr.length;i++){
if(i<start){
arr[i].waittime=nmb*20*toEnd;
tmp.push(arr[i]);
}else if(i==start){
if(arr[i].c!=player.c){
arr[i].waittime=nmb*20*toEnd;
tmp.push(arr[i]);
}
}else if(i==end){
if(arr[i].c!=player.c){
tmp.push(arr[i]);
}
}else if(i>end){
tmp.push(arr[i]);
}
}
arr=tmp;
player=null;
return true;
}else{
return false;
}
}
function insertArr(arr,index,obj){
var tmp = [];
for(var i=0;i<arr.length;i++){
if(i==index){
tmp.push(obj);
tmp.push(arr[i]);
}else{
tmp.push(arr[i]);
}
}
return tmp;
}
function push(tnode,index){
var tdir = calDir(tnode.x,tnode.y,player.x,player.y);
var dis = Math.abs(tnode.dir-tdir);
if((dis<90&&dis>=0)||(dis>270&&dis<360)){
console.log("front");
if(boom(tnode,index,1)){return ;}
for(var i=arr.length-1;i>=index;i--){
arr[i].waittime=20;
}
if(index>0){
arr = insertArr(arr,index,{x:tnode.x,y:tnode.y,waittime:0,index:tnode.index,c:player.c,dir:tnode.dir});
}else{
arr.unshift({x:tnode.x,y:tnode.y,waittime:0,index:tnode.index,c:player.c,dir:tnode.dir});
}
}else{
console.log("behind");
if(boom(tnode,index,2)){return ;}
for(var i=arr.length-1;i>index;i--){
arr[i].waittime=20;
}
if(index<arr.length-1){
arr = insertArr(arr,index+1,{x:tnode.x,y:tnode.y,waittime:20,index:tnode.index,c:player.c,dir:tnode.dir});
}else{
arr.push({x:tnode.x,y:tnode.y,waittime:20,index:tnode.index,c:player.c,dir:tnode.dir})
}
}
reCreatePlayer();
}
function reach(tx,ty,cx,cy,dir){
var rx=false,ry=false;
if(dir>=0&&dir<90){
rx=(cx>=tx);
ry=(cy>=ty);
}else if(dir<=180&&dir>90){
rx=(cx<=tx);
ry=(cy>=ty);
}else if(dir<=270&&dir<180){
rx=(cx<=tx);
ry=(cy<=ty);
}else if(dir<=360&&dir<270){
rx=(cx>=tx);
ry=(cy<=ty);
}
return rx&&ry;
}
function reach(obj,target){
if(target.x){
if(target.f==-1){
return obj.x<=target.x;
}else{
return obj.x>=target.x;
}
}else if(target.y){
if(target.f==-1){
return obj.y<=target.y;
}else{
return obj.y>=target.y;
}
}else if(target.dir||target.dir==0){
if(target.f==-1){
return obj.dir<=target.dir;
}else{
return obj.dir>=target.dir;
}
}
return true;
}
function drawMap(node){
var obj = {x:20,y:20,c:'yellow',index:1,dir:90};
while(obj.index<node.length){
var index = obj.index;
var target = node[index];
console.log(target);
if(reach(obj,target)){
if(target.x)
obj.x = target.x;
if(target.y)
obj.y = target.y;
if(target.dir)
obj.dir = target.dir;
obj.index++;
}else{
if(target.dir||target.dir==0){
obj.dir+=target.ds;
}
var tmp=moveOne(obj.x,obj.y,obj.dir,1);
obj.x=tmp.x;
obj.y=tmp.y;
draw(obj,ctxbg);
}
}
}
function reFresh(){
ctx.clearRect(0,0,800,400);
}
function moveTo(node){
//console.log("move ...");
if(pauseFlag){
setTimeout(function(){
moveTo(node);
},10);
return ;
}
reFresh();
if(player){
movingPlayer();
draw(player,ctx);
var flag=false;
for(var i=0;i<arr.length;i++){
var ball = arr[i];
var x = ball.x-player.x;
var y = ball.y-player.y;
var dis = Math.sqrt(x*x+y*y);
if(dis<=20&&(!flag)){
console.log("hit:"+i);
push(ball,i);
flag=true;
break;
}
}
}
for(var i=0;i<arr.length;){
var obj = arr[i];
var index = obj.index;
if(index>=node.length){
arr.splice(i,1);
}else{
if(obj.waittime>0){
obj.waittime--;
draw(obj,ctx);
i++;
}else{
var index = obj.index;
var target = node[index];
if(reach(obj,target)){
//console.log("reach",target,obj);
if(target.x)
obj.x = target.x;
if(target.y)
obj.y = target.y;
if(target.dir)
obj.dir = target.dir;
obj.index++;
}else{
if(target.dir||target.dir==0){
obj.dir+=target.ds;
}
var tmp=moveOne(obj.x,obj.y,obj.dir,1);
obj.x=tmp.x;
obj.y=tmp.y;
draw(obj,ctx);
}
i++;
}
}
}
if(arr.length>0){
var time=10;
if(player==null){
var allflag=true;
for(var i=0;i<arr.length;i++){
if(arr[i].waittime>0)
allflag=false;
}
if(allflag)
reCreatePlayer();
else
time=1;
}
setTimeout(function(){
moveTo(node);
},time);
}else{
reFresh();
}
}
setTimeout(function(){
moveTo(node);
},10);
drawMap(node);
</script>