collisions with javascript and canvas

1

Hi, I'm good at this and I'm stuck with the collisions, in Mario.prototype.checkCollition I have to reposition the character Mario to the left of the obstacle but it's not that if I hit the other side it stays to the right, I do not know if it should be in 3 ifs, I also want Mario to be able to rest on an obstacle, any help please?

//CONSTRUCTOR MARIO
function Mario(ctx){
    this.ctx = ctx;
    
    this.img = new Image();
    this.img.src = 'img/mario.jpg';
    
    this.h = this.ctx.canvas.height / 10;
    this.w = this.h / 1.5;
    this.x = this.w * 3;
    this.y0 = 0.95 * this.ctx.canvas.height - this.h;
    this.y = this.y0;
    
    this.vx = 0;
    this.vy = 0;
    this.g = 0.3;
    
    this.img.frameIndex = 0;
    this.img.frames = 7;
    this.img.animateEvery = 3;
    this.drawCount = 0;
}

//LINE OF Y0
Mario.prototype.y0Line = function(){    
    this.ctx.beginPath();
    this.ctx.moveTo(0, this.y0);
    this.ctx.lineTo(this.y0, this.y0);
    this.ctx.stroke();
};
Mario.prototype.y0Line2 = function(){
    this.ctx.beginPath();
    this.ctx.moveTo(0, this.y);
    this.ctx.lineTo(this.y, this.y);
    this.ctx.stroke();
};


//DRAWING MARIO
Mario.prototype.draw = function(){
    this.ctx.drawImage(
        this.img,
        (this.img.width / this.img.frames) * this.img.frameIndex,
        0,
        this.img.width / this.img.frames,
        this.img.height,
        this.x,
        this.y,
        this.w,
        this.h
    );  
    this.animate();
};


//ANIMATING MARIO
Mario.prototype.animate = function(){
    if (this.isJumping()) return;
    
    this.drawCount++;
    
    if (this.drawCount === this.img.animateEvery) {
        this.img.frameIndex++;
        this.drawCount = 0;        
        
        if (this.img.frameIndex === this.img.frames) {
            this.img.frameIndex = 0;
        }
    }    
};



Mario.prototype.move = function(){
    this.x += this.vx;
    this.y += this.vy;  
    
    if (this.x <= 0) this.x = 0;
    if (this.x + this.w > this.ctx.canvas.width) this.x = this.ctx.canvas.width - this.w;
    
    if (this.isJumping()) {        
        this.vy += this.g;  
        
    } else{
        this.y = this.y0;
        this.vy = 0;
    }
};  


Mario.prototype.checkCollition = function(arrayObs){         
    
    arrayObs.forEach(function(o){
      
        if (this.x + this.w >= o.x &&
            this.y + this.h >= o.y &&
            this.x <= o.x + o.w) {
            
            this.x = o.x - this.w;
        }
    }.bind(this));
    
};



//KEY CODES
Mario.prototype.TOP = 38;
Mario.prototype.LONGJUMP = 65;
Mario.prototype.DOWN = 40;
Mario.prototype.LEFT = 37;
Mario.prototype.RIGHT = 39;

Mario.prototype.onKeyDown = function(evt){
    switch (evt.keyCode) {
        case this.LEFT: this.vx = -10; break;
        case this.RIGHT: this.vx =10; break;
        case this.TOP: 
        case this.LONGJUMP: this.jump(evt.keyCode);break;
        case this.DOWN: this.vy += 10; break;
    }
};

Mario.prototype.onKeyUp = function(evt){    
    switch (evt.keyCode) {
        case this.LEFT: 
        case this.RIGHT: 
        this.vx = 0; break;
    }
};

//ACTIONS
Mario.prototype.jump = function(code){
    if (this.isJumping()) return;
    if (code === 65) this.vy -= 11;
    if (code === 38) this.vy -= 8;
};

//CHECK IF ITS JUMPING
Mario.prototype.isJumping = function(){        
    if (this.y < this.y0) {             
        return true; 
    }  
};
    
asked by francisco dwq 30.05.2018 в 14:23
source

1 answer

0

You have the solution to the collision on the left, but you need to do it for the other 3 sides: right, up and down (Mario has to be able to hit the boxes to get coins, right?).

I propose an alternative: detect the collision in general, without checking if it is on the left or on the right - you know it by the velocity vector (vx, vy) - and, if there is one, do not move it:

Mario.prototype.checkCollisionBefore = function(arrayObs){         

    return arrayObs.some(function(rect){

      return (this.x + this.vx < rect.x + rect2.width &&
         x + this.vx + this.width > rect2.x &&
         y + this.vy < rect2.y + rect2.height &&
         this.height + y + this.vy > rect2.y) 
    }.bind(this));

};

This feature is based on this example

    
answered by 30.05.2018 в 16:18