Bouncing Ball, a simple Android example
in
Android Processing
•
1 year ago
I have just created a very simple Android version of my `Bouncing Ball' sketch: a little ball bounces around your phone's screen, move it with your finger or by moving your phone.
This is a trivial example of course, based on information from the Wiki and this forum. However, seeing the complete code of such an example might help the absolute beginner (i.e. someone like me).
The app is on the market (free and no ads of course) here:
https://play.google.com/store/apps/details?id=processing.test.bouncingball
The source code is available below or at
http://www.gwoptics.org/processing/android/BouncingBall/
Andreas
- /*
- * Bouncing Ball, a simple example for an Android app made with
- * This app has been tested with Processing 2.05a, Android SDK 17
- * on a Nexus 1 device. Andreas Freise 27.03.2012
- */
- import ketai.sensors.*;
- KetaiSensor sensor;
- float accelerometerX, accelerometerY;
- // some global variables to simplify matters
- boolean rest;
- boolean showinfo;
- boolean screenpressed;
- float fps=60; // frames per second for frameRate() command
- Ball ball;
- void setup()
- {
- size(screenWidth, screenHeight, P3D);
- orientation(LANDSCAPE);
- frameRate(fps); // set framerate explicitly
- ball = new Ball(screenWidth/2.0, screenHeight/2.0);
- // init global variables
- rest=false;
- screenpressed=false;
- showinfo=false;
- // for text output we might need to set some text properties
- textAlign(CENTER, CENTER);
- textSize(36);
- }
- void draw()
- {
- background(0);
- ball.move();
- ball.display();
- if (showinfo) {
- pushStyle();
- fill(200);
- text("Bouncing Ball: \n" +
- "A simple example app made with Processing\n" +
- "See http://www.gwoptics.org for more!", screenWidth/2.0, screenHeight/2.0);
- popStyle();
- }
- // if the phone has been shaken,
- // wake up the ball
- if (accelerometerX*accelerometerX+accelerometerY* accelerometerY>12*12) {
- rest=false;
- }
- }
- /*
- * Read the touch events to simply know when a finger is
- * on the screen or not.
- */
- public boolean surfaceTouchEvent(MotionEvent me) {
- final int action = me.getAction() & MotionEvent.ACTION_MASK;
- if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN)
- {
- rest=false; // if screen has been pressed, wake up ball
- screenpressed=true;
- ball.reset(mouseX, mouseY, 0, 0); // set ball position to finger
- }
- else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP)
- {
- screenpressed=false;
- ball.reset(mouseX, mouseY, 2*(mouseX-pmouseX), 2*(mouseY-pmouseY)); // throw ball!
- }
- return super.surfaceTouchEvent(me);
- }
- /* Read accelerometer data and set two gloabal variables */
- void onAccelerometerEvent(float x, float y, float z)
- {
- accelerometerX = x;
- accelerometerY = y;
- }
- /* Check for MENU button */
- void keyPressed() {
- if (key == CODED) {
- if (keyCode == MENU) {
- if (showinfo) {
- showinfo=false;
- }
- else {
- showinfo=true;
- }
- keyCode=1;
- }
- }
- }
- /* Override the parent (super) Activity class:
- * States onCreate(), onStart(), and onStop() aren't called by the sketch.
- * Processing is entered at onResume() and exits at onPause()
- */
- public void onResume(){
- super.onResume();
- sensor = new KetaiSensor(this); // init sensors
- sensor.start(); // start sensors
- }
- public void onPause() {
- sensor.stop(); // stop sensors when skecht is paussed/quit
- super.onPause();
- }
And the Ball class:
- public class Ball
- {
- // some local variables of the ball
- float x;
- float y;
- float xold;
- float yold;
- float xspeed;
- float yspeed;
- float phi;
- float phispeed;
- float gravity;
- float friction;
- float phifriction;
- float wallfriction;
- float slowing;
- float reverseSpeed;
- float slowSpeed;
- PImage ball;
- float xmin;
- float ymin;
- float xmax;
- float ymax;
- float phiscale;
- Ball(float tempX, float tempY)
- {
- rest = false;
- x = tempX;
- y = tempY;
- xspeed = 0;
- yspeed = 0;
- phi = 0;
- phispeed = 0;
- slowing=0.0;
- gravity = 0.6*30.0/fps;
- friction = 0.98;
- phifriction = 0.99;
- wallfriction=0.5;
- reverseSpeed = -0.98;
- slowSpeed = 0.98;
- ball=loadImage("ball.png");
- xmin = 0;
- ymin = 0;
- xmax = width-ball.width;
- ymax = height-ball.height;
- phiscale =2.0/(ball.height);
- }
- void reset(float newX, float newY, float newXspeed, float newYspeed)
- {
- x=newX;
- y=newY;
- xspeed=newXspeed;
- yspeed=newYspeed;
- xold=x-xspeed;
- yold=y-yspeed;
- }
- void move()
- {
- /* if ball is not at rest, check for motion and collisions */
- if (!rest && !screenpressed)
- {
- xold=x;
- yold=y;
- y=y+yspeed;
- x=x+xspeed;
- phi=phi+phispeed;
- if (y >= ymax)
- {
- yspeed = yspeed * reverseSpeed;
- xspeed = xspeed * slowSpeed;
- y = ymax;
- }
- if (y <= ymin)
- {
- yspeed = yspeed * reverseSpeed;
- xspeed = xspeed * slowSpeed;
- y = ymin;
- }
- if (x >= xmax)
- {
- xspeed = xspeed * reverseSpeed;
- yspeed = yspeed * slowSpeed;
- x = xmax;
- }
- if (x <= xmin)
- {
- xspeed = xspeed * reverseSpeed;
- yspeed = yspeed * slowSpeed;
- x = xmin;
- }
- /* change speed due to acceleration */
- xspeed=xspeed+gravity * accelerometerY;
- yspeed=yspeed+gravity * accelerometerX;
- /* apply frcition */
- xspeed=friction*xspeed;
- yspeed=friction*yspeed;
- /* if we are in contact with a wall, set rotational speed */
- if (y >= ymax)
- {
- phispeed=wall_speed(phispeed, x-xold);
- }
- if (y <= ymin)
- {
- phispeed=wall_speed(phispeed, -1.0*(x-xold));
- }
- if (x >= xmax)
- {
- phispeed=wall_speed(phispeed, -1.0*(y-yold));
- }
- if (x <= xmin)
- {
- phispeed=wall_speed(phispeed, y-yold);
- }
- phispeed=phifriction*phispeed;
- /* check if ball is still moving */
- if ( y==yold && x==xold && phispeed<1)
- {
- slowing=slowing+1;
- }
- else
- {
- slowing=0.0;
- }
- /* wait roughly 2 seconds before setting ball to rest */
- if (slowing>2*fps) {
- rest=true;
- slowing=0.0;
- }
- }
- else {
- if (screenpressed) {
- x=mouseX;
- y=mouseY;
- }
- }
- }
- void display()
- {
- pushStyle();
- pushMatrix();
- stroke(255);
- float offsetX=x+ball.width/2;
- float offsetY=y+ball.height/2;
- translate(offsetX, offsetY);
- rotate(phi);
- translate(-offsetX, -offsetY);
- image(ball, x, y);
- popMatrix();
- popStyle();
- }
- float wall_speed(float oldphispeed, float speed2) {
- return wallfriction*oldphispeed+(1-wallfriction)*speed2*phiscale;
- }
- }
1