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 java.lang.reflect.Field; 32 import java.lang.reflect.Method; 33 34 import com.badlogic.gdx.Gdx; 35 import com.badlogic.gdx.math.Vector2; 36 import com.badlogic.gdx.physics.box2d.Body; 37 import com.badlogic.gdx.physics.box2d.BodyDef; 38 import com.badlogic.gdx.physics.box2d.BodyDef.BodyType; 39 import com.badlogic.gdx.physics.box2d.CircleShape; 40 import com.badlogic.gdx.physics.box2d.Contact; 41 import com.badlogic.gdx.physics.box2d.ContactImpulse; 42 import com.badlogic.gdx.physics.box2d.ContactListener; 43 import com.badlogic.gdx.physics.box2d.EdgeShape; 44 import com.badlogic.gdx.physics.box2d.Fixture; 45 import com.badlogic.gdx.physics.box2d.FixtureDef; 46 import com.badlogic.gdx.physics.box2d.Manifold; 47 import com.badlogic.gdx.physics.box2d.PolygonShape; 48 import com.badlogic.gdx.physics.box2d.World; 49 50 public class ContactListenerTest extends Box2DTest implements ContactListener { 51 52 @Override createWorld(World world)53 protected void createWorld (World world) { 54 world.setContactListener(this); 55 { 56 BodyDef bd = new BodyDef(); 57 Body ground = world.createBody(bd); 58 59 EdgeShape shape = new EdgeShape(); 60 shape.set(new Vector2(-20, 0), new Vector2(20, 0)); 61 ground.createFixture(shape, 0); 62 shape.dispose(); 63 } 64 65 { 66 BodyDef bd = new BodyDef(); 67 Body ground = world.createBody(bd); 68 69 EdgeShape shape = new EdgeShape(); 70 shape.setRadius(0); 71 shape.set(new Vector2(-8, 1), new Vector2(-6, 1)); 72 ground.createFixture(shape, 0); 73 shape.set(new Vector2(-6, 1), new Vector2(-4, 1)); 74 ground.createFixture(shape, 0); 75 shape.set(new Vector2(-4, 1), new Vector2(-2, 1)); 76 ground.createFixture(shape, 0); 77 shape.dispose(); 78 } 79 80 { 81 BodyDef bd = new BodyDef(); 82 Body ground = world.createBody(bd); 83 84 PolygonShape shape = new PolygonShape(); 85 shape.setAsBox(1, 1, new Vector2(4, 3), 0); 86 ground.createFixture(shape, 0); 87 shape.setAsBox(1, 1, new Vector2(6, 3), 0); 88 ground.createFixture(shape, 0); 89 shape.setAsBox(1, 1, new Vector2(8, 3), 0); 90 ground.createFixture(shape, 0); 91 shape.dispose(); 92 } 93 94 { 95 BodyDef bd = new BodyDef(); 96 Body ground = world.createBody(bd); 97 98 EdgeShape shape = new EdgeShape(); 99 float d = 2 * 2 * 0.005f; 100 shape.setRadius(0); 101 shape.set(new Vector2(-1 + d, 3), new Vector2(1 - d, 3)); 102 ground.createFixture(shape, 0); 103 shape.set(new Vector2(1, 3 + d), new Vector2(1, 5 - d)); 104 ground.createFixture(shape, 0); 105 shape.set(new Vector2(1 - d, 5), new Vector2(-1 + d, 5)); 106 ground.createFixture(shape, 0); 107 shape.set(new Vector2(-1, 5 - d), new Vector2(-1, 3 + d)); 108 ground.createFixture(shape, 0); 109 shape.dispose(); 110 } 111 112 { 113 BodyDef bd = new BodyDef(); 114 bd.position.set(-3, 20); 115 bd.type = BodyType.DynamicBody; 116 bd.fixedRotation = true; 117 bd.allowSleep = false; 118 119 Body body = world.createBody(bd); 120 121 PolygonShape shape = new PolygonShape(); 122 shape.setAsBox(0.5f, 0.5f); 123 124 FixtureDef fd = new FixtureDef(); 125 fd.shape = shape; 126 fd.density = 20.0f; 127 body.createFixture(fd); 128 shape.dispose(); 129 } 130 131 { 132 BodyDef bd = new BodyDef(); 133 bd.position.set(-5, 25); 134 bd.type = BodyType.DynamicBody; 135 bd.fixedRotation = true; 136 bd.allowSleep = false; 137 138 Body body = world.createBody(bd); 139 140 float angle = 0; 141 float delta = (float)Math.PI / 3; 142 Vector2[] vertices = new Vector2[6]; 143 for (int i = 0; i < 6; i++) { 144 vertices[i] = new Vector2(0.5f * (float)Math.cos(angle), 0.5f * (float)Math.sin(angle)); 145 angle += delta; 146 } 147 148 PolygonShape shape = new PolygonShape(); 149 shape.set(vertices); 150 151 FixtureDef fd = new FixtureDef(); 152 fd.shape = shape; 153 fd.density = 20.0f; 154 body.createFixture(fd); 155 shape.dispose(); 156 } 157 158 { 159 BodyDef bd = new BodyDef(); 160 bd.position.set(3, 30); 161 bd.type = BodyType.DynamicBody; 162 bd.fixedRotation = true; 163 bd.allowSleep = false; 164 165 Body body = world.createBody(bd); 166 167 CircleShape shape = new CircleShape(); 168 shape.setRadius(0.5f); 169 170 FixtureDef fd = new FixtureDef(); 171 fd.shape = shape; 172 fd.density = 20.0f; 173 body.createFixture(fd); 174 shape.dispose(); 175 } 176 } 177 178 @Override beginContact(Contact contact)179 public void beginContact (Contact contact) { 180 System.out.println(String.format("beginContact() addr=%d", getContactAddr(contact))); 181 System.out.println(String.format("beginContact() addrA=%d, addrB=%d", 182 getFixtureAddrA(contact), 183 getFixtureAddrB(contact))); 184 System.out.println(String.format("beginContact() fixA=%s, fixB=%s", 185 contact.getFixtureA(), 186 contact.getFixtureB())); 187 188 final Body toRemove = contact.getFixtureA().getBody().getType() == BodyType.DynamicBody ? 189 contact.getFixtureA().getBody() : 190 contact.getFixtureB().getBody(); 191 Gdx.app.postRunnable(new Runnable() { 192 @Override 193 public void run () { 194 world.destroyBody(toRemove); 195 } 196 }); 197 } 198 199 @Override endContact(Contact contact)200 public void endContact (Contact contact) { 201 System.out.println(String.format(" endContact() addr=%d", getContactAddr(contact))); 202 System.out.println(String.format(" endContact() addrA=%d, addrB=%d", 203 getFixtureAddrA(contact), 204 getFixtureAddrB(contact))); 205 System.out.println(String.format(" endContact() fixA=%s, fixB=%s", 206 contact.getFixtureA(), 207 contact.getFixtureB())); 208 209 final Fixture fixtureA = contact.getFixtureA(); 210 final Fixture fixtureB = contact.getFixtureB(); 211 if(fixtureA == null || fixtureB == null) { 212 throw new RuntimeException("No fixture found."); 213 } 214 } 215 216 @Override preSolve(Contact contact, Manifold oldManifold)217 public void preSolve (Contact contact, Manifold oldManifold) { 218 // TODO Auto-generated method stub 219 220 } 221 222 @Override postSolve(Contact contact, ContactImpulse impulse)223 public void postSolve (Contact contact, ContactImpulse impulse) { 224 // TODO Auto-generated method stub 225 226 } 227 getFixtureAddrA(Contact contact)228 public long getFixtureAddrA(Contact contact) { 229 try { 230 long addr = getContactAddr(contact); 231 232 Method getFixtureA = contact.getClass().getDeclaredMethod("jniGetFixtureA", long.class); 233 getFixtureA.setAccessible(true); 234 return (Long) getFixtureA.invoke(contact, addr); 235 } catch (Exception e) { 236 e.printStackTrace(); 237 return 0; 238 } 239 } 240 getFixtureAddrB(Contact contact)241 public long getFixtureAddrB(Contact contact) { 242 try { 243 long addr =getContactAddr(contact); 244 245 Method getFixtureB = contact.getClass().getDeclaredMethod("jniGetFixtureB", long.class); 246 getFixtureB.setAccessible(true); 247 return (Long) getFixtureB.invoke(contact, addr); 248 } catch (Exception e) { 249 e.printStackTrace(); 250 return 0; 251 } 252 } 253 getContactAddr(Contact contact)254 public long getContactAddr(Contact contact) { 255 try { 256 Field addrField = contact.getClass().getDeclaredField("addr"); 257 addrField.setAccessible(true); 258 return addrField.getLong(contact); 259 } catch (Exception e) { 260 e.printStackTrace(); 261 return 0; 262 } 263 } 264 }