Best way to check selected weapon and draw without field name duplication - java

Hi everyone I am making a simple Libgdx game on Android that involves touching the screen and hitting things. However I have came across a slight problem. I have a small selection of weapons to choose from but I don't know what the best way is to actually draw/access the selected weapons. They are all inherited from a basic weapon class. Right now I have a normal hammer class and a fast hammer class which extends hammer.
The fast hammer has some special methods and swings faster. When I just instantiate the classes I want to test it works fine. However I want to do a check to see which hammer has been selected beforehand and then access it and draw it. I can't think of a very elegant way to do this other than a whole mass of if statements.
I originally tried giving a check variable an int. Then If int 1 then hammer = new normalhammer(); else if int 2 then hammer = new fasthammer(); but this clearly won't work because my hammer variable is assigned to the normalhammer class i.e. Hammer hammer; What is the best way to do this thanks.
Hammer hammer;
FastHammer hammer;//this obviously won't work because duplicate names
if(selected==1){//this was the plan but again won't work because duplication
hammer = new Hammer();
}
else if (selected==2){
hammer = new FastHammer();
}
hammerframe = hammer.HammerAnimation.getKeyFrame(hammer.hammerTime+=delta, false);
//then accessing the class variables won't work because again hammer is a duplicate field. I basically want to check what the check int is and then set hammer to the right class based on that int and the rest of the code will automatically retrieve what I need. Is this possible?

Well, here's how I would do it.
Make all your weapon classes implement some interface/superclass that will help with rendering
Keep an "armory" of weapon objects, one for each weapon type
When the player selects a weapon, set the representative existing object into a "current weapon" variable
For rendering, use the existing "current weapon" variable
Then you don't need to deal with the different types in the renderer - it's abstracted behind the interface!

Related

In Java, what's the best way to make class A do something when an event happens in class B without class B knowing of class A's existence?

I'm making a little game and I have a PlayScreen, which has a GameWorld, which has a Player. Now whenever Player touches a teleport block, I dim the PlayScreen, then Player teleports and then the PlayScreen brightens back up again.
Currently to achieve this I added a boolean inTeleportAnimation to Player. Then PlayScreen checks every single frame inside update() if Player is in teleport animation and if so, it starts dimming the screen. Now this seems fine because it only checks for 1 boolean/trigger. But later there might be A LOT of different triggers for the PlayScreen to do something (e.g. dim the screen). It's probably a bad idea to have playScreen.update() check for every single trigger/boolean every frame as it would mean I need another if statement for every possible trigger. I don't want to make PlayScreen and Player's relation bidirectional either.
What would be the best or "correct" way to achieve this?
I would make use of the observer design pattern to solve this task. It should solve your problem of wanting to avoid a bidirectional coupling, because the PlayScreen (the observer in this case) would be notified of the changes to the Player (the observable in this case) as needed, but would otherwise have no reference to, or any other type of tight coupling to the Player.
If you're using Java, as the tags for this post indicate, here is a simple example in Java that should serve to demonstrate its use.
What if your player sets a global flag that gets turned on whenever an update happens in Player (for ex, when inTeleportAnimation is set this flag also gets set, same for other flags) and which is turned off after PlayScreen.update() handles an update, that way Player does not know about PlayScreen and you can avoid unnecessary checks in each frame. But I don't see a way to avoid the checks for each condition (assuming the global flag indicates an update).

Same component on multiple JFrame instances

