Should this For-Loop, in theory, work? - javascript

I have a question over at collision-detection about a similar issue, but it's not exactly the same. I had an issue with a new game project (I'm trying to learn more about HTML5 Canvases and Socket.io) in which my collisions weren't working. I thought that my issue was centered on collisions, but now I'm starting to think something different. The reason I have a different issue posted here at the for-loop area is because I'm not sure if my issue is for-loop related or collision-detection related. Either way, I'd be happy to take one of my questions down.
This code is looping every frame to get the active positions of bullets and ships. If the bullet touches the ship, it'll be removed and some health points will be removed from the ship.
Tutorial I was using: http://jlongster.com/Making-Sprite-based-Games-with-Canvas
That aside, here's my checkCollisions code. It seems that the collision function is working, because when I started to log all the positions every time we had an iteration, it seemed that the position of my object was changing every single time. Is this one of those for-loop issues where I'm going to need a callback?
Thank you so much in advance for all your help. I'll be sure to upvote/select every response that helps out! :)
SOLVED! Turns out one of my arrays wasn't being passed in correctly. I'd like to thank you guys for telling me to always split it into multiple functions, that really helped me figure that one out!
// Let's start out here: I have a players[] array
//that's essentially a list of all players on the server
// and their positions. I omitted server connection functionality since that's not my error
// source.
function checkCollisions() {
for (var i = 0; i < players.length; i++) { // Iterating through all players
var pos = [players[i].posX, players[i].posY];
var size = [SHIP_WIDTH, SHIP_HEIGHT]; // This is the size of each player, it's a ship game. So these are constants.
if (players[i].userId != PLAYER.userId) { // Each player has a userId object, this is just doublechecking if we're not uselessly iterating
for (var j = 0; j < bullets.length; j++) { // We're now looping through bullets, an array of all the bullets being shot by players
var pos2 = bullets[j].pos;
var size2 = BULLET_SIZE;
var sender = bullets[j].sender;
if (boxCollides(pos, size, pos2, size2)) { // Collision code
if (sender != players[i].userId) {
bullets.splice(j, 1);
i--; // Tried here with j--, and by removing the entire line. Unfortunately it doesn't work :(
break;
}
}
}
}
}
}

Have you tried using console.log to see where the program is breaking? This might help you determine if there are multiple bugs or if it's just this one. If there's something wrong in a previous statement, you may not know it if you've fixed the i-- / j-- ...?
Edit: AH I see that you've fixed things, after I'd posted this. Well congrats and good job!

Related

draw function not looping as expected

I'm a beginner on here, so apologies in advance for naivety. I've made a simple image on Brackets using Javascript, trying to generate circles with random x and y values, and random colours. There are no issues showing when I open the browser console in Developer Tools, and when I save and refresh, it works. But I was expecting the refresh to happen on a loop through the draw function. Any clues as to where I've gone wrong?
Thanks so much
var r_x
var r_y
var r_width
var r_height
var x
var y
var z
function setup()
{
r_x = random()*500;
r_y = random()*500;
r_width = random()*200;
r_height = r_width;
x = random(1,255);
y= random(1,255);
z= random(1,255);
createCanvas(512,512);
background(255);
}
function draw()
{
ellipse(r_x, r_y, r_width, r_height);
fill(x, y, z);
}
Brackets.io is just your text editor (or IDE if you want to be technical) - so we can remove that from the equation. The next thing that baffles me is that something has to explicitly call your draw() method as well as the setup() method -
I'm thinking that you're working in some sort of library created to simplify working with the Canvas API because in the setup() method you're calling createCanvas(xcord,ycord) and that doesn't exist on it's own. If you want to rabbit hole on that task check out this medium article, it walks you thru all the requirements for creating a canvas element and then drawing on that canvas
Your also confirming that you're drawing at least 1 circle on browser refresh so i think all you need to focus on is 1)initiating your code on load and 2)a loop, and we'll just accept there is magic running in the background that will handle everything else.
At the bottom of the file you're working in add this:
// when the page loads call drawCircles(),
// i changed the name to be more descriptive and i'm passing in the number of circles i want to draw,
// the Boolean pertains to event bubbling
window.addEventListener("load", drawCircles(73), false);
In your drawCircles() method you're going to need to add the loop:
// im using a basic for loop that requires 3 things:
// initialization, condition, evaluation
// also adding a parameter that will let you determine how many circles you want to draw
function drawCircles(numCircles) {
for (let i = 0; i < numCircles; i++) {
ellipse(r_x, r_y, r_width, r_height);
fill(x, y, z);
}
}
here's a link to a codepen that i was tinkering with a while back that does a lot of the same things you are
I hope that helps - good luck on your new learning venture, it's well worth the climb!
Thank you so much for your help! What you say makes sense - I basically deleted the equivalent amount of code from a little training exercise downloaded through coursera, thinking that I could then essentially use it as an empty sandpit to play in. But there's clearly far more going on under the hood!
Thanks again!

