Android Open Source - 101AndroidApps Bouncy Ball Game






From Project

Back to project page 101AndroidApps.

License

The source code is released under:

Licenced under the Creative Commons Attribution 4.0 licence. For full text see http://creativecommons.org/licenses/by/4.0/

If you think the Android project 101AndroidApps listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.hulzenga.ioi.android.app_004;
//from ww  w. j  a v a2  s.  c om
import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.SystemClock;

import com.hulzenga.ioi.android.R;
import com.hulzenga.ioi.android.util.open_gl.ColorFunction;
import com.hulzenga.ioi.android.util.open_gl.ColorFunctionFactory;
import com.hulzenga.ioi.android.util.open_gl.engine.NodeController;
import com.hulzenga.ioi.android.util.open_gl.engine.SceneGraph;
import com.hulzenga.ioi.android.util.open_gl.engine.SceneNode;
import com.hulzenga.ioi.android.util.open_gl.geometry.Box;
import com.hulzenga.ioi.android.util.open_gl.geometry.Cylinder;
import com.hulzenga.ioi.android.util.open_gl.geometry.Geometry;
import com.hulzenga.ioi.android.util.open_gl.geometry.Grid;
import com.hulzenga.ioi.android.util.open_gl.geometry.Sphere;
import com.hulzenga.ioi.android.util.open_gl.geometry.Transform;

/**
 * Simulates a ball of unit mass falling from a given start Height and starting speed
 * bouncing elastically on a floor
 */
public class BouncyBallGame implements NodeController {

  private static final long SIMULATION_STEP = 10;

  private static final float GRAVITY = 15.0f;

  private static final float BOUNCE_FACTOR     = 0.90f;
  private static final float BOUNCE_STOP_SPEED = 0.15f;
  private static final float EPSILON           = 0.01f;

  private static final float          BALL_RADIUS       = 0.5f;
  private static final float          BALL_START_HEIGHT = 4.0f;
  private volatile     float          mBallHeight       = BALL_START_HEIGHT;
  private static final float          BALL_START_SPEED  = 0.0f;
  private              float          mBallSpeed        = BALL_START_SPEED;
  private static final float          FLOOR_UP          = 2.3f;
  private static final float          FLOOR_DOWN        = 2.0f;
  private volatile     float          mFloorHeight      = FLOOR_DOWN;
  private static final float          FLOOR_SPEED       = 10.0f;
  private              FLOOR_MOVEMENT mFloorMovement    = FLOOR_MOVEMENT.STOPPED;
  private Thread mSimulationThread;
  private boolean mRunning = false;

  public BouncyBallGame(BouncyBall3dGLSurfaceView bouncyBall3dGLSurfaceView) {
    bouncyBall3dGLSurfaceView.setScene(createScene());
  }

  SceneGraph createScene() {
    SceneGraph sceneGraph = new SceneGraph();

    ColorFunction uniformRed = ColorFunctionFactory.createUniform(1.0f, 0.0f, 0.0f, 1.0f);
    ColorFunction uniformGray = ColorFunctionFactory.createUniform(0.6f, 0.6f, 0.6f, 1.0f);
    ColorFunction dirt = ColorFunctionFactory.createRandomBound(0.35f, 0.45f, 0.35f, 0.45f, 0.1f, 0.15f);

    SceneNode cylinder = new SceneNode(new Cylinder(1.0f, 2 * FLOOR_DOWN, 16), uniformRed);
    cylinder.subscribe(new NodeController() {
      @Override
      public void update(SceneNode node) {node.setTranslation(0.0f, mFloorHeight - FLOOR_DOWN, 0.0f);}
    });
    sceneGraph.addNode(cylinder);

    sceneGraph.addNode(new SceneNode(new Cylinder(1.5f, 2 * FLOOR_DOWN - 0.5f, 16), uniformGray));
    sceneGraph.addNode(new SceneNode(new Cylinder(1.6f, 2 * FLOOR_DOWN - 1.0f, 16), uniformGray));

    Geometry box1Geometry = new Box(4.0f, 2.0f, 0.8f);
    Geometry box2Geometry = new Box(5.0f, 1.6f, 0.6f);
    Geometry box3Geometry = new Box(7.0f, 1.2f, 0.4f);

    for (int i = 0; i < 4; i++) {
      SceneNode box1 = new SceneNode(box1Geometry, uniformGray);
      box1.setRotation(0.0f, i * 45.0f, 0.0f);
      sceneGraph.addNode(box1);

      SceneNode box2 = new SceneNode(box2Geometry, uniformGray);
      box2.setRotation(0.0f, i * 45.0f, 0.0f);
      sceneGraph.addNode(box2);

      SceneNode box3 = new SceneNode(box3Geometry, uniformGray);
      box3.setRotation(0.0f, i * 45.0f, 0.0f);
      sceneGraph.addNode(box3);
    }

    Geometry baseSphere = new Sphere(3.0f, 16, 16);
//    baseSphere.discardSelectedVertices(new Geometry.VertexSelector() {
//      @Override
//      public boolean isSelected(Vec3 vertex) {
//        return vertex.y < 1.0f;
//      }
//    });
    SceneNode base = new SceneNode(baseSphere, uniformGray);
    base.setTranslation(0.0f, -2.0f, 0.0f);
    sceneGraph.addNode(base);

    Geometry floorGeometry = new Grid(60.0f, 60.0f, 30, 30);
    Transform.jiggle(floorGeometry, 0.8f, 0.3f, 0.8f);
    floorGeometry.makeFaceted();
    SceneNode floor = new SceneNode(floorGeometry, dirt);
    sceneGraph.addNode(floor);

    SceneNode ball = new SceneNode(new Sphere(BALL_RADIUS, 16, 16), ColorFunctionFactory.createRandom());
    ball.setTranslation(0.0f, BALL_START_HEIGHT, 0.0f);
    ball.subscribe(new NodeController() {
      @Override
      public void update(SceneNode node) {
        node.setTranslation(0.0f, mBallHeight, 0.0f);
      }
    });
    sceneGraph.addNode(ball);

    sceneGraph.setLookAt(0.0f, FLOOR_DOWN, 0.0f);

    return sceneGraph;
  }

