Collision system for game in html5!

8

I'm learning a little about games in html5, css and js.

I made a very basic gameplay, player movement, enemy and a collision system , see:

var canvas;//o elemento canvas sobre o qual desenharemos
var ctx;//o "contexto" da canvas que será utilizado (2D ou 3D)
var dx = 5;//a tava de variação (velocidade) horizontal do objeto
var dy = 5;//a tava de variação (velocidade) vertical do objeto
var x = 250;//posição horizontal do objeto (com valor inicial)
var y = 100;//posição vertical do objeto (com valor inicial)
var WIDTH = 500;//largura da área retangular
var HEIGHT = 200;//altura da área retangular
var playerImg = new Image();
var inimigoImg = new Image();
var xx = 505;// posicao x do inimigo
var yy = 100;// posicao y do inimigo

function myRandom(min, max, multiple) {
    return Math.round(Math.random() * (max - min) / multiple) * multiple + min;
}

function cn(){
	xx = xx - 1;
    inimigoImg.src = "https://i.imgur.com/V2yQ9kO.png";
	ctx.drawImage(inimigoImg, xx, yy);	
	if (xx < 0){
		xx = 505
		yy = myRandom(5,200,5);
	}
	
}

function check(){ // checar colisao
	if (y == yy && x == xx){
		alert('morreu')
	}
}

function Desenhar() {
    playerImg.src = "https://i.imgur.com/u13C8nt.png";
	ctx.drawImage(playerImg, x, y);
	cn();
	check();
}

function LimparTela() {
    ctx.fillStyle = "white";
    ctx.strokeStyle = "black";
    ctx.beginPath();
    ctx.rect(0, 0, WIDTH, HEIGHT);
    ctx.closePath();
    ctx.fill();
    ctx.stroke();
}

function Iniciar() {
    canvas = document.getElementById("canvas");
    ctx = canvas.getContext("2d");
    return setInterval(Atualizar, 10);
}

function KeyDown(evt){
    switch (evt.keyCode) {
        case 38:  /*seta para cima */
            if (y - dy > 0){
                y -= dy;
            }
            break;
        case 40:  /*set para baixo*/
            if (y + dy < 175){
                y += dy;
            }
            break;
        case 37:  /*set para esquerda*/
            if (x - dx > 0){
                x -= dx;
            }
            break;
        case 39:  /*seta para direita*/
            if (x + dx < 475){
                x += dx;
            }
            break;
    }
}

function Atualizar() {
    LimparTela();    
    Desenhar();
}
window.addEventListener('keydown', KeyDown, true);
Iniciar();
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Canvas</title>
</head>
<body>
    <div>
        <canvas id="canvas" width="500" height="200">
        Se você visualizar esse texto, seu browser não suporta a tag canvas.
        </canvas>
    </div>
</body>
</html>

But this collision system is pretty bad, accurate is on the exact X and Y for death. This turns out to be awful, as the mouse should also be killed if this occurs:

What can I do to fix it?

    
asked by anonymous 04.05.2018 / 02:25

2 answers

4

What you are doing is not correct because basically you are checking if one pixel collides with another. You should check the collision using areas / ranges.

Here are the most common types of collisions:

  

Box Collision / box collision

  

BoxCollisionwithmorethanonerectangle

  

CircleCollision

  

