How can I use two different arrays to spawn two different objects? - javascript

I'm making a HTML5 game and I'm having trouble spawning the coins that will appear at the bottom of the screen. I have another object that is randomly spawning blocks that are falling from the top of the screen. When I add the function for spawning coins, the spawning of the blocks doesn't work and the console error says that it can't define something or other. Is there something wrong with my functions?
function animateRandomBlocks()
{
var time = Date.now();
if(time>lastSpawn+spawnRate)
{
lastSpawn = time;
spawnRandomBlocks();
}
for(var i = 0; i < blocks.length; i++)
{
var block = blocks[i];
block.y += spawnRateOfDescent;
if (block.status == 1)
{
ctx.beginPath();
ctx.fillStyle = block.type;
ctx.fillRect(block.x, block.y, block.width, block.height);
ctx.closePath();
}
var blockRight = block.x;
var blockLeft = block.x + block.width;
var blockTop = block.y
var blockBottom = block.y + block.height;
var bobRight = bobX;
var bobLeft = bobX + bobWidth;
var bobTop = bobY;
var bobBottom = bobY + bobHeight;
if (blockRight > bobLeft && blockLeft < bobRight && blockBottom > bobTop && blockTop < bobBottom && block.status == 1)
{
block.status = 0;
}
}
}

Related

Why does collision function won't remove an enemy?

I am trying to remove enemies when they get hit by a bullet, but as i can see this doesn't work.
I am writing this in codehs worksheet (javascript bootcamp).
var char;
var bullet;
var enemy;
var life = 5;
var enemyTimer = Randomizer.nextInt(0,50);
var enemies = [];
function start(){
makeChar();
keyDownMethod(movements);
makeBullet();
setTimer(shootBullet, 30);
addEnemy();
setTimer(makeEnemy, 5);
checkCollision();
}
function makeChar(){
char = new Circle(10);
char.setColor(Color.red);
char.setPosition(getWidth()/2, 430);
add(char);
}
function movements(e){
if (e.keyCode == Keyboard.RIGHT){
char.move(10,0);
}
if (e.keyCode == Keyboard.LEFT){
char.move(-10,0);
}
}
function makeBullet(){
bullet = new Rectangle(5,10);
bullet.setPosition(char.getX(), char.getY());
bullet.setColor(Color.green);
add(bullet);
}
function shootBullet(){
bullet.move(0,-10);
if (bullet.getY() < 0){
bullet.setPosition(char.getX(), char.getY());
}
}
function makeEnemy(){
for (var i = 0; i < enemies.length; i ++){
var b = enemies[i];
b.move(0,5)
b.move(Randomizer.nextInt(-3,3),0);
}
}
function addEnemy(){
setTimer(en,800);
}
function en(){
enemy = new Rectangle(50,50);
var x = Randomizer.nextInt(10, 350);
var y = enemy.getY();
y += 10;
enemy.setPosition(x,y);
add(enemy);
enemies.push(enemy);
}
function intersects(a,b){
return (a.getX() < b.getX() + b.getHeight() && a.getX() + a.getWidth() >b.getX() && a.getY() < b.getY() + b.getHeight() && a.getY() + a.getHeight() > b.getY());
}
function checkCollision(){
for(var i =0; i < enemies.length; i++){
var en = enemies[i];
if (intersects(bullet, en)){
println("hi");
remove(en);
i--;
remove(bullet);
}
}
}
With print I tried to see if it did read collision but it did not even print it.
I want it to remove enemies when it gets hit by a bullet,
Can somebody help?

How to generate random divs but not overlap

I want to generate random divs but not overlap with JavaScript.
Just like this:
random div example
But when the number of DIVS gets larger the browser will be blocked!
Then I use the Web Workers to generate the random divs,the browser will be blocked too.
here is my main js code:
self.onmessage = function(e){
var itemslength = e.data;
console.log(itemslength);
var position = [];
for(var i = 0 ; i < itemslength ; i++){
var length = position.length;
if(length == 0){
x = 900*Math.random();
y = 400*Math.random();
var relxy = [x,y];
position.push(relxy);
}else{
var flag = true;
x = 900*Math.random();
y = 400*Math.random();
do{
console.log('RUNNING!!');
x = x + 50;
y = y + 50;
var relxy = [x,y];
for(var j = 0 ; j < length ; j++){
var x1 = position[j][0];
var y1 = position[j][1];
var z = (x - x1)*(x - x1) + (y - y1)*(y - y1);
if(z > 10000){
flag = flag && true;
}else{
flag = flag && false;
}
}
}while(!flag);
position.push(relxy);
}
}
console.log('FINSHED!!');
postMessage(position);
};
<script>
var worker = new Worker('./js/bubbleworker.js');
var itemslengh = $('.items').length;
worker.postMessage(itemslengh);
worker.onmessage = function(data){
for(var i=0;i<data.data.length;i++){
var x = data.data[i][0];
var y = data.data[i][1];
$('.items:eq(' + i + ')').css({
'position':'absolute','left':x + 'px','top':y + 'px'
})
}
}
</script>
Am i right?
Someone who has a better idea? Thanks!

