06MA4010991AP
Computer Game Design
Week 2
Class Concept (Object Oriented Programming)
Version 1
Basic version of ball movement.


float x; //x position of the ball float y; //y position of the ball float xSpeed; //x speed of the ball float ySpeed; //y speed of the ball void setup() { size(320,240); x = random(0,width); y = random(0,height); xSpeed = random(-5,5); ySpeed = random(-5,5); smooth(); } void draw() { background(0); if(x < 0) //if hit left wall xSpeed = abs(xSpeed); if(x > width) //if hit right wall xSpeed = -abs(xSpeed); if(y < 0) //if hit upper wall ySpeed = abs(ySpeed); if(y > height) //if hit lower wall ySpeed = -abs(ySpeed); x += xSpeed; //update position y += ySpeed; //update position ellipse(x,y,40,40); } |
Version 2
Using array to implement many balls moving using same rule.


float[] x; //array of x float[] y; //array of y float[] xSpeed; //array of x speed float[] ySpeed; //array of y speed int numBalls; //number of balls void setup() { size(320,240); numBalls = 100; x = new float[numBalls]; //initialize array y = new float[numBalls]; //initialize array xSpeed = new float[numBalls]; //initialize array ySpeed = new float[numBalls]; //initialize array for(int i=0;i<numBalls;i++) //initialize values { x[i] = random(0,width); y[i] = random(0,height); xSpeed[i] = random(-5,5); ySpeed[i] = random(-5,5); } smooth(); } void draw() { background(0); for(int i=0;i<numBalls;i++) //draw all balls { if(x[i] < 0) xSpeed[i] = abs(xSpeed[i]); if(x[i] > width) xSpeed[i] = -abs(xSpeed[i]); if(y[i] < 0) ySpeed[i] = abs(ySpeed[i]); if(y[i] > height) ySpeed[i] = -abs(ySpeed[i]); x[i] += xSpeed[i]; y[i] += ySpeed[i]; ellipse(x[i],y[i],40,40); } } |
Version 3
Create a class of Ball, and implement attributes into class.


Ball[] balls; //array of balls int numBalls; //number of balls void setup() { size(320,240); numBalls = 100; balls = new Ball[numBalls]; //initialize array for(int i=0;i<numBalls;i++) //initialize each element (Ball) { balls[i] = new Ball(); } smooth(); } void draw() { background(0); for(int i=0;i<numBalls;i++) //update balls { balls[i].draw(); } } |
class Ball //class of ball { float x; //x position float y; //y position float xSpeed; //x speed float ySpeed; //y speed color col; //color float ballSize; //ball size Ball() //constructor (initialize variables) { x = random(0,width); y = random(0,height); xSpeed = random(-5,5); ySpeed = random(-5,5); col = color(random(255),random(255),ra ndom(255)); ballSize = random(20,40); } void draw() //custom function { if(x < 0) xSpeed = abs(xSpeed); if(x > width) xSpeed = -abs(xSpeed); if(y < 0) ySpeed = abs(ySpeed); if(y > height) ySpeed = -abs(ySpeed); x += xSpeed; y += ySpeed; noStroke(); fill(col); ellipse(x,y,ballSize,ballSize); } } |
Version 4
Using another path and microphone as input. FFT(Fast Fourier transform) converts analog sound into spectrum of volume in different frequencies, and here we use an average of the volume as input.


