Monogame – Working with Touch

*NOTE – This may also work on other platforms with touch as well, but this hasn’t been tested on anything other than Android at the current moment.

One fundamental aspect to understand about touch and gestures is that code needs structured around the idea of continuous input. Thus, any touch recognition code should be encapsulated somewhere within the main game loop; where this is would be dependent upon how one elects to parse input. The reason for this is that the nature of all touch processing is a sequence of touch events that get fired in succession; there are only a few exceptions to this rule.

The other aspect to understand clearly is nomenclature mapping. What you think you want to achieve in your design may, unless you’re already familiar with either the Monogame or Xamarin frameworks, not necessarily be what either of those aforementioned frameworks are calling it through its API parlance. So be prepared to step outside your normal wheelhouse and, perhaps, discard some long-standing assertions about what truly a touch/gesture really is.

First, the consideration needs made as to if you’re going to handle touches or gestures – don’t get too caught up on thinking that a touch is a single press, because this will cause you some unnecessary grief later. If your program ebbs toward the former, there’s usually no requisite configuration needed, other than to check for the existence of a touch-capable input device and adjust your engine accordingly (the only other exception here would be if one wishes to perform touch-to-cursor mappings, but this is outside the immediate scope of this article). Conversely, gesture handling requires some configurations be made before they can be used, and this is where the Monogame documentation, as well as a majority of the information available on various forums, falls fatally short. We will focus on this once we start addressing gesture handling, which follows a look at touch handling.

Checking for the existence of hardware with touch capabilities can be queried through the TouchPanelCapabilities object, triaged through the TouchPanel static object as such:

TouchPanel.GetCapabilities ().IsConnected;

The IsConnected property is a boolean that indicates the presence of a touch-capable device. Obviously, the absence of one suggests either that the device is intermittently available, or that other sources of input are necessary. In this case, neither the touch nor gesture APIs would be valid.

Concerning touches, the current state of the touch panel holds a collection, called TouchCollection, of TouchLocation objects. Each of these correspond to a single touch event generated by the user when a press is determined to have occurred on the sensitive surface. It’s fair to suggest that multiple points of contact yield multiple TouchLocation instances within the TouchCollection (i.e. as a practical example, one finger would generate one instance, two fingers would generate two instances, etc. This can best be observed while debugging a program using this technique, and paying attention to the Id property of the TouchLocation instance(s).). In order to properly ascertain the most accurate state of the touch panel, we’ll need to do the following:

  1. Obtain the current state of the touch panel
  2. Determine if there are any TouchLocation instances in the TouchCollection collection
  3. If there are, take relative action based on any of the properties of the current TouchLocation instance

This can be accomplished using the following general template

TouchCollection tc = TouchPanel.GetState ();
foreach (TouchLocation tl in tc) {
 // Do something here
}

Fortunately, TouchLocation instances are very simple to use. There are only four properties that are of any practical significance, and one utility function for trying to determine the previous location (which, at least during my testing, wasn’t useful for anything). They are as follows:

  • Id – An Integer that uniquely identifies a single TouchLocation instance within a TouchCollection. It’s unknown how its potential values are determined, or if orphaned values are subject to recycling after the host TouchLocation has fallen out of scope.
  • Position – A Vector2 that provides the X and Y coordinate serving as the source for the event. Effectively, this is the location on the sensitive surface where contact was made.
  • Pressure – A floating-point number indicating the pressure of the touch. I’m unclear on how exactly this works, since my tests always reported a zero in this property. The only conclusions I can come up with here are either that my device doesn’t support touch sensitivity of this kind, or I missed a configuration step to enable this functionality.
  • State – An instance of TouchLocationState that determines what kind of touch we’re dealing with. This property can have one of four values:
    • Invalid – The press has been somehow deemed invalid; I’ve never seen this occur in testing, and am left to think that either I failed to satisfy conditions to make this occur, or that it’s simply a dump case for an exceptional condition.
    • Moved – Seen when a press has either remained in the same position or has moved. This is a very important state as it has a great deal of practical application, so do try to keep it in mind.
    • Pressed – Observed when a point of contact on the sensitive surface is newly minted. This is only fired once, and will not be seen again, regardless if the contact remains afterward. This could potentially be a source of confusion for a number of programmers.
    • Released – Likely the last state that a TouchLocation would be in before falling out of scope, it will be fired when the source of contact which generated this particular instance is no longer available.