JavaScript - Improve my grid search algorithm

I have made my own "GhettoSearch," which is used to find the closest path between 2 given coordinates over a Grid, AKA a "list of coordinates."
The grid is an array like this:
var grid [ [somedata, [x,y,z], somedata], [somedata, [x,y,z], somedata] ]etc..
My start and stop positions is only coordinates, the Z coordinate is irrelevant at the moment.
I can almost get to the end, but some detoures are made because of my cost function.
Here is how the search looks complete: http://i.imgur.com/2ZjQBrh.png
Here is the code I currently use for the search:
var Main = {
GhettoSearch: function(Start, Stop, Grid){
var Pgreed = 1; //From current position to next nearby nodes
var Tgreed = 0.25; //from current position to target node
var Pcost = 0;
var Tcost = 0;
var open = [];
var closed = [];
var aReturn = [];
for (i = 0; i < Grid.length; i++) {
Worldmap.GetNode("Node_" + Grid[i][0]).style.backgroundColor = "#FFFFFF";
Pcost = Heuristics.Distance.Manhattan(Grid[i][1], Start, Pgreed);
Tcost = Heuristics.Distance.Manhattan(Grid[i][1], Stop, Tgreed);
open.push([i, (Pcost + Tcost)]);
}
do {
var TmpData = [0, Infinity];
var TmpForI = null;
for (i = 0; i < open.length; i++) {
if (open[i][1] < TmpData[1]) {
TmpData[0] = open[i][0];
TmpData[1] = open[i][1];
TmpForI = i;
}
}
closed.push(TmpData);
open.splice(TmpForI, 1);
for (i = 0; i < open.length; i++) {
Start = Grid[TmpData[0]][1]; //is now the start for recently closed node
Pcost = Heuristics.Distance.Manhattan(Grid[open[i][0]][1], Start, Pgreed);
Tcost = Heuristics.Distance.Manhattan(Grid[open[i][0]][1], Stop, Tgreed);
open[i] = [open[i][0], (Pcost + Tcost)];
}
} while (open.length > 0);
var PathID = null;
var TmpDist = Infinity;
for (i = 0; i < closed.length; i++) {
var NodeID = Grid[closed[i][0]][0];
var NodeCoords = Grid[closed[i][0]][1];
var NodeCost = closed[i][1];
aReturn.push([NodeID, NodeCoords, NodeCost]);
//var Dist = Heuristics.Distance.Manhattan(NodeCoords, Stop, 1);
if (NodeCost < TmpDist) {
TmpDist = NodeCost;
PathID = i;//Because you will remove the closest cord elese. OR? will u xD
}
}
aReturn.splice(PathID, closed.length);
return aReturn;
}
};
As you can see on the image, while going upwards it goes back and fills the empty spots besides the straight path up, how can I avoid this?
Yes, I have looked at different search aproaches such as BFS and a star, but I have problems implementing this in my own search function

Detect coherent neighbors / neighborhood in 2d array