Straight paths Dijkstra’s Algorithm implementation

I have recently been trying to implement Dijkstra’s Algorithm in Javascript using the tutorial here. I'm able to make it go around obstacles successfully, but the paths it makes are simply not optimal, usually coming off as very straight. I think the problem is with how he implemented finding the neighbors. His code seems to pick the neighbors in a near-random order while mine always picks them in a set order, so that's probably a good place to look. I couldn't for the life of me figure it out. I tried everything I could think of.
My filling implementation is this:
function floodFill(array,sx,sy,dx,dy){
var frontier=[[sx,sy]];
array[sy][sx].visited=true;
var look=[[-1,0],[0,-1],[1,0],[0,1]];
var looks=0;
while(frontier.length>0){
if(frontier.length>0){
var current=frontier[0];
frontier.splice(0,1);
if(current[0]==dx && current[1]==dy){
console.log("Broke early!");
break;
}
for(var i=0;i<look.length;i++){
var y=current[0]+look[i][0];
var x=current[1]+look[i][1];
if((y>=0 && y<array[current[0]].length) && (x>=0 && x<array.length)){
if(array[y][x].visited==false && array[y][x].type==0){
frontier.push([y,x]);
looks++;
array[y][x].visited=true;
array[y][x].origin=[current[0],current[1]];
array[y][x].order=looks;
}
}
}
}
}
}
You can find a demo here (you need to open up your javascript console to see it)
Thank you very much for your time.
Here's an image of my problem
Figured out the answer. To put it simply, I wasn't checking diagonals when I was finding the neighbors.
You can find a working version here
The part that I changed
var look=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]];

Speed up simplex algorithm

