Libgdx - Having one Entity partially exempt from Phsyics - java

I'm using LibGDX to make a mobile game, now I'm facing a certain issue.
I have a certain Entity which can collide with the wall, when this happens the wall receives a certain force which then causes it to go off the screen and not be positioned properly anymore.
I have tried using LibGDX's isSensor variable but after doing that my Entity crosses straight through the wall.
How can I make it so the wall does stop the Entity from moving through but isn't affected itself by the force of the Entity?
I'm using the physics body editor for my colission shapes as they are not in normal geometrical formats.
Thank you,
Rene

You just need to make the wall static.
I'm not sure how you do it using the physics body editor as I've never used it, but here's some code I wrote a while back that does something similar...
private void buildRoom()
{
Vector2[] roomCorners = new Vector2[]{new Vector2(0f, 0f),
new Vector2(0f, ROOM_HEIGHT),
new Vector2(ROOM_WIDTH, ROOM_HEIGHT),
new Vector2(ROOM_WIDTH, 0f)};
ChainShape roomShape = new ChainShape();
try
{
roomShape.createLoop(roomCorners);
BodyDef roomDef = new BodyDef();
roomDef.type = BodyDef.BodyType.StaticBody;
Body room = world.createBody(roomDef);
room.createFixture(roomShape, 0);
} finally
{
roomShape.dispose();
}
}

Related

How do I make a Rectangle properly collide with an object in libGDX?

sorry for the badly worded question, I'm not exactly sure how to ask this. I'm making a small game with LibGDX and I'm having trouble with collisions.
Basically, my original idea was to simply check whether or not the terrain rectangle and the player rectangle overlapped each other, and if they did, I would move the player rectangle so that it wouldn't overlap the terrain. However, I did this and it wasn't working how I had expected, and it was basically thinking that the top and bottom of the player rectangle were also colliding with the side of the terrain, and then it slides the rectangle along the terrain.
So, I was recommended to try to make a sort of box cast and honestly it hasn't really been working either. I'm new to libgdx so I'm not sure if there's an easier way to do this or not but I've tried looking around. Here's my code:
void handleCollisions() {
Rectangle pRect = player.getRect();
for(Rectangle mapRect : mapRects) { //mapRect is the terrain rectangle
//if(mapRect.overlaps(pRect)) {
float amountCollidedTop = 0f;
float amountCollidedBottom = 0f;
float amountCollidedLeft = 0f;
float amountCollidedRight = 0f;
float xCollided = 0;
float yCollided = 0;
if(mapRect.overlaps(player.boxCastTop)) {
}
if(mapRect.overlaps(player.boxCastRight)) {
xCollided = player.boxCastRight.x + player.boxCastRight.width - mapRect.x;
if(mapRect.y > player.boxCastRight.y) {
yCollided = mapRect.height-(mapRect.y - player.boxCastRight.y);
} else {
yCollided = mapRect.height-(player.boxCastRight.y-mapRect.y);
}
//what percentage of the box cast is being collided with?
amountCollidedRight = (xCollided*yCollided)/player.boxCastRight.area();
System.out.println(amountCollidedRight);
}
//}
}
}
Here's what the collision looks like
Here is what is appearing in the console
Maybe this isn't the way to go with collisions? If it isn't, is there another way that works better? If anyone needs anything clarified please let me know. Thanks!
You should have a look at the libGDX Demo Projects for reference.
Especially libgdx-demo-cuboc could be interesting for you, since it is a platformer with a simple collision system (most of it is implemented in the class Bob I think).
Or if you want to use Box2D (a 2D physics library that many libGDX projects make use of) you can have a look at the libgdx-demo-vector-pinball project.

Libgdx ,can i attach animation in a Body?

