-
May 3, 2010
Handling mouse events transparently in Swing
Code, TutorialI recently had the task to implement a basic roll-over behavior in a Swing GUI. Pretty simple — or so I thought.
The main problem in Swing is that mouse events are consumed automatically once you employ the very convenient MouseEventHandler, but that might cause some trouble in more sophisticated components. In my case it came down to a JTextPane which can display html and thus had clickable links in it. This JTextPane should be hidden by default and only be visible if a certain element was rolled over by the mouse cursor (similar to a pop-out menu). And there the headaches began: the mouse enter/exit events needed to be captured, but the JTextPane should still receive all mouse events in order to handle the link clicking.
To make things short: this is simple unsolvable in Swing alone. We needs to get our hands dirty and use some of the underlying AWT (yuck!) event handling.
(more…) -
February 19, 2009
“Error 1004: Namespace…”
Code, TutorialI currently work on a rather large AS3-project and therefore embraced then newly introduced namespace-concept, especially since I try to stick to a MVC-architecture. Without namespaces, many classes would have to be in the same package (which clutters them unnecessarily) or expose members / methods as public (which throws all the achievements of the OOP-paradigm out of the window). But namespaces solve that gracefully! Well, if they work, anyway.
-
February 15, 2009
Using reflections for generic filters
Code, TutorialFilters are a great addition to AS3.0 as they provide an easy and appealing tool to work with array. They even manage to relief some of the pain caused by the lack of typed arrays: mixed arrays can be quickly converted into “homogeneous” collections without obscuring the important part of the code too much (see below for an example).
The concept is stunningly simple (and derived from functional programing, a paradigm that starts leaking into the imperative-ruled world): the filter method calls the user-provided function on every element of the target array and returns a new array consisting of all elements on which this function evaluated as true. The user-provided function must feature the following signature:
function filter( object:*, i:int, collection:Array ):Boolean { ... }Where object is the element contained at position i inside the array collection. The index can be useful to create filters similar to the following:
// Returns the first five elements of the collection function filter( object:*, i:int, collection:Array ):Boolean { return i < 5; } // Returns every second element of the collection function filter( object:*, i:int, collection:Array ):Boolean { return i % 2; }Yet the really interesting stuff can be done by applying some operation to the
object. Let’s say we have a mixed array, i.e. objects of various types are contained in it. If we now want only a objects of a certain type — for example Carrot — we could use the following code to do so: function someMethod():void { var vegetables:Array = [ new Carrot(), new Horseradish(), ... ]; // various types var carrots:Array = vegetables.filter( carrotFilter ); // do something with carrots } function carrotFilter( object:*, i:int, collection:Array ):Boolean { return object is Carrot }Usually, filter-functions like the above are needed in various parts of a projects, so it makes sense to define them as static functions in a single class. However, such a class would be project-dependent: in the example above, Carrot might be a straight-forward data-container not intended for reuse — yet the filter-class screams for being a tool usable for all kinds of purposes. So, how could we modify the above type-checking filter to act more generic? Here’s how (using the above example):
function someMethod():void { var vegetables:Array = [ new Carrot(), new Horseradish(), ... ]; // various types var carrots:Array = vegetables.filter( typeFilter( Carrot ) ); // do something with carrots } // Returns a method which filters for objects of class 'someType' public static function typeFilter( someType:Class ) { function inner( object:*, i:int, collection:Array ):Boolean { return object is someType; } return inner; }Notice the subtle difference in usage: typeFilter is actually called, not passed as a parameter itself — the inner function of typeFilter is the true filter. This example uses another kind of functional paradigm named closures, but I don’t want to get into details there. The bottom line is that the inner function of typeFilter can actually acces the local variable someType. The other feature used here is the so-called reflection API: the object someType represents a certain class which can be dynamically set during runtime (see here for some nice examples).
To sum up: filters are a great way of reducing code complexity and combined with reflections (and closures) can become a powerful tool for reusable and generic code. And let me add: map() has even more potential…
-
November 12, 2008
Vector geometry, part one.
TutorialIn the following weeks I plan on writing several articles about collision detection in 2d games, especially for flash. But before that I have to create some common ground which I intend to do with the following posts.
The topic at hand is basic geometry and how to express it usefully in programs. Starting at the most basic element, a point is a tuple of two coordinates (x, y) or (x1, x2) . Points are pretty useless in games, especially since vectors can be misused to ‘emulate’ them. Mathematical a vector is an element of a vector space which satisfies a number of properties (which are interesting, but not really useful in this context).
The fun thing: vectors in 2d euclidean geometry (which I’ll call simply vectors from now on) look exactly like points; they too contain two coordinates (x1, x2). The difference lies in the geometric interpretation and the operations attached to it: a vector is seen as an arrow that points into the direction indicated by the coordinates. Just imagine an arrow drawn from the origin (0,0) up to the point (x1, x2). This arrow is what we call a vector. Note that the vector itself is not “fixed in space”, it describes a direction, not a position.
In contrast to points we can add, subtract and even multiply these arrows — and all those operations have a simple, geometric meaning. I’ve prepared some simple .swfs that contain the important formulas as well as a graphical demonstration of how the operation can be interpreted (try dragging the arrow’s pointy ends around).
-
November 3, 2008
Stop using hitTest()
Tutorial
Every now and then I go over to the Kirupa forum and look around for interesting topics on actionscript game programming (with Flash, I’m not really into Flex). About every tenth post in the game programming area deals with some kind of collision detection or collision response problem. About 99% of those posts can be answered very simple: stop using hitTest().