  public void start(Context context) {

    if (!mRunning) {

      final SoundPool ballSoundPool = new SoundPool(8, AudioManager.STREAM_MUSIC, 0);
      final int bounceSound = ballSoundPool.load(context, R.raw.app_004_bounce, 1);

      ballSoundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
        @Override
        public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
          mSimulationThread = new Thread(new Runnable() {
            @Override
            public void run() {
              boolean restingOnFloor = false;
              float delta;

              while (mRunning) {
                delta = SIMULATION_STEP / 1000.0f;

                switch (mFloorMovement) {
                  case DOWN:
                    mFloorHeight -= FLOOR_SPEED * delta;
                    if (mFloorHeight < FLOOR_DOWN) {
                      mFloorHeight = FLOOR_DOWN;
                      mFloorMovement = FLOOR_MOVEMENT.STOPPED;
                    }
                    break;
                  case UP:
                    mFloorHeight += FLOOR_SPEED * delta;
                    if (mFloorHeight > FLOOR_UP) {
                      mFloorHeight = FLOOR_UP;
                      mFloorMovement = FLOOR_MOVEMENT.DOWN;
                    }
                    break;
                  case STOPPED:
                    break;
                }

                if (!restingOnFloor) {

                  float newHeight = mBallHeight + delta * mBallSpeed - 0.5f * GRAVITY * delta * delta;

                  if (newHeight < mFloorHeight + BALL_RADIUS) {
                    mBallHeight = mFloorHeight + BALL_RADIUS;

                    if (mFloorMovement == FLOOR_MOVEMENT.UP && Math.abs(mBallSpeed) < FLOOR_SPEED) {
                      mBallSpeed = FLOOR_SPEED + Math.abs(0.3f * mBallSpeed);
                    } else {
                      mBallSpeed = -BOUNCE_FACTOR * mBallSpeed;
                    }

                    ballSoundPool.play(bounceSound, 1.0f, 1.0f, 1, 0, 1.0f);
                  } else {
                    mBallHeight = newHeight;
                    mBallSpeed -= delta * GRAVITY;
                  }

                  if (Math.abs(mBallSpeed) < BOUNCE_STOP_SPEED && mBallHeight < mFloorHeight + BALL_RADIUS + EPSILON) {
                    restingOnFloor = true;
                    mBallHeight = mFloorHeight + BALL_RADIUS;
                    mBallSpeed = 0.0f;
                  }
                } else {
                  if (mFloorMovement != FLOOR_MOVEMENT.STOPPED) {
                    restingOnFloor = false;
                    if (mFloorMovement == FLOOR_MOVEMENT.UP) {
                      mBallSpeed = FLOOR_SPEED + EPSILON;
                    }
                  }
                }

                SystemClock.sleep(SIMULATION_STEP);
              }
              ballSoundPool.release();
            }
          });
          mRunning = true;
          mSimulationThread.start();
        }
      });

    }
  }

  public void stop() {
    mRunning = false;
    try {
      mSimulationThread.join();
    } catch (InterruptedException e) {
      //shouldn't happen but not important
    }
  }

  public void moveUp() {
    mFloorMovement = FLOOR_MOVEMENT.UP;
  }

  private enum FLOOR_MOVEMENT {
    UP, DOWN, STOPPED
  }

  @Override
  public void update(SceneNode node) {
    node.setTranslation(0.0f, mBallHeight, 0.0f);
  }
}




Java Source Code List

