/* * Copyright (C) 2016 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.android.apps.santatracker.games.gumball; import org.jbox2d.collision.shapes.CircleShape; import org.jbox2d.collision.shapes.EdgeShape; import org.jbox2d.collision.shapes.PolygonShape; import org.jbox2d.collision.shapes.Shape; import org.jbox2d.common.Vec2; import org.jbox2d.dynamics.Body; import org.jbox2d.dynamics.BodyDef; import org.jbox2d.dynamics.BodyType; import org.jbox2d.dynamics.FixtureDef; import org.jbox2d.dynamics.World; import java.io.IOException; import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.List; /** * Wraps the game world and physics simulation for the gumball game. */ public class PhysicsWorld { /** * All {@link org.jbox2d.dynamics.Body} objects in the world. */ private List<Body> mBodies = new ArrayList<Body>(); /** * The Physics world. */ private World mWorld; /** * Bodies that are to be removed from the scene. */ public List<Body> mBodiesToBeRemoved = new ArrayList<Body>(); /** * Render refresh rate. */ private static final float FRAME_RATE = 1.0f / 45.0f; /** * Create the physics world and draws the boundries */ public void create(Vec2 gravity) { // Create Physics World with Gravity mWorld = new World(gravity); mWorld.setAllowSleep(false); mWorld.setSleepingAllowed(false); mWorld.setAutoClearForces(true); BodyDef groundBodyDef = new BodyDef(); // Create Ground Box groundBodyDef.position.set(new Vec2(5.0f, -2.0f)); Body groundBody = mWorld.createBody(groundBodyDef); PolygonShape polygonShape = new PolygonShape(); // Create top bound groundBodyDef.position.set(new Vec2(5.0f, 32.0f)); groundBody = mWorld.createBody(groundBodyDef); groundBody.createFixture(polygonShape, 1.0f); polygonShape.setAsBox(2.0f, 18.0f); // Create left wall groundBodyDef.position.set(new Vec2(-2.0f, 16.0f)); groundBody = mWorld.createBody(groundBodyDef); groundBody.createFixture(polygonShape, 1.0f); // Create right wall groundBodyDef.position.set(new Vec2(12.0f, 16.0f)); groundBody = mWorld.createBody(groundBodyDef); groundBody.createFixture(polygonShape, 1.0f); } /** * Adds a gumball to the scene. */ public void addGumball(float x, float y, Gumball gumball, float density, float radius, float bounce, float friction, BodyType bodyType) { // Create Shape with Properties CircleShape circleShape = new CircleShape(); circleShape.m_radius = radius; addItem(x, y, circleShape, bounce, gumball, density, friction, bodyType); } public void addPipeSides(float x, float y, int data, float density, float bounce, float friction, BodyType bodyType) { EdgeShape[] edgeShapes = new EdgeShape[2]; edgeShapes[0] = new EdgeShape(); edgeShapes[0].set(new Vec2(.23f, -1f), new Vec2(.01f, .48f)); edgeShapes[1] = new EdgeShape(); edgeShapes[1].set(new Vec2(1.4f, -1f), new Vec2(1.55f, .45f)); addItem(x, y, edgeShapes, bounce, data, density, friction, bodyType); } public void addPipeBottom(float x, float y, int data, float density, float bounce, float friction, BodyType bodyType) { EdgeShape[] edgeShapes = new EdgeShape[1]; edgeShapes[0] = new EdgeShape(); edgeShapes[0].set(new Vec2(.83f, 0f), new Vec2(2.40f, 0f)); addItem(x, y, edgeShapes, bounce, data, density, friction, bodyType); } public void addFloor(float x, float y, int data, float density, float bounce, float friction, BodyType bodyType) { EdgeShape[] edgeShapes = new EdgeShape[1]; edgeShapes[0] = new EdgeShape(); edgeShapes[0].set(new Vec2(-9f, -.8f), new Vec2(9f, -.8f)); addItem(x, y, edgeShapes, bounce, data, density, friction, bodyType); } public void addItem(float x, float y, Shape[] shapes, float bounce, int data, float density, float friction, BodyType bodyType) { // Create Dynamic Body BodyDef bodyDef = new BodyDef(); bodyDef.position.set(x, y); bodyDef.userData = data; bodyDef.type = bodyType; Body body = mWorld.createBody(bodyDef); mBodies.add(body); for (int i = 0; i < shapes.length; i++) { // Assign shape to Body FixtureDef fixtureDef = new FixtureDef(); fixtureDef.shape = shapes[i]; fixtureDef.density = density; fixtureDef.friction = friction; fixtureDef.restitution = bounce; body.createFixture(fixtureDef); } } public void addItem(float x, float y, Shape shape, float bounce, int data, float density, float friction, BodyType bodyType) { // Create Dynamic Body BodyDef bodyDef = new BodyDef(); bodyDef.position.set(x, y); bodyDef.userData = data; bodyDef.type = bodyType; Body body = mWorld.createBody(bodyDef); mBodies.add(body); // Assign shape to Body FixtureDef fixtureDef = new FixtureDef(); fixtureDef.shape = shape; fixtureDef.density = density; fixtureDef.friction = friction; fixtureDef.restitution = bounce; body.createFixture(fixtureDef); } public void addItem(float x, float y, Shape shape, float bounce, Gumball gumball, float density, float friction, BodyType bodyType) { // Create Dynamic Body BodyDef bodyDef = new BodyDef(); bodyDef.position.set(x, y); bodyDef.userData = gumball; bodyDef.type = bodyType; Body body = mWorld.createBody(bodyDef); mBodies.add(body); // Assign shape to Body FixtureDef fixtureDef = new FixtureDef(); fixtureDef.shape = shape; fixtureDef.density = density; fixtureDef.friction = friction; fixtureDef.restitution = bounce; body.createFixture(fixtureDef); } /** * Updates the physics world by removing all pending bodies. */ public void update() { // Update Physics World for (int i = 0; i < mBodiesToBeRemoved.size(); i++) { mWorld.destroyBody(mBodiesToBeRemoved.get(i)); } mBodiesToBeRemoved.clear(); mWorld.step(FRAME_RATE, 10, 10); mWorld.clearForces(); } /** * Gets a reference to the world. */ public World getWorld() { return mWorld; } }