• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright 2011 See AUTHORS file.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 /*
17  * Copyright 2010 Mario Zechner (contact@badlogicgames.com), Nathan Sweet (admin@esotericsoftware.com)
18  *
19  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
20  * License. You may obtain a copy of the License at
21  *
22  * http://www.apache.org/licenses/LICENSE-2.0
23  *
24  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
25  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
26  * governing permissions and limitations under the License.
27  */
28 
29 package com.badlogic.gdx.tests.box2d;
30 
31 import com.badlogic.gdx.ApplicationListener;
32 import com.badlogic.gdx.Gdx;
33 import com.badlogic.gdx.InputProcessor;
34 import com.badlogic.gdx.graphics.GL20;
35 import com.badlogic.gdx.graphics.OrthographicCamera;
36 import com.badlogic.gdx.graphics.g2d.BitmapFont;
37 import com.badlogic.gdx.graphics.g2d.SpriteBatch;
38 import com.badlogic.gdx.math.Vector2;
39 import com.badlogic.gdx.math.Vector3;
40 import com.badlogic.gdx.physics.box2d.Body;
41 import com.badlogic.gdx.physics.box2d.BodyDef;
42 import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
43 import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
44 import com.badlogic.gdx.physics.box2d.Fixture;
45 import com.badlogic.gdx.physics.box2d.QueryCallback;
46 import com.badlogic.gdx.physics.box2d.World;
47 import com.badlogic.gdx.physics.box2d.joints.MouseJoint;
48 import com.badlogic.gdx.physics.box2d.joints.MouseJointDef;
49 import com.badlogic.gdx.utils.TimeUtils;
50 
51 /** Base class for all Box2D Testbed tests, all subclasses must implement the createWorld() method.
52  *
53  * @author badlogicgames@gmail.com */
54 public abstract class Box2DTest implements ApplicationListener, InputProcessor {
55 	/** the camera **/
56 	protected OrthographicCamera camera;
57 
58 	/** the renderer **/
59 	protected Box2DDebugRenderer renderer;
60 
61 	SpriteBatch batch;
62 	BitmapFont font;
63 
64 	/** our box2D world **/
65 	protected World world;
66 
67 	/** ground body to connect the mouse joint to **/
68 	protected Body groundBody;
69 
70 	/** our mouse joint **/
71 	protected MouseJoint mouseJoint = null;
72 
73 	/** a hit body **/
74 	protected Body hitBody = null;
75 
createWorld(World world)76 	protected abstract void createWorld (World world);
77 
78 	/** temp vector **/
79 	protected Vector2 tmp = new Vector2();
80 
81 	@Override
render()82 	public void render () {
83 		// update the world with a fixed time step
84 		long startTime = TimeUtils.nanoTime();
85 		world.step(Gdx.app.getGraphics().getDeltaTime(), 3, 3);
86 		float updateTime = (TimeUtils.nanoTime() - startTime) / 1000000000.0f;
87 
88 		startTime = TimeUtils.nanoTime();
89 		// clear the screen and setup the projection matrix
90 		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
91 		camera.update();
92 
93 		// render the world using the debug renderer
94 		renderer.render(world, camera.combined);
95 		float renderTime = (TimeUtils.nanoTime() - startTime) / 1000000000.0f;
96 
97 		batch.begin();
98 		font.draw(batch, "fps:" + Gdx.graphics.getFramesPerSecond() + ", update: " + updateTime + ", render: " + renderTime, 0, 20);
99 		batch.end();
100 	}
101 
102 	@Override
create()103 	public void create () {
104 		// setup the camera. In Box2D we operate on a
105 		// meter scale, pixels won't do it. So we use
106 		// an orthographic camera with a viewport of
107 		// 48 meters in width and 32 meters in height.
108 		// We also position the camera so that it
109 		// looks at (0,16) (that's where the middle of the
110 		// screen will be located).
111 		camera = new OrthographicCamera(48, 32);
112 		camera.position.set(0, 15, 0);
113 
114 		// create the debug renderer
115 		renderer = new Box2DDebugRenderer();
116 
117 		// create the world
118 		world = new World(new Vector2(0, -10), true);
119 
120 		// we also need an invisible zero size ground body
121 		// to which we can connect the mouse joint
122 		BodyDef bodyDef = new BodyDef();
123 		groundBody = world.createBody(bodyDef);
124 
125 		// call abstract method to populate the world
126 		createWorld(world);
127 
128 		batch = new SpriteBatch();
129 		font = new BitmapFont(Gdx.files.internal("data/arial-15.fnt"), false);
130 	}
131 
132 	@Override
dispose()133 	public void dispose () {
134 		renderer.dispose();
135 		world.dispose();
136 
137 		renderer = null;
138 		world = null;
139 		mouseJoint = null;
140 		hitBody = null;
141 	}
142 
143 	@Override
keyDown(int keycode)144 	public boolean keyDown (int keycode) {
145 		return false;
146 	}
147 
148 	@Override
keyTyped(char character)149 	public boolean keyTyped (char character) {
150 		return false;
151 	}
152 
153 	@Override
keyUp(int keycode)154 	public boolean keyUp (int keycode) {
155 		return false;
156 	}
157 
158 	/** we instantiate this vector and the callback here so we don't irritate the GC **/
159 	Vector3 testPoint = new Vector3();
160 	QueryCallback callback = new QueryCallback() {
161 		@Override
162 		public boolean reportFixture (Fixture fixture) {
163 			// if the hit point is inside the fixture of the body
164 			// we report it
165 			if (fixture.testPoint(testPoint.x, testPoint.y)) {
166 				hitBody = fixture.getBody();
167 				return false;
168 			} else
169 				return true;
170 		}
171 	};
172 
173 	@Override
touchDown(int x, int y, int pointer, int button)174 	public boolean touchDown (int x, int y, int pointer, int button) {
175 		// translate the mouse coordinates to world coordinates
176 		camera.unproject(testPoint.set(x, y, 0));
177 		// ask the world which bodies are within the given
178 		// bounding box around the mouse pointer
179 		hitBody = null;
180 		world.QueryAABB(callback, testPoint.x - 0.0001f, testPoint.y - 0.0001f, testPoint.x + 0.0001f, testPoint.y + 0.0001f);
181 
182 		if (hitBody == groundBody) hitBody = null;
183 
184 		// ignore kinematic bodies, they don't work with the mouse joint
185 		if (hitBody != null && hitBody.getType() == BodyType.KinematicBody) return false;
186 
187 		// if we hit something we create a new mouse joint
188 		// and attach it to the hit body.
189 		if (hitBody != null) {
190 			MouseJointDef def = new MouseJointDef();
191 			def.bodyA = groundBody;
192 			def.bodyB = hitBody;
193 			def.collideConnected = true;
194 			def.target.set(testPoint.x, testPoint.y);
195 			def.maxForce = 1000.0f * hitBody.getMass();
196 
197 			mouseJoint = (MouseJoint)world.createJoint(def);
198 			hitBody.setAwake(true);
199 		}
200 
201 		return false;
202 	}
203 
204 	/** another temporary vector **/
205 	Vector2 target = new Vector2();
206 
207 	@Override
touchDragged(int x, int y, int pointer)208 	public boolean touchDragged (int x, int y, int pointer) {
209 		// if a mouse joint exists we simply update
210 		// the target of the joint based on the new
211 		// mouse coordinates
212 		if (mouseJoint != null) {
213 			camera.unproject(testPoint.set(x, y, 0));
214 			mouseJoint.setTarget(target.set(testPoint.x, testPoint.y));
215 		}
216 		return false;
217 	}
218 
219 	@Override
touchUp(int x, int y, int pointer, int button)220 	public boolean touchUp (int x, int y, int pointer, int button) {
221 		// if a mouse joint exists we simply destroy it
222 		if (mouseJoint != null) {
223 			world.destroyJoint(mouseJoint);
224 			mouseJoint = null;
225 		}
226 		return false;
227 	}
228 
229 	@Override
mouseMoved(int x, int y)230 	public boolean mouseMoved (int x, int y) {
231 		return false;
232 	}
233 
234 	@Override
scrolled(int amount)235 	public boolean scrolled (int amount) {
236 		return false;
237 	}
238 
pause()239 	public void pause () {
240 
241 	}
242 
resume()243 	public void resume () {
244 
245 	}
246 
resize(int width, int height)247 	public void resize (int width, int height) {
248 
249 	}
250 }
251