Game runs choppy

Hey,

I have created a tile based game. I have 1 game thread which keeps on repainting the jdekstoppane and sleep for some time.
The game thread also has several units ( also threads on their own) who also repaint the desktoppane.
But when i scroll the game goes very choppy. Does anyone have some ideas to make the game more fluent or what is causing the choppy
movement of the screen

Why several Threads for painting? I assume “choppy” means low framerate, but rendering from more than one Thread could cause another kind of choppyness. How many Threads are you using? Do you use the repaint() method consequently or do you render manually?

do i have to repaint allways the whole screen when i use bufferstrategy or is their a way that i can keep
drwn parts which havent changed

Yes, you can only show the whole back-buffer with BufferStrategy. But in
an accelerated case (especially in fullscreen mode) that’s super fast.
Even in windowed mode offscreen to the screen ddraw copy
is very fast.

Thanks,
Dmitri

i just dont understand
to draw my screen with 200 tiles en 50 busses on it take 7500 ms for 250 frame
or a roughly 30 ms/ frame which rather high i guess

whats best to use
image, bufferedimager or volantileimage?

Are your sprites translucent, transparent (bitmaps) or opaque?

If they’re translucent this may cause the accelerated surface (the one used by
BufferStrategy or VolatileImage) to be punted to system memory because translucent images
aren’t accelerated. And copying from system memory to the screen is slow.

To answer your question: I’d suggest to use BufferStrategy.
However, if you know that your game will do lots of stuff that’s not
hardware accelerated (doing alpha compositing, antialiasing and such) you might
want to use a BufferedImage as your back-buffer. It’ll provide reasonable
framerate if the size is not too large.

Dmitri

@ Are your sprites translucent, transparent (bitmaps) or opaque
I use almost exclusive transparant pngs
@To answer your question: I’d suggest to use BufferStrategy.
I allready do use a double buffer but my game just runs very slow
because he has to redraw 1000 tiles every frame

see it yourself: http://users.skynet.be/fa006997/Test.jar

I think the problem is that when we read these images we
for some reason create them as IntArgb, which means translucent.
Do you read them with ImageIO or Toolkit.getImage?

Run your app with -Dsun.java2d.trace=count, see that you have a bunch
of loops similar to this:
19456 calls to sun.java2d.loops.MaskBlit::MaskBlit(IntArgb, SrcOver, IntBgr)
These are software blit loops.

Also, which jdk version are you using? I believe there were fixes
in mustang to address these issues.

As a quick hacky workaround you can try this: create a compatilble BITMASK image
and copy your images to them:


Image im = gc.createCompatibleImage(w, h, Transparency.BITMASK);
Graphics2D g2d = (Graphics2D)im.getGraphics();
g2d.setCompositing(AlphaCompositing.Src);
g2d.drawImage(loadedImage, 0, 0, null);

See if that helps.

Thanks,
Dmitri

i idd hat those calls when i ran it

i use the latest 1.5 build version

@ your workaround on what do i have to draw the image? a bufferedImage?

I now draw the bufferedImage on a volatileimage
which i draw each frame

i used ure last workaround for drawing tiles and my fps went up to 200 fps:|
but it chopps even more then before although the fps went up

I removed the sleeping after each frame was drawn
which removed the coppynes :slight_smile: but also fps dropped

i still get a good 75 fps

Ihave uploaded a 1024 and a 1280 version

http://users.skynet.be/fa006997/Test_1280.jar
http://users.skynet.be/fa006997/Test_1024.jar

You didn’t elaborate on your threading adventures. Perhaps this could hold some explanations of the perceived “choppyness”.

I still have threads, only i bundled them together for each type of Vehicle instead of a Thread for each vehicle

for the input should i work with standard classes or use jinput?

One Thread to rule them all.