Having said all of that, you now have enough information to properly utilise touches within your programs. As was stated before, simply ensure that your code is contained within the main game loop somewhere, since the data will likely change per frame, or at least as often as it can. An example of how to implement code based off this logic will be illustrated at the end of this discussion.

Gestures, insofar as Monogame is concerned, are a bit of a hassle to work with, mostly due to the lack of upstream documentation. We will seek to correct this imbalance, if not for the official documentation, then at least for programmers who wish to learn more about them.

As was stated previously, although Monogame performs a considerable amount of work to make available the touch and gesture API for programs deployed on capable hardware, gestures are left a bit open-ended by comparison to their touch counterparts. What this means is that as a programmer, you’re required to provide some configuration before the gesture API can be utilised. Here, we assume that you’re only interested in gestures, and not touch-to-cursor mappings, hence will only discuss the former.

Before proceeding, some basic information should be given as to the nature of gestures, and how they’re procedurally handled.

Although there is some very minor overlap with how a touch and gesture are expressed, they are two discrete entities. Gestures can be composed of one or more points of contact, and it’s expected that the locations of these contacts will change, in a particular way, over an indeterminate amount of time (ergonomic measurements would likely dispute this generalisation, but it is for this conversation a generalisation, and not a scientific claim). The ways in which these contacts change, or at least the resultant shape the change yields, as well as the number of contacts involved in the measurement, hints at the particular kind of gesture. In other words, a single point of contact that has a gradual change in its X-axis, be it positive or negative, which would yield a ray (or a series of small rays), is generally considered to be a horizontal drag gesture. When considering the same principles but looking to the Y-axis instead, we now find ourselves dealing with a vertical drag gesture. Pinch and zoom gestures typically involve two or more points of contact that move near concertedly away from or toward each other along the same logical axis. Perhaps paradoxically, at least when considering a contrast between touches and gestures, taps, double taps, and long-presses are registered as gestures as well; these are more concerned with the sustainment of a single point of contact relative to the time from when it was first recognised.

From a stock perspective, Monogame provides eleven types of gestures, referred to as GestureTypes. These types will effectively determine how gesture detection is performed (it’s unclear if the GestureType framework can be extended to facilitate custom gesture types, but this is a considerably advanced topic which will not be discussed here). However, Monogame will not automatically read the touch panel for gestural input. Instead, it needs instructed on which kinds of gestures to detect, and this is provided by the programmer. In any non-looping block of code, preferably during the initialisation routines, you’ll need to specify what are called EnabledGestures, which is a property of the TouchPanel static object. Multiple gestures can be configured by OR’ing one or more of the types together in the assignment statement. For example, if I wanted to parse for both a HorizontalDrag and a DragComplete gesture, I would write the following statement:

TouchPanel.EnabledGestures = GestureType.HorizontalDrag | GestureType.DragComplete;

Once this is complete, you’ll have done enough to get Monogame to start playing nice with at least these two kinds.

Parsing gestural input is, in essence, no different than parsing touch input, but there are some minor differences to the process. To start, we must first determine if there are any gestures with which to read data from. If we do not do this, attempts to read directly from the gesture store will generate fatal exceptions. Fortunately, the TouchPanel static object provides a boolean property called IsGestureAvailable, which will inform clients of the availability of queued gesture data. If we have data, we must convert the data into a sample, which is packaged into the GestureSample class. As with the TouchLocation object, the GestureSample object contains several properties that are of practical interest to the programmer, especially when making contextual decisions that respond to this kind of input. GestureSamples include the following properties:

  • Delta – A Vector2 instance which provides the delta, or difference, data for the first touch point in the gesture. This will change over time, and will always be relative to the coordinates where the touch was first recognised.
  • Position – A Vector2 instance which contains the current coordinates of the first touch point in the gesture.
  • Timestamp – A TimeSpan instance that indicates the time when the gesture was first recognised.
  • GestureType – A GestureType instance that indicates what type of gesture was determined based off several criteria.

Additionally, GestureSample contains properties called Delta2 and Position2, which are used to track a second point of contact that’s being measured as part of the current gesture. What this implies is that insofar as the stock gestures are concerned, Monogame will only be able to handle gestures where no more than two points of contact are involved.

