LWN.net Logo

A bouncing ball program in Processing

If your web browser supports WebGL, then you should be able to run the Processing sketch whose source code is shown below by clicking in the canvas. (If you're unsure whether your browser supports WebGL, consulting http://doesmybrowsersupportwebgl.com/ and http://caniuse.com/webgl may help answer the question.)

Source code

// bouncing_ball.pde -- a simple bouncing ball in a box
// (C) 2012 Michael Kerrisk, licensed GNU GPLv2 or later.

float xpos, ypos, zpos;
int radius;
float xadj = 3.0, yadj = 2.0, zadj = -4.0;
final int MAX_DEPTH = 1500;
final int MIN_DEPTH = 100;

void drawFrame() {
  background(0.4);
  
  // Draw rear wall
  
  stroke(0);
  strokeWeight(2);
  translate(0, 0, -MAX_DEPTH);
  fill(0.3);
  rect(0, 0, width, height);
  
  // Draw (transparent) front wall
  
  translate(0, 0, MAX_DEPTH - MIN_DEPTH);
  noFill();
  rect(0, 0, width, height);
  translate(0, 0, MIN_DEPTH);
  
  // Draw lines connecting corners of front and rear walls
  
  line(0, 0, -MIN_DEPTH, 0, 0, -MAX_DEPTH);
  line(0, height, -MIN_DEPTH, 0, height, -MAX_DEPTH);
  line(width, 0, -MIN_DEPTH, width, 0, -MAX_DEPTH);
  line(width, height, -MIN_DEPTH, width, height, -MAX_DEPTH);
  
  noStroke();
}

void setup() { 
  size(500, 400, P3D);
  radius = height / 5;   // Set ball size based on built-in variable 'height'
  frameRate(50);
  colorMode(RGB, 1);     // Color scale is 0 to 1
  
  // Set initial ball position
  
  xpos = radius; 
  ypos = height / 3;
  zpos = -MIN_DEPTH;
  
  noLoop();              // Dont start animation until mouse is clicked
}

void mouseClicked() {
  loop();                // Start animation on (first) mouse click
}

int bounce(float adj) {  // Bounce off a wall, injecting some randomness
  final float adjust = 0.5;
  final float MAX_ADJ = 10.0;    // Limit ball velocity each axis
  
  adj = -adj + random(-adjust, adjust);
  adj = min(MAX_ADJ, max(adj, -MAX_ADJ));

  return adj;
}

void draw() {
  drawFrame();

  // Update ball position
  
  xpos += xadj;
  ypos += yadj;
  zpos += zadj;
   
  // Have we bounced off a wall?
  
  if (xpos < radius || xpos > width - radius)
    xadj = bounce(xadj);
  if (ypos < radius || ypos > height - radius)
    yadj = bounce(yadj);
  if (zpos < - (MAX_DEPTH - radius) || zpos > -radius)
    zadj = bounce(zadj);
  
  // Draw circle at current XYZ position
  
  translate(xpos, ypos, zpos);
  //println((int) xpos + " " + (int) ypos + " " + (int) zpos);
  fill(0.5, 1.0, 0.5);
  ellipse(0, 0, radius, radius);
}

(Log in to post comments)

Copyright © 2012, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds