16
Programming / Re: Window managers and "printing messages"
« on: August 08, 2013, 11:26:06 AM »
Hmm. But what about the question I mentioned with whether the window manager+panes should be wrapped or not?
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
You are indeed splitting the game logic. You essentially have a pre-attack piece of logic that checks for possible interrupts, which is handled in 3. The interrupts are sent out as events somehow, and the GUI state is updated to deal with player input for the interrupt.
After that, like I say back in step 5, you are in the usual game loop, which looks at the game and the GUI and draws it. The rest of the game attack logic is executed after the player has dealt with the interrupt GUI stuff. Once the game attack logic FINISHES executing, you do the rest of the game turn logic, which has other monsters execute and so forth
Well, when you attack, everything should happen, the messages for everything that happens since your attack all the way to your next turn (e.g. monsters attack, etc) are going back to the message pane, and then it gets drawn. Once that's one, you can scroll up and down. I don't see any essential logic separation that needs to happen here.
However, let's try another example. Suppose than when you are attacked, you get the choice of parrying with your sword, or using your shield. Perhaps the shield is safer, but doesn't allow you to counter-attack, while parrying using your sword is harder but might allow a counter-attack. Thus, somehow, you should get a prompt between one of your turns and your next turn.
I guess in general, we're just talking about "interrupts". Some action is executing, but we determine that there's some input that can happen before this. That's a very interesting problem that I can't think of a solution to off-hand. I'll try to use events as little as possible, but I feel they are needed.
I assume that whenever your player does an action, it takes a number of ticks. The world stores how many are left to execute.
- Suppose you, the hero H, attack the monster M. You slash it but don't kill it. It takes 50 units util your next action.
- After 25 units, it's M's turn. He attacks you. The logic calls player.startAttack(M).
- player.startAttack(M) checks that there's a possible interrupt. It pushes a ShieldInterruptEvent.
- The GUI catches the ShieldInterruptEvent and creates an ShieldInterruptPane in the GUI, which contains the ShieldInterruptEvent .
- The game is now in the usual loop, but the ShieldInterruptPane is capturing all the input events and not letting them proceed anywhere else.
- Once the player provides adequate input, it uses the ShieldInterruptEvent to make a callback to player.finaliseAttack() with appropriate attack modifications.
You can probably have an Attack class that's being passed around the events and modified as it goes through these things?
The advantage of this is that the same way that the ShieldInterruptEvent is caught by the is caught by the GUI, it may also be caught by the AI enemy, and thus this method can also work for non-player Shield interrupts.
How does this sound?
I'm not sure about your game's specifics. I would say you can NOT queue events, and just handle them as they happen. Then as soon as you notify the EventManager of an Event, it gets handled by all listeners, and the code just continues executing past the .notify(event) call.
What I was saying is that you could have a EventManager.queueEvent(event) and then EventManager.handleQueuedEvents(), but I don't currently see any use for this.
What I would do in that situation is have the message box be the first pane to get access to input. Then, you'd do the turn logic, and shoot off all game events. The message box pane receives all of that, and updates what it needs to show, but doesn't scroll down.
Then, because the message box pane is getting the input first, and it's in a state in which it hasn't shown everything (there's a "more" prompt), it will consume all input. If it's the ENTER key (for example), it scrolls down. If it's not, it does nothing, but it still consumes the input.
Would this work?
I have an EventManager class, which has a singleton instance, but other things can also be/have EventManagers. For instance, any entity in a game can be an EM, the game world itself can also be an EM for purely game related events (nothing that requires UI, etc), and so forth.
The Event Manager interface is simply "notify(event)", and "registerListener(eventType)". Every time you send a notify, it will check whether there are any listeners for that event type, and send them a notification that that event happened.
I've seen some people queue events and handle them explicitly in the loop, but that might not be necessary.
Well, when you attack, everything should happen, the messages for everything that happens since your attack all the way to your next turn (e.g. monsters attack, etc) are going back to the message pane, and then it gets drawn. Once that's one, you can scroll up and down. I don't see any essential logic separation that needs to happen here.
However, let's try another example. Suppose than when you are attacked, you get the choice of parrying with your sword, or using your shield. Perhaps the shield is safer, but doesn't allow you to counter-attack, while parrying using your sword is harder but might allow a counter-attack. Thus, somehow, you should get a prompt between one of your turns and your next turn.
I guess in general, we're just talking about "interrupts". Some action is executing, but we determine that there's some input that can happen before this. That's a very interesting problem that I can't think of a solution to off-hand. I'll try to use events as little as possible, but I feel they are needed.
I assume that whenever your player does an action, it takes a number of ticks. The world stores how many are left to execute.
- Suppose you, the hero H, attack the monster M. You slash it but don't kill it. It takes 50 units util your next action.
- After 25 units, it's M's turn. He attacks you. The logic calls player.startAttack(M).
- player.startAttack(M) checks that there's a possible interrupt. It pushes a ShieldInterruptEvent.
- The GUI catches the ShieldInterruptEvent and creates an ShieldInterruptPane in the GUI, which contains the ShieldInterruptEvent .
- The game is now in the usual loop, but the ShieldInterruptPane is capturing all the input events and not letting them proceed anywhere else.
- Once the player provides adequate input, it uses the ShieldInterruptEvent to make a callback to player.finaliseAttack() with appropriate attack modifications.
You can probably have an Attack class that's being passed around the events and modified as it goes through these things?
The advantage of this is that the same way that the ShieldInterruptEvent is caught by the is caught by the GUI, it may also be caught by the AI enemy, and thus this method can also work for non-player Shield interrupts.
How does this sound?
loop:
receive input
pass input to window manager
tell the window manager to redraw
If we're still talking about a console emulator (that is, the ONLY BASIC drawing method we have is plot_char), some drawing utilities could be in the logical console. Every complex drawing method, in a console, is just an aggregation of plot_chars. So, to draw a widget, that widget will send the instructions necessary to draw itself.
This is oftentimes called a display list. You have a tree of drawable objects that contain other drawable objects that we traverse when drawing the scene (also called a scenegraph). Each node in the graph represents a coordinate (relative to the parent) and possibly drawing instructions (and transformations).
When we draw a widget, we've already scoped to a local point, we just need instructions to draw. We would probably make a library of common methods, like draw_circle and daw_rect, to make things simpler-- though, more importantly, we would try to make sure similar widgets use the same drawing instructions whenever possible or make it so that a widget is a composition of components-- like scrollbars, textfields, etc. At this point though it's just semantics.