Sliding matrix of circles, can't generate or fill new row of circles in 2D array


#1

Hi am creating a 2D array of circles, which slides down every second.

Right now if the height of the circles is bigger than the sketch height, it resets the height of the circles to the top.

So, i generate once a grid and i just slide it, cyclically.

Now, i want it not be bee just a grid repeating itself. I want it that it generates a new row at the beggining everytime, so that it never repeats itself…

But i cant get it to work , i have tried many things but none work…

Any ideas of how can i get this behaviour?

The code works this way:

There is a circle factory function, a line factory functionm and i grid factory function.

The grid factory calls the line factory and this one calls the circle one.

Then on setup i have a setInterval function that, every seconds calls the slide method on the circle object. and if its height is bigger than the height it resets the height to the top.

Here is the codepen:

   let canvasHeight = 500
    let row
    let grid
    let amtOfHorizontalCircles = 15
    let linesAmt = 50
    let ySpacing = 10
    let lineSpacing = canvasHeight/linesAmt 
    
    const createCircle = (fillColor, x, y, maxRadius) => {
    let xpos = x
    let ypos = y
     return {
       xpos,
       ypos,
       display() {
         noStroke()
         fill(fillColor)
         ellipse(xpos, ypos, maxRadius, maxRadius)
       },
       slide(amt) {
         if( ypos >  linesAmt * lineSpacing ) {
           ypos = lineSpacing
         }
         ypos += amt
       },
     }
    }
    
    const createLine = (arr, amt,x, y) => {
      if( arr.length < amt) {
         arr.push(createCircle(`rgba(205, 64, 24, ${Math.random().toFixed(1)})`, x,  y, Math.random()*9))
         createLine(arr, amt, x+=width/amtOfHorizontalCircles, y)
      }
      return arr
    }
    
    
    const createGrid = (arr, linesAmt, y) => {
      if( arr.length < linesAmt) {
        arr.push(createLine([], amtOfHorizontalCircles, 0, y))
        createGrid(arr, linesAmt, y += lineSpacing)} 
      return arr
    }
    
    const slideRow = () => {
      // shits heights, and moves y's to begginig of they are higher tha Height
      grid.forEach( (line) => {
        line.forEach( x => {
        x.slide(ySpacing)
        })
      })
      //grid[grid.length -1] = createLine([], amtOfHorizontalCircles, 0, 0)
    }
    
    
    function setup () {
      createCanvas(300, canvasHeight)
      background("#140c28")
      grid = createGrid([], linesAmt, 10)
      setInterval(slideRow, 1000)
    }
    
    function draw () {
      background("#140c28")
      grid.forEach( row => {
        row.forEach( x => {
          x.display()
        })
      })
    }

#2

Use Array::pop() in order to remove the last row[] 1D array from your grid[] 2D array:

Create a new row[] 1D array by invoking createLine().
Then use Array::unshift() in order to place it at the head of your grid[] 2D array:


#3

Just a bonus tip: You can safely remove the properties xpos & ypos from your returning object{} above. :wastebasket:

Pretty much b/c object{} properties aren’t the same as variables (parameters as well)! :flushed:

Thus reassigning another value to the closure variable xpos won’t reflect on property xpos and vice-versa. :left_right_arrow:

const createCircle = (fillColor, x, y, maxRadius) => {
let xpos = x
let ypos = y

return {
   display() {
     noStroke()
     fill(fillColor)
     ellipse(xpos, ypos, maxRadius, maxRadius)
   },

#4

Thanks guys the answer was given to me at stackoverflow: https://stackoverflow.com/questions/53469544/p5js-sliding-matrix-of-circles-cant-generate-or-fill-new-row-of-circles-in-2d/53469824?noredirect=1#comment93810310_53469824