im kinda new here, anywho... i am interested in the android gaming app development and i am learning on my own how to do so, using Libgdx as my game-engine and already made a small game not something exciting.
i have recently started to learn how to use the World variable and creating bodies in it, i want to create a class that extends Actor, give it animations (i know how to give animations) and to try and display it on the body, so where ever the body goes, the animation is played on it (basically below the animation is the body that is not displayed ofc)
so my question is : is there a way to give this costume actor into the body so it will play it over the body? (attaching them)
Will appreciate the help!
** NOTE : be aware that my knowledge is still limited, i am a college student for Program Engineering and i am not fully into much depth in java yet (my college not teaching game-engines) **
UPDATE
i have created a costume class, made animations to each action (like herowalk, herosit ... etc...)
i wrote a render method in it :
public void render(SpriteBatch batch) {
float posX = bbody.getPosition().x * PPM;
float posY = bbody.getPosition().y * PPM;
float rotation = (float) Math.toDegrees(bbody.getAngle());
sprite.setPosition(posX,posY);
sprite.setRotation(rotation);
sprite.draw(batch);
}
and created a body, placed it in the middle of my screen and attached the sprite to it using SetUserData() :
BodyDef bdef = new BodyDef();
bdef.position.set(160 / PPM, 200 / PPM);
bdef.type = BodyDef.BodyType.DynamicBody;
PolygonShape shape = new PolygonShape();
shape.setAsBox(5 / PPM, 5 / PPM);
bbody = world.createBody(bdef);
Bodyarray.add(bbody);
FixtureDef fdef = new FixtureDef();
fdef.shape = shape;
fdef.filter.categoryBits = BIT_BOX;
fdef.filter.maskBits = BIT_PLATFORM | BIT_BALL;
bbody.createFixture(fdef);
bbody.setUserData(sprite);
and in my main class where i draw with batch i wrote :
player.sprite.setRegion(player.getAnimationup().getKeyFrame(dt, true));
dt += elapsedTime;
player.render(batch);
to constantly change the animations depends on if the player turns to the right, left, up , down.
the only problem i have is that the sprite it self (the animation works perfectly) is being drawn on the bottom left side of the screen (not on 0,0, it looks like it got the x,y of the body but still away from it) and can see that its attached to it when moving the body (i put controls to control the body movement) and i see the sprite moving with it.
for example im trying to check the coordination of X,Y for both the body and the sprite with Gdx.app.log as usual and both have the SAME exact X and Y. (ofc the sprite has his multiplied by PPM (placed it as 100) since the sprite is not a physical body)
what is causing the wrong location of the sprite?
Welcome to Stack Overflow!
The answer to your question is "Not exactly." Box2D gives you a method called Body#setUserData() which lets you create a reference from the Body to any object (in this case an Animation object, but it is up to you to keep their positions in sync. See the pseudo-code below adapted from the libGDX wiki:
// Create an array to be filled with the bodies
// (better don't create a new one every time though)
Array<Body> bodies = new Array<Body>();
// Now fill the array with all bodies
world.getBodies(bodies);
for (Body b : bodies) {
// Get the body's user data - in this example, our user
// data is an instance of the Entity class
Animation anim = (Animation) b.getUserData();
if (anim != null) {
// Update the entities/sprites position and angle
TextureRegion frame = anim.getKeyFrame( ... );
// Now draw the frame using b.getPosition() and b.getAngle()
}
}
By the way, the libGDX wiki is an excellent resource and reference as you start learning libGDX.

Text not displaying in LibGdx Java

I am trying to add text for debugging purposes in my program. I call the players debugDraw method like so in the main class:
public void create () {
//Initialize essentials
cam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.setToOrtho(false);
rend = new ShapeRenderer();
rend.setAutoShapeType(true);
batch = new SpriteBatch();
// Initialize Entities
player = new Player(new Vector2(100, 100), new Vector2(100,100));
enemy = new Enemy(new Vector2(100, 100), new Vector2(100,10));
}
#Override
public void render () {
//Update player
player.update();
//Update camera then set matrix of batch
cam.update();
batch.setTransformMatrix(cam.combined);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// ShapeRenderer begin
rend.begin();
player.render(rend);
enemy.render(rend);
rend.end();
// ShapeRenderer end
// SpriteBatch begin
batch.begin();
player.renderDebugText(batch);
batch.end();
// SpriteBatch end
}
Here is the entity class which is the parent class to player:
public Entity(Vector2 coords, Vector2 dims){
//Assign constructors
position = coords;
dim = dims;
//For debugging purposes of all entities
debugText = new BitmapFont();
debugText.setColor(Color.WHITE);
}
public void renderDebugText(SpriteBatch batch){
debugText.draw(batch, "Vel.x: " + vel.x, 100, 100);
}
However when I run the program, I just get my normal screen with no text at all. I can't seem to figure out why this isn't working. Any help is extremely appreciated.
Nothing immediately looks wrong with the code you posted, so here's a few ideas;
The default BitmapFont is 15pt, if this is drawn at 15px height then it could be very small if you force your game to a high resolution, like Full-HD. My current project is Full-HD and the font I use looks just about right at 45px, so you could try scaling yours by a factor of 3 or 4. E.g. use this after initialising your font;
bitmapFont.getData().setScale(3);
Your Camera should also have the virtual/viewport dimensions, so if you are forcing a particular resolution then you should pass in your virtual dimensions instead.
As #Tenfour04 has suggested, you should try to avoid multiple instances of the same font, so instead of initialising your font in the Entity class, initialise it in your main game and pass it through the Entity constructor. I can't see how this would fix your issue though as this would be purely for performance.
I made a very simple mistake, but from how much code I posted, it is easily missed. On the line where I put
batch.setTransformMatrix(cam.combined);
it should be replaced with
batch.setProjectionMatrix(cam.combined);
Then all errors go away, sorry, I don't know why it took me so long to figure out. Thanks for all the help!

