collision detection in javascript game? - javascript

My Map array ;;
map[0] = [0,0,0,0,0,0]
map[1] = [0,1,0,1,0,1]
map[2] = [0,0,0,0,0,0]
map[3] = [1,0,1,0,1,0]
map[4] = [0,0,0,0,0,0]
map[5] = [0,1,0,1,0,1]
1= Hurdle
0 = Nothing
i've to detect collision detection b/w player and hurdles in map.
player.x & player.y is the reference from left top .
Each hurdle is 40px of width and length .
i need a roughly concept not codes

You have to normalize player position to the collision map unit as player position is in px units and your collision map is in array index units and then test if the field the player tries to enter is not a hurdle.
function normalizePosition(entity){
return {
x: Math.ceil(entity.pos.x / TILE_WIDTH),
y: Math.ceil(entity.pos.y / TILE_HEIGHT)
}
}
Normalize position will give you entity coordinates on the collision map and next you have to test the actual collision to see what kind of tile is the entity entering
function mapCollision(entity, map){
var mapCoords = normalizePosition(entity),
tileType = map[mapCoords.y][mapCoords.x];
return tileType;
}
It will return the code of tile type on the map for player normalized position in case you wanted to have there different things then just blocks like some kind of slowing down traps or whatever other bear pits. You could then handle different cases where zero would default to accepts player entering the tile.
Hope I didn't tell to much :)
Good luck with your game and if you'll remember I'd be happy if you'd share the effects with me when its done :)
Tom
Update
I made a simple example for better interpretation purpose:
http://fiddle.jshell.net/qFCyn/1/

Use this:
var BLOCK_SIZE = 40; // 40px * 40px blocks
var hurdle = map[player.y/BLOCK_SIZE][player.x/BLOCK_SIZE]
if(hurdle) {
// stuff
} else {
// other stuff
}

Related

Is there a way to get the exact point inside navmesh so the pathfinder can work properly?

I am making a first person shooter in Three.js and I wanted to use Don McCurdy's pathfinding algorithm for my enemy AI. For the navmesh I followed Nik Lever's Three.JS Pathfinding Tutorial. In order to use the pathfinder, both the player and the enemies need to be on the surface of the navmesh. The problem is that since the navmesh is slightly off the ground (IDK how to get it on the same elevation as the level) and I want the player to be able to jump, I can't have them simply stick to the navmesh and offset the models. I tried to fix it by raycasting from the player/enemy to the navmesh and using the intersection point, but because of floating point arithmetic the intersection point is always slightly off.
There is a lot of code in my project, so I'm only sharing the troubling bits. If more code is needed, I will add it.
Entity.js
rayCaster is a globally scoped Three.js Raycaster
update(map, navmesh) {
// ...some code...
rayCaster.set(new THREE.Vector3(this.pos.x, this.pos.y + 10, this.pos.z), new THREE.Vector3(0, -1, 0));
var hits = rayCaster.intersectObject(navMesh);
if(hits && hits[0]) this.point = hits[0].point;
}
Game.js
this.pathfinder = new Pathfinding();
this.pathfinder.setZoneData("lvl1", Pathfinding.createZone(this.navmesh.geometry, 3));
update() {
// ...more code...
for(var i = this.enemies.length - 1; i >= 0; i--) {
var group = this.pathfinder.getGroup("lvl1", this.enemies[i].point), path = 0;
if(group != null && group != undefined) path = this.pathfinder.findPath(this.enemies[i].point, player.point, "lvl1", group);
// Path is always null
this.zombies[i].update(this.map, this.navmesh);
}
}

How can I avoid overlapping when creating sprites? JS - PHASER3

I'm new in this and I'm making a small game in JS, the problem that I have now is when I create enemies it sometimes overlaps, creating this:
The way that use to create them is simple,
resetShip(enemy_spaceship) {
enemy_spaceship.y = 0;
enemy_spaceship.x = Phaser.Math.Between(10,globalThis.config.width);
}
In X each sprite will have a random number from 10 to the width of the screen (canvas), the problem is that if a sprite has 440 in X and another one has 450 in X, those 10px aren't enough to separate them, some people told me to create a grid, but like I said I'm new and searching about grid can't find any example that I can use to this, thanks if you can help me :)
One option is for each enemy ship to be allocated a specific region in which it may start. If you have 2 ships, that means the first ship can be anywhere in the first half of the X axis, and the second ship can be anywhere in the second half of the X axis.
To do this, you should update your resetShip function to also take in a minX and maxX, and use that when defining it's location:
resetShip (enemy_spaceship, minX, maxX) {
enemy_spaceship.y = 0;
enemy_spaceship.x = Phaser.Math.Between(minX, maxX);
}
Then, you need to find a way to rest the group of ships, providing valid regions for each ship. Something like this:
resetEnemies(ships) {
//Each ship may be in a region that is 1/Nth of the width
let regionWidth = globalThis.config.width / ships.length
//We need to know the shipWidth so we don't let ships get too
//close to the left edge.
let shipWidth = 64
ships.forEach((ship, i) => {
//Assuming you just want padding on the left so it is no closer than 10px,
//this will define the minX for the Nth ship
const minX = Math.min(10, i*regionWidth)
//The maxX should not let a ship overlap the next region. So, we subtract the shipWidth
//to ensure that, at worst, it is right next to the next ship
const maxX = (i+1)*regionWidth-shipWidth
//Use the updated restShip to put it in a valid location for it's region
resetShip(ship, minX, maxX)
})
}