My advice here is to experiment with the data through debugging until you’re comfortable with how these gestures are read, because there are some nuances with how the data continuously polls respective to different gesture kinds. For example, a HorizontalDrag gesture will, while the drag is occurring, constantly emit the HorizontalDrag signal until the contact source is released, terminating the gesture. At this point, if one is checking for the DragComplete signal as well, releasing the contact source will cause the touch panel to emit the DragComplete signal.

Examples:

To determine if a single press has been made:

TouchCollection tc = TouchPanel.GetState ();
foreach (TouchLocation tl in tc) {
 if (TouchLocationState.Pressed == tl.State) {
  // Execute your domain-specific code here
 }
}

To determine if a press was made, and has been held in the same position for an arbitrary period of time:

TouchCollection tc = TouchPanel.GetState ();
foreach (TouchLocation tl in tc) {
 if (TouchLocationState.Moved == tl.State) {
  // Execute your domain-specific code here
 }
}

To track the position of a horizontal drag:

(1) During game initialisation:

TouchPanel.EnabledGestures = GestureType.HorizontalDrag;

(2) During game loop:

while (TouchPanel.IsGestureAvailable) {
 GestureSample gs = TouchPanel.ReadGesture ();
 if (GestureType.HorizontalDrag == gs.GestureType) {
  // Execute your domain-specific code here
 }
}

PhysicsFS/PhysFS++ Tutorial

This is a follow-up from a promise that I made in my tutorial video on designing an asset manager using SFML. That video can be found here.

This tutorial is centred around PhysFS++, a C++ wrapper for PhysicsFS. For the sake of the tutorial, it’s assumed that the reader is familiar with PhysicsFS and what it’s capable of. Described here is a workflow for simple use of the library. Anything more discrete is beyond the scope and will have to be ascertained by the reader on their own accord.

Lastly of note, PhysFS++ encapsulates PhysicsFS calls in a PhysFS namespace. The functions are global within this namespace and there are only a few classes that are provided. PhysFS++ further encapsulates key PhysicsFS constructs, notably those corresponding to archived files, into said classes that are derivatives of STL stream classes (a huge boon).

Like some other libraries, PhysicsFS requires explicit initialisation before it can be used. This is facilitated by a function named init. It takes one argument of type const char* and is semantically directed at a terminal invocation argument triaged through the much loved argv. However, this can be an empty string especially if you’re not expecting to handle terminal invocations. Thus, a very general call to init can be performed as such:

PhysFS::init (nullptr);

Right of the bat we have to mention a caveat here. From PhysFS++, there’s no way to assert the initialisation process of PhysicsFS. This is counter-intuitive to the upstream library which relies on the tried-and-true zero on failure, non-zero on success return values as sanity checks. Furthermore, while PhysFS++ implements C++ exceptions, the init function doesn’t throw any at all. Ostensibly, what one is left with is an unchecked call to init. Because one needs to compile PhysFS++ from the source, it is possible to modify the code, as I have done, to add a check to this call.

Once init has successfully completed, the next step is to mount an archive file into the virtual filesystem created by init. This is performed with the mount function. mount expects three arguments: the archive file on disk, a string specifying a mount point in the virtual filesystem, and a boolean which appends the mount point to the search path. One should place the archive file in the working directory for the binary file of their executable so PhysFS++ can see it. The second argument can be an empty string which would force root mounting, and the third can be true. Thus, for our example, if we assume we have an archive file named funphotos.zip on our disk in the binary’s working directory, we can issue a call to mount as such:

PhysFS::mount (“funphotos.zip”, “”, 1);

Unfortunately, as was the case with init, mount wraps an upstream function that adheres to the zero-or-nonzero return value paradigm that is outright dropped by PhysFS++ with no exception catering otherwise. Thus, if mount fails to mount the archive for whatever reason, it’ll be a little difficult to ascertain why; plan accordingly.

Assuming mount has returned properly, one can start to work with the files that are contained in the archive. At this point, you should begin working in the mentality of filesystem calls. It’s possible to have archive files with complex directory layouts which would require one to perform recursive searches. That being said, everything should be considered a file – even a directory. An analysis of the PhysicsFS and PhysFS++ APIs will provide for you the full breadth of your available capabilities so for the sake of brevity, only a select number of those will be touched here.

Enumeration of files in a directory can be performed with the enumerateFiles function. It takes as an argument a string which indicates the directory to use as a root for the enumeration. As a return it provides the caller with a vector of strings indicating the name of the file. For ease of use, a call to this to enumerate the files in root can be performed as such:

auto rootfiles = PhysFs::enumerateFiles (“/”);