Im having an arbitrary 2d array and each field has an id and a teamid (here illustrated as colors 1).
I want for every neighborhood an array with the ids
in it.
A neighborhood consists of fields with neighbors with the same teamid horizontally and vertically (not diagonally)
e.g.:
This is what i have:
array[0][0] = {id:1,teamId:1}
array[1][0] = {id:2,teamId:1}
array[2][0] = {id:3,teamId:0}
array[3][0] = {id:4,teamId:2}
array[4][0] = {id:5,teamId:2}
array[5][0] = {id:6,teamId:0}
array[0][1] = {id:7,teamId:1}
array[1][1] = {id:8,teamId:1}
array[2][1] = {id:9,teamId:1}
array[3][1] = {id:10,teamId:2}
array[4][1] = {id:11,teamId:2}
array[5][1] = {id:12,teamId:0}
//and so on..
This is what i want:
neighborhood[1] = [1,2,7,8,9,13,14]
neighborhood[2] = [4,5,10,11]
neighborhood[3] = [16,22,23,24,29,30]
neighborhood[4] = [25,31,32,37,38]
neighborhood[5] = [35,41]
I am not searching for the images, but for the array
neighborhood
thanks in advance!
You can use the logic from dots and block games. A block belongs to a player if he has surrounded it with the walls. So, you need for each cell also 4 walls except for the outer cells. To test if a cell is closed you can use 4 class variables:
var Block = function() {
this.isclosed=0;
this.left=0;
this.top=0;
this.right=0;
this.bottom=0;
return this;
}
Block.prototype = {
isClosed : function () {
if (this.isclosed==true) {
return false;
} else if (this.left && this.top && this.right && this.bottom) {
this.isclosed=true;
return true;
} else {
return this.left && this.top && this.right && this.bottom;
}
}
}
You can try my implementations of dots and blocks game # https://dotsgame.codeplex.com/.
The method for solving this issue is refered as Connected Component Labelling
A similar question was asked once before from which i have my solution:
// matrix dimensions
var row_count = 20;
var col_count = 20;
var numOfTeams = 2;
// the input matrix
var m = [];
// the labels, 0 means unlabeled
var label = [];
var source = document.getElementById("source");
for (var i = 0; i < row_count; i++) {
var row = source.insertRow(0);
m[i] = [];
label[i] = [];
for (var j = 0; j < col_count; j++) {
//m[i][j] = Math.round(Math.random());
m[i][j] = getRandomInt(0, numOfTeams + 1);
label[i][j] = 0;
var cell1 = row.insertCell(0);
cell1.innerHTML = m[i][j];
}
}
// direction vectors
var dx = [1, 0, -1, 0];
var dy = [0, 1, 0, -1];
function dfs(x, y, current_label, team) {
if (x < 0 || x == row_count) return; // out of bounds
if (y < 0 || y == col_count) return; // out of bounds
if (label[x][y] || team != m[x][y]) return; // already labeled or not marked with 1 in m
// mark the current cell
label[x][y] = current_label;
// recursively mark the neighbors
for (var direction = 0; direction < 4; ++direction) {
dfs(x + dx[direction], y + dy[direction], current_label, team);
}
}
function find_components() {
var component = 0;
for (var i = 0; i < row_count; ++i) {
for (var j = 0; j < col_count; ++j) {
if (!label[i][j] && m[i][j]) dfs(i, j, ++component, m[i][j]);
}
}
}
find_components();
var result = document.getElementById("result");
for (var i in label) {
var string = ""
var row = result.insertRow(0);
for (var j in label[i]) {
string += label[i][j] + " "
var cell1 = row.insertCell(0);
cell1.innerHTML = label[i][j];
}
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
table tr td {
min-width: 14px
}
<div style="float:left">
<table id="source"></table>
</div>
<div style="float:right">
<table id="result"></table>
</div>

Is there anything I can do to stop the slight page lag caused by this code?

I have this code cycling through my page, and it causes a slight page lag when a select box is checked. Is there any way to optimize the code? I am still very new to javascript so its possible that I mixed a few things up.
var OpeningEmployees = document.getElementById('opener');
var QuantityDDOptions = jQuery('#opener option').length;
var DropDownNames = new Array();
DropDownNames[0] = "opener";
DropDownNames[1] = "mid";
DropDownNames[2] = "closer";
DropDownNames[3] = "SRTW";
DropDownNames[4] = "CR";
DropDownNames[5] = "Aisles";
DropDownNames[6] = "BD";
DropDownNames[7] = "Fridge";
DropDownNames[8] = "AP";
DropDownNames[9] = "EPV";
OpeningEmployees.onchange = function () {
var openerVals = $("#opener").val();
for (var j = 1; j < DropDownNames.length; j++){
for (var x = 0; x < QuantityDDOptions; x++) {
var EmployeelNumLine = document.getElementById(DropDownNames[j]).options[x].value;
if (openerVals == null){
jQuery("select#"+DropDownNames[j]+" option")[x].removeAttribute("disabled");
$("#"+DropDownNames[j]).multiselect("refresh");
} else if(openerVals.indexOf(EmployeelNumLine) > -1) {
jQuery("select#"+DropDownNames[j]+" option")[x]['disabled'] = "true";
$("#"+DropDownNames[j]).multiselect("refresh");
} else if(!openerVals.indexOf(EmployeelNumLine) > -1){
jQuery("select#"+DropDownNames[j]+" option")[x].removeAttribute("disabled");
$("#"+DropDownNames[j]).multiselect("refresh");
}
}
}
}
In general, if your loop is locking up the thread, you can refactor it as a recursive loop that is invoked using timeouts. That prevents the UI from freezing up.
For large values of n, this will freeze your browser:
for (i = 0; i < n; i++){
//dosomething();
}
This on the other hand, slows you down, but doesn't lock up the browser:
(function iterate(i) {
if (i < n) {
//dosomething();
setTimeout(function () {
iterate(++i);
}, 0);
}
})(0)

Categories

Resources