Also: what are all those threads doing? How many are there? Are they sleeping most of the time? Anyway, all game logic should be handled from the same Thread, and I suggest that this Thread is also made responsible for updating the graphics. Furthermore, all key- and mouse input should be handled from that very same Thread of you want to make it easy for yourself. If one Thread draws while another Thread handles the input which makes the game scroll, the game will be repainting half of the screen, execute some scrolling from another thread and then repaint the other half of the screen, which will result in seeing “double” and "triple"while scrolling. All those Threads may also degrade performance considerably, but I can’t say that for sure.

If you do everything from one Thread, possibly the Event Dispatch Thread (the easiest choice) your problems may be over.

i use a thread for each vehicle type to simulate its speed
thay all sleep a different time and then move each unit of that type so you get the impression
they move at differend speeds

so i will eventually have a thread or 4 i guess maybe more dont know yet

I think the approach you took with all these threads is overly complicated for a game, you are making things more difficult for yourself this way. You are better off doing all the game logic/rendering in the same thread as others have suggested. For example, a way to model the behaviour you want (from the top of my head, so bear with me) is to give each type of vehicle a speed variable, a location %, a current grid x/y and a next grid x/y.


public class VehicleType {
   private float topSpeed;
   private float speedGain; // the power of the engine?
   private String name;
   ...
}

public class VehicleInstance {
   private VehicleType type;
   private float currentSpeed;
   private GridLocation currentLocation; // just something which holds x,y values on the grid
   private GridLocation nextLocation;
   private GridPath currentPath; // an arraylist of gridlocations maybe...
   private float progress;
}

now you can calculate where your vehicle should be on the map. Say that vehiclespeed is in km/h and each tile is 5 by 5 km.


     float previousUpdateTime; 
     float currentUpdateTime; 
     public static final long NANOSPERSECOND = 1000000000;
     public static final int SPEEDTOCROSSTILEINONESECOND = 100; // speed in km/h to cross a single tile in one second
     public static final float PROGRESSPERSECOND = (1.0f / SPEEDTOCROSSTILEINONESECOND) / NANOSPERSECOND; // tile progress per second per km/h

     public void update() {
           previousUpdateTime = currentUpdateTime;
           currentUpdateTime = System.nanoTime();
           float timeDelta = currentUpdateTime - previousUpdateTime;

           for(VehicleInstance vehicle : vehicles) {
                 if(vehicle.currentSpeed < vehicle.type.topSpeed) {
                        vehicle.currentSpeed = vehicle.currentSpeed + vehicle.type.speedGain;
                        if(vehicle.currentSpeed > vehicle.type.topSpeed)
                               vehicle.currentSpeed = vehicle.type.topSpeed;
                 }
                 
                 // progress is between 0.0f (start of tile) and 1.0f (end of tile)
                 vehicle.progress = vehicle.progress + ((PROGRESSPERSECOND * vehicle.currentSpeed) * timeDelta));
                 
                if(vehicle.progress > 1.0f) {
                        vehicle.progress -= 1.0f;
                        vehicle.currentLocation = vehicle.nextLocation;
                        vehicle.nextLocation = vehicle.currentPath.getNext();
                 }
           }
      }

something like this. you also have to add code for the vehicle to break and stuff. ;D Anyway, the speed calculations to update progress are correct. I tested it using MS Excel.

You don’t want to have EDT to be very busy ,otherwise your event handling will
be slowed down.

Dmitri

i use a thread for each vehicle type to simulate its speed
thay all sleep a different time and then move each unit of that type so you get the impression
they move at differend speeds

so i will eventually have a thread or 4 i guess maybe more dont know yet

Well, don’t. The approach is inherently flawed, for a number of reasons. First, multiple threads accessing the same resources concurrently can cause a load of seemingly random errors. Otherwise you need half your methods synchronized, and that may degrade performance. Second, sleeping is a non-exact science. You can’t trust the Threads to get equal CPU time, sometimes they will waste a millisecond or two after sleeping. But why am I saying all this? Just get rid of those multiple threads.

You don't want to have EDT to be very busy ,otherwise your event handling will
be slowed down.

Yes, very importantly. If the framerate is around 50, however, event handling will still be fine (just don’t ever sleep from the EDT).