To actually work with a file in the filesystem, one needs to use the PHYSFS_file ADT. This upstream ADT is encapsulated by one of three classes: PhysFS::ifstream, PhysFS::ostream, or PhysFS::fstream. Each of these is fantastic in that they encapsulate a PHYSFS_file ADT in a standard stream which means that one can now perform established stream operations on the file itself. Each class has its own use: fstream for reading files, ostream for writing to files, and ifstream for bidirectional file handling. In any case, any of these classes can be instantiated with a string argument that contains a fully qualified pathname to a file in the virtual filesystem that one wants to work with. For example, given that our virtual filesystem has a file named goofycats.png located at the path /textures/cats, we could instantiate a read file as such:

PhysFS::fstream gc (“/textures/cats/goofycats.png”);

Again, the underlying upstream call to open the file goes unchecked.

What you do from here is largely subjective relative to your program’s context. Say, for example (and this is actually pretty specific to my own use case), that you have a series of files of various formats in an archive that are being used in a video game program. The multimedia library you’re using should have ADTs that represent types of assets such as textures, fonts, etc. One could do some work to transpose the raw data of these streams into the aforementioned ADTs for use in the multimedia library. The following snippet of code, borrowed from one of my own projects, illustrates this. A PhysFS::fstream instance named f is created with a certain file. Following up is a char array named d is instantiated with the size of f. The read function of f is called to transpose the bytes from f into d. Then, d is used to instantiate an instance of sf::Music from SFML contained in a std::unordered_map:

code

This covers most the basic and general needs of users of PhysicsFS. Should you require anything else from it, you’d do well to read up on the Doxygen file of PhysicsFS or the source for PhysFS++. Lastly, when one is done with the library, you’ll need to call a deinitialization function called deinit:

PhysFS::deinit ();

Development Journal – Teh Rawness

Lets face it, I’m not a professional developer nor a professional mathematician nor a professional anything. Maybe a professional jackass. Yeah I am pretty good at that.

Douchebagery aside, I managed to clobber together an extremely raw working model for a “Drop Objects”-style game for Android that is most definitely going to morph into something a fair bit cleaner and more disturbing. I peddled this off to my tight-knit inner circle of unlucky friends to see what they thought and I received a lot of constructive criticism (because it does suck and really it’s supposed to at this point) and some really cool ideas as to where this could possibly be taken.

If you have an Android device, you can side load (pay attention to steps number two and three) this on there and have at it. Yes, I’m ignoring continues for the time being.

Additionally, don’t bitch or moan at me because this doesn’t work on your shitbox Android device that still runs Gingerbread or some hack-fuck $20 tablet from the Himalayas. This isn’t even anything close to a complete idea but it is somewhat usable.

You can get the APK from my Google Drive here: http://goo.gl/UdTZDL

Development Journal – I Can Haz Procedurally Ramped Difficulty?

Preface – I’m not a mathematician in any way, shape or form.

Shamefully, one of the things that’s always bugged me about any game I’ve ever written was the difficulty was explicitly defined. In other words, I would always have a method that would check the current level and apply random scalars to settings depending upon that check. Does it work? Yes. Is it intuitive? No. Does this make for a horrible game experience? Yes and no (more yes).

Without diving too far into the rabbit hole, I wanted a way to automatically increase the difficulty of a game while still retaining certain qualities. Simply ramping the difficulty could be achieved in a number of ways depending on how you want the game to be. If you want it to react to how the player makes decisions in the game, well that’s a whole other issue that I’m not going to dive into right now as it could get complex really quick. For the project that I’m working on now, I wanted something a little more simple. Why not a logarithm?

Logarithmic graphs are really nice to look at but present some interesting hurdles that you need to compensate for in other ways.

First of all, I decided that I’d play with the natural logarithm instead of another base. I like smaller numbers as they’re always easier to manage (plus, I’m lazy). To entangle it a bit more with the game, I decided to take the natural logarithm of the value of the current level multiplied by two, squared. So it would look something like this:

ln((currentLevel*2)^2)

Java has a nice log method in Math that operates on the natural so the code actually looks something like this:

(float)Math.log((Math.pow(currentLevel * 2, 2)));

This little modification to the natural log gives a relatively nice curve.

Image