I am playing around with a great simplex algorithm I have found here: https://github.com/JWally/jsLPSolver/
I have created a jsfiddle where I have set up a model and I solve the problem using the algorithm above. http://jsfiddle.net/Guill84/qds73u0f/
The model is basically a long array of variables and constraints. You can think of it as trying to find the cheapest means of transportation of passengers between different hubs (countries), where each country has a minimum demand for passengers, a maximum supply of passengers, and each connection has a price. I don't care where passengers go, I just want to find the cheapest way to distribute them. To achieve this I use the following minimising objective:
model = {
"optimize": "cost",
"opType": "min",
"constraints": { \\etc...
I am happy with the model and the answer provided by the algorithm ... but the latter takes a very long time to run (>15 seconds...) Is there any possible way I can speed up the calculation?
Kind regards and thank you.
G.
It sounds as though you have a minimum-cost flow problem. There's a reasonable-looking TopCoder tutorial on min-cost flow by Zealint, who covers the cycle-canceling algorithm that would be my first recommendation (assuming that there's no quick optimization that can be done for your LP solver). If that's still too slow, there's a whole literature out there.
Since you're determined to solve this problem with an LP solver, my suggestion would be to write a simpler solver that is fast and greedy but suboptimal and use it as a starting point for the LP by expressing the LP in terms of difference from the starting point.
#Noobster, I'm glad that someone other than me is getting use out of my simplex library. I went through, looked at it, and was getting around the same runtime as you (10 - 20 seconds). There was a piece of the code that was needlessly transposing array to turn the RHS into a 1d array from a 2d array. With your problem, this killed performance eating up 60ms every time it happened (for your problem, 137 times).
I've corrected this in the repo and am seeing runtimes around 2 seconds. There are probably a ton of code clean up optimizations like this that need to happen but the problem set I built this (http://mathfood.com) for are so small that I never knew this was an issue. Thanks!
For what its worth, I took the simplex algo out of a college textbook and turned it into code; the MILP piece came from wikipedia.
Figured it out. The most expensive piece of the code was the pivoting operation; which it turns out was doing a lot of work to update the matrix by adding 0. Doing a little logic up front to prevent this dropped my run-time down on node from ~12 seconds to ~0.5.
for (i = 0; i < length; i++) {
if (i !== row) {
pivot_row = tbl[i][col];
for (j = 0; j < width; j++) {
// No point in doing math if you're just adding
// Zero to the thing
if (pivot_row !== 0 && tbl[row][j] !== 0) {
tbl[i][j] += -pivot_row * tbl[row][j];
}
}
}
}

Javascript: Simple Particle Motion, Particle Elastically Bouncing Off Other Particle

I've created this rather simple javascript; balls or 'molecules' moving around the screen. I was hoping to add to the functionality that when one ball comes into contact with another, they swap velocities. We don't need to worry about any angles, just when they come into contact with each other, the velocities swap. (Instead of changing the velocities though, in the code linked I've just coded a colour change)
I've been trying to call the function 'someplace' to recognise when the molecules touch, but I've had no luck with that. I don't really understand why.
Link to code:
http://jsbin.com/arokuz/5/
There seems to be three main problems:
The molecules seem to be randomly changing, rather than when two molecules touch.
When one sets the array to have say, 3 molecules, only two appear, the first is actually there, but unresponsive to .fillstyle changes, so invisible against the canvas
With the function method I would only be able to recognise when molecules in series (1 and 2 or 4 and 5) in the array touch...how could I check all the molecules?
You are only comparing a molecule with 2 other ones, which in fact might be anywhere.
Collision detection is a topic quite hard to solve, but if you want to have your idea
working quickly you might go for a n^2 algorithm with 2 nested for loops.
the code is quite expected :
// collision
for(var t = 0; t < molecules.length-1; t++)
for(var tt = t+1; tt < molecules.length; tt++) {
var p1 = molecules[t];
var p2 = molecules[tt];
if (sq(p1.x-p2.x) +sq(p1.y-p2.y) < sq(p1.radius+p2.radius) )
{
p1.collided = 8; // will diplay for next 8 frames
p2.collided = 8; // .
}
}
the fiddle is here :
http://jsbin.com/arokuz/10
The reason only two appear when three are made isn't because the first one doesn't render it is rather the last one doesn't, this is because of how you draw them by comparing its distance with the next one in the list - as it is the last there is no next and thus throws a null error and continues (check the console).
The reason why they seem to "randomly" detect collisions or not is because they are not checking against all other molecules - only the next in the list, unfortunately the only simply way to do it would be to go through all other balls for every ball and checking.
To get the molecules to detect distance you could use the pythagorean theorem, I typically use it such as:
var distx = Math.abs(molecule1.x - molecule2.x);
var disty = Math.abs(molecule1.x - molecule2.y);
var mindist = molecule1.radius + molecule2.radius;
return Math.sqrt(distx*distx+disty*disty) < mindist;

Jquery/Javascript only running a custom function once after CSS changes

I'm using Jquery to draw lines between the cells in a web-based spreadsheet application. I accomplish this with a mixture of background-image, background-position and background-repeat. The entire system is working very nicely, and allows me to map between different cells in the application.
However, I'm having some trouble with my Jquery/Javascript code.
function draw_line(start_row, start_col, finish_row, finish_col){
//Change CSS background properties
}
function loadData(){
for (i = 0; i < values; i++){
//Add element to spreadsheet - change CSS properties.
//Draw line between the two cells
draw_line(start_row, start_column, line, column);
}
}
loadData();
The problem is that although the for loop should run several times for all the elements involved, it will actually only run once. However, if I comment out the draw_line function, the for loop executes the correct number of times, and all of the elements get placed on the spreadsheet.
I've also tried running setTimeout, but that didn't help. Anyone every experienced this sort of behavior before? (Just for reference, I'm running JQuery v1.6.4, on FF)
Hope someone can help. Thanks!
I have no idea if this is actually causing your problem, but it's bad and risky code so you should fix it. This line of your code:
for (i = 0; i < values; i++)
is using an implicitly declared global variable as i. If any other code you are running is also doing that, then the value of i will get trounced and wreck your for loop.
Change that line to this to make i a local variable so nothing else can trounce it:
for (var i = 0; i < values; i++)

Categories