Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

collision detection on multiple canvas layers

I am struggling on figuring out how to detect collisions on assets drawn on different canvas layers. I have made two arrays that hold the stuff I want to "collide" with called collidable_objects_layer1 and collidable_objects_layer2. These arrays basically draw the tables and the wall in the back which the character should not be able to pass through.

bar.js basically holds the whole bar "scene" you see in the link below. and main.js is the loop that makes my player move. I think my architecture is all messed up cause I don't see an easy way to tie these two together so any advice on that(are modules necessary here or are they just hurting me?). the way it is now I am not sure how I add more "scenes" with different collision testing.

I'm assuming the collision testing happens in the main loop

function main() {
    var now = Date.now();
    var dt = (now - last_time) / 1000.0;

    clearCanvas();
    drawCharacter();
    frame++;
    last_time = now;
    requestAnimFrame(main);
}

so a couple questions really, what would the algorithm(psuedocode) look like to have my player detect these collidable objects in bar.js. second, is my architecture appropriate to handle multiple scenes, for example, once the player leaves the "bar" to "outside" (outside.js) how can I handle that transition so my player can detect objects regardless of its "scene". I was thinking I end up with a Scene class or something, I am not sure.

thanks in advance. find the plunk link here

like image 230
atsituab Avatar asked Sep 01 '16 05:09

atsituab


People also ask

Which method is used to collision detection between two rectangles?

Axis-Aligned Bounding Box One of the simpler forms of collision detection is between two rectangles that are axis aligned — meaning no rotation. The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles. Any gap means a collision does not exist.

How does the layer collision matrix work?

The Layer Collision Matrix allows you to control which GameObjects can collide and interact with others based on the layers to which they are assigned. This means you can have certain objects able to collide only with specific ones if desired.

How do you use collision layers in Unity?

Setting up layer-based collision detectionIn the Unity menu bar, go to Edit > Project Settings > Physics to open the Physics Manager window. Select which layers on the Collision Matrix will interact with the other layers by checking them.

What is meant by collision detection?

Definition. Collision detection is the process of determining computationally if two or more objects intersect, the time, and the parts of the objects that are involved in the intersection.


1 Answers

Creating an object interface.

The object bar and player are both global in your example so accessing one from the other is no issue. Ie inside player you can call bar(); which will init the bar.

What you want to do is provide a more extensive interface to the scene object bar. This interface provides access to the object in a controlled way (via functions).

First lets look at what is needed.

When the player moves we would like to know if the way is clear. If not then don't move, if so then move. Thus we need a function that returns true or false for a given position depending on what is at that position.

The interface

I will only add pseudo code here, you can workout the details.

In your bar object rather than return the function init return an object that will be the public interface to the object bar

var bar = (function(){
    //... all the code and function

    return {   // return a interface object
       init : init,  // with the function init
    };
})();

Now the object bar has properties as methods. To init bar

bar.init(); // rather than bar() as you had it.

Extending the interface

To extend the interface to bar with a collision test you add a function inside bar to test a given position

var bar = (function(){
    //... all the code and function
    function isPositionBlocked(x,y){ // returns true if location x y 
                                     // if blocked
         //... code to find what is at x,y
         if(blocked){
             return true;
         }
         return false;
    }

and then add that function to the returned interface object.

    return {   // return an object
       init : init,  // with the function init
       test : isPositionBlocked, // with the new test function.
    };
})();

Now you can access the test function from within the player object (assuming the player has access to the object bar)

From inside player

  // movex movey are the directions to move
  // posx, posy are the current direction
  if(! bar.test(posx + mousex, posy + movey)){ // if not blocked
      posx += movex;
      posy += movey;
  }

That is how you access details between objects when using immediately invoked objects var obj = (function(){...code; return {}})();

Alternative implementations

You can also create the interface object inside bar letting you access the interface from within bar.

var bar = (function(){
    //... all the code and functions
    var API = {};
    API.init = function(){ //... init code
    API.test = function(x,y){ //... blah blah

    function someInternalFunction(){
        var result = API.test(x,y);  // access the interface from 
                                           // within the bar object
    }
    return API;
})();

I use the acronym API (Application Protocol Interface) as the prefered name interface is a reserved word in Javascript, but any name is ok. The API object can contain anything you want outside objects to have access to (in other languages these are called public properties) and everything inside the object bar that you do not want to give outside access to is private though in javascript these terms are generally not used.

'this' is bound to the interface

When you add a function to an object

API.test = function(x,y){...

it is automatically bound to that object and thus you can access the object via the this token.

EG inside test

API.init = function(){//...
API.test = function(x,y){//...
    this.init(); // if you wanted to init
    // this refers to the object API

Thus if you use the direct return object

 return {
    init : init,
    test : testFunction,
 }

you can still get access to the properties of the returned object via this

var test = (function(){
     function init(){};
     function testFunction(){
        if(this.init){  
           return true;
        }
     }
     return {
        init : init,
        test : testFunction,
     }
})();

console.log(test.test()); // output >> true;

But calling the function testfunction from inside the object can have unpredictable results as it is not bound to the interface object, so be carefull. I generally create the API object and only define public functions as part of that object to prevent calling them incorrectly.

like image 107
Blindman67 Avatar answered Sep 26 '22 08:09

Blindman67