Need help w/ infinite world w/ random numbers

Hello. So, I am trying to make a program that generates an infinite world where each block has a 50% chance of being either blue or red. The program I have works fine when I move side to side, but when I move up and down the blocks are completely randomized each time (rather than just shifting over). Is there any way I can make it work, or even use a better system? I am a total newbie.

let relCenX=300;
let relCenY=300;
let wKey=false;
let sKey=false;
let aKey=false;
let dKey=false;

function setup() {
	createCanvas(600, 600);
}

function draw() {
	background(100);
	noStroke();
	fill(0);
	rectMode(CORNER);
	rect(0,0,600,600)
	
	if (aKey) {
		relCenX=relCenX-1;
	}
	if (dKey) {
		relCenX=relCenX+1;
	}
	if (sKey) {
		relCenY=relCenY+1;
	}
	if (wKey) {
		relCenY=relCenY-1
	}
	
	let blockBeingCheckedX=round(relCenX/50);
	let blockBeingCheckedY=round(relCenY/50);
	
	for (let i = 0; i < 11; i = i + 1) {
		for (let e = 0; e < 11; e = e + 1) {
			randomSeed((blockBeingCheckedX*184012.32413*blockBeingCheckedY))
			let e2=round(random(1,2))
			if (e2 == 1) {
				fill(255,0,0);
			} else {
				fill(0,0,255);
			}
			rect(50+(50*e)-((((relCenX+25)/50)-floor((relCenX+25)/50))*50),50+(50*i)-((((relCenY+25)/50)-floor((relCenY+25)/50))*50),50,50)
			blockBeingCheckedX=blockBeingCheckedX+1;
		}
		blockBeingCheckedY=blockBeingCheckedY+1;
	}
}

function keyPressed() {
	if (key=='a') {
		aKey=true;
	}
	if (key=='w') {
		wKey=true;
	}
	if (key=='d') {
		dKey=true;
	}
	if (key=='s') {
		sKey=true;
	}
}

function keyReleased() {
	if (key=='a') {
		aKey=false;
	}
	if (key=='w') {
		wKey=false;
	}
	if (key=='d') {
		dKey=false;
	}
	if (key=='s') {
		sKey=false;
	}
}

It doesn’t run for me. I simply get a blank screen under p5.js. You are missing some variable declarations.

Hi @Voleia,

We cannot execute your code, since it is incomplete, leaving some of the variables undefined. That includes aKey, dKey, sKey, and wKey.

I added the variable declarations

try it now, i added the whole thing

Nope. No response from pressing keys. Javagar points out the problem in his post. :+1:

Your code still leaves aKey, dKey, sKey, and wKey undefined.

Perhaps you intended to define those variables here:

let w=false;
let s=false;
let a=false;
let d=false;

Right, I did that by accident due to changing something. I’ll fix tat in the post, but its not what was causing the problem for me.

Thanks. I fixed it in the post, but its not what was causing the problem: just an editing error.

Offhand, it looks like your rect() function is generating the same code for blocks w,s as it does for a,d. You may need another rect() function that takes into account up and down movement from w,s key presses.

Inside the nested loop, you are using randomization to recompute the color of each block. You can do that once at the outset instead in the setup function, and store the block colors in an Array. Then, whenever drawing the world, access the Array to get the color of each block.

Thanks, I’ll try that

Javagar, I need a few million total blocks, which is too much for an array

Hi @Voleia, I tried your sketch, then wanted the edges scrolling more smoothly, so I changed lines 31,32 to

  for (let i = -1; i < 12; i++) {
    for (let e = -1; e < 12; e++) {

and you need to know that i = i + 1; can be simplified to i += 1; (many operators do the same) and then there’s i++;

Please explain how this statement is designed to get us to the necessary place in the random sequence to handle up and down movements through the world:

randomSeed((blockBeingCheckedX*184012.32413*blockBeingCheckedY))

Alternatively, it might be worthwhile to consider using two-dimensions of Perlin noise space to define the colors of the blocks. See noise().

EDIT:

Try out the demo code below. Note that the viewer’s position moves toward the lower right. You can modify the code to use the keys, instead, to control the viewer’s position.

function setup() {
  createCanvas(110, 110);
  frameRate(2);
}

function draw() {
  for (let x = 0; x <= 10; x++) {
    for (let y = 0; y <= 10; y++) {
      if (noise(x + frameCount, y + frameCount) < 0.5) {
        fill(0);
      } else {
        fill(255);
      }
      rect(x * 10, y * 10, 10, 10);
    }
  }
}

Thanks! That works for what I need

Hey, I have another question. Do you know how to make the noise bigger? Like, make each “blob” of noise twice as big or something like that

Is a “blob” of noise simply a block, or is it a cluster of adjacent blocks with the same color?

EDIT:

Assuming that a “blob” of noise is a cluster of adjacent blocks with the same color, you can try this:

function setup() {
  createCanvas(410, 410);
  frameRate(2);
}

function draw() {
  for (let x = 0; x <= 40; x++) {
    for (let y = 0; y <= 40; y++) {
      fill(blockColorMapper(x, y, frameCount, frameCount));
      rect(x * 10, y * 10, 10, 10);
    }
  }
}

function blockColorMapper(x0, y0, xShift, yShift) {
  // x0 -> original x coordinate of block
  // y0 -> original y coordinate of block
  // xShift -> how much to shift x coordinate of block
  // yShift -> how much to shift y coordinate of block
  let blobFactor = 5; // higher values -> bigger blobs of color
      if (noise((x0 + xShift) / blobFactor, (y0 + yShift) / blobFactor) < 0.5) {
        return "red";
      } else {
        return "blue";
      }
}

Note the blobFactor variable. Here’s an image with a blobFactor of 5:

Also see @The_Traveler’s suggested links.

1 Like