Matter.js: Method to count how many times that an object has rotated?

I am creating a project in which a body is picked up and thrown by the user (with a mouse constraint). The body is set so that it can pivot about the constrain point. I need to find out, from the moment that it is let go, how many times it fully rotates (+-360 degrees) before landing. Reading the documentation, the only thing that I could find regarding the rotation was Matter.Body.rotate() which actually just sets the rotation of a body instead of recording it. How should I go about this?
Basically: How can I count an objects rotations?
This worked for me tbh:
var rad = 6.28;
var nrad = -6.28;
Events.on(engine, "tick", function () {
if(boxA.angle > rad){
rad+=6.28;
nrad+=6.28;
hrt +=1;
//hrt is the rotation c0unter
}
if (boxA.angle < nrad){
nrad-=6.28;
rad-=6.28;
hrt +=1;
}
rnum.innerHTML = "Spins: " + hrt;
fnum.innerHTML = fcounter; });

life decrease on collision

I am making a little game using HTML5 Canvas and javascript. I am so far that I have a kite moving some sort of power up on collision and an obstacle on collision.
Now I'm at the point I want to add lives and when you hit an obstacle your life will decrease 1.
I tried some stuff and when you hit an obstacle the life decreases but it decreases constantly and the player image gets removed instead of the obstacle image.
here is the life thing you can check all the code there.
http://nickzijlstra.com/kite
Here the code I think is the most important for the problem.
function hitObject(player, obj){
var a = (obj.x - player.x),
b = (obj.y - player.y),
c = Math.sqrt(a*a + b*b),
r0 = player.image.width/2,
r1 = obj.image.width/2;
if (c < r0+r1) {
player.drawable = false;
lifes -=1;
window.location.reload(true);
}
}
If someone sees the problem or knows the solution I would really appreciate it!
The reason the player disappears is because of this line in the hitObject function:
player.drawable = false;
This will cause the player to not be drawn because of this condition in your drawing function:
if (player.drawable == true) {
context.drawImage(player.image, player.x, player.y, player.image.width, player.image.height);
}
I presume you actually want to move the obj back to a random spot on the top of the screen if the player gets hit. It doesn't do this at the moment, which is why the lives go down rapidly: the object hits the player, it removes a life, and then the next frame it hits the player again (even though the player isn't visible).
What you might want is something like:
...
if (c < r0+r1) {
lifes -=1;
// Respawn the object.
obj.y = -50;
obj.x = Math.random() * canvas.width;
...
At a guess, I'd say that you should replace the
player.drawable = false;
with
obj.drawable = false;
and wrap the whole collision detection inside of an if obj.drawable=true so that removed obstacles won't collide with the kite.

JS Canvas Collision-Detection using getImageData

As a very inexperienced programmer, I'm trying to code a game that detects when the player collides with certain colors on the canvas. I have a black square with coordinates "player.x" and "player.y" and dimensions 50x50 that moves around when you press the arrow keys. I also have a stationary red (255,0,0) square elsewhere on the canvas.
The function below is supposed to grab a slightly larger square around the "player" square and find out if there's any red in it. If there is, it will send up an alert. The problem is, this doesn't seem to be working.
function collideTest(){
var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
var whatColor = c.getImageData(player.x - 5, player.y - 5,60,60);
for (var i = 0; i < 3600; i++) {
if (whatColor.data[i] == 255) {
alert("red");
}
}
}
I'm semi-aware that this is not the most efficient way to detect red pixels, but I wanted to simplify the code before posting it here. Is there something obviously wrong with the function?
The problem could lie in the way the function is called. It gets called at the end of another function that detects user-input and changes the coordinates of the "player" square. THAT function gets called right before everything is drawn on the canvas.
Thanks in advance for any help!
var whatColor = c.getImageData(player.x - 5, player.y - 5,60,60);
player.x and player.y must not be decimal, make sure they are rounded or getImageData will be angry and not play nice.
For each single pixel on the canvas, the whatColor.data array holds 4 sequential pieces of color information: red,green,blue,alpha(opacity). So the whatColor.data looks like this for each pixel:
whatColor.data[i] is the red component of the color.
whatColor.data[i+1] is the green component of the color.
whatColor.data[i+2] is the blue component of the color.
whatColor.data[i+3] is the alpha(opacity) component of the color.
So your iteration would look like this (4 indexes per pixel):
for(var i = 0, n = whatColor.data.length; i < n; i += 4) {
var red = whatColor.data[i];
var green = whatColor.data[i + 1];
var blue = whatColor.data[i + 2];
var alpha = whatColor.data[i + 3];
if(red==255){ ... it's a hit, do your thing! ... }
}
See here for a mini-tutorial on the imageData.data array: http://www.html5canvastutorials.com/advanced/html5-canvas-get-image-data-tutorial/
By the way, you might look at one of the canvas libraries that simplify game making with canvas. Here are just a few: easelJs, KineticJs, FabricJs, and more!

Categories