// constants float speed = 2; float g = .75; //arbitrary--looks good float leftwall = -200; float rightwall = 200; float backwall = -100; float frontwall = 100; float yheight = 20; float rest = 15000; //used to reset game after pause with no arrow keys float fr = 12; //frame rate float tpf = 1/fr; //used to calculate time in motion float sr = 10; //sphere radius float rd = PI/12; //variables that actually vary float oldmouseX =0; float oldmouseY =0; float xd = 0; float yd = 0; float zd = 0; float xdold = 0; float zdold = 0; float yda = 0; float origxrot = -PI/6; //so viewer has good view float origzrot = 0; float xrot = origxrot; float zrot = origzrot; float xpos = 0; float ypos = (-yheight); float zpos = 0; float last; float elapsed = 0; //time in motion PFont myfont; void setup() { size(1000,600,P3D); frameRate(fr); last = millis(); myfont = loadFont("Pedro-Regular-28.vlw"); //font has been created and added to data folder textFont(myfont); } void draw() { background(255); fill(250,0,250); text(" Use arrows to tilt board.",30,70); text(" Time in motion: " + nice(elapsed)+" secs.",width/3,70); text(" Game will re-set after a pause.",2*width/3,70); translate(width/2,height/2); if ((millis()-last)>rest) { xrot=origxrot; zrot=origzrot; xpos = 0; zpos = 0; ypos = (-yheight); xd = 0; zd = 0; yd = 0; yda = 0; elapsed = 0; } rotateZ(zrot); rotateX(xrot); fill(100,0,200); stroke(0); box(rightwall-leftwall, yheight, frontwall-backwall); moveball(); translate(xpos, ypos, zpos); stroke(255,0,0); sphere(sr); } void moveball() { //determines x and z deltas from angle of board //accelerates even if same angle zd = .5*(speed*sin(origxrot-xrot)+zdold)*(1+g); xd = .5*(speed*sin(zrot-origzrot)+xdold)*(1+g); //println(xd); zdold = zd; xdold = xd; if (yda>0) { //if moving down, continue and accelerate yda+=g; yd = yda*cos(zrot)*cos(xrot); xd = yda*sin(zrot); zd = -yda*cos(zrot)*sin(xrot); ypos +=yd; xpos +=xd; zpos +=zd; } else if ((abs(xd)+abs(zd))>.1) { //if xd and/or yd essentially non-zero // change in position elapsed +=tpf; xpos +=xd; zpos +=zd; //check for falling off board if (xpos>(rightwall+sr)) { xd = 0; zd = 0; yda = 1; } if (xpos<(leftwall-sr)) { xd = 0; zd = 0; yda = 1; } if (zpos>(frontwall+sr)) { xd = 0; zd = 0; yda = 1; } if (zpos<(backwall-sr)) { xd = 0; zd = 0; yda = 1; } } } void keyPressed() { if (keyCode==LEFT) { zrot -= rd; } if (keyCode==RIGHT) { zrot += rd; } if (keyCode==UP) { xrot += rd; } if (keyCode==DOWN) { xrot -= rd; } last = millis(); } String nice(float f) { //returns string with at most 2 characters past decimal point String s = str(f); int p = s.indexOf("."); int sl = min(p+3,s.length()); return s.substring(0,sl); }