Collision system for game in Html5!

Asked

Viewed 1,082 times

8

I’m learning a little about games in Html5,css and js.

I made a very basic game, player drive, 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 very bad, precise is in the exact X and Y to death. This turns out to be horrible, because the mouse should be killed too if this occurs: inserir a descrição da imagem aqui inserir a descrição da imagem aqui

What can I do to fix?

  • Do you need to create a safety margin or something? I don’t know :(

  • Yes, you need to determine if x and y are within certain ranges.

  • Try using an API, your game can get much more complete in terms of physics, for example: https://github.com/jriecken/sat-js

  • 1

    It is important to study about Bounding Box, essential for understanding collision detection systems

2 answers

4


What you’re doing is not right because basically you’re checking to see 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 collission

inserir a descrição da imagem aqui

Box Collision with more than one rectangle

inserir a descrição da imagem aqui

Circle Collision

inserir a descrição da imagem aqui

Pixel Perfect - ( ignore being a circle again)

inserir a descrição da imagem aqui

In a perfect world you should use pixel-by-pixel collision in your game, but if you do you will notice a significant break in your game’s FPS. For this same reason it is common to use rectangles to represent the collision area of an object, it is much simpler, faster, and cheap in terms of resources for the machine.

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.

Article MDN that mentions Box Colision and Circle Colision.

2

By setting a range based on the mouse dimensions (23x26) you can define the collision. You can subtract the value of the mouse you move (y) by the moving mouse (yy), thus defining a crease. Just subtract the value y at value yy defining the value at which a collision will be considered. The same with the 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>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.