Say you're building a Tetris game. As any proper programmer, you have your view logic on one side, and your business logic on the other side; probably a full-on MVC going on.
When the model sends its update(), the view redraws itself, as expected.
But then... if you wanted to add, say, an animation to vanish a line, how would you implement that in the view?
Make any assumptions you want---excepting that "Everything is properly encapsulated".
Personally, I would separate draw the screen as often as possible, even if there was no update of the block position. So I would have a loop somewhere with an "update" and a "render" part. Update plays the ball to the logic which does or does not any update of positions and/or block removal. Render plays the ball to the graphics part, which draws the blocks where they should be.
Now if there are lines to erase, the logic knows and can mark those lines to be removed. I assume here, that every piece consists of 4 single blocks and any of these blocks is a single object. Now when this block has the "die"-flag set, you may take some render-parts to vanish the block (let's say, 500ms to explode). After this time, the object may be disposed and the block a line above falls down. Why 500ms? Well, you should definitely use time-based movement as this keeps the game speed the same on different computers.
Btw, there are already so called game engines which provide such an update-render-loop. For example XNA, if you go the .NET line. You may also code your own engine but beware, it's not an easy task and it's very time consuming. I did this once and don't expect it to be an engine like the Source Engine ;-)
Most games execute a loop that constantly redraws the view of the game as fast as possible, rather than waiting for a change in the model state and then refreshing the view.
If you like the model view pattern, then it might work well for the view to continue to draw some types of objects after they are removed from the model, fading them out over a few milliseconds.
Another approach would be to combine class MVC with something like differential execution - the 'view' is a model of what is presented, but the drawing code compares the stream of events the 'view' creates with the stream from the previous rendering. So if in one stream there's a line, and the next there isn't, the drawing code can animate the difference. This allows the drawing to be abstracted away from the view . Frequently the 'view' in MVC is a collection of widgets, rather than being something which draws the display directly, so you end up with nested MVC hierarchies anyway: the application is MVC ( data model, view objects, app controller ), where the view object has a collection of widgets each of which is MVC ( widget state (eg button pressed ), look and feel/toolkit binding, mapping of toolkit events -> widget state ).
I've often wondered this myself.
My own thoughts have been along this line:
1) The view is given the state of the blocks (shape, yada-yada), but with extra "transitional" data:
2) The fact that a line must be removed is encoded in the state, NOT computed in the view.
3) The view knows how to draw transitions now:
No change: state is the same for this particular block
Change from "falling" to "locked": state is "locked in" (by a dropping block)
Change from "locked" to "remove": state is "removed" (by a line completion)
Change from "falling" to "remove": state is "removed", but old state was "falling"
Its interesting to think of a game as an MVC. Thats a perspective I've never taken (for some odd reason), but definitely an intriguing one that makes a lot of sense. Assuming you do implement your Tetris game with an MVC, I think there are two things you might want to take into account in regards to communication between your controller and your view: There is state, and there are events.
Your controller is obviously the central point of interaction for the user. When they issue keyboard commands, your controller will interpret them, and make the appropriate state adjustments. However, sometimes the game will enter a state that coincides with a particular event...such as filling a line with blocks that should now be removed.
Scoregraphic has given you a great foundation. Your view should operate on a fixed cycle to maintain consistent speed across computers. But in addition to updating the screen to render new state, it should also have a queue of events that it can perform animations in response to. In the case of filling lines in Tetris, your controller could issue strongly typed event objects that derive from some kind of base event type into the view event queue, which could then be used by the view to perform the appropriate animated responses.
Related
I was wondering if, whenever I have a situation in which I have to hide some UI element temporarily, it is sufficient to hide it (many frameworks give this option) or I should delete the object in memory and recreate it later when needed again (with the same parameters).
What are the pros and cons of each solution? I was thinking that maybe by hiding the element you save state informations that may be important, and you also save the allocation time, so maybe it is the better way for elements that must be hidden for a short period of time. But what if the time becomes bigger? I would then have a non-needed object in memory for the whole time.
One example, to give a clear picture of what I am talking about, would be a toolbar that changes buttons based on some context change. That is, normally there are some buttons attached to the toolbar, but when the user select one action in some other part of the interface, those buttons must be replaced by new ones (one of which is the "Done" button). Similarly, when the user selects the "Done" button in the toolbar, it goes back to the initial state.
I don't know if this is a stupid question and maybe it could be that I'm doing something like premature optimization... but I will be thankful for all your answers.
I think that the general rule of the thumb is that elements that you plan to reshow, should be hidden; otherwise destroyed (some exceptions obviously apply). When/if this becomes infeasible, you could consider further optimizations.
It's a very good question. Here's what occurs to me:
Suppose (just for the sake of argument) you have lots of different forms that could be displayed in the same space. Then if you create/destroy controls, you are only paying at any one time for the controls that the user can see. On the other hand, if you hide/show controls, you are paying all the time for the large number of controls the user isn't looking at (and may never look at). So I always create/destroy. (Actually I keep previously used controls in pools so I'm not actually re-creating them.)
Many people store user state in the controls of the UI, but personally I hate that and I never do it. I think if some information is worth remembering it belongs in application data structure. This means of course, that the controls of the current visible form have to be "bound" or kept current with the application data structure. I just make sure I can do that no matter what.
I've had to be inventive to accomplish these in a way that simplifies application code, and as a result the method I use is not well known, which exacts another kind of price.
There is no general answer to this question. It depends on the system type, CPU and RAM restrictions, the number of UI elements in question, how frequently the UI is going to be shown / recreated, etc. Perhaps if you could give an example we might be able to give you more concise feedback.
Javascript objects are not like Windows (GDI) objects: they usually don't have a will to send/receive messages - almost passive. It takes less code to hide, right?
Perhaps it depends on total amount of interactive objects per user session.
New to GWT here...
I'm using the UIBinder approach to layout an app, somewhat in the style of the GWT Mail sample. The app starts with a DockLayoutPanel added to RootLayoutPanel within the onModuleLoad() method. The DockLayoutPanel has a static North and a static South, using a custom center widget defined like:
public class BigLayoutWidget extends ResizeComposite {
...
}
This custom widget is laid out using BigLayoutWidget.ui.xml, which in turn consists of a TabLayoutPanel (3 tabs), the first of which contains a SplitLayoutPanel divided into WEST (Shortcuts.ui.xml) and CENTER (Workpanel.ui.xml). Shortcuts, in turn, consists of a StackLayoutPanel with 3 stacks, each defined in its own ui.xml file.
I want click events within one of Shortcuts' individual stacks to change the contents of Workpanel, but so far I've only been able to manipulate widgets within the same class. Using the simplest case, I can't get a button click w/in Shortcuts to clear the contents of Workpanel or make WorkPanel non-visible.
A few questions...
Is ResizeComposite the right type of class to extend for this? I'm following the approach from the Mail example for TopPanel, MailList, etc, so maybe not?
How can I make these clicks manipulate the contents of panels in which they do NOT reside?
Are listeners no longer recommended for handling events? I thought I saw somewhere during compilation that ClickHandlers are used these days, and the click listener "subscription" approach is being deprecated (I'm mostly using #UiHandler annotations)
Is there an easy way to get a handle to specific elements in my app/page? (Applying the "ID" field in the UI.XML file generates a deprecation warning). I'm looking for something like a document.getElementById() that get me a handle to specific elements. If that exists, how do I set the handle/ID on the element, and how can I then call that element by name/id?
Note that I have the layout itself pretty well nailed; it's the interaction from one ui.xml modularized panel to the next that I can't quite get.
Thanks in advance.
If you don't have a use for resizing events than just use Composite
What you want is what the GWT devs called message bus (implemented as HandlerManager). You can get a nice explanation in the widely discussed (for example, on the GWT Google Group, just search for 'mvp') presentation by Ray Ryan from Google I/O 2009 which can be found here. Basically, you "broadcast" an event on that message bus and then a Widget listening for that event gets the message and does its stuff.
Yep, *Handlers are the current way of handling events - the usage is basically the same so migration shouldn't be a problem (docs). They changed it so that they could introduce custom fields in the future, without breaking existing code.
If you've set an id for any DOM element (for Widgets I use someWidget.getElement().setId(id), usually in combination with DOM.createUniqueId()) you can get it via GWT.get(String id). You'll get then a RootPanel which you'll have to cast to the right Widget class - as you can see it can get a little 'hackish' (what if you change the type of the Widget by that id? Exceptions, or worse), so I'd recommend sticking with MVP (see the first point) and communicating via the message bus. Remember however, that sometimes it's also good to aggregate - not everything has to be handled via the message bus :)
Bottom line is I'd recommend embracing MVP (and History) as soon as possible - it makes GWT development much easier and less messy :) (I know from experience, that with time the code starts to look like a nightmare, if you don't divide it into presentation, view, etc.)
I have a cocoa interface that uses core plot. When I press a button in the interface, a plot is drawn. I wanted to create a sequence of graphs by calling the plotting method multiple times along with calls to sleep() in between. But it seems that even though the call to reload data is made that nothing happens until the function exits(only showing last graph as well). Now I know that CPAnimation exists but before I start using it I was wondering what it is that happens when the function exits that makes the graph refresh. Would I have to yield to the thread that takes care of the refreshing instead of using sleep?
Ok I figured out how. I called the reloadData method from a method in a separate thread (which always returns). This boiled down to calling reloadData from an IBAction and also with an NSTimer. Finally instead of using sleep I will use NSConditionLock coordinate the processing and the refreshing
Presumably, Core Plot (or your code) sets the view as needing display. That doesn't happen immediately; it happens when you return to the event loop.
Whenever you use sleep in a Mac OS X application, you kill a puppy. Use NSTimer instead. Have your timer callback method do the work required for one graph, and set whatever instance variables are necessary for your the method to know which graph it should draw, so that the method draws each graph in turn until it runs out of them.
Or, better yet, present a list of graphs that the user can choose from, instead of making the user watch all the graphs as a slide-show. (Unless an explicitly-labeled slide-show is what you're implementing.)
Core Plot, like most Cocoa drawing frameworks, is lazy: it draws at the end of the run loop iteration. This is to ensure that things aren't drawn too often.
Rather than drawing immediately, the layers are marked as needing drawing.
As was pointed out by others, a better approach to sleeping is to use NSTimer to avoid blocking the run loop, or to use NSObject methods like performSelector:withObject:afterDelay:
Peter has it right—the reload data method doesn't actually draw anything. The plot is marked as needing display and refreshed the next time the layers are drawn to the screen. If you use sleep, it never gets a chance to draw.
Also note that Core Plot is a fairly young project; CPAnimation and the related classes are stubs. They don't really do anything yet. :-)
I have a set of nonGUI objects which have a one to one realtionship with GUI objects.
All events are routed through the top level window.
Many ( not all ) events occuring on the GUI object result in calling a method on the associated object.
Some methods in the NonGui objects which when called change the GUI objects.
One example would be some sort of game like Rogue with a modern GUI.
You have the area a player occupies in one turn ( call it a region )
and you have the object ( a button ) associated with it on the GUI.
Keep in mind it's only an analogy ( and not even the real problem ) and no analogy is perfect.
The question is, how does one design this sort of thing?
Since the button class is from a third party library, I cannot imbed a reference to the nonGUI object in it, though I can imbed a reference to the GUI object in the nonGUI object. So it looks likeI will have to create a map from a buttons to "regions" somewhere, but where do I put it? In the toplevel window? In the top level model?
Do IU spin off some sort of interface class?
Suggestions?
It would help if you mentioned your platform and language, but generally it sounds like you are describing Model-View-Controller.
Your "GUI" object(s) are the View. This is where you keep all the rendering logic for your user interface. User interactions with the View are handled by the Controller.
The Controller is a thin layer of event handles. User interaction calls methods on the Controller, which then routes them to the Model.
Your "non-GUI" object(s) are the Model. This is the object that contains business logic and whose state is ultimately updated by clicking buttons on your GUI.
You mention "embedding" references between the objects. This is not necessary as long as events in your GUI can be routed by some mechanism to your Controller. This design pattern is useful because it separates your UI logic from your business logic. You can "snap on" a new Views very easily because there is very little event wiring between the View and the controller.
The Wikipedia article has more information and links to implementation examples.
Waste a little time looking at Falcon's Eye (though it is Nethack rather than Rogue). There's a long history of skinning rogue like games (or command line apps in general), which isn't quite classic mvc - it already has a full UI, instead you're adding a decorator to that UI with either a direct translation, or another metaphor (such as gparted, the gnome partition editor, which allows construction of a sequence of partition editing commands by direct manipulation)
I've been developing Web applications for a while now and have dipped my toe into GUI and Game application development.
In the web application (php for me), a request is made to the file, that file includes all the necessary files to process the info into memory, then the flow is from Top to Bottom for each request. (mainly)
I know that for Games the action happens within the Game Loop, but how are all the different elements of a game layered into that single loop (menu system, gui, loading of assets and the 3d world) with the constant loading and unloading of certain things.
Same for GUI programs, i believe there's an "application loop" of some sorts.
Are most of the items called into memory and then accessed, are the items linked in and loaded into memory when needed?
What helped me develop web applications faster is when i understood the flow of the program, it doesn't have to be detailed, just the general idea or pseudo code.
There's almost always a loop in all of these - but it's not something you would tend to think about during most of your development.
If you take a step back, your web applications are based around a loop - the Web Server's accept() loop:
while(listening) {
get a socket connection;
handle it;
}
.. but as a Web developer, you're shielded from that, and write 'event driven' code -- 'when someone requests this URL, do this'.
GUIs are also event driven, and the events are also detected by a loop somewhere:
while(running) {
get mouse/keyboard/whatever event
handle it
}
But a GUI developer doesn't need to think about the loop much. They write 'when a mouse click occurs here, do this'.
Games, again the same. Someone has to write a loop:
while(game is in progress) {
invoke every game object's 'move one frame' method;
poll for an input event;
}
... while other code is written in a more event-driven style: 'when a bullet object coincides with this object, trigger an explosion event'.
For applications and to a lesser extent Games the software is event driven. The user does "something" with the keyboard or mouse and that event is sent to the rest of the software.
In Games the Game Loop is important because is focused on processing the screen and the game state. With many Games needing real time performance. With modern 3D Graphics API much of the screen processing is able to be dumped onto the GPU. However the Game State is tracked by the main loop. Much of the effort of a team for a game is focused on making the processing of the loop very smooth.
For application typically heavy processing is spawned on onto a thread. It is a complex subject because of the issues surrounding two things trying to access the same data. There are whole books on the subject.
For applications the sequence is
user does X, X and associated information (like X,Y coordinates) is sent to the UI_Controller.
The UI decides which command to execute.
The Command is Executed.
The model/data is modified.
The Command tells the UI_Controller to update various areas of the UI.
The UI_Controller redraws the UI.
The Command returns.
The Application waits for the next event.
There are several variants of this. The model can allow listeners to wait for changes in the data. When the data the listener execute and redraws the UI.
As far as game programming went I was merely a hobbyist, however this is what I usually did:
I had an object that represented a very generic concept of a "Scene" in the game. All the different major sections of the game derived from this Scene object. A scene could really be anything, depending on what type of game it is. Anyway, each more specific scene that derived from scene had a procedure to Load all of the necessary elements for that scene.
When the game was to change scenes, the pointer to the active scene was set to a new scene, which would then load all of its needed objects.
The generic Scene object had virtual functions such as Load, Draw, and Logic that were called at particular times in the game loop from the active scene pointer. Every specific scene had its own ways of implementing these methods.
I don't know if that's how it's supposed to be done or not, but it was a very easy way for me to control the flow of things. The scene concept also made it easy to store multiple scenes as collections. With multiple scene pointers stored in a stack of sorts at one time, scenes could be stored in reserve and maintain their full state when returned to, or even do things like dim but to continue to draw while the active scene drew over them as an overlay of sorts.
So anyway, if you do it like that it's not precisely like a web page but I guess if you think about it the right way it's similar enough.