I'm trying to create a simple infinite runner game. I am using Box2D for physics. When I play the game, I can see the blocks (things you are jumping on) shuttering / moving really fast from side to side (dunno if that's the word I should use). It is like there is something wrong with delta.
My game's logic:
Array of blocks - static bodies, I have always 10 blocks on the scene (if you can't see it, remove it, spawn new one, etc)
Player - dynamic body - jumping on the blocks
Camera - following player
My world has got vertical gravity (makes player fall down). I move the player by updating his linear velocity
Vector2 velocity = body.getLinearVelocity();
body.setLinearVelocity(5, velocity.y);
Drawing him this way:
batch.draw(texture, body.getPosition().x - 0.5f + delta, body.getPosition().y - 0.5f + delta, 1, 1);
As you can see, I tried to add delta to the drawing, but that didn't change anything. I draw my blocks the same way.
When I change the physics update time to 60 times per second (same as FPS), game runs much more smoothly, but I can still see that strange effect (my eyes hurt after playing it!).
Do you have any idea what can cause it? If you need anything else, I can add it.
Related
I'm making a 2D platformer game. I have created a texture for the platform, that is meant to be repeated over and over to fill the entire platform, without going over. My first attempt was to draw all the pixels from the bitmap manually, but this caused the background to flicker through while moving the platform (the movement and drawing threads are seperate, so the movement can run at a specific speed, while the FPS doesn't need to suffer). I found this technique worked better:
// Init
bitmap = new BitmapDrawable(res, Texture.PLATFORM.getBitmap());
bitmap.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
// Drawing loop
int x = getX() + (isStill() ? 0 : (int)MainActivity.offsetX);
int y = getY() + (isStill() ? 0 : (int)MainActivity.offsetY);
bitmap.setBounds(x, y, x + getWidth(), y + getHeight());
bitmap.draw(canvas);
However, the bitmap appears to be staying static while the platform is acting as a "view hole" to see through to the bitmap. The only work around I can think of is to somehow "offset" the static bitmap:
bitmap.offset(x, y);
Obviously, that isn't a function. I couldn't find one that would do what I want when looking through the docs.
To summon things up, the BitmapDrawable is causing the background to not move with the platform, making it look super weird.
Thanks in advance!
Try these tips in your code:(I assumed the game moves forward in the horizontal direction)
The GUY should only move up and down(with the appropriate touch input) and not forward and backward as you want the focus(or camera alternatively) solely on the GUY.I noticed that the WALL was moving up in your video when the GUY moved from initial higher position of the wall to little bit lower position later, rectify this because the GUY should move down(try to implement Gravity effect).
The WALL should only move forward(mostly) and backward(less often I guess).The WALL shouldn't move up and down normally. Do not apply Gravity effect to it. You can create at least 2 BitmapDrawable instance of WALL for a screen. They are going to be reused sequencially(for eg: If the 1st one goes totally outside of the screen, reshow it in the desired position using setBounds() method) and continue same for others the whole game.
The currently BLUE BACKGROUND, if it is a part of a larger map, then it needs to be appropriately offsetted.
One of the obstacles that I can think of at the time of writing this is to move the WALL down until it goes out of the screen which results in the death of the GUY.
At those places, where I have used the word move, you need to use the setBounds(a, b, c, d) method to make necessary position based changes as I didn't find other way to update the position of a BitmapDrawable instance. I think, you need to use game framework like libGdx to get method of luxury like setOffset(x, y) or of similar sort.
Sorry that I could only present you the ideas without specific code as I do not have past experience working in a project like this. Hope, it helps you in anyway possible.
I am creating a Java desktop 2D Game using LibGDX.
I need to be able to move objects (controlled by the player with W/A/S/D).
The movement speed is always the same (read out from a field of the moving object).
While they are moving, they should still be affected by physics.
This means that when moving away from a magnet would make you move slower, moving towards it makes you faster and moving past it would cause you to move a curve. (see blue part of image)
Also a single impulse in while moving would knock you away but you keep moving (see red part of image)
You should also be able to change direction or stop, only stopping your own movement, so you will still be affected by physics.
So I need to apply constant forces that will still be accessible (and removable) after the next step.
Can I do this with Box2D?
-If yes, how?
-If no, any other libraries that can do this? I don't really need density and stuff like that, the use cases in the image is pretty much all I need (+ Collision Detection).
*A magnet would be a body constantly pulling other bodies in a certain range to itself
*Kockback would just be a simple impulse or the collision of a projectile with the object.
EDIT: If you know The Binding of Isaac, thats the kinda physics I'm aiming for.
Set the distance where the magnet has his influence:
float magnetRadius = 30;
Set the attractive force of the magnet:
float magnetForce = 400;
Get the position of the player and of the magnet:
Vector2 magnetPos = magnet.getWorldCenter();
Vector2 playerPos = player.getWorldCenter();
Now calculate the distance between the player and the magnet:
Vector2 magnetDist = new Vector2((playerPos.x - magnetPos.x), (playerPos.y - magnetPos.y));
float distance = (float) Math.sqrt((magnetPos.x) * (magnetPos.x) + (magnetPos.y) * (magnetPos.y));
Then, if the player is inside the magnet's radius, you must apply a force to him that depends on the distance of the player from the magnet:
if (distance <= magnetRadius) {
float vecSum = Math.abs(magnetDist.x)+Math.abs(magnetDist.y);
Vector2 force = new Vector2((magnetForce*magnetDist.x * ((1/vecSum)*magnetRadius/distance)), (magnetForce*magnetDist.y * ((1/vecSum)*planetRadius/distance)));
player.applyForceToCenter(force, true);
}
I'm making a platformer game. The jumping and movement are working, and now I want to program the collisions. I have a sort of idea as to how this will work:
I wasn't sure whether this question should be here or in the game dev site.
I have two Vector2's - velo and momentum (velo is the velocity). Both are (0, 0). The momentum is what's added to the velocity each frame.
Each frame, I first get the input. Momentum is increased and/or increased based on the keys pressed (e.g: if (Gdx.input.isKeyPressed(Keys.A)) { momentum.x -= speed; })
I then multiply the momentum by 0.15. This is so that it slows down.
After this, I multiply the velocity by 0.8.
Then, I add the momentum to the velocity, to increase the velocity, as
this is what actually moves the player.
I then add the velocity to the position of the player.
To apply the gravity, I add a gravity vector (0, -10) to the position of the player.
So I need to find a way to move the player, but not allowing it to overlap any part of the world. The world is made up of lots of Rectangle instances. The player's body is also an instance of Rectangle. Would it be easier to rewrite the collisions using Box2D? What I've tried is checking if the player overlaps any rectangles when it's moved, and if it will, not moving it. But this doesn't seem to take everything into account - sometimes it works, but other times, it stops before touching the world.
TL;DR: I want to make collisions of my player with a world which is stored as a grid of rectangles. How would I do this, as my player is also a Rectangle. Would it be easier to use Box2D?
This answer gives a good overview about the details of collision detection:
https://gamedev.stackexchange.com/a/26506
However, that might be a bit overwhelming if you just want to get a simple game going. Does your game loop happen in fixed interval or is it dependent on the framerate? Maybe you could solve a part of your issue by simply dividing the collision detection into more steps. Instead of moving the full way during one update, you could make 10 little updates that each move you only a 10th of the distance. Then you do a collision check after each step, so it's less likely that you stop too early or move through thin objects.
That would of course be more taxing on the performance, but it's a naive and easy to implement approach to a solution.
EDIT:
Just wrap the position update in a for loop. I don't know how your code for collision checking and updating, but the general structure would be something like
for (int i = 0; i < 10; i++) {
newPosX += deltaX * 0.1; // 1/10th of the usual update
newPosY += deltaY * 0.1; // 1/10th of the usual update
if (checkCollision(newPosX, newPosY))
{
posX = newPosX;
posY = newPosY;
}
else
{
break; // We hit something, no more mini-updates necessary.
}
}
I am using Box2D with libgdx. I am having an issue with the default collision action. When I jump or hit the top of an object, everything works fine. My object doesn't stick. If it hits the top, it stands on it. If it hits the bottom, it falls back down. But if it hits either of the sides, my object sticks, as long as I'm moving in that direction. In other words, the gravity has no effect on it while it collides with the side of the block/wall. I did some research, but all solutions said to use the b2Settings, which I can't use with libgdx. Is there any way I can fix this? The code I use to move my character(moving left) is as follows:
level.character.body.setLinearVelocity(
-level.character.terminalVelocity.x,
level.character.body.getLinearVelocity().y);
Here's an illustration. As you can see, it sticks to the brick instead of falling. (My character is currently a coin :p)
Instead of using SetLinearVelocity, try using ApplyForce or ApplyImpulse to move things around. The problem is that SetLinearVelocity allows you to create unrealistic situations, for example in this case when the ball hits the wall it should stop and the horizontal velocity really should be zero, but you are overriding the natural result and saying that the ball did not stop at all, and it is still moving.
Note that you may still get this problem even when using ApplyForce or ApplyImpulse, if the force is strong enough and there is enough friction between the fixtures (just like in the real world, if you push something against a wall hard enough and the surfaces are not too slippery, you can stop it from falling).
I am making a game with LibGDX (Java).
I need the camera to follow a fast moving character. The easiest way to do it is to just write this:
this.getCamera().position.set(obj.x, obj.y, 0);
But, is there any algorithm to make this more smooth? Like when camera is not that strict, and is always a bit late: character goes quick right, camera follows with slight delay, or if you suddenly appeared somewhere far, camera doesn't teleport instantly but travels at a top speed to you when it comes closer it slows down a bit and finds you again.
Is there any libgdx libs that do that or anyone had this experience?
Try something simple like lerping a tenth of the distance. It works surprisingly well.
float lerp = 0.1f;
Vector3 position = this.getCamera().position;
position.x += (Obj.x - position.x) * lerp * deltaTime;
position.y += (Obj.y - position.y) * lerp * deltaTime;
Take a look at Aurelion Ribon's Java Universal Tween Engine. This performs interpolation and has several easing equations that I think would get you what you are looking for. It also has other advanced features like waypointing and chaining certain actions together for other interesting effects.
Your game logic could check to see if the character is moving quickly or has a step change in terms of position. In response to this, turn your current camera position over to the tween engine and let it take over -- smoothly zooming to the character's current position.