EDIT: The Problem was in my code, I was not querying the array with the right index.
For anyone looking for an answer for this problem, Karthik Ar answered it right. Thanks for all the comments!
I´m struggling to create an array of unique canvas elements inside a for loop.
It seems as all elements were a copy of the first element created. Im saying this because I need to store this canvas in an array and then access their contexts anytime later.
var _ctxs = new Array();
function createCells()
{
_w = window.innerWidth;
_h = window.innerHeight;
var side = 300;
//set amount of steps
var stepsW = Math.ceil(_w/side) + 1;
var stepsH = Math.ceil(_h/(side/2)) + 1;
console.log("create cells");
for (var i = 0; i < stepsH; i++)
{
var p = (i%2 == 0)?0:side/2;
for (var j = 0; j < stepsW; j++)
{
var _tempCanvas = $('<canvas/>', {id: "i_" + i + "_" + j, width : side, height : side});
_tempCanvas.css({
'position' : 'absolute',
'top' : (i*(side/2)+1) - side/2,
'left' : (j*side + p) + 1 - side/2
});
//var _tempCtx = _tempCanvas[0].getContext('2d');
_ctxs.push(_tempCanvas[0]);
$('body').prepend(_tempCanvas);
k++;
};
};
}
Any Thoughs? Thanks in advance!
Looks working by your code check the array.
$(document).ready(jqueryready);
function jqueryready(){
for (var i = 0; i < 5; i++)
{
for (var j = 0; j < 5; j++)
{
var _tempCanvas = $('<canvas/>', {id: i+""+j, width : 10, height : 10});
console.log(_tempCanvas[0].id);
$('body').prepend(_tempCanvas);
};
}
}
This creates unique id for canvas.
Related
var initialPos = [];
var totalNum = 5;
var dt = 1;
for (var i = 1; i <= totalNum; i++)
{initialPos.push([i*100*Math.random(),i*100*Math.random()])}
var vx = 5;
var vy = 5;
var newPos = [];
var x_Pos;
var y_Pos;
for (var j = 0; j <= totalNum - 1; j++) {
x_Pos = initialPos[j][0] + vx*dt;
y_Pos = initialPos[j][1] + vy*dt;
newPos.push([x_Pos,y_Pos])
initialPos = newPos;
};
console.log(initialPos);
initialPos is an array of ordered pairs. I am trying to create another array called newPos and push some modified elements from initialPos to it, however I keep getting the error that the property of 0 of undefined cannot be read. Any suggestions on to fix this? Thanks in advance!
The issue is in this line initialPos = newPos;
You are assigning initialPos to newPos.
The first time you go through the loop newPos looks something like this [ 27.07844010497107, 137.90462488567533 ]; and you are reassigning initialPos to this value.
The second time you go through the loop when j === 1, initialPos[1] is undefined as you assigned it to newPos that has a length of 1.
I am not sure what you want to do exactly, but isn't it what you need?
var initialPos = [];
var totalNum = 5;
var dt = 1;
for (var i = 1; i <= totalNum; i++)
{initialPos.push([i*100*Math.random(),i*100*Math.random()])}
var vx = 5;
var vy = 5;
console.log(initialPos);
for (var j = 0; j <= totalNum - 1; j++) {
initialPos[j][0] = initialPos[j][0] + vx*dt;
initialPos[j][1] = initialPos[j][1] + vy*dt;
};
console.log(initialPos);
As a side note, I suggest you look at immutability. Here is one article for instance. It would prevent such bugs.
I know how to construct the above triangle using a single symbol.
I do not understand how to change my code to use two symbols.
Your problem may be solved using a number of different solutions...
For the heck of it, here's how I would do it using canvas, to create an image (copied/pasted and adapted an answer I gave to another SO user yesterday...). This solution probably won't fit your needs but then again as Jishnu V S stated, you gave us nothing to help you with.
ps : Yeah, I know, WAY overkill compared to simple html lists... Oh well xD
fiddle
HTML
<canvas id="canvas" width=1000 height=1000></canvas>
JS
var rows = 8,
cols = 1,
size = 64;
var canvas = document.getElementById("canvas");
var surface = canvas.getContext("2d");
//creating tile
function box(img) {
this.xaxis = 64;
this.yaxis = 0;
//Set your image selection logic here...
this.src = (img > 0 ) ? "https://cdn0.iconfinder.com/data/icons/typicons-2/24/times-512.png" : "http://img.freepik.com/free-icon/minus-big-symbol_318-70354.jpg?size=338&ext=jpg";
console.log(img);
}
//creating map
var map =[];
function setMap() {
for (var i = 0; i < rows; i++) {
var arr = [];
map.push(arr);
for (var o = 0; o < cols; o++) {
var selectImg = (i % 2 == 0) ? 0 : 1; //select your image based on row
map[i].push(new box(selectImg));
}
cols = (cols < 8) ? cols + 1 : cols;
}
}
console.log(map)
//rendering map
function render() {
for (var i = 0; i < rows; i++) {
for (var x = 0; x < map[i].length; x++) {
var tile = map[i][x];
tile.xaxis *= x;
tile.yaxis += (i*64);
var img = new Image();
img.onload = (function(x,y) {
return function() {
surface.drawImage(this, x, y, 64, 64);
}
})(tile.xaxis, tile.yaxis);
img.src = tile.src;
}
}
}
setMap();
render();
I've got this array in a "global" position (out of every function in my doc).
var arrayBidimensional;
Then, i'm trying to filling it like this:
var objetoLetra = new objectLetter("","","","","");
arrayBidimensional=new Array(tamano);
for (i=0; i <tamano; i++)
arrayBidimensional[i]=new Array(tamano);
var random = Math.floor((Math.random()*26)+0);
for (var i = tamano - 1; i >= 0; i--)
{
for (var j = tamano - 1; j >= 0; j--)
{
random = Math.floor((Math.random()*26)+0);
objetoLetra.letra = letras[random];
objetoLetra.letraposx = j;
objetoLetra.letraposy = i;
objetoLetra.formapalabra = "no";
objetoLetra.iden = j+""+i;
arrayBidimensional[i][j] = objetoLetra;
}
}
so when i tried to reach to this array in some position like array[X][X]
all i've got is the very first position. Example: if the first position (That is 0,0) is "A", then, the entire array got "A" on every single position, even if it is [(max position), (max position)].
How do i see that?, well, i'm building a Table with td-s like this:
'<td width="30">'+arrayBidimensional[i][j].letra+'</td>'
Then, the entire table is just a lot of "A" every single cell... So... What i am doing wrong?
Please and thank you!
You need to create a new objectLetter for each location in the array:
arrayBidimensional = new Array(tamano);
for (i=0; i < tamano; i++) {
arrayBidimensional[i] = new Array(tamano);
}
for (var i = tamano - 1; i >= 0; i--)
{
for (var j = tamano - 1; j >= 0; j--)
{
var objetoLetra = new objectLetter("","","","","");
var random = Math.floor((Math.random()*26)+0);
objetoLetra.letra = letras[random];
objetoLetra.letraposx = j;
objetoLetra.letraposy = i;
objetoLetra.formapalabra = "no";
objetoLetra.iden = j+""+i;
arrayBidimensional[i][j] = objetoLetra;
}
}
Here's what a Multidimensional Array should look like in JavaScript:
var multi = [['String', 0, 'something else'],['another String', 42, 'whatever']];
or
var multi = new Array(new Array('String', 0, 'something else'), new Array('another String', 42, 'whatever'));
console.log(multi[1][2]); // 'whatever'
console.log(multi[0][1]); // 0
I'm attempting to emulate an infinite looping chaser on an LED strip with Javascript.
What I'm trying to accomplish:
Only use loops or recursive functions. No fancy JS.
Support any length of LED strip (var ledLength)
Support of multiple chasers
Support any number of LEDs (var ledDepth) with any number
of spaces separating the chasers (var blankDepth)
Loop infinitely
No magic numbers
I have this working for 1 chaser:
$(function(){
var ledLength = 20;
for(var i = 0; i < ledLength; i++) {
$('#led').append($('<div>').addClass('node'));
}
$('#led').css('width', ($('.node').length + 1) * $('.node').last().outerWidth(true));
var colors = ['green', 'red', 'blue'];
// add a "clearing" color
colors.push('black');
var ledDepth = 3;
var blankDepth = 2;
var chaserSize = ledDepth + blankDepth;
var iteration = 0;
var loop = setInterval(animate, 250);
function animate() {
if(iteration == ledLength + ledDepth) iteration = 0;
var offset = iteration < chaserSize ? iteration : chaserSize;
for(var i = 0; i <= offset; i ++) {
var colorOffset = i < ledDepth ? i : ledDepth;
$('.node').eq(iteration-i).css('background', colors[colorOffset]);
}
iteration++;
}
});
Or you can view it on the JSBin.
How would I go about tracking multiple chasers on a strip? Meaning after the initial chaserSize has been created and is moving to the right, another would be created and move long with it and loop infinitely.
Any help in to the right direction would be greatly appreciated.
I decided to take a different approach to this using an array.push method.
Basically, I continue to add points, loop through them all to increase their location, and remove them if their location is greater than the length of the strip.
This works for all LED lengths, chaser sizes (colors + blanks between each chaser).
Code:
$(function(){
// create the strip
var ledLength = 30;
for(var i = 0; i < ledLength; i++) {
$('#led').append($('<div>').addClass('node'));
}
$('#led').css('width', ($('.node').length + 1) * $('.node').last().outerWidth(true));
var points = [];
var colors = ['green', 'red', 'blue', 'pink', 'orange', 'purple'];
var ledDepth = colors.length || 6;
var blankDepth = 2;
var chaserSize = ledDepth + blankDepth;
// push blank nodes on the back of colors array
for(var i = 0; i < blankDepth; i++) {
colors.push('blank');
}
var iteration = 0;
// loop!
var loop = setInterval(animate, 100);
function animate() {
if(points.length) {
for(var i = 0; i < points.length; i++) {
// increase each pin by 1
points[i].pin++;
// remove point if pin is greater than led length
if(points[i].pin > ledLength) {
points.splice(i, 1);
}
}
}
if(iteration < chaserSize) {
points.push({pin: 0, color: colors[iteration]});
}
// draw points
for(var i = 0; i < points.length; i++) {
if(points[i].color == 'blank') { // this if for 'resetting'
$('.node').eq(points[i].pin).css('background', 'black');
} else { // this is for changing color
$('.node').eq(points[i].pin).css('background', points[i].color);
}
}
// iterate before reset
iteration++;
// reset sub-iterator (creator)
if(iteration >= chaserSize) {
iteration = 0;
}
}
});
Or JSBin
How do I generate objects on a map, without them occupying the same space or overlapping on a HTML5 Canvas?
X coordinate is randomly generated, to an extent. I thought checking inside the array to see if it's there already, and the next 20 values after that (to account for the width), with no luck.
var nrOfPlatforms = 14,
platforms = [],
platformWidth = 20,
platformHeight = 20;
var generatePlatforms = function(){
var positiony = 0, type;
for (var i = 0; i < nrOfPlatforms; i++) {
type = ~~(Math.random()*5);
if (type == 0) type = 1;
else type = 0;
var positionx = (Math.random() * 4000) + 500 - (points/100);
var duplicatetest = 21;
for (var d = 0; d < duplicatetest; d++) {
var duplicate = $(jQuery.inArray((positionx + d), platforms));
if (duplicate > 0) {
var duplicateconfirmed = true;
}
}
if (duplicateconfirmed) {
var positionx = positionx + 20;
}
var duplicateconfirmed = false;
platforms[i] = new Platform(positionx,positiony,type);
}
}();
I originally made a cheat fix by having them generate in an area roughly 4000 big, decreasing the odds, but I want to increase the difficulty as the game progresses, by making them appear more together, to make it harder. But then they overlap.
In crude picture form, I want this
....[]....[].....[]..[]..[][]...
not this
......[]...[[]]...[[]]....[]....
I hope that makes sense.
For reference, here is the code before the array check and difficulty, just the cheap distance hack.
var nrOfPlatforms = 14,
platforms = [],
platformWidth = 20,
platformHeight = 20;
var generatePlatforms = function(){
var position = 0, type;
for (var i = 0; i < nrOfPlatforms; i++) {
type = ~~(Math.random()*5);
if (type == 0) type = 1;
else type = 0;
platforms[i] = new Platform((Math.random() * 4000) + 500,position,type);
}
}();
EDIT 1
after some debugging, duplicate is returning as [object Object] instead of the index number, not sure why though
EDIT 2
the problem is the objects are in the array platforms, and x is in the array object, so how can I search inside again ? , that's why it was failing before.
Thanks to firebug and console.log(platforms);
platforms = [Object { image=img, x=1128, y=260, more...}, Object { image=img, x=1640, y=260, more...} etc
You could implement a while loop that tries to insert an object and silently fails if it collides. Then add a counter and exit the while loop after a desired number of successful objects have been placed. If the objects are close together this loop might run longer so you might also want to give it a maximum life span. Or you could implement a 'is it even possible to place z objects on a map of x and y' to prevent it from running forever.
Here is an example of this (demo):
//Fill an array with 20x20 points at random locations without overlap
var platforms = [],
platformSize = 20,
platformWidth = 200,
platformHeight = 200;
function generatePlatforms(k) {
var placed = 0,
maxAttempts = k*10;
while(placed < k && maxAttempts > 0) {
var x = Math.floor(Math.random()*platformWidth),
y = Math.floor(Math.random()*platformHeight),
available = true;
for(var point in platforms) {
if(Math.abs(point.x-x) < platformSize && Math.abs(point.y-y) < platformSize) {
available = false;
break;
}
}
if(available) {
platforms.push({
x: x,
y: y
});
placed += 1;
}
maxAttempts -= 1;
}
}
generatePlatforms(14);
console.log(platforms);
Here's how you would implement a grid-snapped hash: http://jsfiddle.net/tqFuy/1/
var can = document.getElementById("can"),
ctx = can.getContext('2d'),
wid = can.width,
hei = can.height,
numPlatforms = 14,
platWid = 20,
platHei = 20,
platforms = [],
hash = {};
for(var i = 0; i < numPlatforms; i++){
// get x/y values snapped to platform width/height increments
var posX = Math.floor(Math.random()*(wid-platWid)/platWid)*platWid,
posY = Math.floor(Math.random()*(hei-platHei)/platHei)*platHei;
while (hash[posX + 'x' + posY]){
posX = Math.floor(Math.random()*wid/platWid)*platWid;
posY = Math.floor(Math.random()*hei/platHei)*platHei;
}
hash[posX + 'x' + posY] = 1;
platforms.push(new Platform(/* your arguments */));
}
Note that I'm concatenating the x and y values and using that as the hash key. This is to simplify the check, and is only a feasible solution because we are snapping the x/y coordinates to specific increments. The collision check would be more complicated if we weren't snapping.
For large sets (seems unlikely from your criteria), it'd probably be better to use an exclusion method: Generate an array of all possible positions, then for each "platform", pick an item from the array at random, then remove it from the array. This is similar to how you might go about shuffling a deck of cards.
Edit — One thing to note is that numPlatforms <= (wid*hei)/(platWid*platHei) must evaluate to true, otherwise the while loop will never end.
I found the answer on another question ( Searching for objects in JavaScript arrays ) using this bit of code to search the objects in the array
function search(array, value){
var j, k;
for (j = 0; j < array.length; j++) {
for (k in array[j]) {
if (array[j][k] === value) return j;
}
}
}
I also ended up rewriting a bunch of the code to speed it up elsewhere and recycle platforms better.
it works, but downside is I have fewer platforms, as it really starts to slow down. In the end this is what I wanted, but its no longer feasible to do it this way.
var platforms = new Array();
var nrOfPlatforms = 7;
platformWidth = 20,
platformHeight = 20;
var positionx = 0;
var positiony = 0;
var arrayneedle = 0;
var duplicatetest = 21;
function search(array, value){
var j, k;
for (j = 0; j < array.length; j++) {
for (k in array[j]) {
if (array[j][k] === value) return j;
}
}
}
function generatePlatforms(ind){
roughx = Math.round((Math.random() * 2000) + 500);
type = ~~(Math.random()*5);
if (type == 0) type = 1;
else type = 0;
var duplicate = false;
for (var d = 0; d < duplicatetest; d++) {
arrayneedle = roughx + d;
var result = search(platforms, arrayneedle);
if (result >= 0) {
duplicate = true;
}
}
if (duplicate = true) {
positionx = roughx + 20;
}
if (duplicate = false) {
positionx = roughx;
}
platforms[ind] = new Platform(positionx,positiony,type);
}
var generatedplatforms = function(){
for (var i = 0; i < nrOfPlatforms; i++) {
generatePlatforms(i);
};
}();
you go big data, generate all possibilities, store each in an array, shuffle the array,
trim the first X items, this is your non heuristic algorithm.