PIXI Logic is Skewed from the Actual Visuals - javascript

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.

Related

Array functions 'push' and 'splice' Javascript

1 of spades,1 of diamonds,1 of clubs,1 of hearts,2 of spades,2 of diamonds,2 of clubs,2 of hearts,3 of spades,3 of diamonds,3 of clubs,3 of hearts,4 of spades,4 of diamonds,4 of clubs,4 of hearts,5 of spades,5 of diamonds,5 of clubs,5 of hearts,6 of spades,6 of diamonds,6 of clubs,6 of hearts,7 of spades,7 of diamonds,7 of clubs,7 of hearts,8 of spades,8 of diamonds,8 of clubs,8 of hearts,9 of spades,9 of diamonds,9 of clubs,9 of hearts,10 of spades,10 of diamonds,10 of clubs,10 of hearts
,,,
[This is what the program returns]
I'm trying to make a program in JavaScript that allows someone to play poker. I am using the ProcessingJS terminal in Khan Academy. Below is my full program so far. What it's supposed to do is make an array called deck which includes the names of all the cards (not including the face cards) in a deck of cards. That part of the program works. The next part attempts to make a new array called current that is an exact copy of deck. It then tries to print out current, and it does so successfully.
The last for loop is what is causing the problem. It tries to take a random card from current and copy it to another array called player which is supposed to be the player's hand. It then tries to remove that card from the array current.
However, when it tries to print out the array player, all it prints is three commas. I have no idea what the issue is and I have looked at many websites that talk about push and splice. I really have no idea what is wrong.
Again, I want the program to display the player's hand. Thank you for your help.
var deck = [];
var current = [];
var enemy = [];
var player = [];
var suits = ['spades', 'diamonds', 'clubs', 'hearts'];
for (var i = 1; i < 11; i++) {
for (var x = 0; x < 4; x++) {
if (i <= 10) {
deck.push(i + ' of ' + suits[x]);
}
}
}
for (var c = 0; c < 40; c++) {
current[c] = deck[c];
}
println(current);
var y;
for (var a = 0; a < 4; a++) {
y = random(0, (current.length - 1));
player.push(current[y]);
current.splice(y);
}
println(player);
Why not just simplify this without using splice?
From what I understand, you're drawing the card using random. So, just push that card to the players hand with player.push(current[y]).
Also, when you call current.splice(y), I don't think you're deleting just the card that was drawn. That deletes every card in the deck after the index y. Change this to current.splice(y, 1).

PixiJS sorting sprites

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

Move Camera to make all objects fit exactly inside the frustum - three.js

EDIT : I have rephrased my question to help users with the same problem.
I have a three.js scene on which I have added some spheres.
I want to move the camera towards a specific direction until all the objects (which are randomly positioned inside the scene) are "fitting exactly" the user's screen.
I have found the answer to my problem!
1. I move the camera (zooming to the desired direction) inside a loop, and in every repeat I create a new frustum using the camera's matrix
2. I check if any of my spheres intersects with a plane of the frustum. If it does, that means that part of one of my objects is outside the frustum so I break the loop and move the camera to its last position.
The above might also works for any object (not only spheres) because every object has a boundingSphere that can be calculated (it might not be very precise the result though).
It also works when zooming out, you 'd just have to move the camera from the object until none of the has a negative distance from all the planes (negative distance means object is "outside" the plane of the frustum).
Code (only for zooming out - r72) :
var finished = false;
var camLookingAt = /* calc. */ ;
while( finished === false ){
var toDirection= camera.position.clone().sub(camLookingAt.clone());
toDirection.setLength(vec.length() - 1); // reduce length for zooming out
camera.position.set(toDirection.x, toDirection.y, toDirection.z);
camera.updateMatrix(); // make sure camera's local matrix is updated
camera.updateMatrixWorld(); // make sure camera's world matrix is updated
var frustum = new THREE.Frustum();
frustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ) );
for (var j = frustum.planes.length - 1; j >= 0; j--) {
var p = frustum.planes[j];
for (var i = myMeshSpheres.length - 1; i >= 0; i--) {
var sphere = new THREE.Sphere(myMeshSpheres[0].position.clone(), myMeshSpheres[0].radius);
if( p.distanceToSphere(sphere) < 1 ){ // if is negative means part of sphere is outside plane/frustum
finished = true;
}
}
}

javascript - 2D array initilisation speed

