I am developing java game using box2d for my physics, I have got helicopter, ex:
I reduced gravity by setting:
body.setGravityScale(0.03f);
So it acts bit realistic (is affected by gravity only little bit, floating in the air)
To move it, down/up left/right I have controller, thats how I control my helicopter:
body.applyLinearImpulse(new Vector2(pValueX * 3, pValueY * 3), mainBody.getWorldCenter());
Where pValueX and pValueY are 1 or -1 (directions up/down left or right)
It works good, but now I am trying to achieve more realistic effect, when moving helicopter left/right I wanted to tilt it little bit so it works like real helicopter, but could not find proper way how to do it, I have tried applying force in different part of the body, but it makes my helicopter rotating 360 degrees if keep pressing left or right.
This question is old, but in case it's still relevant, I created a helicopter using JBox2D (which pretty much maps directly to Box2D). For tilting left/right (i.e. forwards/backwards relative to the pilot):-
heli.applyTorque(TURN_TORQUE);
or
heli.applyTorque(-TURN_TORQUE);
This rotates the heli, and then if the player wants lift:
Vec2 force = new Vec2();
force.y = (float)Math.cos(chopper.getAngle()) * -1;
force.x = (float)Math.sin(chopper.getAngle());
force.mulLocal(ROTOR_FORCE);
heli.applyForceToCenter(force);
What you can do is, just define two constants as maxForceLeft and maxForceRight. When you press left apply some force on the cockpit part of the helicopter and keep comparing it with the maxForceLeft,once it reaches that value stop applying the force.Do the same for the right button by applying the force on the tail rotor part of the helicopter.In this way you can avoid rotating it 360 degrees.Depending upon the kind of effect you want for your helicopter you can apply the forces in either upward or downward direction.
http://www.iforce2d.net/b2dtut/rotate-to-angle
What you need is rotating the body to a desired angle..
This is a great tutorial to achieve this.
I hope this would help.
Related
So I had a quick question. I'm currently making a small game in java and I wanted to experiment with hiding the player behind fake 3D objects on the screen (Isometric drawing). Unfortunately I can't post a picture (Not enough rep). Basically it's a 3D block that is 32 by 48 that gives an illusion that it's 3D by having half of it a lighter color and the other half a darker one. The player is the same size as the block and can move freely around the map of these 'blocks'. If the player moves behind a block, it's bottom part is hidden behind it. The opposite when it moves in front, covering the non-player block. Now I made an example program in GameMaker Studio just to test it out. To make it work in GM, I made a script for each sprite that was one line of code:
depth = y * -1
This causes the bottom part of the player to 'hide' behind the blocks when it moves behind them. I looked into it a bit on GM's wiki and it's pretty much changing the 'depth' of the instances. Now my question is, how would I do something like this in Java?
P.S. This is not in a diamond. It is in a straight 2D world (looking 45 down towards objects from front).
EDIT:
Here are some pictures of the GameMaker version:
Player Outside
Player Inside
Read about drawing isometric worlds.
Read about Java and isometric development.
Thanks to Kayaman for solving the problem:
If you draw your player first, then a wall on the block south of it, the top half of the wall will mask the bottom half of the player. So no, you don't need to draw halves separately. This means of course that you need to draw the player at the same time as the map, so you can't first draw the map and then the player.
Just for future use, layering images in java is determined by the order in which they are added. This was the exact answer I was looking for. The GM code was GameMaker's way of setting the order in which the images were added to the screen.
Thanks to everyone for the help!
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).
In my first libgdx 3D game i now switched from createBox to createRect, to create only the visible faces (if a wall is on the left side of another wall, its right face is not visible...). I am creating 4 models:
frontFace
backFace
rightFace
leftFace
They are almost drawn how they actually should.
But there is one big issue: The side faces are only visible if i look in the positive z-Direction.
If i look the other side (negative z-Direction), they don't draw. The front and back faces only draw, if i look to them in negative x-Direction.
Has this something to do with the normals? I have set them to:
normal.x = 0;
normal.y = 1;
normal.z = 0;
Is that the error? How should i set the normals? What do they stand for? I have some basic idea about normal mapping for lighting, is that the same?
Important note: I have disabled backface culling, but it did not make any difference. View frustum culling is turned on. If any more informations are needed please post a comment and i will add them as soon as possible. Thanks
Perhaps not directly related, but still important to note: don't use createRect or createBox for anything other than debugging/testing. Instead combine multiple shapes into a single model/node/part. Or even better, use a modeling application where possible.
You didn't specify how you disabled backface culling. But keep in mind that you should not change the opengl state outside the shader/rendercontext (doing so will result in unpredicted behavior). To disable backface culling you can either specify it using the material attribute IntAttribute.CullFace (see: https://github.com/libgdx/libgdx/wiki/Material-and-environment#wiki-intattribute), the DefaultShader (or default ModelBatch) Config defaultCullFace member (see http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g3d/shaders/DefaultShader.Config.html#defaultCullFace) or the (deprecated) static DefaultShader#defaultCullFace member (see http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g3d/shaders/DefaultShader.html#defaultCullFace).
Whether a face is front or back is based on the vertex winding. Or in other words: the order in which you provide the corners of the rectangle is used to decide which side is front and which side is back. If you use one of the rect methods, you'll notice the arguments have either the 00, 01, 10 or 11 suffix. Here, when looking at the face, 00 is lower-left, 01 upper-left, 11 is upper-right and 10 is lower-right.
For a rectangle, it's normal is the perpendicular facing outwards the rectangle. For example if you have a rectangle on XZ plane with it front face on the top, then its normal is X=0,Y=1,Z=0. If its front face it facing the bottom, then its normal is X=0,Y=-1,Z=0. Likewise if you have a rectangle on XY plane, its normal is either X=0,Y=0,Z=1 or X=0,Y=0,Z=-1. Note that the normal is not used for face culling, it's most commonly used for lighting etc. Specifying an incorrect/opposite normal will not cause the face to be culled (it might cause incorrect/black lighting though).
For your purpose I'd recommend you to use Decal class. Decals are bitmap sprites that exist in a 3D scene. This article is about using of decals in LibGDX. I hope it is what you wanted.
I'm currently making a top down gfx actiong RPG on java, using jbox2d. Basically I want the enemies to recoil back after they get hit by the player (with top down graphics I don't have friction or gravity). I tried with restitution, applying impulse and setting linear velocity but I didn't get what I expected: the enemies teleport to the destination istantly and if they are near the wall they get ported out of the map. How can I fix this and what is the best to do it in your opinion? thanks a lot
I don't know how you are using jbox2d and c++ at the same time...
Regardless, if your enemies are represented physically by b2_dynamicBodys then you probably want to apply a linear impulse and set the linear damping of the enemy body to a value greater than zero. Linear damping works like air drag - The faster the object is moving, the larger the force applied in the opposite direction. Applying a large linear impulse and setting a high linear damping will cause your enemies to fly away from your hero with a very high initial velocity, but they will come to rest very quickly.
I hope this helps!
I am creating vehicle like this on the image:
As you can see, there is:
1) main vehicle body (Red rectangle)
2) wheels
3) vehicles arm (black rectangle)
Arm is connected with vehicles main body using Revolute joint in shown anchor center point, this arm can be moved up and down (with following angle limits) so as you can see it can move in 90 degrees only.
My question is, I am moving this arm by applying angular impulse, it works, I can move arm, but it keeps falling down to the default position. I am struggling how to "disable" joint, so arm can be moved only using my controller so its not affected by gravity, so player can move arm slightly up for example and arm should stay in this position, instead of falling down.
Any help would be great, thanks.
The best way to disable gravity impact is to set gravityScale to zero at b2BodyDef. But this parameter appeared only in last versions of Box2D, and, maybe, there is no such thing in your java port
Anyway, your idea with gravity isn't so good I think. It is not physic, not realistic and you can find some related troubles because of this. For example, what if some another force, except gravity, will impact the arm? It will cause all the same problem.
In my opinion, better way to make the arm - use motor of revolute joint. Some tutorial you can find there in section "Revolute joint motor". You can enable/disable motor and change its speed run-time to simulate vehicle logic. In addition, it may be useful also change run-time upper/lower limits of the joint, to prevent arm moving when no action preformed. Another way to achieve this - set motor speed to zero, that will transform motor into some kind of friction force.