I'm working on a game project. I created a GUI class and I want to create an instance of it for each player of the game. So each player will have one screen of the game.
Some information will be displayed on a specific player screen and some will be common. To display common informations, I created a static JLabel in which I put an icon. But I have a problem, the icon only appears on one of the screens.
Why does this happen?
Short answer: you can't. A basic rule of the Swing library is that a component will only be displayed in one and only one container, usually the last container that the component was added to.
The longer answer: you don't want to. You want to structure your program in such a way that the program's model, its logical underpinnings, is well separated from its view, the GUI itself. So what you want to do is have each GUI element share the same model, and use this information to create its own unique view. This has advantages as well, since if a player wants to display elements in a different perspective or point of view, they can do this without affecting what the other players see.
Side note: note that a single ImageIcon can be shared and viewed in multiple separate locations of your GUI since it is not a Swing component, but the JLabel can't be viewed in multiple locations.
Side note 2: Be sure to read: The Use of Multiple JFrames: Good or Bad Practice?, as this contains information pertinent to your program structure.
Side note 3, regarding:
To display common informations, I created a static JLabel...
I would avoid using static fields if at all possible. While this is fine to do in small simple toy programs, it does not scale well since the more static fields you use, the greater the risk of increasing the coupling of your code, and thus increasing its (cyclomatic) complexity, and thus increasing its risk of having hard to cure bugs. Follow good OOP practices by hiding your information, increasing your class cohesion and reducing code coupling, and you'll be a happy coder with cleaner, easier to debug and enhance programs.

How can I combine multiple ACM graphics objects in Java into one object?

I have finished writing a Hangman game, but I want to move the hangman out of the canvas when the game is over. I create that hangman with any partition of his body. When I move the object it can move only one object at a time. How can I bunch them together?
You have to create an object of the class GCompound. This class of object allows you to create new object that can be manipulated like GOval and so. In the Stanford course, there is an example called GFace.
Probably you can refactor your code to make the whole hangman one object through the whole implementation and whenever needed make different parts visible. When the time comes to remove him, just dispose of the whole thing either by resetting them to non-visible or try making a new object I guess... If you cna post the code of your implementation I may be able to give you some more help...

adding another class to my java applet program