I'm making a 2D isometric game where the tile map is held in a 2D array. Here's what a 16*16 map looks like just so you get the idea:
Before the game loop begins the size and contents of the map array must be initialized and I have noticed that this is one of the biggest bottlenecks when loading the program. If the map is 5000*5000 it can take about 7 seconds on my relatively high end computer (which i figure seems pretty slow).
Is this more a problem with the speed of javascript or is my code doing something wildly inefficient?
The array which holds the tile contents is initialized like so:
// Create Array to represent tile contents
mapArray = new Array(mapWidth);
for (var i = 0; i < mapWidth; i++) {
mapArray[i] = new Array(mapHeight);
for (var j = 0; j < mapHeight; j++) {
mapArray[i][j] = new Tile("water", 0, false);
}
}
and the objects which that array hold is the tile class below:
// Tile class
function Tile(type, height, mouseOver) {
// Add object properties like this
this.type = type;
this.height = height;
this.mouseOver = mouseOver;
}
If you're registering individual event listeners to each tile, that could certainly slow down your program. Consider cutting down the number of listeners by only listening to mouseover/mousemove events on the container, and then deriving the tile from the (x, y) coordinates of the mouse.

Generating random unique data takes too long and eats 100% CPU

WARNING: CPU Usage goes to 100%, be careful.
Link to the jsFiddle
This script has been written to design a dynamic snake and ladder board. Everytime the page is refreshed a new board is created. Most of the time all of the background images do not appear, and the CPU usage goes up to 100%. But on occasion all of them appear and the CPU usage is normal.
Opera shows some of the background images, Firefox lags and asks me if I wish to stop the script.
I believe that the problem is with these lines of code:
for(var key in origin) // Need to implement check to ensure that two keys do not have the same VALUES!
{
if(origin[key] == random_1 || origin[key] == random_2 || key == random_2) // End points cannot be the same AND starting and end points cannot be the same.
{
valFlag = 1;
}
console.log(key);
}
Your algorithm is very ineffective. When array is almost filled up, you literally do millions of useless iterations until you're in luck and RNG accidentally picks missing number. Rewrite it to:
Generate an array of all possible numbers - from 1 to 99.
When you need a random numbers, generate a random index in current bounds of this array, splice element and this random position, removing it from array and use its value as your desired random number.
If generated numbers don't fit some of your conditions (minDiff?) return them back to array. Do note, that you can still stall in loop forever if everything that is left in array is unable to fit your conditions.
Every value you pull from array in this way is guaranteed to be unique, since you originally filled it with unique numbers and remove them on use.
I've stripped drawing and placed generated numbers into array that you can check in console. Put your drawing back and it should work - numbers are generated instantly now:
var snakes = ['./Images/Snakes/snake1.png','./Images/Snakes/snake2.jpg','./Images/Snakes/snake3.gif','./Images/Snakes/snake4.gif','./Images/Snakes/snake5.gif','./Images/Snakes/snake6.jpg'];
var ladders = ['./Images/Ladders/ladder1.jpg','./Images/Ladders/ladder2.jpg','./Images/Ladders/ladder3.png','./Images/Ladders/ladder4.jpg','./Images/Ladders/ladder5.png'];
function drawTable()
{
// Now generating snakes.
generateRand(snakes,0);
generateRand(ladders,1);
}
var uniqNumbers = []
for(var idx = 1; idx < 100; idx++){ uniqNumbers.push(idx) }
var results = []
function generateRand(arr,flag)
{
var valFlag = 0;
var minDiff = 8; // Minimum difference between start of snake/ladder to its end.
var temp;
for(var i = 0; i< arr.length; ++i) {
var valid = false
// This is the single place it still can hang, through with current size of arrays it is highly unlikely
do {
var random_1 = uniqNumbers.splice(Math.random() * uniqNumbers.length, 1)[0]
var random_2 = uniqNumbers.splice(Math.random() * uniqNumbers.length, 1)[0]
if (Math.abs(random_1 - random_2) < minDiff) {
// return numbers
uniqNumbers.push(random_1)
uniqNumbers.push(random_2)
} else {
valid = true
}
} while (!valid);
if(flag == 0) // Snake
{
if(random_1 < random_2) // Swapping them if the first number is smaller than the second number.
{
var temp = random_1; random_1 = random_2; random_2 = temp
}
}
else // Ladders
{
if(random_1>random_2) // Swapping them if the first number is greater than the second number.
{
var temp = random_1; random_1 = random_2; random_2 = temp
}
}
// Just for debug - look results up on console
results.push([random_1, random_2])
}
}
drawTable()
I had a problem like this using "HighCharts", in a for loop - "browsers" have an in-built functionality to detect dead scripts or infinite loops. So the browsers halts or pop-ups up a message saying not responding. Not sure if you have that symptom!
This was resulted from a "loop" with a large pool of data. I wrote a tutorial on it on CodeProject, you might try it, and it might be your answer.
http://www.codeproject.com/Tips/406739/Preventing-Stop-running-this-script-in-Browsers

Categories