Search code examples
randomprocessing

Creating random pixeled lines in Proccesing


I'm trying to make a game and I'm stuck on random level design. Basically, I'm trying to create a line from one edge/corner to another edge/corner while having some randomness to it.

See below image 1 [link broken] and 2 for examples. I'm doing this in processing and every attempt I've tried hasn't yielded proper results. I can get them to populate randomly but not in a line or from edge to edge. I'm trying to do this on a 16 x 16 grid by the way. Any ideas or help would be greatly appreciated thanks!

Image 2:

enter image description here


Solution

  • Based on your description, the challenge is in having a connected line from top to bottom with a bit of randomness driving left/right direction.

    There are multiple options.

    Here's a basic idea that comes to mind:

    • pick a starting x position: left's say right down the middle
    • for each row from 0 to 15 (for 16 px level)
      • pick a random between 3 numbers:
        • if it's the 1st go left (x decrements)
        • if it's the 2nd go right (x increments)
        • if it's the 3rd: ignore: it means the line will go straight down for this iteration

    Here's a basic sketch that illustrates this using PImage to visualise the data:

    void setup(){
      size(160, 160);
      noSmooth();
      
      int levelSize = 16;
      
      PImage level = createImage(levelSize, levelSize, RGB);
      level.loadPixels();
      java.util.Arrays.fill(level.pixels, color(255));
      
      int x = levelSize / 2;
      for(int y = 0 ; y < levelSize; y++){
        int randomDirection = (int)random(3);
        if(randomDirection == 1) x--;
        if(randomDirection == 2) x++;
        // if randomDirection is 0 ignore as we don't change x -> just go down
        // constrain to valid pixel
        x = constrain(x, 0, levelSize - 1);
        // render dot
        level.pixels[x + y * levelSize] = color(0);
      }
      
      level.updatePixels();
      
      // render result;
      image(level, 0, 0, width, height);
      fill(127);
      text("click to reset", 10, 15);
    }
    
    // hacky reset
    void draw(){}
    void mousePressed(){
      setup();
    }
    

    The logic is be pretty plain above, but free to replace random(3) with other options (perhaps throwing dice to determine direction or exploring other psuedo-random number generators (PRNGs) such as randomGaussian(), noise() (and related functions), etc.)

    Here's a p5.js version of the above:

    let levelSize = 16;
    let numBlocks = levelSize * levelSize;
    let level = new Array(numBlocks);
    
    function setup() {
      createCanvas(320, 320);
      
      level.fill(0);
      let x = floor(levelSize / 2);
      for(let y = 0 ; y < levelSize; y++){
        let randomDirection = floor(random(3));
        if(randomDirection === 1) x--;
        if(randomDirection === 2) x++;
        // if randomDirection is 0 ignore as we don't change x -> just go down
        // constrain to valid pixel
        x = constrain(x, 0, levelSize - 1);
        // render dot
        level[x + y * levelSize] = 1;
      }
      
      // optional: print to console
      // prettyPrintLevel(level, levelSize, numBlocks); 
    }
    
    function draw() {
      background(255);
      // visualise
      for(let i = 0 ; i < numBlocks; i++){
        let x = i % levelSize;
        let y = floor(i / levelSize);
        fill(level[i] == 1 ? color(0) : color(255));
        rect(x * 20, y * 20, 20, 20);
      }
    }
    
    function prettyPrintLevel(level, levelSize, numBlocks){
      for(let i = 0; i < numBlocks; i+= levelSize){
        print(level.slice(i, i + levelSize));
      }
    }
    
    function mousePressed(){
      setup(); 
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>

    The data is a structured a 1D array in both examples, however, if it makes it easier it could easily be a 2D array. At this stage of development, whatever is the simplest, most readable option is the way to go.