Bullet physics, textured sphere doesnt roll

I am trying to battle my way through learning Java and bullet physics all in one go. Quite possible a little too much to do all at once but I like a challenge.
So far, I've learned how to import g3db objects, apply bullet physics to them and interact with them on the screen by using the following code:
assets = new AssetManager();
assets.load("globe.g3db", Model.class);
assets.load("crate.g3db", Model.class);
assets.finishLoading();
Model model = assets.get("globe.g3db", Model.class);
ModelInstance inst = new ModelInstance(model);
inst.transform.trn(0, 20, 0);
btRigidBody body;
btSphereShape sh = new btSphereShape(1);
sh.calculateLocalInertia(1, new Vector3(0,0,0));
body = new btRigidBody(new btRigidBody.btRigidBodyConstructionInfo(3, new btDefaultMotionState(inst.transform), sh));
body.setUserValue(Minstances.size);
body.proceedToTransform(inst.transform);
motionState = new MyMotionState();
motionState.transform = inst.transform;
body.setMotionState(motionState);
dynamicsWorld.addRigidBody(body );
Minstances.add(inst);
This works fine, if I set it above the ground it falls and comes to rest on the ground, however when it moves about it slides rather than rolls.
Is there an easy fix?
To allow rolling of a physical body, you need to calculate its local inertia and provide it to the construction info. In your code you're almost doing it right.
The method
btCollisionShape.calculateLocalInertia(float mass, Vector3 inertia)
indeed calculates local inertia but stores it in its second argument 'Vector3 inertia'. No changes are applied to btCollisionShape itself.
After obtaining the vector of inertia you need to pass it to
btRigidBodyConstructionInfo(float mass, btMotionState motionState, btCollisionShape collisionShape, Vector3 localInertia)
as the last argument.
The correct code should look like this:
btRigidBody body;
btSphereShape sh = new btSphereShape(1);
Vector3 inertia = new Vector3(0,0,0);
sh.calculateLocalInertia(1, inertia);
body = new btRigidBody(new btRigidBody.btRigidBodyConstructionInfo(3, new btDefaultMotionState(inst.transform), sh, inertia));
Local inertia is not required to perform the simulation, but without it, all forces applied to bodies are treated as central forces and therefore cannot affect angular speed.
You need to read out and set the rotation as well, right now you are just reading \ applying the translation.
Create a new quaternion and get the xyzw values and apply them to your object.
something like this (c++ code, but you can easily do the same in java):
btTransform trans;
Quat myquat;
yourBulletDynamicObject->getMotionState()->getWorldTransform(trans);
btQuaternion rot = trans.getRotation();
myquat.w = rot.w();
myquat.x = rot.x();
myquat.y = rot.z();
myquat.z = rot.y();
set myquat back on your object.

Andengine and box2d collision detection

I'm using AndEngine and Box2d in android application.
What to I have to do so that when player and coin collide, the player goes through coin without hitting against it as if it is a wall?
public class GameScene extends Scene {
GameScene() {
Body playerBody = PhysicsFactory.createBoxBody(world, playerSprite, BodyType.DynamicBody, fixtureDef);
PhysicsConnector playerConnector = new PhysicsConnector(playerSprite, playerBody, true, false);
world.registerPhysicsConnector(playerConnector);
Body coinBody = PhysicsFactory.createBoxBody(world, coinSprite, BodyType.StaticBody, fixtureDef);
PhysicsConnector coinConnector = new PhysicsConnector(coinSprite, coinBody, true, false);
world.registerPhysicsConnector(coinConnector);
}
private ContactListener createContactListener(){
//if player and coin collide --> destroy coin
}
}
Read about sensor fixtures in Box2D. You want your coin to be a sensor. From the Box2D manual:
Sometimes game logic needs to know when two fixtures overlap yet there
should be no collision response. This is done by using sensors. A
sensor is a fixture that detects collision but does not produce a
response.

Categories

Resources