Circumvent frequent repaint()-calls for tile-based game - java

I just started to work on a tile-based simulation game (3D but the graphics will all be 2D pngs/bitmaps). The graphical concept is similar to e.g. gnomoria. I managed to implement the graphical part of the world using a custom subclass from Panel (AWT) that draws the cubes starting at the lowest level left back and works its way up. This way the images of the cubes fit together correctly, but the painting takes too long for a 196*196*100 cubes big world.
Now what I'm asking for are methods to circumvent the repainting of the whole world everytime it changes a little bit.
I think I got a decent idea for the changing process of a single top layer block by just repainting the visible side (either top/left/right) so that it isnt necessary to repaint all the following cubes. But what I'm unable to solve is the repaint whenever I'm moving the screen, i.e. moving the world using a KeyListener. My first idea was to just move the Panel in the Frame but that didn't solve the problem as it still redraws everything if I move the world. Btw I already use hardware acceleration which accelerated :D things a bit, but it is still far away from the goal.
The current result is that the Panel moves, but as soon as something enters the screen that was offscreen before, it repaints this section. The repaint is quite fast but not fast enough to not be visible and disturbing.

Related

How do I run my java program off screen and update the view when I ask it to?

I'm currently learning computer science in high school and using "ReadyToProgram Java". We're trying make a pong game using basic shapes and classes etc. The way my game updates its view is to clear the whole screen and then redraw the paddle and pong in a while loop. It's flashes constantly! When I used Turing in the past grade, we had a command called view.update, where it runs the program off screen and only when you use view.update the program will update the screen. Is there something similar in java? Thanks!
The concept you're looking for is known as double buffering. In general, the concept is that you have an off-screen buffer that you do your graphical operations to, then copy the off-screen buffer to the on-screen display.
I don't know exactly what graphical toolkit you're using for your work. AWT can do this with Graphics.drawImage(). See Double Buffering with awt for one discussion of how to do this. In Swing, this can be handled with JComponent.setDoubleBuffered()
If you are using something else, you may wish to look it up using the exact phrase "double buffering".
Update:
The other answer, of course, is to not clear the entire screen and redraw. Given how the pong objects move, you should be able to clear just the portion of each paddle and ball that has moved.

libgdx Cutting an image

I have been trying to "cut" an image for some time now, I ll explain why and what I tried.
So I wanted to create an hp "bar" except it's not a bar but a heart and so I though it would be easy all I had to do is have two pictures draw them on top of each other and then just cut one to make it appear as in hp was being lost, but I was not able to find a way to cut the image.
Setting the height just resizes the image as you might have guessed
I tried using textureRegion to kind of hack it but it didn't go so well
I found a method called clip begin which also uses scissors but for some reason that just doesn't seem to be working.
I might be using the clip begin wrong but I can't really find any real documentation on it, all I'm doing is:
image.clipBegin(x,y,height,weight);
image.clipEnd();
I almost forgot, I'm using a scene2d Image, might be a better way to go around it but not sure what that would be.
I would appreciate any ideas on how to do this, thank you.
You want to use the OpenGL Scissor support that Libgdx exposes. See the Libgdx Clipping wiki
and the Libgdx ScissorStack documentation.
The API isn't particularly friendly (its designed to support dynamically pushing multiple constraining rectangles, which as far as I've seen, isn't used very often).
The important point to remember with the scissor stack is that it only applies to actual draw commands that get issued. Since most APIs try to batch up draw commands, this means actual drawing might not happen when it looks like it should happen. To ensure clipping is happening you must flush any buffered draws before pushing the scissor (otherwise the wrong thing might get clipped) and you must flush any draw calls before popping the scissor (otherwise things you want clipped might avoid the scissors).
See libgdx ScissorStack not working as expected or libGDX - How to clip or How to draw on just a portion of the screen with SpriteBatch in libgdx? or Making a Group hide Actors outside of its bounds.

Andengine Parallax Background

Background:
I am making a 2D side-scroller.
When the player touches the screen, the player moves forward (the camera follows the player).
I cannot find an answer to this question although it seems rather straightforward.
Question:
How can I get my parallax background to scroll only when my player moves?
(example code would make things much easier for me)
I am using autoparallaxbackground but it seems that it simply just scrolls at the rates you pass in, with no regard to the camera. Moreover, I am not fully sure of the difference between autoparallaxbackground and parallaxbackground.
Any help is appreciated!
AutoParallaxBackground extends ParallaxBackground, adding one simple feature: automatically changing mParallaxValue with time. As you may imagine, if you don't need your background constantly moving, you may use ParallaxBackground as your base class, and then use setParallaxValue(final float pParallaxValue) to manually adjust the position.

2d platformer - only move objects currently on the screen?

Now the answer doesnt have to be centered with the programming language I am using (Java), it is really a general question. I am making a 2d platformer, and am autogenerating a terrain with over 30000 tiles (300x100 map). Now, this is obviously causing so so so much lag and flickering.
The one way I can think of to prevent this is to only move objects on screen, but this is really difficult for me to think it through.
It is a side scroller, the guy moves until he reaches the middle, and when hes in the middle, the platforms begin to move, and that is when it gets SO intensive. It has to do those for loops for a whole 30000 tiles every time the swing timer ticks.
Is anyone willing to enlighten me? Just maybe a nudge in the right direction would be great.
Thank you!
You'll likely be using some variation on MVC for this, and you'll have no choice but to move everything in the model -- the non-GUI logical representation of your program -- that needs moving, but the overhead for this shouldn't be huge. You'll only need to move things in the view -- the GUI portion of your program -- that are within the view's viewport (on the screen), and this will be a very limited subset of the objects on your map.

Which component to subclass to draw in Java2D (for a 2D game)

I have created my own canvas that has been extended from the JPanel, however I have noticed that w/ the content and so forth, that all of the sudden my FPS took a hit. I am following the swing rules from Filthy Rich Clients, by using paintComponent, creating a clip area, only redrawing what has been changed, and so forth. I have the FPS set to a constant 50 FPS, and I notice that sometimes my FPS will jump down to 31/32 FPS and go back up to 50 and so forth. While running my program it's only using about 25MB of RAM and 0 of my CPU, even when rendering. I also have OpenGL set.
Note: I have NO images, this is strictly using the shapes in Graphics.
Is there a major performance hit by drawing everything on a JPanel? Should I be extending a different component (I keep seeing Canvas component)? How "smart" is it to build a game such as tetris (or any of the other retro games) in JPanel?
It's a possibility that this is a timer issue, as I just added 100 additional painting calls and the FPS still does the 50 32/31 thing.
After much investigation I have found that the issue is not the JPanel at all. As a matter of fact, the issue is with the Timer in java. It's not 100% accurate, which has resulted in the FPS being way off. My solution to fixing this was reading this: koonsolo.com/news/dewitters-gameloop
I realise that you've found an issue with the Timer class, however I have another comment for you, which you may find useful:
You've not mentioned whether you're using the double-buffer technique. If you're not, then you may notice a FPS improvement.
Just in case you're not familiar with the technique, it involves creating a separate panel buffer, redraw your scene on this buffer, then switch this buffer with the one on the screen, etc.

Categories