圆圈碰撞有时会失败

时间:2013-12-13 11:30:48

标签: javascript html5-canvas collision geometry intersect

我知道如何检查两个圆圈是否相互交叉。但是,有时圆圈会相互粘连,它们会开始旋转。

我该如何解决这个问题?

这是我的代码:

FFIELD.Footballer = function(id, x, y, c, xn, yn) {
this.type = 'footballer';
this.ident = id;
this.x = x;   
this.r = 17;                
this.y = y;     
this.color = c;
this.moving = false;
this.xn = xn; 
this.yn = yn; 
this.vx = 0;
this.vy = 0;
this.sxy = [this.x, this.y]; 
this.lxy = [this.x, this.y]
this.wallsC = 0; 

//lenleft calculates speed using distance between start and endpoint    
//EXAMPLE OF USING SPEED in the update function:
//this.x += this.vx*this.speed;
//this.y += this.vy*this.speed;

this.lenleft = function() {
    //if any of walls was already hit
    if (this.wallsC != 0) {
        this.lxy = this.sxy;
        this.sxy = [this.x, this.y];
        this.raz = [(this.sxy[0] - this.lxy[0]) *0.1, (this.sxy[1] - this.lxy[1])*0.1];
        this.len = this.len - Math.sqrt(this.raz[0]* this.raz[0] + this.raz[1] * this.raz[1]);
        this.speed = this.len/6; 
    //if no walls were hit  
    } else {
        this.raz = [(this.xn - this.x)*0.1, (this.yn - this.y)*0.1];
        this.len = Math.sqrt(this.raz[0]* this.raz[0] + this.raz[1] * this.raz[1]);
        this.speed = this.len/6; 
    }
}

//if end point atribute is set
if(xn != null) {
    this.lenleft();        
    this.vx = this.raz[0] / this.len
    this.vy = this.raz[1] / this.len      
}      


this.deflect = function(i) {     

    //elastic collision
    nx = FFIELD.entities[i].x - this.x; 
    ny = FFIELD.entities[i].y - this.y;
    absn = Math.sqrt(Math.pow(nx,2) + Math.pow(ny,2));        
    nx = nx / absn;
    ny = ny / absn;
    scp = this.vx * nx + this.vy * ny;
    bcp = FFIELD.entities[i].vx * nx + FFIELD.entities[i].vy * ny;
    this.vx = this.vx - nx * scp + nx * bcp;
    this.vy = this.vy - ny * scp + ny * bcp;
    FFIELD.entities[i].vx = FFIELD.entities[i].vx + nx * scp - nx * bcp;
    FFIELD.entities[i].vy = FFIELD.entities[i].vy + ny * scp - ny * bcp;    

    // if this circle is not moving  
    if(scp == 0) {
        FFIELD.entities[i].lenleft();
        this.len = FFIELD.entities[i].len;        
        this.moving = true;
    }
    // if other circle is not moving  
    if(bcp == 0) {
        this.lenleft();
        FFIELD.entities[i].len = this.len;            
        FFIELD.entities[i].moving = true;
    }
    // if both circles are moving  
    else {
        this.lenleft();
        FFIELD.entities[i].lenleft();
    }
}

this.walls = function() {
    //keeping wallsC count because of lenleft function
    if (this.y <= 18) {            
        this.vy = this.vy * -1;             
        this.wallsC += 1;            
    }
    if (this.y >= FFIELD.HEIGHT - 18) {            
        this.vy = this.vy * -1; 
        this.wallsC += 1;
    }
    if (this.x <= 18) { 
        this.vx = this.vx * -1;              
        this.wallsC += 1;
    }
    if (this.x >= FFIELD.WIDTH - 18) { 
        this.vx = this.vx * -1;             
        this.wallsC += 1;
    }
}

this.move = function () {
    if (this.speed > 0) {                       
        this.moving = true;
    }
    else {
        this.vx = 0;
        this.vy = 0;
    }            

}

this.update = function() {

    for (var i = 0; i < FFIELD.entities.length; i++)  
    {  
            if (FFIELD.entities[i].ident != this.ident) {
                hit = FFIELD.collides({x: this.x, y: this.y, r: this.r}, FFIELD.entities[i]);                      
                if (hit) {  
                    this.deflect(i);
                }
            }
    }
    this.move();
    this.walls();

    if(this.moving) {  
        this.speed-=0.04;               
        this.x += this.vx*this.speed;
        this.y += this.vy*this.speed;                        
    }       
};

this.render = function() {
    FFIELD.Draw.circle(this.x, this.y, this.r, this.color);
};

};


// this function checks if two circles overlap
FFIELD.collides = function(a, b) {           
      return Math.abs((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)) 
                                < (a.r + b.r) * (a.r + b.r);
};

0 个答案:

没有答案