import krister.Ess.*; //import ess library Ball[] balls; int numBalls; AudioInput myInput; //microphone input FFT myFFT; //fft analysis float micLevel; //sound level void setup() { size(320,240); Ess.start(this); //initialize ess myInput=new AudioInput(); //initalize microphone myInput.start(); //start microphone myFFT=new FFT(); //initialize fft numBalls = 50; balls = new Ball[numBalls]; for(int i=0;i<numBalls;i++) { balls[i] = new Ball(); } smooth(); } void draw() { background(0); micLevel = myFFT.getLevel(myInput) * 50; //analyze sound level and scale up for(int i=0;i<numBalls;i++) { balls[i].draw(); } } |
class Ball { float x; float y; float xSpeed; float ySpeed; color col; float ballSize; float xFactor; //acceleration of X float yFactor; //acceleration of Y Ball() { x = random(0,width); y = random(0,height); xSpeed = random(-5,5); ySpeed = random(-5,5); col = color(random(255),random(255),ra ndom(255)); ballSize = random(20,60); xFactor = random(0.001,0.02); yFactor = random(0.001,0.02); } void draw() { //accelerate to center, affect by xFactor and yFactor xSpeed += (width/2-x) * xFactor; ySpeed += (height/2-y) * yFactor; //let mic level affect speed xSpeed += random(-micLevel,micLevel); //reference to sound level ySpeed += random(-micLevel,micLevel); //reference to sound level //reduce speed (friction) xSpeed *= 0.98; ySpeed *= 0.98; //update ball position x += xSpeed; y += ySpeed; noStroke(); fill(col); ellipse(x,y,ballSize,ballSize); } } |
Version 5
Make use of OpenGL's addictive blending function to create glowing visual effect, and use sound file feed for input.


import processing.opengl.*; //import processing opengl import javax.media.opengl.*; //import java opengl (for extra functions) import krister.Ess.*; Ball[] balls; int numBalls; AudioInput myInput; AudioChannel myChannel; //using sound file as input feed FFT myFFT; PGraphicsOpenGL pgl; //opengl renderer for processing GL gl; //opengl renderer in java PImage flare; //flare image float micLevel; void setup() { size(320,240,OPENGL); Ess.start(this); //myInput=new AudioInput(); //myInput.start(); myChannel=new AudioChannel("song4.aif"); //load music file myChannel.play(Ess.FOREVER); //loop music myFFT=new FFT(); flare = loadImage("flare.png"); //load image numBalls = 200; balls = new Ball[numBalls]; for(int i=0;i<numBalls;i++) { balls[i] = new Ball(); } smooth(); } void draw() { background(0); pgl = (PGraphicsOpenGL) g; gl = pgl.gl; pgl.beginGL(); //start controlling java opengl gl.glEnable(GL.GL_BLEND); // Turn on the blend mode gl.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE); // Define the blend mode scale(2); //compensate scale error micLevel = myFFT.getLevel(myChannel) *20; //analyze sound channel instead of mic input println(micLevel); for(int i=0;i<numBalls;i++) { balls[i].draw(); } pgl.endGL(); //stop controlling java opengl } |
class Ball { float x; float y; float xSpeed; float ySpeed; color col; float ballSize; float xFactor; float yFactor; Ball() { x = random(0,width); y = random(0,height); xSpeed = random(-5,5); ySpeed = random(-5,5); colorMode(HSB); //using HSB color space col = color(random(255),255,255); //get high satuation colors ballSize = random(20,60); xFactor = random(0.01,0.04); yFactor = random(0.01,0.04); } void draw() { xSpeed += (width/2-x) * xFactor; ySpeed += (height/2-y) * yFactor; xSpeed += random(-micLevel,micLevel); ySpeed += random(-micLevel,micLevel); xSpeed *= 0.9; ySpeed *= 0.9; x += xSpeed; y += ySpeed; noStroke(); //fill(col); //ellipse(x,y,ballSize,ballSize); tint(col); image(flare,x- ballSize/2,y - ballSize/2,ballSize,ballSize); } } |
Version 6
Create more forms of particles and using ArrayList for a variable number of particle.


import processing.opengl.*; import javax.media.opengl.*; import krister.Ess.*; ArrayList balls; //using ArrayList instead of array int numBalls; AudioInput myInput; AudioChannel myChannel; FFT myFFT; PFont font; //font PGraphicsOpenGL pgl; GL gl; PImage flare; PImage p1; //CD cover image float micLevel; void setup() { size(320,240,OPENGL); Ess.start(this); myChannel=new AudioChannel("song4.aif"); myChannel.play(Ess.FOREVER); font = loadFont("font.vlw"); //load font myFFT=new FFT(); flare = loadImage("flare.png"); p1 = loadImage("p2.png"); //load cd cover image numBalls = 200; balls = new ArrayList(); //initialize ArrayList smooth(); } void draw() { background(0); pgl = (PGraphicsOpenGL) g; gl = pgl.gl; pgl.beginGL(); gl.glEnable(GL.GL_BLEND); gl.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE); scale(2); micLevel = myFFT.getLevel(myChannel) *30; for(int j=0;j<micLevel/100;j++) //add balls into array list { balls.add(new Ball()); //initialize a ball and put into array list } for(int i=0;i<balls.size();i++) //update balls in array list { Ball b = (Ball)balls.get(i); //fetch the ball from list if(b.life>0) b.draw(); //update ball else { balls.remove(i); //remove ball from list i--; //adjust the position of counter } } pgl.endGL(); } |
class Ball { float x; float y; float xSpeed; float ySpeed; color col; float ballSize; float xFactor; float yFactor; int life; //life of ball (number of frames exist in canvas) int form; //form of ball (different looking) Ball() { x = random(0,width); y = random(0,height); xSpeed = random(-5,5); ySpeed = random(-5,5); colorMode(HSB); col = color(random(255),255,255); ballSize = random(50,100); xFactor = random(0.01,0.04); yFactor = random(0.01,0.04); life = (int) random(30,70); form = (int) random(3); //random form 3 modes } void draw() { life--; xSpeed += (width/2-x) * xFactor; ySpeed += (height/2-y) * yFactor; xSpeed += random(-micLevel,micLevel); ySpeed += random(-micLevel,micLevel); xSpeed *= 0.9; ySpeed *= 0.9; x += xSpeed; y += ySpeed; noStroke(); if(form == 0) //mode 0 for image of cd cover { tint(col); image(p1,x- ballSize/2,y - ballSize/2,life,life); } else if(form == 1) //mode 1 for flare { tint(col); image(flare,x- ballSize/2,y - ballSize/2,ballSize,ballSize); } else if(form == 2) //mode 2 for text (*) { fill(col); textFont(font); textAlign(CENTER); text("*",x,y); } } } |
Version 7
Convert the sketch into full screen application.

//full screen application script static public void main(String args[]) { PApplet.main(new String[] { "--present","tutor_2_ball_v7" } ); } import processing.opengl.*; import javax.media.opengl.*; import krister.Ess.*; ArrayList balls; int numBalls; AudioInput myInput; AudioChannel myChannel; FFT myFFT; PFont font; PGraphicsOpenGL pgl; GL gl; PImage flare; PImage p1; float micLevel; void setup() { size(screen.width,screen.height,OPENGL); //using computer screen size Ess.start(this); myInput=new AudioInput(); myInput.start(); myChannel=new AudioChannel("song4.aif"); myChannel.play(Ess.FOREVER); font = loadFont("font.vlw"); myFFT=new FFT(); flare = loadImage("flare.png"); p1 = loadImage("p2.png"); numBalls = 200; balls = new ArrayList(); smooth(); } void draw() { background(0); pgl = (PGraphicsOpenGL) g; gl = pgl.gl; pgl.beginGL(); gl.glEnable(GL.GL_BLEND); gl.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE); scale(2); micLevel = myFFT.getLevel(myChannel) *100; for(int j=0;j<micLevel/10;j++) { balls.add(new Ball()); } println(micLevel); for(int i=0;i<balls.size();i++) { Ball b = (Ball)balls.get(i); if(b.life>0) b.draw(); else { balls.remove(i); i--; } } fill(micLevel*20); textFont(font); textAlign(CENTER); text("RADIOHEAD - IN RAINBOWS",width/2,height/2); //display text pgl.endGL(); } |
class Ball { float x; float y; float xSpeed; float ySpeed; color col; float ballSize; float xFactor; float yFactor; int life; int form; Ball() { x = random(0,width); y = random(0,height); xSpeed = random(-5,5); ySpeed = random(-5,5); colorMode(HSB); col = color(random(120,180),255,255); ballSize = random(150,300); xFactor = random(0.01,0.04); yFactor = random(0.01,0.04); life = (int) random(30,70); form = (int) random(3); } void draw() { life--; xSpeed += (width/2-x) * xFactor; ySpeed += (height/2-y) * yFactor; xSpeed += random(-micLevel,micLevel); ySpeed += random(-micLevel,micLevel); xSpeed *= 0.9; ySpeed *= 0.9; x += xSpeed; y += ySpeed; noStroke(); if(form == 0) { tint(col); image(p1,x- ballSize/2,y - ballSize/2,life,life); } else if(form == 1) { tint(col); image(flare,x- ballSize/2,y - ballSize/2,ballSize,ballSize); } else if(form == 2) { fill(col); textFont(font); textAlign(CENTER); text("*",x,y); } } } |
Reference Videos
Murcof - Mir Nodes from Simon on Vimeo.