Like my question says can someone tell me, why does my circle texture/sprite are acting like a rectangle ?
Code:
`
#Override
public void create() {
batch = new SpriteBatch();
img = new Texture("ball.png");
sprite = new Sprite(img);
sprite.setPosition(-sprite.getWidth()/2,-sprite.getHeight()/2);
world = new World(new Vector2(0, -1f),true);
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set((sprite.getX() + sprite.getWidth()/2) /
PIXELS_TO_METERS,
(sprite.getY() + sprite.getHeight()/2) / PIXELS_TO_METERS);
body = world.createBody(bodyDef);
PolygonShape shape = new PolygonShape();
shape.setAsBox(sprite.getWidth()/2 / PIXELS_TO_METERS, sprite.getHeight()
/2 / PIXELS_TO_METERS);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 0.1f;
fixtureDef.restitution = 0.8f;
body.createFixture(fixtureDef);
shape.dispose();
//CONTINUE
// BOTTOM
BodyDef bodyDefBottom = new BodyDef();
bodyDefBottom.type = BodyDef.BodyType.StaticBody;
float w = Gdx.graphics.getWidth()/PIXELS_TO_METERS;
// Set the height to just 50 pixels above the bottom of the screen so we can see the edge in the
// debug renderer
float h = Gdx.graphics.getHeight()/PIXELS_TO_METERS- 50/PIXELS_TO_METERS;
bodyDefBottom.position.set(0,0);
FixtureDef fixtureDef2 = new FixtureDef();
EdgeShape edgeShape = new EdgeShape();
edgeShape.set(-w/2,-h/2,w/2,-h/2);
fixtureDef2.shape = edgeShape;
bodyEdgeScreenBottom = world.createBody(bodyDefBottom);
bodyEdgeScreenBottom.createFixture(fixtureDef2);
edgeShape.dispose();
// TOP
BodyDef bodyDefTop = new BodyDef();
bodyDefTop.type = BodyDef.BodyType.StaticBody;
w = Gdx.graphics.getWidth()/PIXELS_TO_METERS;
// Set the height to just 50 pixels above the bottom of the screen so we can see the edge in the
// debug renderer
h = Gdx.graphics.getHeight()/PIXELS_TO_METERS;
bodyDefTop.position.set(0,0);
fixtureDef2 = new FixtureDef();
edgeShape = new EdgeShape();
edgeShape.set(-w/2,h/2,w/2,h/2);
fixtureDef2.shape = edgeShape;
bodyEdgeScreenTop = world.createBody(bodyDefTop);
bodyEdgeScreenTop.createFixture(fixtureDef2);
edgeShape.dispose();
// LEFT
BodyDef bodyDefLeft = new BodyDef();
bodyDefLeft.type = BodyDef.BodyType.StaticBody;
w = Gdx.graphics.getWidth()/PIXELS_TO_METERS;
// Set the height to just 50 pixels above the bottom of the screen so we can see the edge in the
// debug renderer
h = Gdx.graphics.getHeight()/PIXELS_TO_METERS;
bodyDefLeft.position.set(0,0);
fixtureDef2 = new FixtureDef();
edgeShape = new EdgeShape();
edgeShape.set(w/2,-h/2,w/2,h/2);
fixtureDef2.shape = edgeShape;
bodyEdgeScreenLeft = world.createBody(bodyDefLeft);
bodyEdgeScreenLeft.createFixture(fixtureDef2);
edgeShape.dispose();
// RIGHT
BodyDef bodyDefRight = new BodyDef();
bodyDefRight.type = BodyDef.BodyType.StaticBody;
w = Gdx.graphics.getWidth()/PIXELS_TO_METERS;
// Set the height to just 50 pixels above the bottom of the screen so we can see the edge in the
// debug renderer
h = Gdx.graphics.getHeight()/PIXELS_TO_METERS;
bodyDefRight.position.set(0,0);
fixtureDef2 = new FixtureDef();
edgeShape = new EdgeShape();
edgeShape.set(-w/2,-h/2,-w/2,h/2);
fixtureDef2.shape = edgeShape;
bodyEdgeScreenRight = world.createBody(bodyDefRight);
bodyEdgeScreenRight.createFixture(fixtureDef2);
edgeShape.dispose();
//CONTINUE
Gdx.input.setInputProcessor(this);
//debugRenderer = new Box2DDebugRenderer();
font = new BitmapFont();
font.setColor(Color.BLACK);
camera = new OrthographicCamera(Gdx.graphics.getWidth(),Gdx.graphics.
getHeight());
}
private float elapsed = 0;
#Override
public void render() {
camera.update();
// Step the physics simulation forward at a rate of 60hz
world.step(1f / 60f, 6, 2);
body.applyTorque(torque, true);
sprite.setPosition((body.getPosition().x * PIXELS_TO_METERS) - sprite.
getWidth() / 2,
(body.getPosition().y * PIXELS_TO_METERS) - sprite.getHeight() / 2)
;
sprite.setRotation((float) Math.toDegrees(body.getAngle()));
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
//debugMatrix = batch.getProjectionMatrix().cpy().scale(PIXELS_TO_METERS,
// PIXELS_TO_METERS, 0);
batch.begin();
if(drawSprite)
batch.draw(sprite, sprite.getX(), sprite.getY(),sprite.getOriginX(),
sprite.getOriginY(),
sprite.getWidth(),sprite.getHeight(),sprite.getScaleX(),sprite.
getScaleY(),sprite.getRotation());
font.draw(batch,
"Restitution: " + body.getFixtureList().first().getRestitution(),
-Gdx.graphics.getWidth()/2,
Gdx.graphics.getHeight()/2 );
batch.end();
//debugRenderer.render(world, debugMatrix);
}
#Override
public void dispose() {
img.dispose();
world.dispose();
}
#Override
public boolean keyDown(int keycode) {
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
return false;
}
// On touch we apply force from the direction of the users touch.
// This could result in the object "spinning"
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
body.applyForce(1f,1f,screenX,screenY,true);
//body.applyTorque(0.4f,true);
return true;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
#Override
public boolean scrolled(int amount) {
return false;
}
`
I have tried searching for other posts but couldn't find anything that explains to me why it is acting like a rectangle and how to resolve this. I have also tried searching for other methods to draw the texture , even using CircleShape but that cannot put inside texture from image. I'm pretty newbie in libgdx, I'm still learning everyday.
I'm little confused... You are creating PolygonShape and expecting it will behave as circle?
PolygonShape shape = new PolygonShape();
shape.setAsBox(...
All you can achieve this way is polygon with ball sprite inside. If you want to have a circle use mentioned by you CircleShape
CircleShape shape = new CircleShape();
shape.setRadius(1); //or anything you need
...
//assing it to the fixture etc
then update it when drawing with its position and angle - that's all
Related
I'm making a game in libgdx where the main character has a light on him and where the light doesn't reach it should be dark, I'm using the setBlendFunction from SpriteBash to emulate the light. My problem is I don't know how I can make all around the light texture dark, I could size the light texture to fit the whole screen but that would be sloppy and an inconveniente in code. Does anyone have any ideas? Thanks you.
Here is a picture of the game showing my problem
Why dont't you use Box2dlight for your requirement. In my opinion you can use shader for lighting but the effect that you want that can only be achieved by using box2d body and box2dlight.
public class MyGdxGame extends ApplicationAdapter implements InputProcessor{
SpriteBatch batch;
OrthographicCamera cam;
RayHandler rayHandler;
World world;
Texture texture;
PointLight box2d;
Box2DDebugRenderer renderer;
Vector3 vector3;
Array<Body> bodies;
#Override
public void create() {
Pixmap pixmap=new Pixmap(1, 1, Pixmap.Format.RGBA8888);
pixmap.setColor(Color.WHITE);
pixmap.fillRectangle(0,0, pixmap.getWidth(), pixmap.getHeight());
world=new World(new Vector2(0,-9.8f),false);
rayHandler=new RayHandler(world);
renderer=new Box2DDebugRenderer();
bodies=new Array<>();
vector3=new Vector3();
batch=new SpriteBatch();
cam = new OrthographicCamera();
cam.setToOrtho(true,40,64);
texture=new Texture(pixmap);
rayHandler.setAmbientLight(0,0,0,.5f);
box2d=new PointLight(rayHandler, 100, new Color(1,1,1,1), 25, 10, 10);
Gdx.input.setInputProcessor(this);
{
BodyDef bodyDef = new BodyDef();
bodyDef.position.set(20, 10);
bodyDef.type = BodyDef.BodyType.StaticBody;
PolygonShape p = new PolygonShape();
p.setAsBox(8, 1.5f);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = p;
Body body = world.createBody(bodyDef);
body.createFixture(fixtureDef);
Sprite sprite=new Sprite(texture);
sprite.setSize(8*2,1.5f*2);
body.setUserData(sprite);
}
{
BodyDef bodyDef = new BodyDef();
bodyDef.position.set(20, 40);
bodyDef.type = BodyDef.BodyType.StaticBody;
PolygonShape p = new PolygonShape();
p.setAsBox(8, 1.5f);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = p;
Body body = world.createBody(bodyDef);
body.createFixture(fixtureDef);
Sprite sprite=new Sprite(texture);
sprite.setSize(8*2,1.5f*2);
body.setUserData(sprite);
}
}
#Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glClearColor(1,1,1,1);
world.step(1/60f,4,6);
renderer.render(world,cam.combined);
batch.setProjectionMatrix(cam.combined);
batch.begin();
world.getBodies(bodies);
for (Body body:bodies){
Sprite sprite=(Sprite) body.getUserData();
sprite.setPosition(body.getPosition().x-sprite.getWidth()/2,body.getPosition().y-sprite.getHeight()/2);
sprite.draw(batch);
}
batch.draw(texture,100,100);
batch.end();
rayHandler.setCombinedMatrix(cam);
rayHandler.updateAndRender();
}
#Override
public void resize(int width, int height) {
}
#Override
public void dispose() {
batch.dispose();
rayHandler.dispose();
}
#Override
public boolean keyDown(int keycode) {
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
vector3.set(screenX,screenY,0);
Vector3 v=cam.unproject(vector3);
box2d.setPosition(v.x,v.y);
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
#Override
public boolean scrolled(int amount) {
return false;
}
}
OUTPUT IS :
This is typically done with a FrameBuffer.
You want to instantiate and recreate as necessary in the resize() method so it always matches the size of the screen/window. In resize():
if (frameBuffer != null && (frameBuffer.getWidth() != width || frameBuffer.getHeight() != height)){
frameBuffer.dispose();
frameBuffer = null;
}
if (frameBuffer == null){
try {
frameBuffer = new FrameBuffer(Pixmap.Format.RGBA8888, width, height, false);
} catch (GdxRuntimeException e){ // device doesn't support 8888
frameBuffer = new FrameBuffer(Pixmap.Format.RGB565, width, height, false);
}
}
And in render(), before drawing anything in your game, you first draw the shadow map on the frameBuffer:
frameBuffer.begin();
Gdx.gl.glClearColor(/* ... */); // This will be your ambient color, a dark color, like gray
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
spriteBatch.setProjectionMatrix(camera.combined); // same camera as your game scene
spriteBatch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE); //additive blending
spriteBatch.begin();
// draw light sprites, such as a white circle where your character is standing
spriteBatch.end();
frameBuffer.end();
Then draw your game scene normally. Don't forget to change your blend function back to what you normally use (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA by default) before drawing that. And finally, draw the shadow map over the game:
// Use identity matrix so you don't have to worry about lining up the frame buffer texture
spriteBatch.setProjectionMatrix(spriteBatch.getProjectionMatrix().idt());
// Set multiplicative blending for shadows
spriteBatch.setBlendFunction(GL20.GL_ZERO, GL20.GL_SRC_COLOR);
spriteBatch.begin();
spriteBatch.draw(frameBuffer.getColorBufferTexture(), -1, 1, 2, -2); //dimensions for full screen with identity matrix
spriteBatch.end();
i'm fairly new to libgdx in general. Basically I have the ball bouncing world and i am just experimenting with it. Before I had a fixed camera position as such:
http://prntscr.com/567hvo
After I have putted the following line in the render method so the camera keeps following the player (which is the circle) :
camera.position.set(player.getPosition().x, player.getPosition().y, 0);
The player is a Body type.
So when I do this it does follow the player, but the shape renderer acts weird now. Look at what happens:
http://prntscr.com/567i9a
Even though I am referring to the same x and y position of the player to the camera and the shape renderer, they are not in the same position.
Here is my code:
public class Game extends ApplicationAdapter {
World world = new World(new Vector2(0, -9.8f), true);
Box2DDebugRenderer debugRenderer;
OrthographicCamera camera;
static final int PPM = 100;
static float height,width;
Body player;
RayHandler handler;
PointLight l1;
ShapeRenderer shapeRenderer;
#Override
public void create() {
shapeRenderer = new ShapeRenderer();
height = Gdx.graphics.getHeight();
width = Gdx.graphics.getWidth();
//set camera
camera = new OrthographicCamera();
camera.setToOrtho(false, (width)/PPM/2, (height)/PPM/2);
camera.update();
//Ground body
BodyDef groundBodyDef =new BodyDef();
groundBodyDef.position.set(new Vector2(width/PPM/2/2, 0));
Body groundBody = world.createBody(groundBodyDef);
PolygonShape groundBox = new PolygonShape();
groundBox.setAsBox((width/PPM/2/2), 0.1f);
groundBody.createFixture(groundBox, 0.0f);
//wall left
BodyDef wallLeftDef = new BodyDef();
wallLeftDef.position.set(0, 0f);
Body wallLeftBody = world.createBody(wallLeftDef);
PolygonShape wallLeft = new PolygonShape();
wallLeft.setAsBox(width/PPM/20/2, height/PPM/2);
wallLeftBody.createFixture(wallLeft,0.0f);
//wall right
BodyDef wallRightDef = new BodyDef();
wallRightDef.position.set((width/PPM)/2, 0f);
Body wallRightBody = world.createBody(wallRightDef);
PolygonShape wallRight = new PolygonShape();
wallRight.setAsBox(width/PPM/20/2, height/PPM/2);
wallRightBody.createFixture(wallRight,0.0f);
//Dynamic Body
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set((width/PPM)/2/2, (height / PPM)/2/2);
player = world.createBody(bodyDef);
CircleShape dynamicCircle = new CircleShape();
dynamicCircle.setRadius(5f/PPM);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = dynamicCircle;
fixtureDef.density = 0.4f;
fixtureDef.friction = 0.2f;
fixtureDef.restitution = 0.6f;
player.createFixture(fixtureDef);
debugRenderer = new Box2DDebugRenderer();
//Lighting
handler = new RayHandler(world);
handler.setCombinedMatrix(camera.combined);
PointLight l1 = new PointLight(handler,5000,Color.CYAN,width/PPM/2,width/PPM/2/2/2,height/PPM/2/2);
new PointLight(handler,5000,Color.PURPLE,width/PPM/2,width/PPM/2/1.5f,height/PPM/2/2);
shapeRenderer.setProjectionMatrix(camera.combined);
}
public void update() {
if(Gdx.input.isKeyJustPressed(Keys.UP)) {
player.applyForceToCenter(0, 0.75f, true);
}
if(Gdx.input.isKeyJustPressed(Keys.RIGHT)) {
player.applyForceToCenter(0.5f, 0f, true);
}
if(Gdx.input.isKeyJustPressed(Keys.LEFT)) {
player.applyForceToCenter(-0.5f, 0f, true);
}
}
#Override
public void dispose() {
}
#Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
debugRenderer.render(world, camera.combined);
world.step(1/60f, 6, 2);
handler.updateAndRender();
shapeRenderer.begin(ShapeType.Filled);
shapeRenderer.setColor(1, 1, 1, 1);
shapeRenderer.circle(player.getPosition().x, player.getPosition().y, 5f/PPM, 100);
shapeRenderer.end();
camera.position.set(player.getPosition().x, player.getPosition().y, 0);
camera.update();
update();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
You are only setting the shapeRenderers projectionmatrix once so it is not updating when you render.
You should put
shapeRenderer.setProjectionMatrix(camera.combined);
to your render method right before
shapeRenderer.begin(ShapeType.Filled);
Basically i have a circle object which acts as the player, and it can only jump. What I want to do is make the circle object keep rolling while having a constant gravity or force act on the circle object to make it keep rolling to the right on the ground. I have tried making a constant gravity by setting the vector2 x value to 0.5f:
World world = new World(new Vector2(0.5f, -9.8f), true);
When i do this the ball rapidly keeps moving faster as time goes on.
Is there way I can achieve my desired effect?
Play class code:
public class Play implements Screen,ContactListener{
World world = new World(new Vector2(0f, -9.8f), true);
Box2DDebugRenderer debugRenderer;
OrthographicCamera camera;
static final int PPM = 100;
static float height,width;
Body player;
RayHandler handler;
PointLight l1;
Body groundBody;
float tileSize;
boolean playerOnGround = false;
int footContact;
ShapeRenderer shapeRenderer;
PointLight light;
TiledMap tileMap;
OrthogonalTiledMapRenderer tmr;
BallJump game;
int level;
Color lightColor = new Color();
public Play(int level,BallJump game ) {
this.level = level;
this.game = game;
}
#Override
public void show() {
shapeRenderer = new ShapeRenderer();
height = Gdx.graphics.getHeight();
width = Gdx.graphics.getWidth();
//set camera
camera = new OrthographicCamera();
new FitViewport(width/PPM/2, height/PPM/2, camera);
if((height + width) > 1500 && (height + width) < 2000) {
camera.zoom = 0.5f;
} else if ((height + width) > 2000) {
camera.zoom = 0.75f;
}
camera.update();
//player Body
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set((width/PPM)/2/2, (height / PPM)/2/2);
player = world.createBody(bodyDef);
CircleShape dynamicCircle = new CircleShape();
dynamicCircle.setRadius(5f/PPM);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = dynamicCircle;
fixtureDef.density = 0.4f;
fixtureDef.friction = 1f;
fixtureDef.restitution = 0f;
player.createFixture(fixtureDef).setUserData("player");;
debugRenderer = new Box2DDebugRenderer();
//Lighting
handler = new RayHandler(world);
light = new PointLight(handler,500,Color.MAGENTA,4f,width/PPM/2/2/2,height/PPM/2/2);
light.attachToBody(player);
// tile map
tileMap = new TmxMapLoader().load("test2.tmx");
tmr = new OrthogonalTiledMapRenderer(tileMap,0.01f);
TiledMapTileLayer layer = (TiledMapTileLayer) tileMap.getLayers().get("block");
tileSize = layer.getTileHeight()*2;
for(int row = 0; row < layer.getHeight(); row++) {
for(int col = 0; col < layer.getWidth(); col++) {
Cell cell = layer.getCell(col, row);
if(cell == null) { continue;}
if(cell.getTile() == null) { continue;}
BodyDef bdef = new BodyDef();
bdef.type = BodyType.StaticBody;
bdef.position.set((col + 0.5f) * tileSize /PPM/2, (row + 0.5f) * tileSize /PPM/2);
PolygonShape cs = new PolygonShape();
cs.setAsBox(tileSize/2/PPM/2, tileSize/2/PPM/2);
FixtureDef fdef = new FixtureDef();
fdef.friction = 0f;
fdef.shape = cs;
world.createBody(bdef).createFixture(fdef).setUserData("ground");;
world.setContactListener(this);
}
}
}
public void update() {
playerOnGround = footContact > 0;
if(Gdx.input.isKeyJustPressed(Keys.UP) || (Gdx.input.isTouched())) {
if(playerOnGround)
player.applyForceToCenter(0, 0.75f, true);
}
else if (Gdx.input.isKeyPressed(Keys.SPACE)) {
player.setTransform((width/PPM)/2/2, (height / PPM)/2/2, 0);
}
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void beginContact(Contact contact) {
Fixture a = contact.getFixtureA();
Fixture b = contact.getFixtureB();
if(b.getUserData().equals("player") && b.getUserData() != null) {
footContact++;
player.setAngularDamping(5f);
}
if(a.getUserData().equals("player") && a.getUserData() != null) {
footContact++;
player.setAngularDamping(5f);
}
}
#Override
public void endContact(Contact contact) {
Fixture a = contact.getFixtureA();
Fixture b = contact.getFixtureB();
if(b.getUserData().equals("player") && b.getUserData() != null) {
footContact--;
}
if(a.getUserData().equals("player") && a.getUserData() != null) {
footContact--;
}
}
#Override
public void preSolve(Contact contact, Manifold oldManifold) {}
#Override
public void postSolve(Contact contact, ContactImpulse impulse) {}
#Override
public void render(float delta) {
camera.position.set(player.getPosition().x, player.getPosition().y, 0);
update();
camera.update();
shapeRenderer.setProjectionMatrix(camera.combined);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(1/60f, 6, 2);
handler.updateAndRender();
handler.setCombinedMatrix(camera.combined);
debugRenderer.render(world, camera.combined);
}
}
The gravity is a force, which is applied to every (dynamic) body in the world in every step.
That means, that the velocity of those affected object increases every frame.
Thats just the expected result, think about the reality:
If you jump from a high place, you get faster and faster, until you hit the ground (or air resistance limits your speed).
If you want to move with a constant speed (in Box2D), you should do something like that:
Vector2 vel = this.player.body.getLinearVelocity();
if (vel.x < MAX_VELOCITY) {
circle.applyLinearImpulse(impulse.x, impulse.y, pos.x, pos.y, wake);
Where impulse.x is a float, defining the impulse strength applyed in x-direction, impulse.y is the same for y-direction, pos.x and pos.y is the position, to which you want to apply the impulse (if not the center, the body will get some torque-effect) and the boolean wake defines, if the body should wake up.
i'm trying to make a program with Box2D and libgdx that makes the character jump on a static body (here, a circle). But my camera (that is following the dynamic body (the player)) keeps going down, even if my character stays on top of the circle as intended. So my questions are :
1) Why my camera keeps falling down, when it's supposed to follow the "playerBody" that is staying on top of the static body ?
2) Why my camera bounce when I press the Z key, but not my playerbody ?
Thanks in advance. You may try to run it in eclipse, to see better what I mean, here's what I put in my Activity class :
(I got no errors/warnings at all.)
//private SpriteBatch batch;
//private Texture texture;
//private Sprite sprite;
//public Body body;
World world;
Body playerBody;
Body planetBody;
CircleShape planetCircle;
PolygonShape playerBox;
OrthographicCamera camera;
Box2DDebugRenderer debugRenderer;
static final float BOX_STEP=1/60f;
static final int BOX_VELOCITY_ITERATIONS=6;
static final int BOX_POSITION_ITERATIONS=2;
static final float WORLD_TO_BOX=0.01f;
static final float BOX_WORLD_TO=100f;
boolean jump = false;
long lastGroundTime = 0;
#Override
public void create() {
world = new World(new Vector2(0, -50), true);
debugRenderer = new Box2DDebugRenderer();
camera = new OrthographicCamera();
camera.viewportHeight = 320;
camera.viewportWidth = 480;
camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f);
camera.update();
//Ground body
/*BodyDef groundBodyDef =new BodyDef();
groundBodyDef.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2 - 100 + 125);
Body groundBody = world.createBody(groundBodyDef);
PolygonShape groundBox = new PolygonShape();
groundBox.setAsBox((camera.viewportWidth) * 2, 10.0f);
groundBody.createFixture(groundBox, 0.0f);
*/
//Planet
BodyDef planetDef = new BodyDef();
planetDef.type = BodyType.StaticBody;
planetDef.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2 - 100);
Body planetBody = world.createBody(planetDef);
CircleShape planetCircle = new CircleShape();
planetCircle.setRadius(125f);
FixtureDef planetFixtureDef = new FixtureDef();
planetFixtureDef.shape = planetCircle;
planetFixtureDef.density = 1.0f;
//planetFixtureDef.friction = 0.0f;
//planetFixtureDef.restitution = 0;
planetBody.createFixture(planetFixtureDef);
//Player
BodyDef playerBodyDef = new BodyDef();
playerBodyDef.type = BodyType.DynamicBody;
playerBodyDef.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2 - 100 + 125 + 50);
playerBody = world.createBody(playerBodyDef);
PolygonShape playerBox = new PolygonShape();
playerBox.setAsBox(5.0f, 15.0f);
FixtureDef playerFixtureDef = new FixtureDef();
playerFixtureDef.shape = playerBox;
playerFixtureDef.density = 1.0f;
//playerFixtureDef.friction = 1.0f;
//playerFixtureDef.restitution = 1;
playerBody.createFixture(playerFixtureDef);
playerBody = world.createBody(playerBodyDef);
//Dynamic Body
/*BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2);
Body body = world.createBody(bodyDef);
CircleShape dynamicCircle = new CircleShape();
dynamicCircle.setRadius(5f);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = dynamicCircle;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.0f;
fixtureDef.restitution = 1;
body.createFixture(fixtureDef); */
Gdx.input.setInputProcessor(this);
}
#Override
public void dispose() {
/*batch.dispose();
texture.dispose();*/
/*dynamicCircle.dispose();
groundBox.dispose();*/
playerBox.dispose();
planetCircle.dispose();
}
#Override
public void render() {
//Gdx.gl.glClearColor(1, 1, 1, 1);
update();
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
/*batch.setProjectionMatrix(camera.combined);
batch.begin();
//sprite.draw(batch);
batch.end();*/
camera.position.set(playerBody.getPosition().x, playerBody.getPosition().y, 0);
camera.update();
//camera.apply(Gdx.gl10);
debugRenderer.render(world, camera.combined);
world.step(BOX_STEP, BOX_VELOCITY_ITERATIONS, BOX_POSITION_ITERATIONS);
//playerBody.setAwake(true);
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
public void update()
{
if(jump == true /*Gdx.input.isKeyPressed(Gdx.input.)*/ && grounded() == true)
{
playerBody.setLinearVelocity(0, 0);
playerBody.applyLinearImpulse(new Vector2(0,150), new Vector2(playerBody.getPosition().x, playerBody.getPosition().y));
jump = false;
}
//playerBody.setTransform(new Vector2(camera.viewportWidth / 2, playerBody.getPosition().y), playerBody.getAngle());
//planetBody.setTransform(new Vector2(camera.viewportWidth / 2, camera.viewportHeight / 2), 0);
}
#Override
public void resume() {
}
#Override
public boolean keyDown(int keycode) {
//if(keycode == Keys.S)
return false;
}
#Override
public boolean keyUp(int keycode) {
if(keycode == Keys.Z)
jump = true;
return false;
}
public boolean grounded()
{
if(playerBody.getPosition().y <= ((camera.viewportHeight / 2) - 100 + 125))
{
return true;
}
else
{
return false;
}
}
You are creating two playerBody in the world. The second one is assigned but has no fixture. This is the one you are manipulating in your code and your camera is following. Remove the second playerBody = world.createBody(playerBodyDef); and it should work (better).
I'm beginner with libgdx and i looking for answer how to link actor and body(box2d) for a lot time, so please help me :(
I have following code:
/// CLASS ACTOR
public class MyActor extends Actor
{
Texture texture;
float actorX = 0, actorY = 0;
public boolean clicked = false;
public String id;
public MyActor(float x, float y, String id, String tekstura)
{
this.texture = new Texture(Gdx.files.internal(tekstura));
this.id = id;
actorX = x;
actorY = y;
setBounds(actorX, actorY, texture.getWidth(), texture.getHeight());
addListener(new InputListener()
{
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button)
{
MyActor co = ((MyActor) event.getTarget());
co.clicked = true;
System.out.println(co.id);
co.remove();
return true;
}
});
}
#Override
public void draw(SpriteBatch batch, float alpha)
{
batch.draw(texture, actorX, actorY);
}
}
/*....................
.......................
........................
..........................*/
//CREATING SIMPLE OBJECT
MyActor samolot1 = new MyActor(100, 300, "samolot1", "data/jet.png");
samolot1.setTouchable(Touchable.enabled);
stage.addActor(samolot1);
// //////////////// WORLD /////////////////////////////////////////////
// 1
BodyDef bodydef_mojapostac = new BodyDef();
bodydef_mojapostac.type = BodyType.DynamicBody;
bodydef_mojapostac.position.set(400, 100);
CircleShape shape_mojapostac = new CircleShape();
shape_mojapostac.setRadius(30);
FixtureDef fixturedef_mojapostac = new FixtureDef();
fixturedef_mojapostac.density = 0.1f;
fixturedef_mojapostac.friction = 0.8f;
fixturedef_mojapostac.restitution = 0.7f;
fixturedef_mojapostac.shape = shape_mojapostac;
Body BodyMojaPostac = world.createBody(bodydef_mojapostac);
BodyMojaPostac.createFixture(fixturedef_mojapostac);
BodyMojaPostac.setUserData(samolot1);
and render()
......
batch.begin();
world.getBodies(tmpBodies);
for (Body body : tmpBodies)
if (body.getUserData() != null)
{
System.out.println(body.getUserData());
MyActor dupa = (MyActor) body.getUserData();
batch.draw(dupa.texture, dupa.actorX, dupa.actorY);
}
batch.end();
.....
I can link body with sprite but i don't know how with actor :(
After having trouble with this combination as well I'd like to share my solution:
public class PhysicsActor extends Image {
private Body body;
private Fixture fixture;
public PhysicsActor(World world, BodyDef bodyDef, FixtureDef fixtureDef, TextureRegion textureRegion) {
super(textureRegion);
body = world.createBody(bodyDef);
setFixture(getBody().createFixture(fixtureDef));
}
#Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
}
public Body getBody() {
return body;
}
public Fixture getFixture() {
return fixture;
}
I use it like this:
bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(Toolkit.Screen2World(x), Toolkit.Screen2World(y));
pShape = new PolygonShape();
pShape.setAsBox(Toolkit.Screen2World(width/2), Toolkit.Screen2World(height/2)); //In Toolkit I have my methods to scale the world
fixtureDef = new FixtureDef();
fixtureDef.shape = pShape;
//Set some more attributes i.e. density
//Add the PhysicsActor
PhysicsActor leftBar = new PhysicsActor(world, bodyDef, fixtureDef, new TextureRegion(Resources.barLeftTexture, 0, 0, width, height));
leftUpperBar.setSize(width, height);
this.addActor(leftUpperBar);
You only must set your width and height manually (in my case I use the resolution of my Texture).
Resources.barLeftTexture:
public static Texture barLeftTexture;
barLeftTexture = new Texture(Gdx.files.internal("data/barLeft.png"));
I noticed that your question may be outdated for you (the OP) but maybe it helps somebody stumbling across this question.