Hey, guys! I'm new to this forum and I'd like to say first that I was amused by the account activation.

I decided to join here because it seems like the most likely place I can finally find the solution to a problem I've been having for the last week... I've tried help from GameDev and from the Oracle forums over the last few days, but I haven't received the solution to it yet.

Basically, what I have is a tile engine that I've constructed for a side-scrolling game I'm developing. It reads in a .png image that gets converted to an array representing the level's tiles, which then is used to calculate the view that is drawn to the screen. The user can move the little character in the middle of the screen (which right now there is no collision detection, so he/she can move the player about in any direction regardless of what tile).

The problem is that the thing is super slow! Originally, I found that I was redrawing the view every time rather than shifting it, which was thought to have been the bottleneck, but I converted it to draw the view only when the player has moved to where a new view has to be calculated and rerendered, and the slowness is still there. My computer is a beast gaming machine, so I'm not thinking it's computer performance related at all, but I must have messed up somewhere.

I'll post the code for the classes that compose the tile engine below. I would greatly appreciate any and all help and/or criticism and/or advice pertaining to the tile engine that anyone is willing to offer. :] I apologize that this post will be so lengthy, but since there are several components to the engine rather than just one class, I don't want to leave a stone unturned for anybody. Thanks again! :]

This class represents the Player and manages his current state of animation:

/* This class's purpose will be to store the data of the player character for movement and appearance. It will also * take input. The player image will be created as a sheet of animation frames and split by the class. */

This class represents the Level object that stores the .png images that will compose the drawn level and the array that represents the tiles in a more memory-efficient manner. It also manages updating the level's view and rendering it, as well as drawing it to the screen:

Once again, I apologize for posting so much, especially as a first post. I really hope you guys will be able to assist me in locating the problem! :] Thanks so much!

Edit: Also, I put the application through the Profiler in Netbeans and it seems that the drawLevel() method is incurring a lot of overhead, as is the run method. However, I'm still not sure as to how to go about fixing this.

The few improvements you can make:- You don't need to draw into a buffer and then draw that buffer to the screen. Since you are using BufferStrategy, it draws it into a back buffer for you until you call show().- Follow BufferStrategy's javadoc's instructions on how to correctly put the drawing code in while loops.- You are drawing a 1280x768 image in drawLevel()!! That might be a big cause of the slowdown.

EDIT: Aha, I found out why the code looks familiar: been watching Bucky lately?

If you post the complete source as a .rar uploaded to somewhere I can try it out on my computer. It's kind of time consuming to catch the flow of a program by just looking at the code. But do listen to Ra4king's advice first and see if it solves the problem. I'm no Java2D expert.

ra4king: I made the changes you suggested. However, it did not make the program any faster. Is there a way I can restructure or modify the code so that it will process any faster than this? It seems like the bottleneck may be the design of the method and the data's structure. Else, how could scrollers achieve the speed that they get? Appreciate the assistance!

theagentd: I do not have a .rar compressor; however, I uploaded it as a .zip to the following URL: http://www.mediafire.com/?md5faqehgkub4z2I would of course appreciate if you could take a look and see if there is anything that you think could be done to speed it up :] It doesn't seem to me like a side scroller should be a troublesome program to make, but I think I just have it designed improperly.

Thank you guys very much! Looking forward to see if there is any possible solution in sight.

Btw, I forgot to say, yes, I had watched the Bucky videos. :p He actually derived much of what he used in that video from a book called Developing Games in Java, which I realized once I gave it a read; that, or the two are just uncannily similar. I like his manner and way of explaining things; he does a good job.

Anywho, I used the Profiler in Netbeans and found that the drawLevel method was taking up 21% of the program's CPU usage, whereas nearly every other method didn't even scratch the surface. When it has to redraw the whole level view, it usually takes up 26 ms, whereas otherwise it takes up about 0-1 to just shift the view.

- Create 'compatible' images rather than instantiating BufferedImages directly. That is, use GraphicsConfiguration.createCompatibleImage(width,height,transparency). Search the forums for more details. I can't promise it will help, but in theory it will mean that the BufferedImage can use hardware acceleration.

- Don't call nanoSeconds() all over the place. Calculate the time that has passed since the last update in the game loop, and pass that 'delta time' to the update methods. If each update method calculates its own delta time, there's a danger of different game objects getting out of sync.

- As I recall, the Java documentation recommends creating then disposing of Graphics objects whenever you change a BufferedImage, rather than hanging on to a reference to the same one indefinitely. I don't know how much this affects things in practice.

- You can cast your Graphics references to Graphics2D if you like. This will give you more functions to play with.

- Your KeyListener methods should just record which keys are pressed or released. They shouldn't do any real work. Currently you appear to be using the methods to redraw the entire level. Calls to the update functions should happen in the game loop itself, not in the key listeners. The problem is that the key events are processed in a different thread to the game loop, and you're going to run into some nasty thread-safety glitches if you're not careful.

