@Override public void show() { // , , MyWorld.CAMERA_WIDTH = MyWorld.CAMERA_HEIGHT* Gdx.graphics.getWidth()/Gdx.graphics.getHeight(); world = new MyWorld(); renderer = new WorldRenderer(world, MyWorld.CAMERA_WIDTH, MyWorld.CAMERA_HEIGHT,true); controller = new WorldController(world); Gdx.input.setInputProcessor(this); // }
private void ChangeNavigation(int x, int y){ controller.resetWay(); // , , () if(height-y > world.getPlayer().getPosition().y * renderer.ppuY) controller.upPressed(); // , , if ( x< world.getPlayer().getPosition().x * renderer.ppuX) controller.leftPressed(); // , , if (x> (world.getPlayer().getPosition().x )* renderer.ppuX) controller.rightPressed(); } @Override public boolean touchDown(int x, int y, int pointer, int button) { if (!Gdx.app.getType().equals(ApplicationType.Android)) return false; ChangeNavigation(x,y); return true; } @Override public boolean touchUp(int x, int y, int pointer, int button) { if (!Gdx.app.getType().equals(ApplicationType.Android)) return false; controller.resetWay(); return true; } @Override public boolean touchDragged(int x, int y, int pointer) { ChangeNavigation(x,y); return false; }
render()
, which fires after a certain amount of time and processes the logic and draws objects. @Override public void render(float delta) { Gdx.gl.glClearColor(0, 0, 0, 232F/255); Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); controller.update(delta); renderer.render(delta); }
World world; // Player player; // Array<MovingPlatform> platforms = new Array<MovingPlatform>(); // public MovingPlatform groundedPlatform = null;
public MyWorld(){ width = 30; height = 8; // , () world = new World(new Vector2(0, -20), true); createWorld(); } private void createWorld(){ BodyDef def = new BodyDef(); def.type = BodyType.DynamicBody; Body boxP = world.createBody(def); player = new Player(boxP); player.getBody().setTransform(3.0f, 4.0f, 0); player.getBody().setFixedRotation(true); Body box = createBox(BodyType.StaticBody, 1, 1, 0); for(int i = 0; i < 10; i++) { box = createBox(BodyType.DynamicBody, (float)Math.random(), (float)Math.random(), 13); box.setTransform((float)Math.random() * 10f - (float)Math.random() * 10f, (float)Math.random() * 10 + 6, 0); } platforms.add(new MovingPlatform(world, 3F, 3, 1,0.25F, 2, 0, 2)); for(int i=1;i<width; ++i){ Body boxGround = createBox(BodyType.StaticBody, 1F, 1F, 0); boxGround.setTransform(i,0,0); } } private Body createBox(BodyType type, float width, float height, float density) { BodyDef def = new BodyDef(); def.type = type; Body box = world.createBody(def); PolygonShape poly = new PolygonShape(); poly.setAsBox(width, height); box.createFixture(poly, density); poly.dispose(); return box; }
BodyDef
is a body definition that contains all data about a solid body. You can reuse this definition for various objects.BodyType
- body type. It can be one of three possible:Body
, in fact, the body itself.Body
objects can be moved, rotated using the setTransform()
method. public class Player { final static float MAX_VELOCITY = 3f; public final static float SPEED = 5f; public final static float SIZE = 0.8f; public Fixture playerPhysicsFixture; public Fixture playerSensorFixture; Body box; public Player(Body b){ box = b; PolygonShape poly = new PolygonShape(); poly.setAsBox(0.4f, 0.4f); playerPhysicsFixture = box.createFixture(poly, 3); poly.dispose(); CircleShape circle = new CircleShape(); circle.setRadius(0.41f); circle.setPosition(new Vector2(0, 0f)); playerSensorFixture = box.createFixture(circle, 1); setFriction(10F); circle.dispose(); box.setBullet(true); } public Body getBody(){ return box; } // public void setFriction(float f){ playerSensorFixture.setFriction(f); playerPhysicsFixture.setFriction(f); } public Vector2 getPosition(){ return box.getPosition(); } public Vector2 getVelocity() { return velocity; } Vector2 velocity = new Vector2(); public void update(float delta) { Vector2 vel = box.getLinearVelocity(); velocity.y = vel.y; box.setLinearVelocity(velocity); if(isJump) {box.applyLinearImpulse(0, 8, box.getPosition().x, box.getPosition().y); isJump = false;} } boolean isJump = false; public void jump(){ isJump = true; } public void resetVelocity(){ getVelocity().x =0; getVelocity().y =0; } }
applyLinearImpulse()
- set the momentum to the object. As in the real world, if you push an object, then according to the impulse, the body will move until the friction suppresses the impulse.setLinearVelocity()
- set the speed of movement. Unlike the impulse, the speed will be constant until you change it.setLinearVelocity()
to move along the X axis. While you keep your finger on the wheelbarrow, the character will move, when you release, the character will stop. If you use applyLinearImpulse()
to move horizontally, the character will still move some time after you remove your finger from the screen.applyLinearImpulse()
for left / right movement. As an example, if the character moves on a slippery surface (ice, as an example).box.setBullet(true);
indicates that the body should be treated like a bullet when it detects collisions.MovingPlatform
is a moving platform. public class MovingPlatform { Body platform; Vector2 pos = new Vector2(); Vector2 dir = new Vector2(); Vector2 vel = new Vector2(); float maxDist = 0; float width; //Vector2 l = new Vector2(); public MovingPlatform(World world, float x, float y, float width, float height, float dx, float dy, float maxDist) { platform = createBox(world, BodyType.KinematicBody, width, height, 1); this.width = width; pos.x = x; pos.y = y; dir.x = dx; dir.y = dy; vel.x = dx; vel.y = dy; this.maxDist = maxDist; platform.setTransform(pos, 0); platform.getFixtureList().get(0).setUserData("p"); platform.setUserData(this); } public void resume(){ dir.x= vel.x; dir.y = vel.y; } public void pause(){ vel.x = dir.x; vel.y = dir.y; dir.x = 0; dir.y = 0; platform.setLinearVelocity(dir); } public void update(float deltaTime) { if(dir.x < 0 && platform .getPosition().x < pos.x-maxDist) { platform .getPosition().x =pos.x; dir.mul(-1); } if(dir.x > 0 && platform .getPosition().x> pos.x+maxDist) { platform .getPosition().x =pos.x+maxDist; dir.mul(-1); } platform.setLinearVelocity(dir); } private Body createBox(World world,BodyType type, float width, float height, float density) { BodyDef def = new BodyDef(); def.type = type; Body box = world.createBody(def); PolygonShape poly = new PolygonShape(); poly.setAsBox(width/2, height/2); Fixture f = box.createFixture(poly, density); poly.dispose(); return box; } }
WorldController
, the logic is updated in response to user actions in the update()
method. boolean grounded ; public void update(float delta) { Array<MovingPlatform> platforms = world.getPlatforms(); // for(int i = 0; i < platforms.size; i++) { MovingPlatform platform = platforms.get(i); platform.update(Math.max(1/60.0f, delta)); } grounded = isPlayerGrounded(Gdx.graphics.getDeltaTime()); // processInput(); // world.getPlayer().update(delta); }
// private void processInput() { Player player = world.getPlayer(); // if (keys.get(Keys.LEFT)) player.getVelocity().x =- Player.SPEED; // if (keys.get(Keys.RIGHT)) player.getVelocity().x = Player.SPEED; // if (keys.get(Keys.UP)) // if(grounded) // player.jump(); // if(!grounded) // world.getPlayer().setFriction(0f); // else{ if(keys.get(Keys.RIGHT) || keys.get(Keys.LEFT)) world.getPlayer().setFriction(0.2f); else world.getPlayer().setFriction(100f); } }
private boolean isPlayerGrounded(float deltaTime) { world.groundedPlatform = null; List<Contact> contactList = world.getWorld().getContactList(); for(int i = 0; i < contactList.size(); i++) { Contact contact = contactList.get(i); if(contact.isTouching() && (contact.getFixtureA() == world.getPlayer().playerSensorFixture || contact.getFixtureB() == world.getPlayer().playerSensorFixture)) { Vector2 pos = world.getPlayer().getPosition(); WorldManifold manifold = contact.getWorldManifold(); boolean below = true; for(int j = 0; j < manifold.getNumberOfContactPoints(); j++) { below &= (manifold.getPoints()[j].y < pos.y - 0.4f); } if(below) { if(contact.getFixtureA().getUserData() != null && contact.getFixtureA().getUserData().equals("p")) { world.groundedPlatform = (MovingPlatform)contact.getFixtureA().getBody().getUserData(); } if(contact.getFixtureB().getUserData() != null && contact.getFixtureB().getUserData().equals("p")) { world.groundedPlatform = (MovingPlatform)contact.getFixtureB().getBody().getUserData(); } return true; } return false; } } return false; }
if (!keys.get(Keys.LEFT) && !keys.get(Keys.RIGHT)) contact.setFriction(200F); else contact.setFriction(0F);
WorldRenderer
class, WorldRenderer
are WorldRenderer
. public class WorldRenderer { Box2DDebugRenderer renderer; public static float CAMERA_WIDTH = 10f; public static float CAMERA_HEIGHT = 15f; public float ppuX; public float ppuY; MyWorld world; public OrthographicCamera cam; public WorldRenderer(MyWorld world, float w, float h, boolean debug) { renderer = new Box2DDebugRenderer(); this.world = world; CAMERA_WIDTH = w; CAMERA_HEIGHT = h; ppuX = (float)Gdx.graphics.getWidth() / CAMERA_WIDTH; ppuY = (float)Gdx.graphics.getHeight() / CAMERA_HEIGHT; this.cam = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT); SetCamera(CAMERA_WIDTH / 2f, CAMERA_HEIGHT / 2f); } public void SetCamera(float x, float y){ this.cam.position.set(x, y,0); this.cam.update(); } public void dispose(){ world.dispose(); } public void render(float delta) { renderer.render(world.getWorld(), cam.combined); world.getWorld().step(delta, 4, 4); } }
render()
method takes place. This example is used to draw a Box2DDebugRenderer in debug mode to display the borders of objects. In the final version of your application in the render()
method, you need to display any sprites for all objects.world.getWorld().step(delta, 4, 4);
indicates the frequency with which to update physics. In most cases, I think, there is no need to update physics more often than drawing takes place.Source: https://habr.com/ru/post/161977/
All Articles