I am developing a game using libgdx. My Gameobjects are all subclasses of Actor. Now i want to take Advantage of the Actions which can be used with the Actors. If my Key-Controlled Player collides with a Computer-Controlled Enemie the Player should be knocked back. I can get this with a moveBy-Action. But when my Player collides with a Wall or another Zombie while he stil moves cause of knockback the Action should interrupt.
Is there a way to achieve this? Or are Actions not made for things like this?
Thanks
Of cause there is a way to stop actions.
One way would be that you remove the action from your actor with
actor.removeAction(Action action).
You can clear your actors actions with actor.clearActions(). This does delete all actions.
You can reset your Action or SequenceAction. sequence.reset() or action.reset()
stop updating the Actions at a collision by overriding the .act(float delta) of your actor
Else write a MyAction extends Action or MyAction extends
TemporalAction type which overrides the update (float percent)
and has a boolean for interrupted. If interrupted don't update if
not update.
i would recomend take a look into the actions to see how they work and maybe write your own Action that can be interupted. (your own action should be the best because it will be how you like it) Else remove the Action on collision.
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).
In a game that I am making I have two different mousePressed() methods, one for single fireing and one for auto fireing, If you get a automatic weapon it will change the mousePressed() methid from the one for single fireing to the one for automatic fire.
Later on when you lose the automatic weapon it will cahnge back to the mousePressed() for single fireing (I do this by having two MouseAdapters and the using addMouseListener and removeMouseListener).
The problem is that if you keep holding down the mouse as you lose your aoutomatic weapon you will still shoot automatically until you release the mouse and then press it again and the it will switch to the single fireing mousePressed().
How would I make it so that it will switch the MouseAdapter while the mouse is being pressed?
I suggest you implement two classes: NormalWeapon and AutomaticWeapon or something similar. These classes should implement a fire method that keeps firing until there is no more bullets. Your MouseAdapter will still send the fire command normally, but it won't fire anymore. It will "force" the player to release the button and it will also prevent that you don't keep firing when you don't have any bullets left.
I'm looking into how I should design my games in regards to management/transitioning of different "screens" as well as effect timings. I'm currently using AndEngine on Android, which doesn't have an explicit game loop, although I'm interested in hearing how these issues are dealt with both with or without a game loop.
I've already written a temporary system that I'm using to handle the different "screens" in my game (splash, menu, game, options etc), which is based on "scenes" within AndEngine. I've got 3 base "scenes" which act as layers for a background, content and popups. Each Screen has onTransitionIn() and onTransitionOut() methods which are called by the ScreenManager when it's own methods (such as closePopup(), that sort of thing) are called. However, all code in the transition methods would obviously be run at once, meaning all animations, the screen status etc would be executed instantly. To overcome this problem, I used the postDelayed(runnable, delay) method in the Android Handler class. That way, I was able to change the screen status after the transition animations were completed and run one animation after another. Now the entire system is pretty much based on running delayed code via the handler. Unsurprisingly, it's crude, not particularly stable and generally amateurish.
The second issue regarding "effect timings" is closely linked to my usage of the Handler class. Let's just say I want to create an effect when a user completes a task, where some animation is played and a number is increased on the screen. At the moment, the only way of having one run after the other is by using the Handler. As stated previously, this appears to me like a crude/unstable/amateurish method.
I'd really like to know how these issues are generally handled in games (both with/without an explicit loop).
From your description, it sounds like when you want to trigger a chain of actions, you're basically firing them all off at once, each with some fixed delay. This is quite fragile - if you change the duration of one of the actions, it might no longer sync up with something that's supposed to happen after it.
A more robust approach would be to use the Observer Pattern. Each action could have an onCompleted() event (and/or various other events, depending on the nature of the action), which could be used to trigger the start of the next action.
For example, let's say that when the user presses the selects a menu item, you want this sequence of events:
Play an animation of the selected item.
When 1 is finished, transition the current screen off.
When 2 is finished, transition the next screen on.
It sounds like you're doing something like this:
void onItemSelected(MenuItem menuItem) {
runNow(new SelectedItemAnimationHandler(menuItem)); // Takes 500ms
// Delay for 500ms to wait until end of selection anim.
postDelayed(new ScreenTransitionOffHandler(currentMenu), 500); // Takes 1000ms
// Delay for 1500ms to wait until end of transition off.
postDelayed(new ScreenTransitionOnHandler(nextMenu), 1500);
}
You might chain the events by creating Actions (which fulfil the 'subject' role in the Observer pattern) and ActionObservers (which fulfil the 'observer' role):
void onItemSelected(MenuItem menuItem) {
// Set up the actions
// Actions call onCompleted() on any observers when they complete.
SelectedItemAnimationAction sa = new SelectedItemAnimationAction(menuItem);
ScreenTransitionOffAction stoff = new ScreenTransitionOffAction(currentMenu);
ScreenTransitionOnAction ston = new ScreenTransitionOnAction(nextMenu);
// Add some observers to the actions
sah.addOnCompletedHandler(new ActionObserver() {
public void onCompleted() {
stoff.start();
}
});
stoff.addOnCompletedHandler(new ActionObserver() {
public void onCompleted() {
ston.start();
}
});
// Start the first action
sa.start();
}
This way, you don't need to specify the duration of the SelectedItemAnimationHandler when you set up the ScreenTransitionOffHandler.
EDIT: Tried to make implementation of the Observer pattern clearer.
EDIT 2: Changed runNow(action) to action.start()
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).
I have a poker framework for which I am trying to develop a "player" for. Basically I am implementing an object that implements a Player interface defined by the framework. I am trying to put a GUI on top of this player, the way that game play works is that the Dealer invokes the act() method on my player and expects a return type of Action. The problem I have is that once the act() method is invokes, I update the GUI (written using Swing) to display the options available, however I now need the method NOT to return until the player has chosen an option. The options are displayed as JButtons, which when clicked are handled by an actionListener object. How can I make the act() method not return until the user has acted? I need the thread to sleep/wait until it is woken up by the event being triggered, am unsure of the syntax and best way to do this. Any ideas?
Thanks,
Aly
I think the approach is flawed. The Act method should not wait. Instead it should register for an event (lets call it the Acted event) on the Player instance. At the same time it should start a timer, of say 20 seconds, and if the Acted event is not raised before the timer runs out, the dealer should make the player fold (or check, depending on the situation) automatically and do the same for the next player in line.
That's just off the top of my head, but think about it.
If I undestood your ploblem, you need to use an ActionListener for this.
The ActionListener is an interface implemented in the class you want to be warned when an event occurs. When an specific event is triggered in other part of your code, this class is warned by an abstract method of the Action Listener interface.
It isn't easy to show you with a short answer, but I got an hello world example that can help you.
http://java.sun.com/docs/books/tutorial/uiswing/events/actionlistener.html
HIH