I'm doing a little strategy game to help me learn Java in a fun way. The thing is I visioned the units as objects that would self draw on the game map (using images and buffering) and would react to the mouse actions with listeners attached to them.
Now, based on some tutorials I've been reading regarding basic game programming, all seems to be drawn in the Graphics method of my Map class. If a new unit emerges, i just update the Map.Graphics method, it's not as easy as making a new Unit object which would self draw... In this case, I'd be stuck with a whole bunch of Map methods instead of using classes for rendering new things.
So my question is, is it possible to use classes for rendering units, interface objects, etc, or i'll have to create methods and just do some kind of structural programming instead of object oriented? I'm a little bit confused and I'd like to have a mental blueprint of how things would be organized.
Thanks!
Sounds like your objects need to have a common interface that they can all be down-casted to for rendering.
E.g. have a generic list of your interface type, populate it with the game objects, then enumerate the list and call the common method to do the rendering.
This is C# code, but it should be similar for Java
public interface IRenderable
{
void RenderMe(Graphics graphics)
}
List<IRenderable> myGameObjects;
foreach (IRenderable myGameObject in myGameObjects)
{
myGameObject.RenderMe(myMap);
}
While the objects are held in the list they can respond to events and update their internal state ready for the next render cycle.
As ck said, you could do this with a drawable interface, something like:
public interface GameElement {
public void draw(Graphics g);
}
public class Sprite implements GameElement{
private Image image;
private int x;
private int y;
public void draw(Graphics g) {
g.drawImage(image,x,y,null);
}
}
public class GameLoop {
public void drawElements(final Graphics2D g, final List<GameElement> elements) {
for (final GameElement gameElement : elements) {
gameElement.draw(g);
}
}
}
but the way you said you want to do it, with a listener, may give you problems in the future.
As dash-tom-bang already pointed, all elements are rendered in a single game loop, after all of them were already updated. If you do this with a listener and you have a game loop or any other thread modifying the unit list, you can end up with a concurrent access modification.
Besides, this way you will draw all elements in a single point, that will avoid some weird flickering on your game.
While "real" game projects come in many forms, ultimately you have something like this:
while True:
ProcessUserInput()
for o in objects:
o.Update()
for o in objects:
o.Render()
Use whatever mechanism you find dear to implement any and all of these functions. :) Polymorphism is fine, so you should feel free to use that if you're comfortable with that. The "world map" likely should be the first item in the list, unless your rendering system is sufficiently advanced to handle out-of-order drawing (depth sorting, basically).
From your question, it may be that the units are owned by the map? In that case, the Map.Render function would iterate over all of the units that it owns, calling Render on each one of them in turn. Regardless, it's probably cleanest if the code to draw a unit is in the class for that unit.
Good luck!
Related
I am making a game in java using the MVC design pattern (with swing) and I do not know how to make the Controller class separate from the view Class.
until now I have a model that contains all the data, a controller which in charge of all the logic and now I think about how to separate the view.
I have the GameView which extends the Jpanel and has a paintComonent:
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
draw(g2D);
}
public void draw(Graphics2D g2D){
drawComponent(background, g2D);
drawComponent(arenaController.getArena().getPlane(), g2D);
drawComponent(arenaController.getArena().getPlayer().getBoat(), g2D);
ArrayList<PlaneDrop> planeDrops = arenaController.getArena().getPlaneDrops();
for(PlaneDrop planeDrop : planeDrops){
drawComponent(planeDrop, g2D);
}
g2D.drawString("Life: " + arenaController.getArena().getPlayer().getLife(), 10, 30);
g2D.drawString("Score: " + arenaController.getArena().getPlayer().getScore(), GAME_WIDTH - 50, 30);
}
but on the other hand, I have the GameEngine which in charge of the configuration and run
#Override
public void run() {
arenaController.init();
long waitTime = 0;
Graphics g = this.getGraphics();
gameViewer.paintComponent(g);
while(arenaController.isRunning()){
long startTime = System.currentTimeMillis();
gameViewer.paintComponent(g);
update(); // update game
gameViewer.repaint();
long endTime = System.currentTimeMillis() - startTime;
waitTime = (MILLISECOND / FPS) - endTime / MILLISECOND;
try{
Thread.sleep(waitTime);
} catch (Exception e){}
}
}
the run() method in the engine invokes the paintComponent() method of the view (which for me sounds like the controller --> invokes the viewer) but I find it is not the best way to do that and it is not recommended to invoke the paintComponent() directly.
So I want a clear separation of the controller and the view but I having trouble finding the appropriate way to do that.
Okay, so you're running into a series of problems.
First
Swing is already a MVC
Second
The form of "MVC" which is taught and discussed today isn't actually how the original intent of MVC was meant to be used. It was considered more of guide line or recommendation than a stead fast rule or paradigm.
The problem is, you end up with "purests" who insist on an absolute separation of all models, controllers and views, in some cases, to the detriment of the API or solution (this when you end up with "massive view controller" problems).
Why? Consider a button. It's a view, it has a model and it can act as a controller.
You don't need a seperate "controller" to control the button. It can register the keyboard and mouse actions it needs to monitor with the underlying system. It can coordinate changes between the model and itself (the view) and it becomes a self contained unit of work.
Seriously, could you imagine having to create a seperate controller every time you created a button or any other UI component ... 😱😓
When you add the button to another container (view), the button is acting as it's own view/controller. The parent container may then have a larger model and a number of sub views which it is "controlling" or coordinating.
The container may also be controlled via an external controller which is acting to coordinate the changes between the container and the large model, allowing it to be decoupled, but in this case, I would design it in such away so that the implementation logic was decoupled, so that the outter controller didn't care about "how" stuff got done, just that there was a contract in place to allow of the passage of information between these layers.
So, what's the point?
Don't get hung up on trying to produce a "clean" MVC, especially in Swing, you're going to be tearing your hear out.
Also remember, you can have a controller talk to another controller, this allows it to disseminate information where sub controllers don't need or want all the information which might be available to the parent controller. It also allows it to control distinctly different controllers, allowing for a greater decoupling of elements and a nice plug and play approach.
So, how does this help you?
This should provide you with some places to jump off from.
If you don't want the GameEngine to talk directly to the view, you could establish a "rendering" controller. Who's responsibility would be to coordinate changes made by the game engine to the model with the underlying view (ie, schedule a rendering pass).
This would allow the GameEngine to "control" one or more "rendering" controllers and allow for a separation in how the underlying rendering is actual done from the GameEngine
You can do this because a controller can be responsible for other controllers - it's just a coordinator between the model and the next layer (typically a view)
In this example, you could change the rendering system simply by changing the implementation of the "rendering" controller (and if you're using interfaces, this becomes much simpler) without effecting the GameEngie, which, at the end of the day is the benefit of following this type of design - separation of responsibility through de-coupling.
Passing thoughts...
Don't, ever, call paintComponent directly. There is a reason why it's protected
Don't use getGraphics. This isn't how custom painting is done in Swing. getGraphics is at best just a snapshot of the last paint pass made by Swing. Remember, in Swing, you don't control the painting process, this is taken care of for you, instead, you schedule a paint pass (ie repaint) and let the system take care of the reset
If you want/need control over the painting process, then you need to use a java.awt.Canvas and a BufferStrategy instead.
Solution:
A good way to split data and logic in a Game is using an Entity Component System.
LibGDX's Ashley is what I use.
These Systems help keeping even the largest games relatively clean and understandable.
However there is some initial work required, so for small games you might just be better off with mixing logic and data in classes like Player or Enemy, put all instances of your Game Objects into a List and have a Canvas that paints them all ordered by their Z-Index.
Brief explanation of an Entity Component System:
In an Entity Component System you Entities as your Game Objects. These Entites are like empty objects, but with the capability to take posess an indefinite amout of Components (one per Component Type). These Components give the Entity the ability to be something (like extending an Class, but not limited to one).
So if your Entity has a TextureComponent it is displayable, but without giving it a TransformComponent it cannot yet be drawn at a specific location. If you now also give it a BodyComponent it can have a physical body in your world and can be pushed around. The TransformComponent will be updated everytime the Body is moved.
All the Logic is performed by Systems. The process all Entites with specific Component Types.
A self drawn visualization (I apologize for the looks, I'm not an artist):
I have a setup which should be able to run multiple cameras at the same time. These cameras detect objects (not in a OO-kind of way, but a physical object, like a chair) and give these objects unique IDs.
However, I am thinking about how I should determine from which camera a motion is detected. The reason why this is needed is because if something (could be a human or an object) moves from camera1 to camera2, the ID should remain the same.
I have no solution for this, which is why I ask you.
My setup, however, looks like this.
public class Camera extends Thread{
public int cameraID;
private ImageHandling imgHandling;
public void run(){
while(true){
//read images from camera
.
.
.
imgHandling.initialize(this);
//imgHandling does all the image analysis and also handles the tracking AND the motion detection. This should not be relevant for this question.
//The identification of different movements is also done in the imageHandling.
}
}
}
This means that every camera will have its own ImageHandling class. Also, every camera is a thread, and the fetching of images is meant to be in the run-method. Also, each camera has a unique ID, i.e. if the setup has 3 cameras, the IDs will be 1, 2 and 3.
I'm programming in Java, but I don't think that a solution has to be language specific.
Based on additional information from the chat, the basic question is more along the lines of "How do we track a moving object" rather than "How do we find out which camera detected movement".
For the sake of completeness, "How do we find out which camera detected movement" is actually fairly easy (and basically covered in the question). Pass the Camera instance to the ImageHandling class.
What happens then gets more interesting...
What you really need to do once a Camera detects motion is to have a MovingObject class that keeps track of one moving object. Obviously some manager somewhere needs to keep a list of Movingobjects.
At a guess you would have something like:
class MovingObject
{
Camera firstDetectedOn;
int speed;
int directionOfMotion;
int width;
int height;
}
The manager then needs to be smart and allow merging of objects.
e.g. If an object is seem on camera1 and then a similar object (size/direction/speed) is seen on camera2, then perhaps they are the same object and not 2 separate ones. Add to that the physical layout - if cam2 is East of cam1 and the object in cam1 is moving East then it is much more likely to be the same than if the object in cam1 was moving West.
One approach may be to keep the items as unique objects and record somewhere that they "might" be the same. If the object disappears of cam1 but you know it might be the object found on cam2, then you may be able to assume it is in fact the same.
I'm trying to write a simple ball game, and there's several turns (ie., ball lives). The ball "dies" when it passes the bottom border of the screen. What I have so far works, but doesn't seem to be the proper way to do things:
if (ball.getY() > bottomOfScreen) {
ball.die();
remove(ball);
}
The die() method basically fades the ball's colour slowly (dark_gray -> pause(50) -> light_gray -> pause(50)), but doesn't actually do anything useful.
The remove(), obviously, gets rid of the ball from the screen, which is what I want. It makes sense to me for this remove() to be a part of Ball's die() method, as opposed to it being a separate method call in the main program -- but I'm not sure how to go about this?
Can an object delete itself? And, if it can, is object suicide better than object murder, from a philosophical/methodological point of view?
Thanks!
The object can remove itself given it has some sort of reference to the view rendering mechanism. Your sample doesn't give enough information so I'll exemplify one way to do it:
public class Ball {
private ViewRenderer view;
public void remove() {
view.remove(this);
}
}
Neither suicide nor murder is better or worse. It depends on your design and requirements.
In this sample though, murder might be preferable since this way the Ball object doesn't need to know in which context it's being used.
It is possible to create a method in which the ball removes itself, but it's a bad thing to do. In order to remove itself from the screen, the Ball must have a reference to the screen. This creates a circular chain of references (Ball has a reference to screen, screen has a reference to Ball) which is going to make your design more complicated and your testing much more complicated.
Suicide is fine - the screen tells the ball to die, and the ball dies. But this is about removal of a relationship, not dying. The thing maintaining the relationship is the screen, and so it should be the thing doing the removal.
Also remember that the two do not necessarily have to happen together. The screen might want to keep a dead ball around for some reason, and it might want to remove a ball that isn't dead. Even if that doesn't happen in your app right now, allow for the possibility.
In a sense of deleting the object from memory: no, in Java that is handled by the garbage collector exclusively.
What you could do is to remove the object from collections containing it, but this would require the object to have access to those collections (which in most cases would not be feasible, since there might be a lot of collections).
I'd suggest the containing object (the screen in your case) to poll for the contained object's (the ball's) state and remove it after it is actually dead.
There is presumably some object (e.g. the Screen, or the ViewRenderer in Johan's example) that holds a reference to the Ball, and removing this reference has to be done by the Screen ("object murder"). "Object suicide" amounts to Ball passing a message to the Screen asking to be "murdered".
Since it is the Ball that knows when it has passed the boundary, it makes sense to me (without knowing the details of your design) for the removal to be initiated by the Ball. Then the Screen can find out about this change by one of several means:
The Screen can poll the Ball.
The Ball can hold a direct backward reference to the Screen, which creates an unfortunate circular dependency.
The Ball can hold a reference to the screen via a BallObserver interface. This is an application of the observer pattern.
The first is simplest, and this makes it a good choice if it fits naturally into your mechanism for painting the screen. The third is more flexible in principle, but you might not need this flexibility in practice. The middle option might be OK in a simple program, but you should probably consider it as a step on the way to the third.
And if you don't have a Screen (or ViewRenderer, or whatever) object and really mean "a separate method call in the main program" then you should probably reconsider your design.
No, objects cannot suicide. Any reference of itself is just a reference.
To "clear" the object within itself one would just clear all instance variables.
To "clear" the object outside itself one would set the variable equal to null.
Lets suppose we have a class Shape which has a method rotate(int velocity). This method makes a shape rotate with a speed of velocity(the parameter passed to rotate). This method has been called in a project, say at 100 places.
But now a new requirement comes, that the rotate functionality will also depend on the color of the shape, i.e. if the color is blue then the velocity should be decreased by 1, else no change should be made.
One solution to this problem would be to change the rotate(int velocity) method to rotate(int velocity, Color color), then add an if statement inside rotate method to check for the color, and make a change in 100 calls of rotate.
E.g.
shape.rotate(50, blue) ;
Inside the rotate method,
void rotate(int velocity, Color color) {
if(color == blue)
--velocity ;
}
Another solution would be to make color as an instance variable of the shape object, and then without adding a new argument to the rotate method, simply set the color before calling it, and squeeze the if check inside the rotate method.
E.g.
shape.setColor(blue) ;
shape.rotate(50) ;
Inside the rotate method,
void rotate(int velocity) {
if(this.color == blue)
--velocity ;
}
Yet another solution would be to overload the rotate method and create a new method named rotate(int velocity, Color color) and use it in the new calls. This would leave the existing code which uses rotate(int velocity) unchanged.
Which of these would be the best possible solution? Or, does there exist a better solution? If yes, then what could it be?
Regards
I'd say there are a couple of questions you need to ask yourself.
Do you care about the color outside of the rotate method? If yes, make it an instance variable; if no, pass it to the rotate method.
Are you likely to care about the color outside of the rotate method further down the line? If yes, make it an instance variable; if no, pass it to the rotate method.
Are you always going to care about the color when calling the rotate method? If yes, make it an argument (to force them to set the color when rotating the shape).
A good principle of OO is to co-locate related behavior and state. In this case the rotate behavior of shape depends on the colour state of shape, so it makes sense to co-locate both in the Shape class, c.q. create a field 'colour' and use it within the rotate method to customize the rotation behavior.
Apart from this design decision, you are really also asking about a refactoring decision: how do I handle the application code that depends on shape? My approach in cases like this is to think ahead: how many changes like these to the Shape class can we expect? If this is a rare change then you could just go ahead and change all the code locations that initialize the shape class so a colour is set. If shape changes more often, then you should be more rigorous and make your code less tightly coupled. A way to do that in this case is to create an abstract factory (or use the factory offered by a D.I. framework like Spring) so that the application code does not need to know the creation details of shape.
BTW your third option seems sub-optimal to me: part of the code is not made aware of the addition of the colour state to shape, and keeps calling the old 'deprecated' rotate method. This means that setting a shape's colour to blue will not universally affect the rotation behavior, but only in 'special cases'. This weakens the design and makes it harder for the developers after you to understand it.
I think the first option is is tedious to implement. What if you miss at one place, what if later u realize that you need rotate(single parameter) again.
The second option is irrelevant as many have already pointed out.
3rd I think is the best solution, as it will not break your code. You can have both the overloaded method, can use any of them as per requirement.
As for me, I see classic example of inheritance usage here.
class Shape {
public void rotate(int v) {}
}
class GreenShape extends Shape {
public void rotate(int v){
super.rotate(v + 10);
}
}
I'm developing a fair sized hospital simulation game in java.
Right now, my pain method is starting to look a little big, and I need a way to split it up into different sections...
I have an idea, but I'm not sure if this is the best way.
It starts by painting the grass, then the hospital building, then any buildings, then people, then any building previews when building. The grass and hospital building will not change, so I only need to paint this once. The buildings themselves won't change very often, only when new ones are built.
I was thinking, use boolean values to determine which sections need repainting?
Ideal, id like to be able to split up the paint method, and then call each one when needed, but I'm unsure how to physically split it up.
I am still quite new to java, and learning on the go.
Thanks in advance.
Rel
Another idea is to create a super class or interface for all items that must be drawn on the screen. Lets cvall this class ScreenObject. You can then have a draw(Graphics2d g) method specified in the ScreenObject class. Next, each object that must be drawn implements the draw() method and is only concerned about drawing itself. You can even consider creating a variable that determines whether this draw method should be run at all.
In the main class that paints the screen you can have a reference to all ScreenObjects in an ArrayList and your paint() method will simply iterate over this calling draw() on each object.
I'm assuming from your description that your scene is split up into tiles. Keeping an array of booleans is a good way to keep track of which tiles need redrawn on the next update. A LinkedList might perform a little better in some situations. (I'm thinking of a Game of Life simulation where there are tons of tiles to redraw and you need to check each neighbor, so you may not need to go this route.)
Without seeing your code I can't give very specific advice on splitting up your paint method. I can tell you that in sprite animations, each sprite object typically has its own draw method that takes the main Graphics object (or more likely a buffer) as a parameter. Since the sprite should know its own image and location, it can then draw itself into the main image. Your paint method can then just loop through your list of sprites that need to be redrawn and call their draw method.
You might look to Killer Game Programming in Java for more detailed information.
Well I am not really an expert at programming but to split up my paint method Ive always just made a new method that takes a Graphics object and call that from paint, it has always helped me to keep my code organized but I have never had a big project like it sounds you are working on so it might not work for your situation.