com.hulzenga.ioi.android.AppActivity.java
com.hulzenga.ioi.android.AppDetailsDialog.java
com.hulzenga.ioi.android.App.java
com.hulzenga.ioi.android.TableOfContentsActivity.java
com.hulzenga.ioi.android.app_001.HelloWorldActivity.java
com.hulzenga.ioi.android.app_002.Ball.java
com.hulzenga.ioi.android.app_002.BouncyBallsActivity.java
com.hulzenga.ioi.android.app_002.BouncyBallsView.java
com.hulzenga.ioi.android.app_003.MonsterDatabaseActivity.java
com.hulzenga.ioi.android.app_003.MonsterEditDialog.java
com.hulzenga.ioi.android.app_003.MonsterGenerator.java
com.hulzenga.ioi.android.app_003.MonsterListAdapter.java
com.hulzenga.ioi.android.app_003.database.MonsterContract.java
com.hulzenga.ioi.android.app_003.database.MonsterDatabaseHelper.java
com.hulzenga.ioi.android.app_003.database.MonsterProvider.java
com.hulzenga.ioi.android.app_004.BouncyBall3dActivity.java
com.hulzenga.ioi.android.app_004.BouncyBall3dGLSurfaceView.java
com.hulzenga.ioi.android.app_004.BouncyBall3dRenderer.java
com.hulzenga.ioi.android.app_004.BouncyBallGame.java
com.hulzenga.ioi.android.app_005.ElementActivity.java
com.hulzenga.ioi.android.app_005.ElementAdapter.java
com.hulzenga.ioi.android.app_005.ElementAnimator.java
com.hulzenga.ioi.android.app_005.ElementSnakeView.java
com.hulzenga.ioi.android.app_005.ElementView.java
com.hulzenga.ioi.android.app_005.Element.java
com.hulzenga.ioi.android.app_006.EmptyFragment.java
com.hulzenga.ioi.android.app_006.ExposureFragment.java
com.hulzenga.ioi.android.app_006.SettingChangeListener.java
com.hulzenga.ioi.android.app_006.SettingIconFragment.java
com.hulzenga.ioi.android.app_006.SettingMenuFragment.java
com.hulzenga.ioi.android.app_006.SettingMenuLvl2Fragment.java
com.hulzenga.ioi.android.app_006.Setting.java
com.hulzenga.ioi.android.app_006.SimpleCameraActivity.java
com.hulzenga.ioi.android.app_006.SimpleCameraPreview.java
com.hulzenga.ioi.android.app_007.ButtonsFragment.java
com.hulzenga.ioi.android.app_007.HighScores.java
com.hulzenga.ioi.android.app_007.LinksFragment.java
com.hulzenga.ioi.android.app_007.Menu.java
com.hulzenga.ioi.android.app_007.Review.java
com.hulzenga.ioi.android.app_007.Score.java
com.hulzenga.ioi.android.app_007.StatusFragment.java
com.hulzenga.ioi.android.app_007.WikiGameActivity.java
com.hulzenga.ioi.android.app_007.Wiki.java
com.hulzenga.ioi.android.app_008.OverheidActivity.java
com.hulzenga.ioi.android.app_008.OverheidFeedAdapter.java
com.hulzenga.ioi.android.app_008.OverheidFeedFragment.java
com.hulzenga.ioi.android.app_008.OverheidFeedItem.java
com.hulzenga.ioi.android.app_008.OverheidFeed.java
com.hulzenga.ioi.android.app_008.OverheidPagerAdapter.java
com.hulzenga.ioi.android.app_009.ThumbsUpActivity.java
com.hulzenga.ioi.android.app_009.ThumbsUpServer.java
com.hulzenga.ioi.android.app_009.ThumbsUpService.java
com.hulzenga.ioi.android.app_010.CompassActivity.java
com.hulzenga.ioi.android.app_010.CompassDetailsView.java
com.hulzenga.ioi.android.app_010.CompassView.java
com.hulzenga.ioi.android.util.Constrain.java
com.hulzenga.ioi.android.util.DeveloperTools.java
com.hulzenga.ioi.android.util.FileManager.java
com.hulzenga.ioi.android.util.ScreenMetrics.java
com.hulzenga.ioi.android.util.open_gl.ColorFunctionFactory.java
com.hulzenga.ioi.android.util.open_gl.ColorFunction.java
com.hulzenga.ioi.android.util.open_gl.ShaderTools.java
com.hulzenga.ioi.android.util.open_gl.engine.NodeController.java
com.hulzenga.ioi.android.util.open_gl.engine.SceneGraph.java
com.hulzenga.ioi.android.util.open_gl.engine.SceneNode.java
com.hulzenga.ioi.android.util.open_gl.geometry.Box.java
com.hulzenga.ioi.android.util.open_gl.geometry.Cylinder.java
com.hulzenga.ioi.android.util.open_gl.geometry.Geometry.java
com.hulzenga.ioi.android.util.open_gl.geometry.Grid.java
com.hulzenga.ioi.android.util.open_gl.geometry.Sphere.java
com.hulzenga.ioi.android.util.open_gl.geometry.Transform.java
com.hulzenga.ioi.android.util.open_gl.vector.Vec3.java
com.hulzenga.ioi.android.util.open_gl.vector.Vec4.java
fi.iki.elonen.NanoHTTPD.java