I was wondering how i can speed up whole game done with libgdx (for example after clicking a button). The way i have in my game is modify a timestep variable used in
world.step(TIMESTEP, VELOCITYITERATIONS, POSITIONITERATIONS);
but im now sure if it's a good idea. If there a any better way to archive that?
When using Box2D you can speed up your game by modifying the physics step. One problem is that you should use a constant steptime. I use the following code below in my games:
private float accumulator = 0;
private void doPhysicsStep(float deltaTime) {
// fixed time step
// max frame time to avoid spiral of death (on slow devices)
float frameTime = Math.min(deltaTime, 0.25f);
accumulator += frameTime;
while (accumulator >= Constants.TIME_STEP) {
WorldManager.world.step(Constants.TIME_STEP, Constants.VELOCITY_ITERATIONS, Constants.POSITION_ITERATIONS);
accumulator -= Constants.TIME_STEP;
}
}
This makes sure that your steptime is constant, but it's synchronized with the render loop. You could use that and call it like doPhysicsStep(deltaTime * speedup) (speedup is 1 by default, and maybe 1.5 after a button was pressed). This might probably result in not optimal results, but you could give it a try.
Otherwise you can go the hard way like it was suggested in the comments and invest more time by modifiying every place in your code where it is necessary (all forces need to be modified, which in many cases isn't as trivial as force * speedup, because in the real/physics world, not everything acts linear).
Related
Hello I am currently trying to move objects in my libgdx android application. The main issue is that i can't move my objects unaffected by the fps. Up to now i was using the delta time like this:
public void move(float delta){
this.setX(this.getX() + this.speed.x * delta); //moving just along x axis to keep it simple
this.speed.x += 1 * delta //some acceleration;
}
The move method is called on each frame. Imagine I have two devices, one with 1fps and one with 2fps, and now we move a object for 1 second with a start speed of zero. The object wouldn't have moved on the first device while it would have on the second one.
To sum up if the fps is increased the object moves slightly faster.
Up to now this little differnce was no problem but in this case it is important that the object moves 100% synchronous, because i want to measure the time the objects needs to reach some point.
So what is the right way to go here?
Actually... the way you are moving your objects when multiplying it by delta makes it FPS independent already :) Let see below graphic to understand it better:
open the picture in full size!
Atlhough you are adding some value to x twice per second when having 2FPS the value is twice smaller than when having 1FPS what means that in the every integer point of time the x of the object will be the same.
The situation you are afraid of would be true if you wouldn't multiply it by delta - then every second you would add the same value twice when having 2FPS than when having 1FPS - it means that after one second the object would be twice far more when having 2FPS than when having 1FPS.
Only thing affect by the FPS is rendering smoothness - but if you are refreshing the screen twice times more it is obvious that it will be more smooth.
By the way - if you are using Scene2D and looking for some other ways to move object look at Actions especially MoveToAction. Take a look at this tutorial to get some information.
Thanks to m.antkowicz provided informations i could do some better research and found some interesting artices. According to my current knowlege it is pretty hard move objects with dynamic accelleration based on the deltatime. The right way to go is to use fixed time stamps.
for(int a=0;a<380;a++){
try{
Thread.sleep(5);
}catch(Exception e){
System.out.println(e);
}
item.setLocation(300, a);
}
here is the process of my item moving downwards, but my problem is i cannot move it inch by inch.
item only shows up in (300,0) and (300,380), suppose to be 0,1,2,3,4----380 Help :((
You're blocking the UI thread.
Basically, the caller running your rendering code (where you draw the ball) looks something like this:
while (true) {
drawing = your_code();
copy_drawing_to_GPU(drawing);
}
What this means, is that your code updates only show up after you return. Your for-loop runs entirely inside one "draw call" (it's usually called a frame, the origin of the term FPS - Frames Per Second - in gaming). Your code ends up doing this:
Get called
Sleep 5 ms
Move 1 px
Sleep 5ms
Move 1 px
... repeat many times ..
Return to caller
Actually draw the object, only once
Hopefully this makes sense.
There's a couple solutions for this:
The best solution, and what is usually used in games, is using "delta times". Basically, you calculate the speed you want your ball to move at in pixels/millisecond, and the time elapsed since the last frame, and multiply those together to get how many pixels to move this frame. This is fairly easy to implement:
time = System.currentTimeMillis()
while (true) {
drawing = update(System.currentTimeMillis() - time); // the "delta time"
copy_to_GPU(drawing);
time = System.currentTimeMillis();
}
Then, inside your code, instead of using a for loop you'd simply do:
item.setLocation(300, item.yPosition + deltaTime * item.ySpeed);
if (item.yPosition >= 380) {
item.yPosition = 380;
item.ySpeed = 0;
}
This correctly spreads your location updates over the correct number of frames. As a bonus, it also makes your program "lag-independent" - if your program starts lagging and takes a long time to render a frame, it will look choppy, but the ball will still be moving at the same speed (to an extent, you need more advanced techniques for serious lag).
The other option is to use a separate thread. This option kinda sucks, and I don't suggest using it.
I'm trying to make a game for J2ME something like the game Zuma, the structure of classes that you need to know is as follow :
-Level class which holds info about a level such as a vector of points (class I made called Point, the path that the balls will follow), vector of balls (class I made called Ball) to hold different balls object, speed (the speed of the balls in that specific level).. (There're more fields but nothing that you need to worry about)
-Frog class (just so you'd know it exists) if you're not familiar wit the game zuma it serves as a controllable turret that can shoot balls.). (No need to worry about the fields in that class)
-MyGameCanvas which obviously extends GameCanvas and implement runnable, holds instance of frog and a level (the currently played level).. (There're more fields but nothing that you need to worry about). The run method serve as a listener for user input if user pressed right rotate the frog (essentially a sprite) by X amount if pressed left rotate by -X amount, pressed OK shoot a ball. Beside taking care of input the thread calls a render method which renders what going on, on the screen and updates balls position from the balls vector (by using the current level instance) using the vector of points (from the level instance aswell), now the problem is that I wanted each level to have different speed, by speed I mean that balls will "roll" (=move) on screen slower, so I can do it with just using the speed value in the Thread.sleep method and increase the sleep time because the run method is taking input from user making the frog movements and input reaction to be slowed down aswell, I thought maybe doing each ball a seperate thread but thats not really good in my opinion because there'll be alot of threads + when I update each ball location on the screen I actually use the WHOLE ball vector from the level instance for things like if a ball need to gove backwards if there's a gap between the ball and the one behind him, or when to render the ball depending if the ball after him is already rendered and on the "track" (the points vector), so I don't really know how I should do it, any advices guidance would be highly appriciated ! Thanks in advance and hopefully you could understand what I wrote.. Also I don't think I need to give code examples really because I don't wanna use what I want to CHANGE what I wrote so it wouldn't really help providing the run/render methods, all you need to know is the structure of the classes I gave you and the fields they have that I told you about.
Various developers use various methods for controlling the speed of sprite-movement.
JavaME is one of the many platforms that requires you to also consider different resolutions and CPU speed. So it's never as simple as just incrementing the x value 1 pixel in each cycle of the main game loop.
Assuming 2 devices with different screen resolution, but otherwise running the same speed. Incremending x value by 1 in the cycle of the game loop, would obviously result in the sprite reaching the end of the screen faster on the small resolution.
Assuming 2 device with the same screen resolkution, but with different CPU's. Incrementing x value by 1 in the cycle of the game loop, would obviously result in the sprite reaching the end of the screen faster on the device with the fastest CPU.
Here is one way of working around that:
Create a variable, call it itemWait (where "item" is the name of the object you want to control the speed for).
The itemWait variable holds a value that tells the game loop how long should pass before next movement.
For example, say that the sprite should wait 40 milliseconds for each pixel it moves. The code would look somewhat like this:
// Variables defined outside the game loop
long lastTime, thisTime;
int cyclems;
int itemTime; // Replace "item" with the name of the object, like e.g. ballTime.
int itemWait = 40; // Wait 40 ms for each movement
int itemPixelsToMove = 1;
while (running == true) { // Game loop
lastTime = thisTime; // Set lastTime to the time-stamp of the previous cycle
thisTime = System.currentTimeMillis(); // Get the current time-stamp
cyclems = (int) (thisTime - lastTime); // How long did it take to execute previous loop
itemTime += cyclems; // How long has passed since last move
while (itemTime > itemWait) { // If it's time to move
itemTime -= itemWait;
moveItem(itemPixelsToMove);
}
// Do other game logic
// Draw everything
// Handle input, unless you handle it with keyPressed()
}
Using that method, the code doesn't care how fast the device is. And if you want to port the game to a different screen resolution, you can simply change either itemPixelsToMove or itemWait.
For example, say you set itemWait = 40; for 240x320 resolutions. Then you would set it to 40/240*480 = 80 for 480x640 resolutions. (This requires of course, that you also scale the graphics).
We've used this approach in www.PirateDiamonds.com - in case you're curious. The same code runs on whatever screen resolution you want.
I am developing an AI simulation of predator and prey. I would like to simulate the AI hiding behind obstacles, if it is being chased. But I am still trying to figure out the best way to implement this.
I was thinking along the lines of checking on which side of the obstacle the predator is on and trying to go on the opposite side. Maybe using the A* path finding algorithm to ensure that it gets there using the shortest path.
Now the main reason I am writing is in case somebody is able to point me in the right direction of implementing this (maybe somebody has done this before) or have any other good ideas how to implement it. I have never done anything like this before in terms of programming AI or making any game.
All the obstacles are either horizontal or vertical squares/rectangles.
Please note that the circle in red is the predator while the circle in green is the prey being chased.
I can't give any code off the top of my head, but I can tell you a few things:
First, you need to define the goal of this program. For this case, it is to get the AI to hide behind an obstacle, keeping the user and the AI on opposite sides whenever possible.
Next, you need to decide what needs to be done inside the code (without writing any real code) to accomplish this goal. For instance:
We need to determine what "zone" of the scene is considered "behind the obstacle"
Next, we need to determine a path for the AI to get to that zone without going through the obstacle.
Lastly, we need to add some sort of delay to this so the AI doesn't constantly change its mind for every pixel the user moves across the screen
This isn't per se an easy problem, but it is certainly achievable without breaking too much of a sweat. I'd recommend you find a way, even if it is slow and requires a ton of code, then write the code for it, and lastly refine. If you worry about refinement, then you never get any of the problem solved.
HINT: Determine a vector that points from the player to the middle of the obstacle. Then, multiply the vector by 2 and add it to the position of the player and that gives you a point on the other side of the obstacle (assuming it is a rectangle). Apply a Math.min() or Math.max() restrictor to the x and y values you get to keep the AI as close or far from the obstacle as you wish. That should be a decent start! :)
Update -- I decided to add some code!
// This assumes a few variables:
int obstacleCenterX, obstacleCenterY;
int aiX, aiY, aiWalkSpeed;
int predatorX, predatorY;
private void updateAIMovement() {
int slope_x = obstacleCenterX - predatorX;
int slope_y = obstacleCenterY - predatorY;
int destination_x = predatorX + (slope_x * 2);
int destination_y = predatorY + (slope_y * 2);
if(aiX != destination_x){
aiX += (slope_x / Math.abs(slope_x)) * aiWalkSpeed;
}
if(aiY != destination_y){
aiY += (slope_y / Math.abs(slope_y)) * aiWalkSpeed;
}
}
I have not tested anything at all, but I think this might be somewhat of a right path to take. I could have done A LOT to improve just that little code snippet, but I didn't (such as some trig to make sure the player moves at a true speed when going diagonally, etc...)
Hopefully this helps a little!
I would check if there is something crossing the direct line between x and each observer. If it is, x is hidden.
I'm trying to implement 'lever' into my android game, here's image showing what do I want, showing how does it work:
1)
2)
I managed to do basic of it by using joint:
final RevoluteJointDef revoluteJointDef = new RevoluteJointDef();
revoluteJointDef.initialize(anchorBody, movingBody, anchorBody.getWorldCenter());
revoluteJointDef.enableLimit = true;
revoluteJointDef.upperAngle = MathUtils.degToRad(40);
revoluteJointDef.lowerAngle = MathUtils.degToRad(-40);
physicsWorld.createJoint(revoluteJointDef);
And it works, I can move lever stick in left/right direction, and as it should you can not exceed proper angle, so this part is done. But now I'm looking for a way, when execute actions after moving this lever (for example open some doors/gate)
Here's my basic idea, how to check which part of the stick has been touched by player (left or right) by creating stick's body with this way:
So explaining, by adding 2 sensors, one on left side and one on right side, so in contact listener I would check which side has been touched.
But still I have no idea how to check if action should be performed, I know I could check on every update if stick angle is 40 or -40, but is it effective way? Or maybe there is better? I will be greatly thankful for any tips! Thanks
You don't need to worry about efficiency here, the performance penalty for checking the angle is absolutely negligible. I measured the times needed to get the angle of a Sprite and a Body using the following code snippet:
double testEnd;
double testStart;
testStart = System.nanoTime();
for (int i = 0; i<1000000; i++) {doStuff()}
testEnd = System.nanoTime();
Log.v("speed test", "it takes "+ (testEnd - testStart)/1000000 + " nanoseconds");
So, on Desire Z it takes only 157 ns to find the angle of a Sprite and 393 ns to do the same with Body. It is also much simpler than using contact listeners. Just a side note, the angles of Sprites can be outside of (-360, +360) degrees if you rotate the Sprite.
Both the methods you mention would work, it's just a matter of which you find more convenient. It also seems like you already understand the implementation, so I don't think anyone could answer this question any better than to say, 'whichever suits you better'.
Putting a sensor at each end of the lever's range and using a contact listener to detect when the lever touches them is the most 'correct' way. It conveniently gives you events both when the lever touches the sensors and when they stop touching, but it's a little more work to set up.
Checking the joint angle after every time step will work fine too, but you'll need to compare the angle with the value in the previous step if you want to detect a start/finish touching 'event'. If you want a lever that can give continuous values (eg. speed control for some other object) instead of a simple on/off switch then you would be better off with this method.