I need some help with a Java assignment I have, I'm required to build a clone of Pac-Man.
The problem is, I don't know how to draw the movements of the Pac-Man or the Ghosts. I'm thinking I should only draw the walls once, and continiously redraw the characters, but I don't know how I should do it or what methods of drawing I should use.
Generally speaking, it is no good idea not to redraw the complete GUI of any game you write several times each second (the quotient of complete redraws over a second is referred to as the 'frame-rate' of a game). If you do not do this, you might observe weird effects like: The contents look strange if you resize or move the window in case its not displayed in full-screen, there might by weird graphical effects, and, most important, the images of your game-characters won't disappear at their previous positions, if you do not draw the background over them again.
Common approach is to set up a Thread that is not doing anything else but invoking some redraw methods about 60 times each second (60 fps (frames per second) appear fluent to the human eye as our temporal resolution lies in that scale) and to use another Thread that updates the position data of the characters and passes it to the draw-Thread together with the static wall-position-data.
Related
I'm running a game/simulation on JavaFX and when I started it seemed reasonable to add an AnimationTimer to perform the tick updates. My Entity's are composed of a Polygon that holds their shape and position. I added the Polygon's to the scene via a Group and everything renders like magic. However, since it's an simulation, I now want to run millions of ticks with no rendering, to advance to the future and see the results. The problem is, since my Entity's (x,y) positions are inside the Polygon, every time handle() is called in the animation, it seems that the screen is updated.
What is the proper way to split the game loop and render, to be able to call render only after some amount of ticks?
I thought of creating my own MyPolygon class to hold the simulation data, and then when the time comes to draw, create on the fly one Polygon per Entity, but that seems also overkill for me (but maybe I'm wrong).
Also, I'm not sure how to change the ticks per second rate on the AnimationTimer. So I'm not sure it is suited for this specific need.
It seems like a very simple design choice, so there has to be a proper way to do it with JavaFX...
I am building a Java2D video game with multiple sprites updating on the screen at once, and was looking for feedback with regard to best way to handle updates via use of Timers.
I was looking for feedback on best way to handle Timer design that would update locations of each Sprite. Currently, the way I have been doing it, is I have one Timer. When it expires, I update the position of each Sprite. I only ever Update Sprite location by 1 pixel, to keep motion smooth. If something was to update slower that then rest of the Sprite, I update it's position say on every 3 or 5th call of a getImage() call (used to get the current icon image of the sprite).
Now with this approach, all updates are dependent on the main timer, and the Sprites sort of update in relation to each other. So if I wanted to speed up the game, I just update the refresh rate of the main timer.
However, I don't know if this is the best approach. Would it be better to put each object on it's own timer, but would that cause other issues? Maybe cause problems for the main paint() method?
Was just looking for feedback on a good design technique for this.
It is possible to keep using one timer while having perfectly smooth animations despite different animation and movement speeds between different sprites. The way to do is by changing your animation and movement of sprites from a tick based approach (move x many pixels per update) to a time based approach (move x many pixels per how much time has elapsed since the last update).
This would mean your Sprite class (or whatever you have), has floating point x and y positions, as well as floating point x and y velocities. To change the speed of a certain sprite, you would change the velocity (which would be pixels/drawingUnitsEtc per millisecond/nanosecond), and won't be limited by how fast you can make the timer run.
However, I don't know if this is the best approach. Would it be better to put each object on it's own timer, but would that cause other issues?
Well if you did use a timer per Sprite that used a different speed, you would run into overhead problems if the timers ran on their own thread, and if the timers were executed on the same thread then you are technically updating your Sprites based on how much time has elapsed but just moving the velocity constant to an integer.
You would also run into a problem of how you can ensure the Timer consistently returns. With separate timers, imagine that there may be two sprites that are walking next to each other in game which want to update at 10ms, but one of them is running at 11ms due to a laggy timer, eventually one will run into the back of the other and turn around and mess up your level design or some other game mechanic. Another one is that they could be two Sprites of the same kind but now one is now an animation frame ahead of the other while that didn't hold true for the first few seconds that you saw them. With a single timer that updates all sprites that operate together you'll get those consistent results.
Assuming you're using java.util.timer's schedule method.
You could use the scheduleAtFixedRate method for cleaner looking code.
Only use one instance of Timer and attach all sprites to it, this keeps all sprites running on the same thread because then you eliminate all forms of concurrent modification, using a new thread for each sprite is way overkill as the threads will be running as fast as possible and maxing out the computer.
You could also simply make something along the lines of a SpriteManager class which extends Thread so that you don't even need to use timer, all sprites will be running as fast as possible but on one thread, it wont put too much load on the cpu but it worth it. Professionally, movement falls under physics so a game would have some physics thread that handles all updates to everything.
You could get even more detailed in the physics thread by realising that throughout the course of gameplay the amount of objects on the thread will change therefore will update less frequently making everything slower (even if it is microseconds). To keep everything running smoothly you can delta scale. Delta scaling simply takes the time it took last frame as a hint to how fast the thread is running and scales the speed of objects up or down appropriately - this is how (most) games don't run slower when the frame rate drops, instead, they look like they jumped to where it would be at that point in time.
How do I get the mouse position. I have tried:
int mouseX = MouseInfo.getPointerInfo().getLocation().x;
int mouseY = MouseInfo.getPointerInfo().getLocation().y;
But that does it for the whole screen. Anyway to do it relative to the JPanel/JFrame
If I'm only using Graphics JFrame and JPanel that is being repainted every millisecond, should I have buffers? Or will it be fine?
How do I add a mouseAcionEvent only to the frame so it gets X() and Y() of mouse but only in frame?
Use a MouseListener instead of MouseInfo. MouseListener will trigger events which are contextual to the component which raised them, which means you won't need to translate the events into the component space as the event will already be converted to within the component context.
See How to write a mouse listener for more details
How should I update my game rePaint() every millisecond or another way?
Use a javax.swing.Timer...
See How to use Swing Timers for more details...
Should I use buffers?
That will depend. Swing components are already double buffered, but if you use a more complex timing mechanism (AKA game loop), you might find it useful, even to roll your own.
I, personally, would start simple
How can I improve the way I thought out my code in the first place? Is it right having 10 loops or only all in 1 to reduce lag ect.
There are probably lots of things, but start with broader idea...
Breakdown entities to their own responsibilities, for example, the player should know where it is and how it should be painted. It could even know how it's suppose to move based on the current state of the game. This way you could create any number of entities, all with there own set of rules which are isolated and easily updated.
Devise a controller mechanism which is responsible for taking in keyboard and mouse events and simply updating the current state of the game model. That is, rather than going "the user pressed the 'left' key, move player to the left", it would simply raise a flag in the game model that the "left" state has been triggered (or untriggered) and the engine would, on the next update loop, ensure that each entity knew about the change
Don't use magic or hard coded numbers, instead provide some kind of ability to scale the scene. For example, you could decide what is shown on the screen based on the size of the window...
This program will have an infinite canvas (ie as long as the user scrolls, it becomes bigger) with a tiled background image, and you can drag and drop blocks and draw arrows between blocks. Obviously I won't use a layout manager for placing blocks and lines, since they will be absolutely positioned (any link on this, possibily with a snapping feature?). The problem arises with blocks and lines. Basically I'll have two options:
Using a simple layout for each building block. This is the simplest and clearest approach, but does it scale well when you have hundreds of objects? This may not be uncommon, just imagine a database with 50 tables and dozens of relationships
Drawing everything with primitives (rectangles, bitmaps, etc). This seems too complicated (especially things like text padding and alignment) but may be more scalable if you have a large number of objects. Also there won't be any event handler
Please give me some hints based on your experience. I have never drawn with Java before - well I did something rather basic with PHP and on Android. Here is a simple preview
DISCLAIMER
You are not forced to answer this. I am looking for someone who did something like this before, what's the use of writing I can check an open source project? Do you know how difficult it is to understand someone else's code? I'm talking about implementations details here... Moreover, there is no guarantee that he's right. This project is just for study and will be funny, I don't want to sell it or anything and I don't need your authorization to start it.
Measuring and drawing text isn't such a pain, since java has built in classes for doing that. you may want to take a look at the 2D Text Tutorial for more information. In fact, I did some text drawing computations with a different graphics engine which is much more primitive, and in the end it was rather easy (at least for the single-line drawing, for going multiline see the previous link).
For the infinite canvas problem, that's also something I always wanted to be able to do. A quick search here at stackoverflow gives this which sounds nice, althought I'm not sure I like it. What you can do, is use the way GIMP has a scroll area that can extend as you move - catch the click of the middle mouse button for marking the initial intention to move the viewport. Then, when the mouse is dragged (while the button is clicked) move the viewport of the jscrollpane by the offset between the initial click and the current position. If we moved outside the bounds of the canvas, then you should simply enlarge the canvas.
In case you are still afraid of some of the manual drawing, you can actually have a JPanel as your canvas, with a fixed layout. Then you can override it's paint method for drawing the connectors, while having child components (such as buttongs and text areas) for other interaction (and each component may override it's own paint method in case it wants to have a custom-painted rect).
In my last drawing test in java, I made an application for drawing bezier curves (which are basically curves made of several control points). It was a JPanel with overidden paint method that drew the curve itself, and buttons with custom painting placed on the location of the control points. Clicking on the control point actually was clicking on a button, so it was easy to detect the matching control point (since each button had one control point associated with it). This is bad in terms of efficiency (manual hit detection may be faster) but it was easy in terms of programming.
Anyway, This idea can be extended by having one child JPanel for each class rectangle - this will provide easy click detection and custom painting, while the parent will draw the connectors.
So in short - go for nested JPanels with custom drawing, so that you can also place "on-canvas" widgets (and use real swing widgets such as text labels to do some ready drawing) while also having custom drawing (by overriding the paint method of the panels). Note that the con of this method is that some swing look-and-feel's may interfere with your drawing, so may need to mess a bit with that (as far as I remember, the metal and nimbus look-and-feel's were ok, and they are both cross-platform).
I created a game using Swing, and it was a bit unreliable, so I started remaking it using Slick2D game engine and I have encountered issues.
The background of the game rolls across the screen at a certain about of pixels each time the update method is called. This keeps speeding up and slowing down, so the background will move very fast, and then very slow, and keeps fluctuating.
I have tried * by delta (which monitors the refresh rate, I think!) on my value which moves the background, but as this wont give me an exact value I can use to reset the background to the left hand side (2 background move from right to left. left hand one goes to the right at -800 pixels).
What is causing this and how do I overcome it?
Thanks
Here's some reading for you (there's a gamedev-specific StackExchange site, BTW):
https://gamedev.stackexchange.com/questions/6825/time-based-movement-vs-frame-rate-based-movement
https://gamedev.stackexchange.com/questions/1589/fixed-time-step-vs-variable-time-step
One of the most important points in these articles is that things move at a certain rate OVER TIME, not over a certain number of frames. Since frame rates can unpredictably change, time-based and frame-based movement don't wind up being equivalent to one another.
And here's some explanation...
So, your computer and OS are multithreaded, and thus, you can never know what's happening outside your app, and what the overall load is on the machine. Because of this, even when you're in full-screen mode you aren't getting exclusive access to the CPU. So, that's one factor to why things speed up and slow down.
The delta's purpose in Slick2D is to allow you to deal with this speed up/slow down, and allow your app to change its frame rate dynamically so that the perceived movement on the screen doesn't change due to the load on your machine. The delta is not the monitor the refresh rate (which is constant); the delta is the number of milliseconds that have passed since the last call to update.
So how do you use this delta properly? Let's say your background is supposed to move at a rate of 100px/sec. If the delta (on a given call to update) is 33 milliseconds, then the amount you should move your background on this update is 100*(33/1000.0) = 0.033 - so you would move your background by 0.033 pixels. This might seem weird, and you may wonder what the point is of moving <1 pixel, but stick with me.
First, the reason you have to divide it by 1000.0 instead of 1000, is because you want the movement of the delta to give you a floating point number.
You'll notice that the 2D graphics stuff in Slick2D uses float values to track the placement of things. That's because if the delta tells you to move something by 0.033 pixels, you need to move it by 0.033: not 0, and not 1 pixels. Sub-pixel movement is critical to smoothing out the increase/decrease in frame rates as well, because the cumulative effect over several sub-pixel movements is that, when the moment is right, all those little movements add up to a whole pixel, and it's perfectly smooth, resulting in the correct overall movement rate.
You may think that, since your screen resolves images to a given pixel, and not sub-pixel elements, that it doesn't matter if you do sub-pixel movement, but if you convert all your movement tracking to floats, you'll see that the effect you're observing largely goes away.