P5js: why is my bg framerate not refreshing properly?

Viewed 102

I have 2 sets of code in here. One is the simple bounce off code. The other is a function. I've tried to make it a function but it doesn't seem to be working properly.

  1. The bg framerate doesn't clear in the sense that a string of balls show rather than a ball bouncing and animating.

  2. if(this.y_pos > 400) this condition doesn't seem to be working even tho it works when it is drawn in the draw function.

        var sketch = function (p) {
          with(p) {

            p.setup = function() {
              createCanvas(800, 600);
                
              //    x_pos = 799;
              //    y_pos = 100;
           
              //    spdx = -random(5,10);
              //    spdy = random(12,17);
            };
        
            p.draw = function() {
              background(0);
              
              //    fill(255);
              //    ellipse(x_pos,y_pos,50);
              //    x_pos += spdx;
              //    y_pos += spdy;
                 
              //    if(y_pos > 400)
              //    {
              //        spdy *= -1;
              //    }
              
              // for( var i = 0; i < 10; i++)
              
              avalance(799, 100, random(5,10), random(12,17));
            };

            function avalance(x, y, spdx, spdy)
            {
                this.x_pos = x;
                this.y_pos = y;
                this.spdx = spdx;
                this.spdy = spdy;
                
                this.x_pos = 799;
                this.y_pos = 100;
                
                this.spdx = 1;
                this.spdy = 1;
                
                this.movement = function()
                {
                    this.x_pos += -spdx;
                    this.y_pos += spdy;
                    
                    if(this.y_pos > 400)
                    {
                        this.spdy *= -1;
                    }
                }
                
                this.draw = function()
                {
                    this.movement();
                    this.drawnRox();
                }
                
                this.drawnRox = function()
                {
                    fill(255);
                    ellipse(this.x_pos,this.y_pos,50);
                }
                
            }


            
          }
        };
        
        let node = document.createElement('div');
        window.document.getElementById('p5-container').appendChild(node);
        new p5(sketch, node);
    body {
      background-color:#efefef;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
    <div id="p5-container"></div>

2 Answers

Let's address both issues:

  1. The draw() function is called for each new frame and in it you call avalance which creates a new ball. To fix that you need to
  • Create a global variable let ball; out of setup() and draw() so that you can reuse that later;
  • In setup create a new ball and assign it to your ball variable: ball = new avalance(799, 100, random(5,10), random(12,17));
  • In draw() you want to update the ball and that's what its own draw() function does (I would advise renaming it update() for example, to avoid confusion with the p5 specific draw() function). So you just need to call ball.draw() in draw().

This creates a ball which moves but still don't respect your 400px limit.

  1. The issue is that in movement() you add spdx and spdy to the position but when the ball crosses the limit you update this.spdy, so you need to update the function with this code:

    this.x_pos += -this.spdx; this.y_pos += this.spdy;

And you should be good! Here is a code pend with your code working as you intend.

Also as a bonus advise: You probably want to use some p5.Vector objects to store positions, speeds and accelerations it really makes your code easier to read and to use. You could also rename your function Avalance (capital A) to show that you actually use a class and that this function shouldn't be called without new.

As @statox suggested, do new avalance(799, 100, random(5,10), random(12,17)) in the setup() section and call draw of the ball in draw() section.

You can test the code below by clicking "Run code snippet".

        var sketch = function (p) {
          with(p) {

            var ball;

            p.setup = function() {
              createCanvas(800, 600);
                
              ball = new avalance(799, 100, random(5,10), random(12,17));
            };
        
            p.draw = function() {
              background(0);

              ball.draw();
            };

            function avalance(x, y, spdx, spdy)
            {
                
                function movement ()
                {
                    x += -spdx;
                    y += spdy;
                    
                    if (y > height || y < 0)
                    {
                        spdy *= -1;
                    }
                    if (x > width || x < 0)
                    {
                        spdx *= -1;
                    }
                }
                
                this.draw = function()
                {
                    movement();
                    drawnRox();
                }
                
                function drawnRox ()
                {
                    fill(255);
                    ellipse(x,y,50);
                }
                
            }


            
          }
        };
        
        let node = document.createElement('div');
        window.document.getElementById('p5-container').appendChild(node);
        new p5(sketch, node);
    body {
      background-color:#efefef;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
    <div id="p5-container"></div>

Related