Working on a sidescrolling platform type game and running into a weird issue with my character. If he moves into the side of a platform and I continue to hold the movement button he just sticks to it and doesnt fall until I let up the movement key. Here is my movement code:
public void move(float percent){
float desiredVel = speed.x *percent;
float velChange = desiredVel - b2body.getLinearVelocity().x;
float impulse = b2body.getMass() * velChange;
b2body.applyLinearImpulse(new Vector2(impulse,0),b2body.getWorldCenter(),true);
}
This is called given a percent based on a touchpad controller, but basically percent is somewhere between -1 and 1. This is my body/fixture for the character:
BodyDef bdef = new BodyDef();
bdef.position.set(704/ Constants.PPM, 1000/Constants.PPM);
bdef.type = BodyDef.BodyType.DynamicBody;
b2body = world.createBody(bdef);
b2body.setFixedRotation(true);
//Hitbox
FixtureDef fixtureDef = new FixtureDef();
PolygonShape shape = new PolygonShape();
shape.setAsBox(20/Constants.PPM,45/Constants.PPM);
fixtureDef.shape = shape;
//Add in category and mask bits
hitbox = b2body.createFixture(fixtureDef);
hitbox.setUserData("hitbox");
And this is the body/fixture for the platforms:
bdef.type = BodyDef.BodyType.StaticBody;
bdef.position.set((rect.getX() + rect.getWidth() / 2) / Constants.PPM, (rect.getY() + rect.getHeight() / 2) / Constants.PPM);
body = world.createBody(bdef);
shape.set(new Vector2(-rect.getWidth()/2/Constants.PPM, rect.getHeight()/2/Constants.PPM),new Vector2(rect.getWidth()/2/Constants.PPM, rect.getHeight()/2/Constants.PPM));
fdef.shape = shape;
fdef.friction = 0.5f;
fdef.density = 1;
fdef.filter.categoryBits = Constants.GROUND_BIT;
body.createFixture(fdef).setUserData("platform");
This is caused by the friction generated by the player pushing into the platform which overcomes gravity.
A few things you could try:
Reduce the friction of the character or platforms to reduce friction.
Add a sensor to detect when these friction collisions are happening and disable the user input for that direction.
Add friction free bodies on sides of platforms or sides of player
Related
I have issue in my LibGdx program. I gave 800 height and 480 width to my camera. I am drawing target under coordinates :
randomTargetX = new Random().nextInt((350 - 100) + 1) + 100;
randomTargetY = new Random().nextInt((600 - 300) + 1) + 300;
But after clicking on target my cannonball don't overlap target rectangle.
I am doing this in Touch:
if (Gdx.input.justTouched()) {
touchX = Gdx.input.getX();
touchY = Gdx.input.getY();
camera.unproject(touch.set(touchX, touchY, 0));
if (touch.y>200) {
isTouched = true;
rectangleCannonBall.x = (width / 2) - 50 / 2;
rectangleCannonBall.y = 0;
double angle = 180.0 / Math.PI * Math.atan2(rectangleCannonBall.x - touch.x, touch.y - rectangleCannonBall.y);
spriteCannon.setRotation((float) angle);
}
}
Doesn't work.
It's a cannonball game:
First i am setting camera.
Randomly showing targets inside range of coordinates.
On touch unprojecting camera with Vector3 new position.
On touch calculating target position with cannon position and getting angle to rotate cannon.
After rotating cannon I fire ball towards target.
Now when I do Rectanglar1.overlaps(rec2) , it doesn't work because of both rectangles have different points but by visible both overlaps each other.
When I check coordinates of Rectangle of Target and Touch its different.
The line:
camera.unproject(touch.set(touchX, touchY, 0));
Doesn't do anything.
Try with:
touch = camera.unproject(touch.set(touchX, touchY, 0));
I want to get the angle between point 1 and point 2 in relation to a center point. How do I do this using Vector2?
Vector2 center = new Vector2((float)Gdx.graphics.getWidth /2, (float)Gdx.graphics.getHeight /2);
Vector2 point1 = new Vector2(center.x, center.y + 200.0f);
Vector2 point2 = new Vector2(center.x + 200.0f, center.y);
It should be 90°, but how do I get that?
Vector2 center = new Vector2(500, 500);
Vector2 point1 = new Vector2(center.x, center.y + 200.0f);
Vector2 point2 = new Vector2(center.x + 200.0f, center.y);
point1.sub(center).nor();
point2.sub(center).nor();
float angle = (MathUtils.atan2(point1.y, point1.x) - MathUtils.atan2(point2.y, point2.x));
angle *= MathUtils.radiansToDegrees;
System.out.println(angle); // 90.0
The angle calculation can be looked up anywhere on the internet. For example here.
It works with one additional step that we perform before the calculation. We need to treat the center as the (0, 0) origin, by subtracting it from the points and normalize them afterwards.
Get the vector of both points and subtract there rotation/worldAngle. Something like this should do:
Vector2 v1 = point1.cpy().sub(origin);
Vector2 v2 = point2.cpy().sub(origin);
float angle1 = v1.angle();
float angle2 = v2.angle();
float angleBetween = Math.abs(angle1 - angle2));
//If the angle is more then 180 then comparing the other way around would be shorter.
if (angleBetween > 180)
angleBetween = 360 - angleBetween;
I am trying to create a sample circle to test the pixel per meter.
My PPM is set to 100.
Height and width was set to 320 and 480
Do you why It won't center in y axis but it will center in x axis. also when I set the radius to 50 it doens't draw anything. Am I missing something here?
this.world = new World(new Vector2(0.0f, -9.8f), true);
BodyDef bodyDef = new BodyDef();
bodyDef.position.set( App.WIDTH / 2 / PPM, App.HEIGHT / 2 / PPM);
bodyDef.type = BodyDef.BodyType.StaticBody;
Body body = world.createBody(bodyDef);
FixtureDef fixtureDef = new FixtureDef();
CircleShape shape = new CircleShape();
shape.setRadius(100 / PPM);
fixtureDef.shape = shape;
body.createFixture(fixtureDef);
shape.dispose();
player = new Player(body);
box2DDebugRenderer = new Box2DDebugRenderer();
box2dCam = new OrthographicCamera();
box2dCam.setToOrtho(false, App.WIDTH / PPM , App.HEIGHT / PPM );
When Radius is 100, when radius is 50 the screen is just plain black
Nevermind guys.
shape.setRadius((float) 20 / PPM); I had to cast it to float to show all lower than 100
PPM was declared int should be float to avoid casting.
to center it on screen
box2dCam.position.set(App.WIDTH / 2 / PPM, App.HEIGHT / 2 / PPM, 0);
I've got the following settings:
private static final float SCENE_WIDTH = 1280;
private static final float SCENE_HEIGHT =720;
//Gravity
world = new World(new Vector2(0,-9.8f), true);
camera = new OrthographicCamera();
viewport = new FitViewport(SCENE_WIDTH, SCENE_HEIGHT, camera);
//viewport.apply();
camera.position.set(SCENE_WIDTH * 0.5f, SCENE_HEIGHT * 0.5f, 0);
And then I create a body with the following features:
//Center the body so it can start falling down
defaultDynamicBodyDef.position.x = SCENE_WIDTH * 0.5f;
defaultDynamicBodyDef.position.y = SCENE_HEIGHT * 0.5f;
// Shape for square
square = new PolygonShape();
// IMPORTANT 100 = 1m
square.setAsBox(100, 100);
// Fixture definition for our shapes
boxFixtureDef = new FixtureDef();
boxFixtureDef.shape = square;
boxFixtureDef.density = 0.8f;
boxFixtureDef.friction = 0.8f;
boxFixtureDef.restitution = 0.15f;
See above where it says IMPORTANT. With these settings when 1m = 100 scaling the square falls down slowly.
But if my settings are like:
private static final float SCENE_WIDTH = 12.8f;
private static final float SCENE_HEIGHT =7.2f;
and then change the square size to:
// Shape for square
square = new PolygonShape();
// IMPORTANT 1m = 1
square.setAsBox(1f, 1f);
the square falls down much faster? I am confused. So to sum up, having world units 1280 and 720 with the square parameters 100 and 100 the body falls slower than world units of 12.8 and 7.2 and 1 & 1 for the squre. In both cases I use world units but the speed of fall is different? Why is that?
Because the gravity is the same in both examples. So the square's will move at the same speed/acceleration and with the smaller viewport in the second example the square will be faster out of screen.
I am experimenting with collision detection using Box2d Between a ball and four walls of a rectangular block which I call the gameBed.
I am using the below code to setup the ball and the LeftEdge(left wall in this case) Bodies. For brevity I am giving the code only for the left wall.
b2World = new World(new Vector2(0, 0), false);
World.setVelocityThreshold(0);
GameBed gameBed = levelManager.retGameBed(); // rectangular block
Vector2 origin = new Vector2();
BodyDef leftWallDef = new BodyDef();
leftWallDef.type = BodyType.StaticBody;
leftWallDef.position.set(gameBed.position); // gameBed.position is the world co-ordinate of the bottom left corner of the rectangular block
Body body = b2World.createBody(leftWallDef);
PolygonShape leftWallShape = new PolygonShape();
origin.x = 0.005f;
origin.y = (float)(gameBed.bounds.getHeight()) / 2;
float widthOfLeftWall = BallsMania_Constants.VIEWPORT_WIDTH/(2 * Gdx.graphics.getWidth());
Gdx.app.log(TAG, "Width of Left Wall is " + widthOfLeftWall);
leftWallShape.setAsBox(.1f,
gameBed.bounds.height/2, origin, 0); // setting the half of width to .1f so that it represents an edge. The height of the edge should be as long as the rectangular edge.
FixtureDef leftWallFixtureDef = new FixtureDef();
leftWallFixtureDef.shape = leftWallShape;
leftWallFixtureDef.restitution = 0.9f;
body.createFixture(leftWallFixtureDef);
leftWallShape.dispose();
// Defining shape and fixture for ball
Ball ball = new Ball();
BodyDef ballBodyDef = new BodyDef();
ballBodyDef.type = BodyType.DynamicBody;
ballBodyDef.position.set(ball.position);
ballBodyDef.linearDamping = 0.4f;
ball.body = b2World.createBody(ballBodyDef);
CircleShape ballShape = new CircleShape();
ballShape.setPosition(new Vector2(0, -1 * (float)(BallsMania_Constants.VIEWPORT_HEIGHT/2.0
- BallsMania_Constants.bottomBaseDelta
+ ball.dimension.x/2)));
ballShape.setRadius(ball.dimension.x/2);
FixtureDef ballBodyFixture = new FixtureDef();
ballBodyFixture.shape = ballShape;
ballBodyFixture.friction = 0.5f;
ballBodyFixture.restitution = 0.5f;
ball.body.createFixture(ballBodyFixture);
ballShape.dispose();
Problem:
The ball doesn't collide with the leftedge; it just permiates through it and doesn't bounce.
Any guidance would be appreciated.