Rumble Pack Games recently released their first game (Krash TV) on mobile and making sure the control options felt good, meant coming up with great feeling touch input. They explore the process they used to get there in the following blog.
Ok, what’s so important about touch input. Well, in 2018 we started making our first game as Rumble Pack Games. We’ve made games before, and we’ve used GameMaker for some fun hobby projects, but this time we were making something to represent our new company. Therefore, we wanted our new game to be as special as we could make it, and this included fun gameplay, vibrant graphics, and very importantly great player control. Seeing as Krash TV was designed for iOS mobile devices, then great player control needs great touch input.
Luckily for us, GameMaker provides a variety of alternatives for this. As we looked further into touch input, we found 2 methods, in particular, looked interesting. How did we decide which to use? Well, we researched each method a little and considered what the use case was for our game. We read the documentation (yeah, we know not everyone likes reading manuals, it is very useful honest) and we tried things out.
Firstly, there is the Gesture Event system made for touch input. This provides both global and object-based events for touch input gestures such as Tap, Drag, Flick, and more. Plus, each gesture provides the relevant data with that event.
This is a great system for many touch games, however, our game needed continuous touch and move, as the player should guide the car around various obstacles. Additionally, there’s no pinch and zoom and no button pressing during the core gameplay. So, all in all, the gesture system did not feel right for our game.
For the second input method, there’s a more direct method of collecting touch input. The GameMaker API to collect mouse input also collects input for the players' fingers touching the screen. Mouse device zero, and its left button check represent the first player finger to touch the screen. This also has the benefit of working on our development machines, for testing purposes, using a mouse. Therefore, this method looked interesting for our gameplay, and we choose to investigate further.
Starting with the basics, we got the touch input every frame. As we have a fast action game, we wanted the user input and the game response to be as quick as possible, therefore we get the player input in the Begin Step event so it’s ready for processing immediately by the Step event for the player car object in that same frame. This means the very latest input is collected at the beginning of the frame processing. (See the Objects Events / Step information in the docs for a great explanation of events and Step processing)
Now we had the input values, we further fleshed-out our player control design. Our player car control idea required the car to move towards where the player touches and moves their finger. From a game design point of view, this gives direct control of the car positioning to the player and very clear visual feedback on what they are physically doing. This is important, as no matter how good our code might be, the logic of the physicality of player control on mobile devices is the starting point for great touch input.
As we want to move the car towards the player’s touchpoint, during the car processing Step, we get the difference between the touchpoint and the car position. We only do this when the player is touching the screen, as unlike the mouse, the touch position is only valid when the player is touching the screen.
The code above shows the processing for the X position. The code for the Y position is just the same. Once we have the difference between the touch position and the car’s position (or “dist” in the case of our oddly named variable) then we can process the car movement in any way we see fit. Our exact method of car physics processing would be something for another blog maybe…
However, “wait” you say, what’s this “smooth it” comment all about? So lastly, something important about the input processing on iOS devices by GameMaker that was valid at the time of writing our code. Our game runs at 60 frames per second, but the input processing by GameMaker only updates at 30 frames per second. Therefore, if the player moved their finger smoothly at 5 pixels per frame, then a new X position of +10 is only reported every other frame. Without the smoothing, we get the following in the situation when trying to move the car instantly every frame.
This gave a flickery movement to the car every other frame. We could have smoothed the movement of the car, and in fact, we did do that later for other gameplay reasons. However, when dealing with the input, we felt the values being processed from the raw input should be as accurate as possible. Therefore, we smooth the difference at this root point of input collection by halving it each frame. This smooths out the input values, and in the case above gives a nice 5 pixels per frame, plus a lead down to zero when the player stops moving or removes their finger. The added benefit is that it will continue to work if the input is gathered at 60 frames per second in the future.
In summary, we are proud of the game we created, and much of this is down to the positive feedback about our player control with touch input. We followed the general principles below and were very happy with the results GameMaker enabled us to create.
We hope that something in our blog is useful. We enjoyed making Krash TV with GameMaker, and we hope everyone out there has fun creating too. You can check out Krash TV here!
Thanks for listening. Rumble Pack Games :-)