My friend and I are working on a game. Right now the game is very simple but we want to understand how we would go about implementing the Single Responsibility Principle between three objects. We have player, enemy, and bullet classes.
The player and enemy both need to be able attack and move, while the
bullet only needs to be able to move.
They all need to be able to collide with one another.
The player moves and attacks based on user input
The enemy moves and attacks based on predetermined attack patterns.
We're really really struggling with the class structure and how to organize the code - we were debating using objects that just hold state and then big controller classes that each do one thing (manage collisions, manage attacking, etc.). Could someone please provide a suggested architecture that follows SRP?
Thank you!
seeing as how box2D bodies cannot be resized, I have a problem with bodies and my animated sprites.
here's the situation which I have no doubt is not unique:
my sprite's dimensions slightly change during different motions like attacking, walking, jumping. seeing as how I was about to use box2D body for collision detection this can cause quite a problem.
so far I thought of 3 ways to solve this issue.
1- not use box2d bodies for collision detection , just use them for object's physical behavior
2- delete and recreate body before each render. or on animation change.
3- trying to recheck the collision on bodies to see if it actually collides with the sprite itself. then act.
and here's the problem I have with each of these solutions.
1- this way makes using box2d as a whole seem rather absurd, also I'll be using not one, but two world logic and trying to keep them in sync. seems like a big headache.
2- this doesn't look very optimized, also I doubt I can just make objects pop in and out of existence in a physics world without side effects.
3- I'm not sure how or even if this can be done, actually this option is the one I require more advice on. will this cause any difficulties in the long run, or cause conflicts in physics.
please let me know if there is a efficient way to solve this , or if any of the above solutions is worth working on.
my thanks
Edit:
It was more of a general question since I still don't have proper graphics for the game I'm writing, but here's my practice material:
walking waiting (standing)
attacking
A body can have multiple fixtures, so you can add all fixtures for each state to the body. If you make them zero density it should not affect the physics behavior of the body. Keep in mind though, that at least one fixture on the body should be non-zero density - you could make one fixture to act as the main fixture, which has density to give the body some mass.
If you just need to detect when these fixtures are touching something, you could make them sensor fixtures, and use your contact listener to keep track of what other things they are currently touching. The contact listener would give you callbacks about all of the fixtures regardless of which state your character is in, and for each state you would keep a list of which things the fixtures for that state are touching.
If you need the fixtures to have physical interaction but only when their state is active, you could do the above but also in BeginContact you would do contact->setEnabled(false) if the contact is for a fixture that is not currently in active state.
If I'm making a game and I want certain things to only update every so often, what's the best way to approach this?
My naive thinking is just keep a "frame" tracker that cycles via mod. math and update certain things at certain numbers.
Is there a better approach?
Much appreciated!
The easiest way to fit your game 'loop' into the libgdx system is to assume your ApplicationListener.render() method is invoked at some unknown (and perhaps variable) frequency. In this callback you'll need to figure out how much time has passed since the last call, update any time-dependent actors, and then draw the update.
This means you should make decisions about updating something "every so often" based on actual elapsed time, and not number of frames.
See the accepted answer on this question for some sample code that does this (note the 'getDeltaTime()' calls):
How to move a sprite with the keyboard keys using libGDX?
I have been looking into box2d (in java with libgdx) lately and have been trying to create my own custom bounce effect (I increase the Restitution after the first bounce)
To do this as a test I simply checked the location of the object and waited for the first bounce.
But now I wanted to actually implement this and came across a problem: How to detect the collision of 2 specific object in box2d?
I found this tutorial:
box2d collision detection - but I am very reluctant to use that code. There must be a simpler and cleaner way to detect a collision between 2 objects (without having to set user data and checking all collisions with giant if() conditions...)
Can anyone help me out? (assuming I am not just hopeful and there actually is a better way)
Subclass b2ContactListener class to handle the collision and reimplement collision callbacks. Then just:
MyContactListener *listener = new MyContactListener();
myB2World->SetContactListener(listener);
And take note, some solutions don't have shortcuts as always but you can find the right solution and there is possibly a hundred ways to detect a collision and you know it, don't you? This is like in the solution of box2d collision detection program for example.
http://blog.allanbishop.com/box2d-2-1a-tutorial-%E2%80%93-part-4-collision-detection/
For my university assignment I have to make a networkable version of pacman. I thought I would best approach this problem with making a local copy of pacman first and then extend this functionality for network play.
I would have to say that I am relatively new to java GUI development and utilizing such features within java.
http://www.planetalia.com/cursos/Java-Invaders/
http://javaboutique.internet.com/PacMan/source.html
I have started following the above links with regards to game development within java and an example of the pacman game.
I decided to represent the maze as an int array with different values meaning different things. However when the paint method inside the main game loop is run i am redrawing the whole maze with this method.
for (int i : theGame.getMaze())
{
if (i == 4)
{
g.setColor(mazeWallColour);
g.fillRect(curX, curY, cellSize, cellSize);
curX += 25;
}
else
{
curX += cellSize;
}
index++;
// Move to new row
if (index == 25)
{
index = 0;
curX = 10;
curY += cellSize;
}
}
However this is providing me with less then 1fps. Although i've noticed the example linked above uses a similar way of redrawing each time the paint method is called and i believe does this on a image that is not viewable (kinda like double buffering [I've used a BufferStrategy like the first link explains]) What would be a better way to redraw the maze?
Any pointers/advice with this would be useful.
Thank you for your time.
http://pastebin.com/m25052d5a - for the main game class.
Edit: I have just noticed something very weird happening after trying to see what code was taking so long to execute.
In the paintClear(Graphics g) method i have added
ocean = sprites.getSprite("oceano.gif");
g.setPaint(new TexturePaint(ocean, new Rectangle(0,t,ocean.getWidth(),ocean.getHeight())));
g.fillRect(10, 10,getWidth() - 20,getHeight() - 110);
which made the whole thing run smoothly - however when i removed these lines the whole thing slowed down? What could have caused this?
Updated code
First off, I'd recommend that you use named constants rather than having random magic numbers in your code and consider using enums for your cell types. While it won't make your code run any faster, it certainly will make it easier to understand. Also, 'i' is normally used as a counter, not for a return value. You should probably call it cellType or something similar. I'd also recommend that you use a 2D array for your stage map since it makes a number of things easier, both logistically and conceptually.
That said, here are a few things to try:
Pull the setColor() out of the loop and do it once. The compiler might be able to do loop-invariant hoisting and thus do this for you (and probably will), but conceptually, you should probably do this anyway since it appears you want all of your walls to be one color anyway.
Try calling drawRect() instead of fillRect() and see if that draws faster. I don't think it will, but it is worth a shot, even if it looks uglier. Similarly, you can try creating an Image and then drawing that. This has the advantage that it is really easy to tell your Graphics object to implement a transform on your image. Also, consider taking this out completely and make sure that it is being a significant performance hit.
Also, normally you don't need to ask for the parent for its Graphics object and implement painting directly on it. Rather, you should override its paintComponent() method and just utilize the Graphics given to you (possibly calling helper methods as you do). Swing components are double-buffered by default, so you don't need to implement that yourself; just let the swing object do its job and let you know when to paint.
Also, you end up repainting the entire screen, which is something of overkill. If you call repaint(Rectangle), Swing can choose to redraw only the sections of your board that are explicitly marked dirty. When you update one of your sprites, call repaint(r) only on the area of the sprite's old and new locations. When you complete a level and need a new board, then you can call repaint() (without parameters) to redraw the entire map.
You should also look at Sun's tutorial to get some tips for efficiency in Swing.
I still consider myself a beginner with Java, but I recently developed a Frogger-esque game with dynamic map and editor using some of the techniques you've mentioned, and I'm only too happy to provide some help.
As mentioned, enum's are the way to go. I set my map up as a 2-dimensional array and set an enum for each different type, writing a method inside my map class to take in one image and divide each square in the map to each value in my enum.
A tutorial that helped me with mapping can be found on Coke and Code. All the source code is there if you need a hand with any of it, although you do seem to have a decent grasp of what you're doing. If you still need help I could always drag out some source code.
It looks like your call to Thread.sleep doesn't do what you intended, but I don't think it's the source of your trouble. You have:
Thread.sleep(Math.max(0, startTime - System.currentTimeMillis()));
startTime will always be less than System.currentTimeMillis(), so startTime - System.currentTimeMillis() will always be negative and thus your sleep will always be for 0 milliseconds. It's different from the example you showed because the example increments startTime by 40 milliseconds before doing the calculation. It is calculating how long to sleep for to pad out the drawing time to 40 milliseconds.
Anyway, back to your problem. I'd recommend measurement to figure out where your time is being spent. There's no point optimising until you know what's slow. You already know how to use System.currentTimeMillis(). Try using that to measure where all the time goes. Is it all spent drawing the walls?
EDIT - I see this got marked as accepted, so should I infer that the problem went away when you fixed the sleep time? I don't have a lot of Java GUI experience, but I can speculate that perhaps your code was starving out other important threads. By setting your thread to have maximum priority and only ever calling sleep(0), you pretty much guarantee that no other thread in your process can do anything. Here's a post from Raymond Chen's blog that explains why.
The code you listed above can't be the source of the 1fps problem... I have code doing far more than this that runs far faster.
Can you benchmark that code and make sure it's the root of the problem?
I'm no game developer, but that framerate seems very slow.
I'm not quite sure how your code is working, but one possibility for improving rendering performance would be to find those parts of the display that don't change much (such as the walls of the maze) and avoid re-creating them for each frame.
Create a BufferedImage containing the constant elements (maze?, background) and then re-draw it first for each frame. On top of this Buffered image, draw the variable elements (PacMan, ghosts, dots, etc).
This technique, along with many other Java2D performance tips, is discussed in Romain Guy's excellent book Filthy Rich Clients.
Just so you don't worry that it's Java, I worked on a Spectrum Analyzer (Like an o-scope) where the entire GUI portion(the trace, menus, button & wheel handling) was done in Java. When I got there it was getting 1fps, when I left it was 12-20. That had a lot of processing going on and was running on a very slow processor.
Look at only updating parts of the GUI that you need to update. Often you can redraw the entire screen but just set a clipping region to the part that is truly updated.
Be careful about inner loops--they are The Speed Killer.
Try to avoid allocating and freeing huge numbers of objects. I'm not saying don't use objects, I'm saying don't create one for each pixel :)
Good luck
Wow, that's a pretty tough problem to give someone just learning Java.
My advice? Think in terms of objects. Can you write something WITHOUT a user interface that mimics the behavior of the game itself? Once you get that working, you can concentrate on the special problems of the user interface. Yes, start with a local version before the networked piece.
I'm not a gamer. I wonder what Java2D API would offer to make your life better?
How much time do you have to finish it?
This might sound obvious but your performance problem is because you are redrawing the entire maze, which doesn't need to be done, instead you need to redraw only changed parts of your maze.
The way I've approached this issue before is by seperating the updating of the maze from the actual redrawing into different threads (kind of like a threaded MVC). Every time you change a cell in your maze you would mark it as "dirty", your redraw thread will check every now and then to redraw only the dirty cells.
Sorry for the extremly generic advice
Java/Swing double-buffers by default. If you're using Swing, you don't need to double-buffer separately, like other answers suggest.
I agree with Allain, that the code you listed can't be the cause of 1fps. I've written highly inefficient Java/Swing animation code that runs much faster than you describe. Do some more testing to narrow down the cause of the slowness.
If possible, you should keep an image of the maze, and draw it in one library call. It probably doesn't need to be full resolution, either -- if you want a blocky, 8-bit feel, I expect the graphics library will be more than happy to oblige 8^)
Also, as others have mentioned, you can save time by redrawing only those parts of the screen that need updating. This can be annoying to implement, but it may allow you to significantly improve your frame rate. Be sure to do some experiments to make sure this is the case before exerting the required effort!