- Try chopping your code down so that it's just a game loop that redraws the level tiles each frame. That'll be easier to debug (for you and, more importantly, for us!).

I get 60 fps on my computer as well. It's not the FPS that's the issue, it's how fast the scrolling is on the level that's bugging me. But thank you for taking a look at the code, in any case, theagentd.

Simon,

Thank you for all those tips... I'm going to go over them tomorrow and refactor my code to reflect them. (Gotta hit the sack soon.) All of those make sense, and since this is my first really big game project, I want to get as many things right as I can, for now and for future games. Once I've made the changes, I'll post back to inform everyone of how those tips helped the code. I'm hoping there's some way I can get this to all work without having to resort to learning OpenGL. XD

...How can it be slow and have constant 60 FPS?! Your problem has absolutely nothing to do with rendering. It's your input handling that's the problem. Just move the input handling to the game loop and do things properly and your "slowness" will magically disappear. You should have described your problem better...

Forgive me for not explaining it better. I will work on fixing that soon and post regarding the performance increase. Question, though: Must I place the KeyListener in main instead of in the LevelRenderer's run method, or is there an alternate means of accomplishing this? I appreciate your help.

Yes I have heard of Terraria. But what does that have to do with this topic?

Where KeyListener is and the way you have things set up is fine for now. If you want to get rid of the pause that comes between the first key press and all further key presses when holding down a key, use your listeners to turn boolean variables that hold the state of certain keys into true if the key is pressed and false when released.

If your game runs at 60FPS, then there is nothing wrong with rendering. What exactly is being slow?

Just keep a boolean for each key (boolean leftKey, rightKey, etc;) and in keyPressed() set the right boolean to true. In keyReleased() set it to false. Then in your gameloop (your run() method) do a check for each of the key booleans and update the player's movement according to which keys are pressed.

You're slowness is as I've said not related to rendering or computer performance at all. It's how the logic is done.

Quote

- Don't call nanoSeconds() all over the place. Calculate the time that has passed since the last update in the game loop, and pass that 'delta time' to the update methods. If each update method calculates its own delta time, there's a danger of different game objects getting out of sync.

Definitely do this. When you've done that, move all the logic out of the key listener functions.

I was just asking because that kind of smooth scrolling is the kind I'd like to see with my game... and the same sort of tile size. But yes, I will update the nanoSeconds() functions so that they are passed in so everything is universal. I appreciate the advice. Also, I've changed the logic of the whole program so that the update methods switch booleans on and off, and as a result, I've noticed a lot of improvement and it looks much smoother. However, the character movement is still on the slow side, much more so that what I'm going for. I'll post the updated code below.

I hope I've got things now in the right place, or at least closer to how they should be. Thank you guys very much for your help! Not that it probably matters too much, but I gave both of you appreciation. ;]

Your game loop should be following a simple flow: update -> render -> sleep.However the sleep should be the amount you want to sleep to achieve the target FPS minus the amount of time it took to update and render, like this example.

Thank you very much for all the advice! I'm learning a lot. I did what you told me and created a couple bits that calculate the sleep amount using the example you showed. I also made a render() and update() function that are now called within the game loop instead, which I think is much more readable, as well. Here's the updated code for LevelRenderer:

If the game is running at 60 FPS you are displaying as many frames as the screen can show. Increasing the FPS of the game further is out of the question, as it will increase the speed of everything in the game PLUS making the game require better hardware to run. What you want to do to achieve faster movement is just to increase the movement speed of the player, right? I haven't been able to figure out how you actually move the player (e.g. update it's coordinates based on input, TL;DR it all you know...) so I can't tell you exactly how to do it in your code, but you should do movement like this:

1 2 3 4

if(upKeyDown){player.y -= delta * moveSpeed;}//Very similar code for all the other directions

- player.y is the current position of the player (you'll probably not write it exactly like this (public access), but whatever) - moveSpeed is a variable that decides the speed of movement (DR. OBVIOUS TO THE RESCUE). - delta is the time since the last update, which should be calculated universally for all objects in the game in the game loop.

All your update methods should take an int delta parameter, and use it to determine how far to move things each update. Doing it like this also makes sure that the game runs at the same speed, regardless of how fast the computer running the game is. Even though the game only runs at 30FPS for example, the objects would make double as long "jumps" each update so they will move the same distance in the same time.I hope things have cleared up a bit. xD

Thank you very much... that's been the problem all along, and I was unable to pinpoint it. It now makes sense... the player's been moving at the slowest possible speed this whole time. The delta method also makes perfect sense now with that illustrated example. I'll get to work updating everything and trying to tie it all together. I appreciate your help and your examples; you've been very helpful.

Lol yes, indeed. I know I have a crap ton to learn. Before this, I was just doing highly simple, static-screen based games like Pong. But I implemented a rough version of what you just explained to me, not everything yet but the most important parts, and it works wonderfully, just like I wanted it to. Thanks so much! I'm sure you'll have plenty of questions to answer from me on the forums in the future (;]) and I know I can come here for help from now on without a problem.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org