I am making a knight's tour implementation in java, and currently I have everything jumbled into one giant mess of code.
I have a class called MainFrame which includes the code to solve the knights tour as well as methods for the menu, etc.
I want to create a new class called KT (for knights tour) which will contain the code for the algorithm, but I'm having lots of issues doing that.
I don't want to post code here because i dont want someone from my class copying or something, so I will just briefly explain.
In class KT, I have declared the variables, arrays, etc. I have methods such as printSolution, move, redo (the backtracking), etc.
However I am unsure how to tie in the code for the buttons (which is declared in MainFrame). For example, I have a loop in the print method that prints the correct solution on the 8x8 board. Right now I'm being asked to create a new method for the button even though I have the button in class MainFrame.
I have a KT k = new KT(); and then I'm launching MainFrame. Is that where I am doing it wrong or is it something really simple that I'm being too dumb to figure out?
tl;dr program works well when i have everything in one class, but i want to make two classes and make everything "look" nice
First of all, give your KnightTour class an actual name. Like, you know, KnightTour. If you were coding this for cash money, the next guy who had to read your code would want to punch the guy who called a class something like KT.
Think about creating this class so that you can use it from a GUI controller like your button and menu laden applet. But so that it can ALSO be used from, say, a character based application where you type commands at a prompt and have your new class evaluate those commands.
The reason I suggest this is because it will force you to create your KnightTour class so that it is PURELY the "business logic" for your app. By that I mean that your KnightTour class should not know anything about buttons, menus, GUIs, text interfaces, or anything like that. You need to think about your KnightTour class in terms of what it must accomplish.
I don't really know what KnightTour does. So I'll just throw out some ideas of what kind of functionality it might need to support. I'm assuming everything takes place on a chess board?
Get the state (occupied, unoccupied) for a given board location (x,y)
Put a chess piece (piece enumerator) on a given location (x,y)
Validate placement of a piece (piece enumerator, location x,y)
Suggest a move, returning a Suggestion object with a piece enumerator and location
Reset the board to start all over.
Now, when you push a button that says "place a piece on 5,5" then you'll handle that event in your GUI controller, and then call the "set piece" method (#2 above) to do that work. If you have a character based application, when you type "put knight at 5,5" then you'll parse that text, and then invoke #2 above. The key point is that both of those user interfaces access the same KnightTour methods to do the same work.
In the actionPerformed method of your MainFrame class just call the appropriate methods to get the solution from KT (which, by the way, I would rename to KnightsTour...readability counts).
Ideally you want all your logic (the model) broken up into sensible methods in KnightsTour, and all your display and button-handling code (the view and controller) in MainFrame. If that's difficult, it's a good sign that you need to rethink how you divided things into methods (and what you're doing with global state...which is frowned upon).
I'm sorry I can't be more specific--I'm kind of hand-tied since you didn't post code.

Java and Its Variables (with many 's'-es) on Swing

I'm about to share abit interesting case here about the java programming and its variables.
First thing I wanted to say is that, we are in these situations:
We have many JLabels with its Naming conventions
(*jll_txtNormalCnn*).
The 'nn' literally means a coordinate of (x,y). TO be
precise, it is a digit of (0-9).
The screenshot of the many Variables used here.
In the screenshot taken; We may see there are 5 x 3 table.
And each column consist of each JLabel placed above it. So it is mimicing as a board with a text on it.
My very simple question is not about the Interface, instead; it is about the programming style. What if.... The variables are sooOOO many. Let say there are 100 Variables using that kind of naming conventions. And once we want to setText() to each of the variables, we want to simplify the coding- instead of typing it one by one.... we wanted to use for-looping to reach each of the Variable.... But, I realized it is impossible.
The code below will not work at all;
for (int x=00; x<101; x++){
(jll_txtNormalC+x).setText("Something");
}
Is there any way around to solve this matter?
I'm not sure whether this is a topic of Dynamic Variable or something, because I never heard about it in Java, except 'Generics', yes I've heard.
I don't think it's a generics problem. It's not about dynamic variables, either. It sounds to me like you're having problems because you've embedded information about the location of the label in a grid inside the variable name. That's a very bad idea, in my view.
Maybe a better idea is to encapsulate that information inside another object and let it maintain the grid of labels. That's far better than your variation on Hungarian notation.
Simply put: don't use separately named variables for this. Use a collection of some kind, whether it's an array (possibly a JLabel[][]), a map or whatever is appropriate.
1) if is your requirement(s) strict quadratic and there are JLabels or JTextFields (with its Swing nested/inherits methods and its derivates including pictures),
2) if you required periodical changes for Component's contents
3) if you want to avoiding memory leaks or GPU performace or freeze
4) if you want to simple and easy to get/set data or changes
then put that to the JTable, by defalut contains JLabel in the cell, by defalut contains JTextField on CellEdit (Mouse or Keyboard input)
1) then you can pretty to forgot about naming, possitionig and another ZOO, all three areas from MVC and JTable would be still consistent
2) you can access to data just from visible/filtered/sorted/removed/rendered TableView
3) you can access to all data from TableModel
4) plus all JTable's features that were added/cames from Java6
5) save lots of time for LayoutManager, possitioning on the screen, Listeners, access to the concrete Component
Normally, when working with grids or matrices you use 2d arrays.
Store your JLabels in a 2d array. You can iterate over them or access labels at (x, y) grid-coordinates using [x][y] notation which is easy to read.
JLabel[][] labelArray = new JLabel[numRows][numCols];
for(int i = 0 ; i < labelArray.length; i++) {
for(int j = 0; j < labelArray[i].length; j++) {
labelArray[i][j].setText("Something");
}
}
store the jlabels in an array (5x3 or 10x10).
You need to use some sort of UI container component (something like a grid), or maybe just an array.
OTOH idea: create an ArrayList or an array and populate it with Jlabels. Iterate through the collection and call setText for each one.
the prober answer is the several times mentioned 2d array.
but, if your labels have to remain single variables, you can also solve this with reflection:
for (int x=00; x<101; x++){
Field f = getClass().getDeclaredField("jll_txtNormalC" + x);
JLabel l = (JLabel)f.get(this);
l.setText("Something");
}

Categories