So suppose I'm developing a chess-like program using Java's Swing. I added a MouseListener to handle user input. To make a move the user must click a valid piece and then click a valid place. What's the best way to track the 2 mouse clicks in a turn? I'm thinking in use some kind of variable to record if is the turn's first click or second.
You have to distinguish the two game states, using a variable is fine.. you can also think something as suggested by NomeN comment and use two different listeners by swapping them.
Your case is quite simple but in general the formalism you use to handle these things is a sort of finite state machine that describes the states of your game and how to pass from one to another.
In this case you can have some states like:
player 1 turn
player 2 turn
main screen
pause screen
option screen
and you decide how and when to pass from a state to another, for example
after player1 moved you pass to player2 turn
after player2 moves you go back to player1 turn
when game starts you go in main screen
if you start a new game then you go to player1 turn
if you press pause key while in game you go from turn to pause screen and when closed you go back to the turn that was going before pause
This is just to give you an idea, so for example your MouseListener could care about states:
enum State { TURN_P1, TURN_P2, MAIN, PAUSE, ... }
public State gameState
...
public void mouseClicked(MouseEvent e)
{
if (gameState == TURN_P1)
{
...
if (move_is_legal and so on)
gameState = TURN_P2;
}
else if (gameState == TURN_P2)
{
...
if (move_is_legal and so on)
gameState = TURN_P1;
}
}
Oops, I answered too quickly. Yes, a structure that encodes a click location, looks for intervening motion events and then records the second click. There should be an initiated state, an accept state, and it should probably record a abort state (maybe a press of ESC).
Related
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).
I wrote a simple little maze game for a terminal which repeatedly asks the user to do something (e.g. "In which direction would you like to go? [N/E/S/W]"). I have a navigate() method running in a loop that fires off these questions, stores their answers and does something depending on the answer.
public enum Dir (N, E, S, W);
public void navigate() {
Dir nextDir = utils.askDirection("Which way do you want to go?");
// Do stuff with answer, like changing position of user in maze
}
Now, I've written a simple GUI for my game. I deliberately put all the references to the terminal in a ConsoleUtils class which implements a Utils interface (this has methods like askQuestion()) - the idea being that I could create a GuiUtils class and have my game either as a terminal game or as a GUI game.
The problem is that the navigate method asks the user a question and then "waits" for the response, which the Utils class gives it by using a Scanner to read the newest line of input. However if I use Event Listeners for the new N/E/S/W buttons in my GUI, they fire off events regardless whether the navigate method has asked for one or not.
--> Image of GUI
Is there any way I can combine this or do I need to write a new navigate method for the GUI?
(To be honest, I'm also not entirely sure whether my GUI class should instantiate a game class, in which case the logic for navigate could end up in a GUI method anyway, or whether the game should have a GUI. I haven't written any code for the event listener either yet, since I'm not sure which class should be calling which. This is probably a separate question.)
Your text based game has a loop that repeatedly asks questions to gather user input. Swing provides this loop for you by continually executing Runnable blocks of code that have been posted to the EventQueue. For example, when the user presses a button labeled E, code is posted to the queue that invokes your ActionEvent implementation to handle your game's interpretation of the move east command.
For reference, a complete example of a very simple guessing game is examined here. In pseudocode, the corresponding text based game might look like this:
initialize
loop
prompt "Guess what color!"
get chosenColor
if chosenColor = actualColor
say "You win!"
reset game
else
say "Keep trying."
end loop
A more elaborate game cited there includes the original text-based source.
I am making some sort of turn-based battle system in a JFrame where the player clicks a button when it's his turn. The problem is: how can the program wait for a mouse click on the button? It goes like this:
while it is the player's turn {
wait for mouse input
if input == attack (for example)
-> attack
else if input == item
-> use item
and so on
You don't wait for a click; you let Swing do that for you. Instead, you put whatever you want to do into an ActionListener and attach it to the button, so it gets executed when the button is clicked.
As far as the turns go, you just need a member variable someplace that keeps track of whose turn it is; the button handler then has to look at that variable to know what to do.
One good way to structure things, by the way, might be to have a Player class, and a Game class, and a member in Game called currentPlayer. Then the ActionListener (which keeps the Game object as a member variable of its own) could look at currentPlayer in the Game and simply invoke makeMove() on the appropriate Player object.
I'm working on a Java Game and I've come to a point where I'm having problems with the KeyListeners/KeyBinding. What I basically want to do is temporarily disable the keyboard/do not allow more inputs when an animation occurs. This animation is generated by updating data.
What I currently get is that I press the key for the animation, the animation starts, and I press another key that does some other function. It gets added to the stack/queue(?) of the keyboardlistener and triggers when the first animation finishes.
I'm using a JPanel that implements KeyListener.
To give an idea of the code:
public void keyPressed(KeyEvent arg0) {
//Prevents Repeated keys
pressed.add(arg0);
if (pressed.size() == 1) {
int key = ((KeyEvent) pressed.toArray()[0]).getKeyCode();
if (key == KeyEvent.VK_ENTER) {
doSomeAnimation();
} else if (key == KeyEvent.VK_SPACE) {
doADifferentAnimation();
}
Update();
}
}
Things I've tried:
1) Set the focusable(false) on the JPanel before the calls to the animations. Then set the focusable(true) and grab the focus when they've been completed.
2) Used a boolean to track when an animation occurred.
3) Use Key Bindings.
No matter what method I used, I always ended up with the problem that I would still take in input from the keyboard when the animation was occurring. Then, once that animation was finished, it'd go to the next element in the stack/queue(?) and process that. Also, these animations would need to occur more than once (so using an array of booleans to verify if it's been executed already wouldn't be helpful).
So, if you have any idea or help (or places to point me to) that would be greatly appreciated.
Some Extra Information: Java 1.6, IDE Eclipse, MVC structure. (This in question is the Controller/Model)
Assuming your animation is driven by an instance of javax.swing.Timer, the queue in question is the EventQueue, which runs events in "the same order as they are enqueued" by the Timer. Because it is impractical to stop other devices on the host platform from evoking your listeners, you have to track the effect in your application. As a concrete example, this game has several overloads of the model's move() method to handle input from disparate sources: keyboard, mouse or animation timer. The timer may be toggled on or off to see its effect. This example, which supplants the EventQueue with a custom implementation, may also offer some insight.
I want to create a simple animation of a game so you can see the playout of a game. It should be an animation in which you just see the game Tic-Tac-Toe played. I have the states of the games in a description. So player 1 marks a cell = state 1; player 2 marks a cell = state 2 etc..
I currently have the game parsed in a ruby program; it will be easy to display just one state (like in the image), but how do I create an animation from it? Is there an easy way to do this? I'm open to solutions in every language but it shouldn't take to much time to implement. I want to show such an animation in a presentation.
<state1>
cell(1,1,x).
cell(1,2,o).
cell(1,3,o).
cell(2,1,o).
cell(2,2,x).
cell(2,3,x).
cell(3,1,b).
cell(3,2,b).
cell(3,3,x).
</state1>
<state2>
...
</state2>
Since you already know how to display one state, the way to animate that is to display each state one after the other in sequence.
Display the first state and set a timer, then when the timer goes off show the next state and set another delay, and so on through all the states.
Since you said you are open to all languages I don't really want to bother with any specific code beyond that high-level overview. For example, in Flash/ActionScript I would use TweenLite to display the symbols with a delay, but I don't know if that specific code would be of any use to you.
I've never programmed Ruby but it probably has a command like setDelay() or setTimer() or something. If not, the same effect can be accomplished with a main loop that will check the time each cycle and if the delay has been long enough it shows the next state.
For ruby you can have a awesome tic-tac-toe from https://github.com/grosser/tic_tac_toe
just do "gem install tic_tac_toe"