PixelPerfect-(ignorethefactthatit'sacircleagain)

Inaperfectworldyoushouldusethepixeltopixelcollisioninyourgame,butifyoudo,youwillnoticeaconsiderablebreakintheFPSofyourgame.Forthissamereasonitiscommontouserectanglestorepresentthecollisionareaofanobject,itismuchsimpler,faster,andcheaperintermsofresourcesforthemachine.

var canvas;//o elemento canvas sobre o qual desenharemos
var ctx;//o "contexto" da canvas que será utilizado (2D ou 3D)
var dx = 5;//a tava de variação (velocidade) horizontal do objeto
var dy = 5;//a tava de variação (velocidade) vertical do objeto
var x = 250;//posição horizontal do objeto (com valor inicial)
var y = 100;//posição vertical do objeto (com valor inicial)
var WIDTH = 500;//largura da área retangular
var HEIGHT = 200;//altura da área retangular
var playerImg = new Image();
var inimigoImg = new Image();
var xx = 505;// posicao x do inimigo
var yy = 100;// posicao y do inimigo


var rectPlayer = {x: 5, y: 5, width: 50, height: 50}
var rectInimigo = {x: xx, y: 5, width: 50, height: 50}


function myRandom(min, max, multiple) {
    return Math.round(Math.random() * (max - min) / multiple) * multiple + min;
}

function cn(){
	xx = xx - 1;
    inimigoImg.src = "https://i.imgur.com/V2yQ9kO.png";
	ctx.drawImage(inimigoImg, xx, yy);	
	if (xx < 0){
		xx = 505
		yy = myRandom(5,200,5);
	}
	
}

function check(){ // checar colisao
  // rectangulos para testar colisao
  // basicamente sao os mesmos que estao a ser desenhados
  var rect1 = {x: x, y: y, width: 25, height: 30}
 var rect2 = {x: xx, y: yy, width: 25, height: 30}

	if (rect1.x < rect2.x + rect2.width &&
   rect1.x + rect1.width > rect2.x &&
   rect1.y < rect2.y + rect2.height &&
   rect1.height + rect1.y > rect2.y) {

   console.log("Colisão");
  }
}



function Desenhar() {
    playerImg.src = "https://i.imgur.com/u13C8nt.png";
	ctx.drawImage(playerImg, x, y);
  
      ctx.rect(x,y,25,30);
      ctx.rect(xx,yy,25,30);
      ctx.stroke();

	cn();
	check();
}

function LimparTela() {
    ctx.fillStyle = "white";
    ctx.strokeStyle = "black";
    ctx.beginPath();
    ctx.rect(0, 0, WIDTH, HEIGHT);
    ctx.closePath();
    ctx.fill();
    ctx.stroke();
}

function Iniciar() {
    canvas = document.getElementById("canvas");
    ctx = canvas.getContext("2d");
    return setInterval(Atualizar, 10);
}

function KeyDown(evt){
    switch (evt.keyCode) {
        case 38:  /*seta para cima */
            if (y - dy > 0){
                y -= dy;
            }
            break;
        case 40:  /*set para baixo*/
            if (y + dy < 175){
                y += dy;
            }
            break;
        case 37:  /*set para esquerda*/
            if (x - dx > 0){
                x -= dx;
            }
            break;
        case 39:  /*seta para direita*/
            if (x + dx < 475){
                x += dx;
            }
            break;
    }
}

function Atualizar() {
    LimparTela();    
    Desenhar();
}
window.addEventListener('keydown', KeyDown, true);
Iniciar();
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Canvas</title>
</head>
<body>
    <div>
        <canvas id="canvas" width="500" height="200">
        Se você visualizar esse texto, seu browser não suporta a tag canvas.
        </canvas>
    </div>
</body>
</html>

I've drawn the rectangles so you can easily visualize what's happening.

MDN article that mentions Box Collision and Circle Collision.

    
04.05.2018 / 11:23
2

By setting a range based on the dimensions in the mouse (23x26) you can define the collision. You can subtract the value of the mouse you move ( y ) by that of the mouse that moves ( yy ), thus defining a range . Just subtract the value y with the value yy by setting it the value at which it will be considered a collision. The same with x and xx :

if (y-yy <= 23 && y-yy >= -23 && x-xx <= 10 && x-xx >= -10){

Example:

var canvas;//o elemento canvas sobre o qual desenharemos
var ctx;//o "contexto" da canvas que será utilizado (2D ou 3D)
var dx = 5;//a tava de variação (velocidade) horizontal do objeto
var dy = 5;//a tava de variação (velocidade) vertical do objeto
var x = 250;//posição horizontal do objeto (com valor inicial)
var y = 100;//posição vertical do objeto (com valor inicial)
var WIDTH = 500;//largura da área retangular
var HEIGHT = 200;//altura da área retangular
var playerImg = new Image();
var inimigoImg = new Image();
var xx = 505;// posicao x do inimigo
var yy = 100;// posicao y do inimigo

function myRandom(min, max, multiple) {
    return Math.round(Math.random() * (max - min) / multiple) * multiple + min;
}

function cn(){
	xx = xx - 1;
    inimigoImg.src = "https://i.imgur.com/V2yQ9kO.png";
	ctx.drawImage(inimigoImg, xx, yy);	
	if (xx < 0){
		xx = 505
		yy = myRandom(5,200,5);
	}
	
}

function check(){ // checar colisao
	if (y-yy <= 23 && y-yy >= -23 && x-xx <= 10 && x-xx >= -10){
		alert('morreu')
	}
}

function Desenhar() {
    playerImg.src = "https://i.imgur.com/u13C8nt.png";
	ctx.drawImage(playerImg, x, y);
	cn();
	check();
}

function LimparTela() {
    ctx.fillStyle = "white";
    ctx.strokeStyle = "black";
    ctx.beginPath();
    ctx.rect(0, 0, WIDTH, HEIGHT);
    ctx.closePath();
    ctx.fill();
    ctx.stroke();
}

function Iniciar() {
    canvas = document.getElementById("canvas");
    ctx = canvas.getContext("2d");
    return setInterval(Atualizar, 10);
}

function KeyDown(evt){
    switch (evt.keyCode) {
        case 38:  /*seta para cima */
            if (y - dy > 0){
                y -= dy;
            }
            break;
        case 40:  /*set para baixo*/
            if (y + dy < 175){
                y += dy;
            }
            break;
        case 37:  /*set para esquerda*/
            if (x - dx > 0){
                x -= dx;
            }
            break;
        case 39:  /*seta para direita*/
            if (x + dx < 475){
                x += dx;
            }
            break;
    }
}

function Atualizar() {
    LimparTela();    
    Desenhar();
}
window.addEventListener('keydown', KeyDown, true);
Iniciar();
<div>
   <canvas id="canvas" width="500" height="200">
      Se você visualizar esse texto, seu browser não suporta a tag canvas.
   </canvas>
</div>
    
04.05.2018 / 06:44