This is just a sample of what I was getting. But why use the current level multiplied by two then using the value of that number raised to the power of two? Because it produced the nicest results in all of the testing that I did plus it ties into the current level which helps to give the impression that the difficulty scales with the levels. Levels pushing into the mid to upper 90’s produce a value that’s 10.xx and quickly ramps up from there which can cause some problems in systemic calculations (since you’re actually using 1.x (1xx.xx%) as a multiplier which will always give you at least the number you’re multiplying against which is not desired in most cases). However this fact is taken into consideration and compensation is made for it where needed.

So what can you do with this value? Well, in the simplest terms, the possibilities are endless. And, frankly, you don’t even have to calculate it the same way I did. You can do whatever you want, so long as it makes some sense. But I chose to tie it to the level and amp it up a little (the base value returned from ln(level) was a little low, even for my tastes). The great thing about this seemingly insignificant number is that it can actually hold a lot of weight for procedurally generating difficulty scalars (which is basically what this is). Variations of this value (mostly being derived from rounding functions like floor or ceiling) can be used to help determine the total number of objects to work with in a level or how many enemies to pack into a wave. If the player has a goal that’s a fraction of a total number of objects, this value can be used to help determine that percentile and you can apply it there and elsewhere. You can also use it as an abstract base in probability calculations so that you can make things happen more slowly in early levels and more quickly in later levels, helping to increase that sense of difficulty.

Another thing to keep in mind that could potentially help is that an exponential curve is the inverse of a logarithmic curve. So if you find yourself in a position where you logically need to do things that go against the logarithmic curve but still need to retain that difficulty, having a second measurement from the exponential curve of the same method that calculates difficulty could be beneficial.

That Time of Year

If I were a religious man (which I am not), there would be one thing that would be my religion; the thing that most made me feel like I was at peace with myself. Would it sound completely strange to say that it would be a video game that would make me feel like that?

As hard as it may be to digest for some of you, this is actually the case with me. It has developed into a bit of a yearly ritual that happens around this time. Sometimes I wait until the first snowfall and other times I wait until around my birthday (which is this year).

I’m talking about a little video game called Parasite Eve. In this day, I could be referencing the trilogy but I’m talking about the very first game released on the Sony Playstation back in 1998.

I’m not going to delve into a whole synopsis of the game and it’s story here. I’ve spent far too much of my time investing into understanding the story, separating from it what was fact and fiction and then bringing it all together. If you want the story, look it up online or buy the game from eBay or the Playstation Network.

What I will say about the game however, with 100% sincerity, is that it is my all time favourite video game. It has stood the test of time where others that would otherwise claim that spot have failed horribly (most notably Chrono Trigger or Final Fantasy VII).  The interesting thing to take away from that statement is the reasoning behind it as it’s extremely difficult to pinpoint why this is the way it is.

I could easily prepare arguments as to why Parasite Eve is amazing on the typical levels that we constantly find ourselves comparing and contrasting video games on: graphics, audio, control, replay value, cinematics, longevity, etc… By those same metrics, I could make a list for you as to why Parasite Eve sucks. After putting some pretty serious thought into it, and by that I mean more than I really should have, Parasite Eve strike a deep chord with me. It’s revealed through the story occasionally as the plot progresses and may only be apparent if you’ve either paid attention or can relate to the main character on this level.

It’s the feeling of solitude.

Not just the feeling but the way the atmosphere was expertly crafted to help drive that feeling home is what really stood out to me.

The first time I played the game was around this time in 2003. That same year, I stayed at my dad’s house for a night and on that night, I played the game for nearly 27 hours straight. In the following weeks, I found myself researching the science behind the story and trying to figure out what was close to actual science and where the line for fiction was interjected.

But then there was the art. Tetsuya Nomura did some seriously amazing work depicting the characters. Yoko Shimomura had to have performed her best work on this game (rivaled only by Legend of Mana); the soundtrack here is one that I still hold in extremely high regard and listen to on a regular basis.

I have a bad habit of replaying games over and over again. This is true with movies as well. It’s slightly different with video games though. Typically I’ll replay it once or twice and then never touch it again. This was the case with Chrono Trigger, Final Fantasy VII and Legend of Dragoon. All three of those games could very easily sit on the top of my favourite games list but the problem is that they didn’t stand the test of time whereas Parasite Eve has.

Since 2003, I’ve made it a point play the game in its entirety using a new file at this time of the year. This is going to be the first year that I’m going to be doing it on my PSP because my Playstation took a dump. Tonight is going to kick that process off. And I’m super fucking pumped.