PixiJS sorting sprites - javascript

I was wondering if any body could help me..
Looking for an idea for sorthing child in the stage.
Currently i have the map, mapObjects and the player on the stage working as well.
//let say room contain everythings going in the room, background, object, player
let room = new PIXI.Container();
//start zsorting them
room.children.sort((a, b) => {
if(a.y < b.y) return -1; //the player will go behind correctly
};
so now the thing is, a got a couple object going infront of other object but the player need to go behind of one and this one gotta stay infront of the other object.
what should i do, if i want them to be sorted correctly
sorry i might be bad for explain.

Create a ground container and add it to the stage first. Make it contain things that are on the ground (the rabbit will never be visually behind them). Have another container up which contains everything that stands up from the ground. Add the up container after you've added the ground container.
let room = new PIXI.Container();
let ground = new PIXI.Container();
room.addChild(ground);
// .. add children to ground here
let up = new PIXI.Container();
room.addChild(up);
// add tower, player, bushes to up here.
You wont have to sort the children of the stage as their order never changes instead you want to sort the children of the up container. Sort it like so:
up.children.sort((a, b) => a.y - b.y)
Don't sort by z but instead sort by y as it only matters where they are on the stage vertically. If the rabbit is closer to the top of the screen you want it to be behind things (like the tower) that are closer to the bottom and thereby appear closer to the viewer.

background.z = 1;
tower.z = 2; // big object
player.z = 3;
towerObject.z = 4; // the object which rabbit should be behind
let room = new PIXI.Container();
// supposing sprites above are children of room Container
room.children.sort((a, b) => {
if(a.z < b.z) {
return -1;
} else if (a.z > b.z) {
return 1;
} else {
return 0;
}
};

Related

PIXI Logic is Skewed from the Actual Visuals

I am pretty new to JavaScript and PIXI. I am making a little game that requires the player to navigate and grab a key (move onto the same space as the key). This takes them to the next level. My problem is that whenever a new level is generated, it somehow uses the x and y coordinates for the key of the previous level to skew the logic. Because of this, the first level works fine, but every level afterwards is messed up.
The levels get skewed up and to the left by the respective values of the previous key. I have a 2d array in the background which holds values of where and where not the player can (holds values for things like walls, turrets, and the key). I randomly generate the key coordinates and for example set grid[9][12] = 3; for the key space. The next level visually looks perfect, with the walls and key generating, and the player being in the top left. However because of the skew, the top left of the visuals is really at [max_X - 9][max_Y - 12] and the player can go off screen to invisibly access the rest of the maze. So I can then phase through walls because the logic has the walls in a different place than the visuals, and the actual key space usually ends up off screen.
Here is my code that generates a new goal (key) object
function createGoal(scene) {
while (true) {
let x = getRandomInt(APP_WIDTH);
let y = getRandomInt(APP_HEIGHT);
//if space is not already occupied, populate
if (grid[x][y] == 0) {
console.log(x);
console.log(y);
goal = null;
goal = new Goal(TILE_WIDTH, x, y);
scene.addChild(goal);
grid[x][y] = 3;
break;
}
}
}
And here is the grid initialization:
const grid = new Array(APP_WIDTH);
for (let i = 0; i < APP_WIDTH; i++) {
grid[i] = new Array(APP_HEIGHT);
for (let j = 0; j < APP_HEIGHT; j++) {
grid[i][j] = 0;
}
}
Any help would be greatly appreciated.

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; });

collision detection in javascript game?

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
}

Categories