I have a draw method drawing a String to the screen using a Graphics2D object. I set up an if statement in the draw method to make the text draw every second (blinking effect), but the text will draw for a second, then not draw only one frame and continue drawing again. I would like for it to draw for a second, then not draw for a second and so on.
Here is the method -
long elapsed = (System.nanoTime() - blinkTimer) / 1000000;
if(elapsed < 1000){
// g.drawString("",x,y); Draw String Here
}else{
blinkTimer = System.nanoTime();
}
blinkTimer is initialized in the constructor as System.nanoTime();
I would like to accomplish this without using the Java Timer object. Thanks in advance!
Added an additional timer -
long elapsed = (System.nanoTime() - blinkTimer) / 1000000;
if(elapsed < 1000){
//g.drawString("",x,y); Draw String Here
breakTimer = System.nanoTime();
}
long breakElapsed = (System.nanoTime() - breakTimer) / 1000000;
if(breakElapsed > 500){
blinkTimer = System.nanoTime();
}
Related
I built a small game in java in which i use a game loop. I add gameobjects which i render using render() and tick() methods. However, now the program gets bigger i encounterted a problem.
How do you solve that when i use velocity to move a picture, the object keeps rendering on old positions? For small programs this aint a problem, but when you get like 100 objects in the screen the FPS keeps dropping to the point the program doesnt work properly anymore. This is just because there are so many objects to render. Is there a way to remove the rendering of the old positions of the object? Here below is some code i have written.
The game loop i used:
public void run() {
this.requestFocus();
long lastTime = System.nanoTime();
double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
long timer = System.currentTimeMillis();
int frames = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1) {
tick();
delta--;
}
if (running) {
try {
render();
} catch (IOException e) {
e.printStackTrace();
} catch (FontFormatException e) {
e.printStackTrace();
}
}
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println("FPS: " + frames);
frames = 0;
}
}
stop();
}
I used the Graphics class in Java to draw the images/strings/rectangles/etc. on the JFrame.
Here below is a picture of the problem. You can see that the object began all the way to the right. I changed the x-axis every tick of the game loop which made the object go to the left. Unfortunately, the object leaves a trace behind it and keeps rendering that, while i want it to only render the newest position.
Object rendering problem picture:
How can i solve this? Thanks in advance.
I'm trying to make a simple game engine and I'm trying to make delta time available to the user. This is how it is calculated and given to the user (they get it as a float):
float deltaTime;
long lastLoop = System.nanoTime();
UpdateInfo updateInfo = new UpdateInfo(0, 0, gameInstance.window.getWindowHandle());
while (!glfwWindowShouldClose(gameInstance.window.getWindowHandle()))
{
deltaTime = (float)((System.nanoTime() - lastLoop) / 1000000f);
updateInfo.setDeltaTime(deltaTime);
if (gameInstance.window.isFPSCounterEnabled())
{
if (System.currentTimeMillis() - lastFrameCount >= 1000)
{
fps = frames;
frames = 0;
lastFrameCount = System.currentTimeMillis();
}
}
else
{
fps = -1;
}
updateInfo.setFPS(fps);
gameInstance.updateGame(updateInfo);
gameInstance.drawGame(gameInstance.window.getDrawboard());
lastLoop = System.nanoTime();
glfwPollEvents();
}
But when I test the delta time value in moving a sprite across the screen, it's really choppy. This is both when VSync is enabled and disabled. Am I calculating it wrong or is my game being unstable?
I am building this game in Java. Basically it is minecraft in 2D. I made it so that block objects are deleted when pressed. My block object rendering sometimes gives a nullpointerexception after clicking/deleting a block (randomly after about 200 blocks). It seems as if the object is sometimes deleted while the game is in the renderingloop. When I add a try-catch, the next render cycle does not have the error anymore. Any ideas what is causing this? Is this gameloop a solid one, I suspect that is what is causing my error.
Render method in my handler:
LinkedList<GameObject> object = new LinkedList<GameObject>();
public void render(Graphics g){
for(int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);//sometimes nullpointer when getting the object I clicked on
tempObject.render(g);
}
}
Deleting with mouseInput
for(int i = 0; i < handler.object.size(); i++){
if(handler.object.get(i).getID() == ID.Block){
int x1 = (int) handler.object.get(i).getX();
int y1 = (int) handler.object.get(i).getY();
//if mouse is over object
if((MouseX >= x1+1 && MouseX <= (x1 +32-1)) && (MouseY >= y1+1 && MouseY <= (y1 +32-1))){
Block b = (Block) handler.object.get(i);
inventory.addInventoryBlocks(b.getType(), 1);
handler.removeObject(handler.object.get(i));
}
}
}
Gameloop:
public void run() {
this.requestFocus();
long lastTime = System.nanoTime();
double amountOfTicks = 60;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
long timer = System.currentTimeMillis();
int frames = 0;
while(running){
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1){
tick();
delta--;
}
if(running)
render();
frames++;
if(System.currentTimeMillis() - timer > 1000){
timer += 1000;
//System.out.println("FPS: " + frames);
frames = 0;
}
}
stop();
}
I assume your mouse input handler runs as a seperate thread. In this case the deletion of a block can occure within your rendering loop.
A solution would be not to delete the blocks immediately in your mouse handler but to save the blocks to delete in a separate array. These blocks can be handled at a dedicated position in your main loop right before rendering.
Most likely your mouse handler is running in the AWT thread while the render is running in another thread. In this case you would be suffering of concurrency troubles.
Try using a critical section.
public static Object lock = new Object();
public void render(Graphics g){
synchronized(lock)
{
for(int i = 0; i < object.size(); i++){
GameObject tempObject = object.get(i);//sometimes nullpointer when getting the object I clicked on
tempObject.render(g);
}
}
}
void mouseInputHandler()
{
synchronized( lock )
{
code
}
}
This could be better refined knowing more about your code's structure but it should get you going in the right direction.
Assuming you are using different threads for updating the game state and rendering, this behavior does not seem that odd to me, as one thread might have deleted an object as the other tries to render it.
A good way to debug this is to force sequential execution of your code. Check if the current behavior persists. A nice introduction (Android) to game loops can be found here
So I'm currently just learning how to do this, and someone said that the code is inefficient because the thread is still running when nothing is updating. When I look at the CPU usage in the task manager, it shoots up to 35 - 45% and 20 in the CPU column when only a black screen is being rendered. Is there a way to make the thread sleep when the CPU isn't updating anything?
Thanks!
public void run() {
long lastTime = System.nanoTime();
long timer = System.currentTimeMillis();
final double ns = 1000000000.0 / 60.0;
double delta = 0;
int frames = 0;
int updates = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1) {
update();
updates++;
delta--;
}
render();
frames++;
if(System.currentTimeMillis() - timer > 1000) {
timer += 1000;
updates = 0;
frames = 0;
}
}
stop();
}
You shouldn't render on your own threads. SWING is thread unsafe so all GUI operations should happen on the SWING thread. It just happens SWING has a thread specially made for this.
timer = new javax.swing.Timer(1000 / 60, this);
timer.start();
#Override
public void actionPerformed(ActionEvent e) {
// Do your stuff (ignore 'e')
}
The only good way of doing it, is to execute the yourThread.wait() when the game stops doing stuff, and then yourThread.notify() when the game makes an action again.
ns is 1000000000 / amountOfTicks;
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if (delta >= 1) {
tick(glad);
updates++;
delta--;
fps_counter = 0;
}
if (delta >= fps_counter / FramesPerTick) { // render
fps_counter++;
frames++;
render(glad);
}
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
frame.setTitle("Ticks: " + updates + " Fps: " + frames);
updates = 0;
frames = 0;
}
So if i have 20 ticks and 3 FramesPerTick i get 60fps
it checks whenever delta is bigger than 1/3, 2/3 and 3/3, so every tick has 3 frames
Everything is jittery, movement, mouse look.
Animation gets more and more jittery the lower the FPS, i dont understand why.
Also when i take the render(glad) method out of the if, it goes up to 400 fps and runs very smoothly.