Multiple collision in canvas - javascript

I am trying to make unblock me game. I have array of objects and I made boundaries collision. But now I am stuck with collision between objects. I made cycle over objects in array but it stops on the last one. How can I make collision check on each object everytime I move with my selected object?
Full code here: http://foxfcb.sweb.cz/ I am newbie in programming so please be patient.
canvas.addEventListener('mousemove', function (e) {
...
var shapes = myState.shapes;
var l = shapes.length;
for (var i = 0; i < l; i++) {
var shape = myState.shapes[i];
var selection = myState.selection;
// collision between objects
if (selection.x < (shape.x + shape.w) && (selection.x + selection.w) > shape.x &&
selection.y < (shape.y + shape.h) && (selection.y + selection.h) > shape.y) {
myState.valid = true; //stop
}
// boundaries collision
else if (myState.selection.x < 0 || myState.selection.y < 0 || myState.selection.x + myState.selection.w > 600 || myState.selection.y + myState.selection.h > 600) {
myState.valid = true; //stop
}
else {
myState.valid = false; //moving
}
}
}

You are resetting the valid flag when you check other objects.
So here is your collision detection as a function. Notice I set state = false once before the loop and if there is a collision I break out of the loop as there is no point detecting other collisions as the flag is either true or false. You were setting the flag back to false on all but the last object if you detected a collision.
var textCollision = function(){
var shapes, l, shape, selection, i;
shapes = myState.shapes;
l = shapes.length;
myState.valid = false; // assume no collision
for (i = 0; i < l; i++) {
shape = myState.shapes[i];
selection = myState.selection;
if (selection.x < (shape.x + shape.w) && (selection.x + selection.w) > shape.x &&
selection.y < (shape.y + shape.h) && (selection.y + selection.h) > shape.y) {
myState.valid = true; //stop
// there is no point testing any others as it will make no dif
break; // step out of the for loop.
}
// boundaries collision
else if (myState.selection.x < 0 || myState.selection.y < 0 || myState.selection.x + myState.selection.w > 600 || myState.selection.y + myState.selection.h > 600) {
myState.valid = true; //stop
// there is no point testing any others as it will make no dif
break; // step out of the for loop.
}
}
}
Break.
Break is a javascript reserved token and is used to break out of loops and switches.
For loop
for(i = 0; i < 10; i++){
if(i === 2){
break; // exit the loop at 2
}
}
While loop
while(i < 10){
if(i === 2){
break; // exit out of the while loop
}
}
Also does the same on do{ }While() loops.
Break only exits the current loop;
for(j = 0; j < 10; j++){ // j loop
for(i = 0; i < 10; i++){ // i loop
if(i === 2){
break; // exit the i loop at 2
}
}
// the break moves execution to the first line after the loop it is in
// the j loop continues as normal
}
Break is also used in switch statements
function num(i){
switch(i){
case 1:
console.log("one");
// no break token so execution continues inside the switch
case 2:
console.log("two");
}
}
num(1); // outputs "one" "two"
To prevent this use break
function num(i){
switch(i){
case 1:
console.log("one");
break; // break out of the switch
case 2:
console.log("two");
// no point having a break here as it is at the end anyways
}
// break moves execution to here
}
num(1); // outputs "one"

Related

How to detect and subtract a variable under a for and if loop?

I have a bunch of objects that when they fall out of screen, it wont stop subtracting.
for (var i = 0; i < maximum_number_objects_spawned; i++){
if (objects[i].y > game_height){
lives = lives - 1;
}
}
For context, I am using a gravity engine to pull these objects down, so it isn't really applicable to use an if "objects[i] is equal to the world_height" statement. Here is something I tried that didn't work:
for (var i = 0; i < maximum_number_objects_spawned; i++){
lives_not_subtracted = true;
if (objects[i].y > game_height && lives_not_subtracted === true){
lives = lives - 1;
lives_not_subtracted = false;
}
}
This still did not work and rather continued to subtract lives infinitely. I am curious as to see why my second method did not work, although it looks as if it should've.
Your loop is wrong, lives_not_subtracted will always true, place it outside the loop or in object like below
var objects = [{
y: 555,
lives_not_subtracted: true
},
{
y: 444,
lives_not_subtracted: true
}
]
for (var i = 0; i < maximum_number_objects_spawned; i++) {
if (objects[i].y > game_height && objects[i].lives_not_subtracted == true) {
lives = lives - 1;
objects[i].lives_not_subtracted = false;
}
}
or check existence of lives_not_subtracted if not exist add it
var objects = [{y: 555}, {y: 444}]
for (var i = 0; i < maximum_number_objects_spawned; i++) {
if (objects[i].y > game_height && !objects[i].lives_not_subtracted) {
lives = lives - 1;
objects[i].lives_not_subtracted = 'anyvalue';
}
}

Having issues trying to solve N Rook problem . Always get n*n solution and not N factorial

I'm trying to get N ways of solves a N rook problem. The issue I am having is currently, I seem to get n*n solutions while it needs to be N! . Below is my code, I have written it in simple loops and functions, so it's quite long. Any help would be greatly appreciated
Note: Please ignore case for n = 2. I get some duplicates which I thought I would handle via JSON.stringify
var createMatrix = function (n) {
var newMatrix = new Array(n);
// build matrix
for (var i = 0; i < n; i++) {
newMatrix[i] = new Array(n);
}
for (var i = 0; i < n; i++) {
for (var j = 0; j < n; j++) {
newMatrix[i][j] = 0;
}
}
return newMatrix;
};
var newMatrix = createMatrix(n);
// based on rook position, greying out function
var collision = function (i, j) {
var col = i;
var row = j;
while (col < n) {
// set the row (i) to all 'a'
col++;
if (col < n) {
if (newMatrix[col][j] !== 1) {
newMatrix[col][j] = 'x';
}
}
}
while (row < n) {
// set columns (j) to all 'a'
row++;
if (row < n) {
if (newMatrix[i][row] !== 1) {
newMatrix[i][row] = 'x';
}
}
}
if (i > 0) {
col = i;
while (col !== 0) {
col--;
if (newMatrix[col][j] !== 1) {
newMatrix[col][j] = 'x';
}
}
}
if (j > 0) {
row = j;
while (row !== 0) {
row--;
if (newMatrix[i][row] !== 1) {
newMatrix[i][row] = 'x';
}
}
}
};
// checks position with 0 and sets it with Rook
var emptyPositionChecker = function (matrix) {
for (var i = 0; i < matrix.length; i++) {
for (var j = 0; j < matrix.length; j++) {
if (matrix[i][j] === 0) {
matrix[i][j] = 1;
collision(i, j);
return true;
}
}
}
return false;
};
// loop for every position on the board
loop1:
for (var i = 0; i < newMatrix.length; i++) {
var row = newMatrix[i];
for (var j = 0; j < newMatrix.length; j++) {
// pick a position for rook
newMatrix[i][j] = 1;
// grey out collison zones due to the above position
collision(i, j);
var hasEmpty = true;
while (hasEmpty) {
//call empty position checker
if (emptyPositionChecker(newMatrix)) {
continue;
} else {
//else we found a complete matrix, break
hasEmpty = false;
solutionCount++;
// reinitiaze new array to start all over
newMatrix = createMatrix(n);
break;
}
}
}
}
There seem to be two underlying problems.
The first is that several copies of the same position are being found.
If we consider the case of N=3 and we visualise the positions by making the first rook placed red, the second placed green and the third to be placed blue, we get these three boards:
They are identical positions but will count as 3 separate ones in the given Javascript.
For a 3x3 board there are also 2 other positions which have duplicates. The gets the count of unique positions to 9 - 2 - 1 -1 = 5. But we are expecting N! = 6 positions.
This brings us to the second problem which is that some positions are missed. In the case of N=3 this occurs once when i===j==1 - ie the mid point of the board.
This position is reached:
This position is not reached:
So now we have the number of positions that should be found as 9 - 2 - 1 - 1 +1;
There appears to be nothing wrong with the actual Javascript in as much as it is implementing the given algorithm. What is wrong is the algorithm which is both finding and counting duplicates and is missing some positions.
A common way of solving the N Rooks problem is to use a recursive method rather than an iterative one, and indeed iteration might very soon get totally out of hand if it's trying to evaluate every single position on a board of any size.
This question is probably best taken up on one of the other stackexchange sites where algorithms are discussed.

How can I stop my loop at number +/- 10 instead of stopping at the number 10?

As shown in the code below, my loop will carry on forever.
I want the program to take the users input and add or subtract 10 based on whether they say up or down by using increments and decrements.
Any hints or help would be amazing! Thank you in advance.
function runprogram() {
var thenumber=prompt('Give me a number to increment or decrement!')
var updown=prompt('Should I increment it up or down?')
var thenumberup= (thenumber + 10)
var thenumberdown=(thenumber - 10)
var i;
if(updown == 'up') {
for(i = thenumber; i < 10; i++) {
alert(i);
}
}
if(updown == 'down') {
for (i = thenumber; i > 10 ; i--) {
alert(i);
}
}
}
The result of the first prompt call is not a number, you must coerce it to a number with +prompt('...').
As #Adrián mentioned in the comments, the comparisons should also be <= and >= otherwise it will stop directly before the target number.
function runprogram() {
var thenumber = +prompt('Give me a number to increment or decrement!')
var updown = prompt('Should I increment it up or down?')
var thenumberup = (thenumber + 10)
var thenumberdown = (thenumber - 10)
var i;
if (updown == 'up') {
for (i = thenumber; i <= thenumberup; i++) {
alert(i);
}
}
if (updown == 'down') {
for (i = thenumber; i >= thenumberdown; i--) {
alert(i);
}
}
}
runprogram();
While you've got an answer that does what you need, I find it a little dissatisfying that you have two loops. Here's another way you could do this with a single loop (by storing a multiplier depending on the direction given):
function run() {
var number = +prompt('number', 0)
var direction = prompt('up or down?', 'up')
var multiplier = direction === 'up' ? 1 : -1
for (var i = 0; i < 10; i++) {
alert(number + (i * multiplier));
}
}
run();

Javascript 'while' loop causing browser to crash

I have a 'search and highlight' function that looks through each node in an element and highlights each instance of the keyword. Within this function I have used a while(true) that seems to be causing the browsers to either crash or lag! Are there any alternatives to this while loop?
Any help would be so greatly appreciated.
console.log(keyword);
if (keyword != "") {
SearchResultCount = 0;
currSelected = -1;
if (element) {
if (element.nodeType == 3) {
while (true) {
var value = element.nodeValue; // Search for keyword in text node
var idxSensitive = value.indexOf(keyword);
var idxInsensitive = value.toLowerCase()
.indexOf(keyword);
if ((idxInsensitive < 0)
&& (idxSensitive < 0))
break; // not found, abort
else if ((idxInsensitive >= 0)
&& (idxSensitive < 0))
var idx = idxInsensitive;
else if ((idxSensitive >= 0)
&& (idxInsensitive < 0))
var idx = idxSensitive;
var span = document.createElement("span");
var text = document.createTextNode(value
.substr(idx, keyword.length));
span.appendChild(text);
span.setAttribute("class",
"highlightedText");
span.style.backgroundColor = "lightblue";
span.style.color = "black";
text = document.createTextNode(value
.substr(idx + keyword.length));
element.deleteData(idx, value.length - idx);
var next = element.nextSibling;
element.parentNode.insertBefore(span, next);
element.parentNode.insertBefore(text, next);
element = text;
SearchResultCount++; // update the counter
}
}
While loops need a false condition or a break to end. All I see is a while (true) which will never evaluate to false. Since you have a never ending loop, it causes your browser to crash. Though it should break if idxSensitive and idxInsensitive are negative numbers, any other value will keep the loop running forever.
To loop something forever(instead of while(true)), you can use:
setTimeout(function, 1);
//Or
for (var i = 0; i < Infinity; i++) {
//Code goes here
}

Values not being pushed to an array inside of a for loop

I am having an issue with a JavaScript Method a game that I am making that will be similar to the popular game 2048, but with a board of any size.
this.board is a property of the game object and is a n by n array that has either 0 or a number in it. this.board[row][column]
For example:
Where SIZE_OF_BOARD = 5; this.board[i] could be [0,0,2,4,0] at the end of the method the desired appearance of this.board[i] would be [0,0,0,2,4], but currently it is [0,0,0], the 2 and 4 are not being pushed to stack inside the column.
My problem is inside the column loop nothing is being pushed to the stack.
game.prototype.right = function () {
for(var i = 0; i < SIZE_OF_BOARD; i++){ // row loop
var zeroCount = 0;
var temp = 0;
var stack = [];
console.log(this.board[i]);
for(var j = 0; j < SIZE_OF_BOARD; j++){ // column loop
if(this.board[i][j] == 0){
zeroCount++;
} else if (temp == this.board[i][j] && temp != 0){
stack.push(temp*2);
zeroCount++;
temp = 0;
} else if (temp!=0){
temp = this.board[i][j];
stack.push(temp);
}
}
console.log(stack);
while(zeroCount > 0){ // add the 0's to the left of the stack.
stack.unshift(0);
zeroCount--;
}
this.board[i] = stack;
console.log(stack);
}
// this.next();
}
Any idea what is going wrong?

Categories