Running background in P5

Viewed 2451

Im trying to make a side-scroller game and I got stuck on the running background part. I've looked for solutions and I've discovered some , but they were using javascript not the p5 library.
I started from the tutorials found on The Coding Train , and looked over all the examples and references on their site.

Although I could avoid this by using something else, just for the sake of it being here in case someone gets stuck on the same issue, could anyone offer a solution to this in p5? Disclaimer: Im a total noob p5.js.

later edit : By running background i mean moving Background image in a loop from left to right

2 Answers

Honestly, from the discussion we had in the comments, it sounds like you're overthinking it.

The general approach to animation (that tutorial is for Processing, but the principles apply to P5.js as well) is as follows:

  • Step 1: Create a set of variables that represent the state of your scene.
  • Step 2: Use those variables to draw your scene every frame.
  • Step 3: Change those variables over time to make your scene move.

You already know what to do: load an image that contains your background, then draw that image, and move it a little bit each frame.

You've said you want to call the background() function instead of the image() function, which doesn't make a ton of sense. The background() function is not any more efficient than the image() function. In fact, the background() function just calls the image() function for you!

From the P5.js source:

p5.prototype.background = function() {
  if (arguments[0] instanceof p5.Image) {
    this.image(arguments[0], 0, 0, this.width, this.height);
  } else {
    this._renderer.background.apply(this._renderer, arguments);
  }
  return this;
};

P5.js simply checks whether the argument is an image, and if so, calls the image() function for you. So it doesn't really make sense to say that using the image() function is "less efficient" than using the background() function.

Taking a step back, you should really avoid thinking about these kinds of micro-optimizations until you A: understand the problem and B: actually have a problem. Don't make assumptions about "efficiency" until you've actually measured your code for performance.

Anyway, back to your question. You also said that you're loading the image twice, which you shouldn't have to do. You can just load the image once (make sure you do that in the setup() function and not the draw() function, and then draw that image twice:

var img;
function preload() {
  img = loadImage("image.jpg");
}
function setup() {
  image(img, 0, 0);
  image(img, 100, 100);
}

And since you can draw two images, you'd then just draw them next to each other. Here's an example using colored rectangles to show the approach more clearly:

var offsetX = 0;

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

function draw() { 
  background(0);
 
  fill(0, 255, 0);
  rect(offsetX, 0, width, height);
 
  fill(0, 0, 255);
  rect(offsetX + width, 0, width, height);
 
  offsetX--;
  if(offsetX <= -width){
  offsetX = 0; 
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.14/p5.js"></script>

There are other ways to do it, like creating an image that contains the wrapping itself. But the general approach is pretty much the same.

If you're still stuck, please try to break your problem down into smaller pieces like I've done here. For example, notice that I created a simple sketch that deals with images, and another simple sketch that deals with moving rectangles. Then if you get stuck, please post a MCVE in a new question post and we'll go from there. Good luck.

Maybe it is a late answer.. but you can make the environment 3D and then move the camera.

Docs: https://p5js.org/reference/#/p5/camera

Example:

function setup() {
   createCanvas(windowWidth - 200, windowHeight - 200, WEBGL);
   background(175);
   frameRate(30);
}

function draw() {
   background(175);

   //move the camera Xaxis when mouse is moved
   let camX = map(mouseX, 0, width, 0,width);
   camera(camX, 0, (height/2.0) / tan(PI*30.0 / 180.0), camX, 0, 0, 0, 1, 0);

   normalMaterial();
   noStroke();
   ambientLight(251,45,43);
   box(100, 100, 50);
   ang += 0.3;
   rotateY(ang * 0.03);
}

Keep calm and Happy Coding!

Related