游戏邦在:
杂志专栏:
gamerboom.com订阅到鲜果订阅到抓虾google reader订阅到有道订阅到QQ邮箱订阅到帮看

分步示意触屏设备虚拟控制器设计过程(二)

发布时间:2012-05-24 15:26:05 Tags:,,

作者:Mike Jones

文章第一部分谈论的是,如何组合基本设计和功能“创建模块”,让你能够沿着边缘轨迹拖曳控制器的操纵杆,然后在你放开时,将其送回至控制器的中心点。如下图所示:

边界轨迹 from blog.flashgen.com

边界轨迹 from blog.flashgen.com

我们设置完“逃跑”轨迹,剩下的就是调遣事件,让“外部世界”知道控制器的具体操作内容。就如我在文章第一部分中提到的,我选择将键盘投射至控制器中,因为多数网页Flash游戏主要着眼于键盘控制,而非鼠标移动(游戏邦注:有些情况下,这和Flash运行时间没有提供Mouselook支持有关)。

目前这听起来像是个简单过程。毕竟只有4个方向键,所以我在控制器上将其设置成上下左右(Up、Down、Left和Right)。如果我只是想进行4个方向的操纵杆控制(想想《Dig-Dug》或《Mr. Doo》),这完全没有问题。但多数现代平台游戏都至少支持8个方向的移动操作。这带来一定问题,因为这意味着你需要设计按键操作组合——例如,左上或右下。若是采用实际键盘,这完全不费吹灰之力,因为用户可以组合按下这些按键,它们会给予相应回应。我们需要效仿这一模式,这意味着你需要进行更多设置,确定你的虚拟控制器要如何通过模拟按键操作进行调遣。

映射按键

首先要做的就是,投射4个方向键。这样你就清楚自己是基于操纵杆的位置调遣事件。要完成这一操作,你需要添加简单的内部循环(或是标记),这会更新有关按键输入模拟的信息。所以如果你要进行的是推向顶部的操作,那么你多半会调遣代表按下“上”按键的事件。

反向控制器

在未来的逐步发展中,你会想要添加的一个设置是,让用户颠倒控制的Y轴(上/下)。这非常适合基于纵向和横向路径飞行的太空飞船游戏。因此和真实飞机一样,按下控制器的“上”按键会促使太空船向下移动,按压控制器的“下”按键会令其向上移动。

你需要通过另一方式检查和调遣模拟按键操作。所以你需要创建新的dispatchKeyCombo()保护方式,在onThumbDrag()方法的底部将其设置成调用状态。代码内容应如下(注意:出于简洁,我移除onThumbDrag()方法中的多数代码内容):

protected function onThumbDrag(e:Event):void
{
// Additional code removed for brevity

dispatchKeyCombo();
}

protected function dispatchKeyCombo():void
{

}

现在每次用户移动操纵杆及onThumbDrag()方法被调用时,dispatchKeyCombo()方法也会自动被调用。设置完存根方法后,下面就来着手添加初始逻辑和事件调遣。首先需要进行的操作是,判断操纵杆是否同边缘存在联系。你可以在onThumbDrag()方法进行调用,这里你有个分层级存储当前操纵杆积极或消极位置的变量_degrees。此前我略过它的具体运用,称后面会进行详述。现在是时候了。你需要层级数值,这样你才能够以当前的层级旋转为基础,将操纵杆的位置投射到方向键。

记住现在你只是添加4个方向的操纵杆支持。要完成这一操作,你需要查看_degrees变量的数值,若这相当于4个方向(上下左右)的必要求值,那么你就可以调遣事件。根据当前设置,4个操纵杆位置的层级数值分别是:右=0,下=90,左=180,下=-90。把握具体数值后,插入逻辑条件,确定需要调遣的数值则就非常简单。

protected function dispatchKeyCombo():void
{
// Thumb stick position – Right
if(_degrees == 0)
{
trace(“Right”);
}
// Thumb stick position – Down
else if(_degrees == 90)
{
trace(“Down”);
}
// Thumb stick position – Left
else if(_degrees == 180)
{
trace(“Left”);
}
// Thumb stick position – Up
else if(_degrees == -90)
{
trace(“Up”);
}
}

从理论上来说,这就是你需要进行的操作。但若你在调试模式中进行测试,你会发现要在移动操纵杆时达到特地数值非常困难,因为你需要非常准确——这通过鼠标很难完成,想想如果你要通过自己的拇指,这将会多么棘手。最显而易见的做法就是,通过系列数值判断操纵杆的位置。这样你就创建同上下左右相关的“区域”。下面是通过区域判断操纵杆位置的更新代码。注意,这里的条件更加复杂,因为我们主要判断操纵杆是否介于数值之间(有时候也需要处理积极和消极数值)。

protected function dispatchKeyCombo():void
{
// Thumb stick position – Right
if(_degrees >= -22 && _degrees <= 22)
{
trace(“Right”);
}
// Thumb stick position – Down
else if (_degrees >= 68 && _degrees <= 112)
{
trace(“Down”);
}
// Thumb stick position – Left
else if((_degrees >= 158 && _degrees <= 180) || (_degrees >= -179 && _degrees <= -158))
{
trace(“Left”);
}
// Thumb stick position – Up
else if(_degrees >= -112 && _degrees <= -68)
{
trace(“Up”);
}
}

如果你在Debug模式中测试这一版本,那么你会看到追踪轨迹更加连贯——显然你可以调节值域,改变操纵杆输出值的准确度。但由于你所瞄准的是触控设备,所以不要设定具体值域,用户的拇指通常不是那么准确(游戏邦注:特别是当他们处在激烈炮战中的时候)。

现在你已设定基本结构,可以着手下个步骤。将键盘输入值投射到操纵杆位置的对应数值。ActionSCript提供各普通按键数值的常量,这使得执行输入内容变得非常简单。在你将任何按键输入代码添加至dispatchKeyCombos()方法前,你需要定义4个新变量。这些属于实体变量,而非方法变量,所以不妨将它们置于类顶部的其他实体变量之下。

private var _primaryKeyCode        :int;
private var _secondaryKeyCode    :int;

private var _previousPrimaryKeyCode        :int;
private var _previousSecondaryKeyCode    :int = 0;

目前你无需担心这块内容;我会在添加额外功能时解释它们的用途。现在你唯一需要关心的内容是_primaryKeyCode,你需要在此变量中存储当前按键代码。

首先,将各trace()陈述替换成_primaryKeyCode变量的引用。根据自己的检测方向,你可以就相关按键输入常量进行调遣。当这些操作完成后,你只需要调遣_primaryKeyCodeas的更新数值,这是新KeyboardEvent()的键码属性,就如如下代码块所示:

protected function dispatchKeyCombo():void
{
// Thumb stick position – Right
if(_degrees >= -22 && _degrees <= 22)
{
_primaryKeyCode = Keyboard.RIGHT;
}
// Thumb stick position – Down
else if (_degrees >= 68 && _degrees <= 112)
{
_primaryKeyCode = Keyboard.DOWN;
}
// Thumb stick position – Left
else if((_degrees >= 158 && _degrees <= 180) || (_degrees >= -179 && _degrees <= -158))
{
_primaryKeyCode = Keyboard.LEFT;
}
// Thumb stick position – Up
else if(_degrees >= -112 && _degrees <= -68)
{
_primaryKeyCode = Keyboard.UP;
}

dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 0, _primaryKeyCode));
}

更新的虚拟控制器呈现下图样式。(我插入外部事件处理器,这样你就能够在上方的文本框中看到当前的方向输入内容,我还将红色边界的初始值设置成0,这样它就呈透明状态)。

当前方向 from blog.flashgen.com

当前方向 from blog.flashgen.com

扩展范围

现在你已设定调遣代码的基本结构,下面就来对其进行扩展,这样虚拟控制器代码就能够将控制器变成8个方向的控制器,而不是当前的4个方向模式。鉴于控制器映射的是模拟按键事件,要在控制中执行附加角度会产生额外要求。

是否还记得我创建的附加变量:_primaryKeyCode和_secondaryKeyCode等?这里你需要用到其中一个,即_secondaryKeyCode。在初始位置中移动操纵杆只需要调遣单个按键事件。将操纵杆移动到这些离轴角度需要你调遣两个按键事件——例如,若你将操纵杆移至上和右之间的位置,你就需要调遣代表向上箭头键及右箭头键的键控代码。

下面就来看看修改后的代码,同时分析二级事件分配器的添加及针对提供8个方向控制器支持的附加“区域”进行的新检查操作。

protected function dispatchKeyCombo():void
{
_secondaryKeyCode = 0;

// Thumb stick position – Right
if(_degrees >= -22 && _degrees <= 22)
{
_primaryKeyCode = Keyboard.RIGHT;
}
// Thumb stick position – Down
else if (_degrees >= 68 && _degrees <= 112)
{
_primaryKeyCode = Keyboard.DOWN;
}
// Thumb stick position – Left
else if((_degrees >= 158 && _degrees <= 180) || (_degrees >= -179 && _degrees <= -158))
{
_primaryKeyCode = Keyboard.LEFT;
}
// Thumb stick position – Up
else if(_degrees >= -112 && _degrees <= -68)
{
_primaryKeyCode = Keyboard.UP;
}
// Thumb stick position – Up/Left
else if(_degrees >= -157 && _degrees <= -113)
{
_primaryKeyCode = Keyboard.UP;
_secondaryKeyCode = Keyboard.LEFT;
}
// Thumb stick position – Down/Left
else if(_degrees <= 157 && _degrees >= 113)
{
_primaryKeyCode = Keyboard.DOWN;
_secondaryKeyCode = Keyboard.LEFT;
}
// Thumb stick position – Up/Right
else if(_degrees >=-67 && _degrees <= -21)
{
_primaryKeyCode = Keyboard.UP;
_secondaryKeyCode = Keyboard.RIGHT;
}
// Thumb stick position – Down/Right
else if(_degrees >= 23 && _degrees <= 67)
{
_primaryKeyCode = Keyboard.DOWN;
_secondaryKeyCode = Keyboard.RIGHT;
}

if(_secondaryKeyCode > 0)
dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 0, _secondaryKeyCode));

dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 0, _primaryKeyCode));
}

你会发现dispatchKeyCombo()方法出现系列变化。最大变化就是我在此代码块前提到的:我添加围绕操纵杆全方位移动的按键输入映射(游戏邦注:而非仅仅围绕其进行上下左右移动)。其次现在出现对变量_secondaryKeyCode的引用。这是应用存储二级按键输入代码的位置。就如我之前提到的,如果你将操纵杆向右上方移动,那么从按键输入角度来看,你就需要在上和右按键中调遣KeyboardEvent()。在方法初始阶段,将_secondaryKeyCode变量的默认值设置成0,只有当用户将虚拟控制器移至需要两个键码数值的位置时,数值才会发生更新。

最后一部分是添加检查操作,以查看_secondaryKeyCode变量值是否大于0,如果大于0,就调遣二级KeyboardEvent()。

if(_secondaryKeyCode > 0)
dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 0, _secondaryKeyCode));

只剩下一块内容,整个方法就大功告成。你也许会发现,你调遣的是KeyboardEvent.KEY_DOWN事件,但你如何让对象关注你的控制器,知道你何时改变方向。你需要调遣KeyboardEvent.KEY_UP事件。这就引出最后两个变量。它们是:_previousPrimaryKeyCode和_previousSecondaryKeyCode。这些用于存储之前调遣的键码。但为避免调遣不必要的事件,它们只有在初级和次级键码的新数值发生改变时会被调用,像下面这样:

if(_primaryKeyCode != _previousPrimaryKeyCode)
{
dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, _previousPrimaryKeyCode));
_previousPrimaryKeyCode = _primaryKeyCode;
}

if(_previousSecondaryKeyCode != _secondaryKeyCode)
{
dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, _previousSecondaryKeyCode));
_previousSecondaryKeyCode = _secondaryKeyCode;
}

若用户改变操纵杆的位置,那么相关输入内容的KeyboardEvent.KEY_UP事件就被调遣。由于这一方法包含众多内容,因此我呈现如下完整版本,这样你就能够看到具体操作流程:

protected function dispatchKeyCombo():void
{
_secondaryKeyCode = 0;

// Thumb stick position – Right
if(_degrees >= -22 && _degrees <= 22)
{
_primaryKeyCode = Keyboard.RIGHT;
}
// Thumb stick position – Down
else if (_degrees >= 68 && _degrees <= 112)
{
_primaryKeyCode = Keyboard.DOWN;
}
// Thumb stick position – Left
else if((_degrees >= 158 && _degrees <= 180) || (_degrees >= -179 && _degrees <= -158))
{
_primaryKeyCode = Keyboard.LEFT;
}
// Thumb stick position – Up
else if(_degrees >= -112 && _degrees <= -68)
{
_primaryKeyCode = Keyboard.UP;
}
// Thumb stick position – Up/Left
else if(_degrees >= -157 && _degrees <= -113)
{
_primaryKeyCode = Keyboard.UP;
_secondaryKeyCode = Keyboard.LEFT;
}
// Thumb stick position – Down/Left
else if(_degrees <= 157 && _degrees >= 113)
{
_primaryKeyCode = Keyboard.DOWN;
_secondaryKeyCode = Keyboard.LEFT;
}
// Thumb stick position – Up/Right
else if(_degrees >=-67 && _degrees <= -21)
{
_primaryKeyCode = Keyboard.UP;
_secondaryKeyCode = Keyboard.RIGHT;
}
// Thumb stick position – Down/Right
else if(_degrees >= 23 && _degrees <= 67)
{
_primaryKeyCode = Keyboard.DOWN;
_secondaryKeyCode = Keyboard.RIGHT;
}

if(_primaryKeyCode != _previousPrimaryKeyCode)
{
dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, _previousPrimaryKeyCode));
_previousPrimaryKeyCode = _primaryKeyCode;
}

if(_previousSecondaryKeyCode != _secondaryKeyCode)
{
dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, _previousSecondaryKeyCode));
_previousSecondaryKeyCode = _secondaryKeyCode;
}

if(_secondaryKeyCode > 0)
dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 0, _secondaryKeyCode));

dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 0, _primaryKeyCode));
}

到目前为止,具体例子都在浏览器或桌面测试过,但我们的目标是让此控制器能够在触控装置上运作。也就是说,如果你现在将此控制器放入设备中,它将无法运作。

为什么?因为你需要告诉游戏,控制器执行多点触控事件,这样它才知道如何进行操作。现在你可以将这些代码放入虚拟控制器中——确保执行多点触控事件,或者你可以将其具体化,放入实际游戏中。就个人而言,我倾向将此放入控制器的构造函数中,主要因为在编码集中阶段,我常常会忘记植入多点触控代码,然后在发现其无法于设备上运作时再匆忙进行设置。显然如果有多个控制器,这些操作会有些重复,但这些代码并不多,完成初始化后,再次进行设置不会产生什么额外费用。

所以最后一个步骤就是将这些代码粘贴至你虚拟控制器的构造函数中(游戏邦注:就在你添加事件处理程序的位置上方)中,然后就大功告成。

Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;

值得一提的是,在于屏幕检测点击和放开操作时,你需要利用MultitouchInputMode.TOUCH_POINT事件。若你需要追踪各种输入内容,以执行各种手势,那么你就需要利用MultitouchInputMode.GESTURE事件。关于控制器,我建议你不要将其纳入其中,否则将产生负面影响。

内容梳理

最后你需要做的是,整理系列松散的字符串。虽然现在如果你将拇指移开控制器,控制器会调遣正确事件,但它们会持续处于调遣状态中。原因很简单,在用户将拇指移开控制器时,全类型事件不会终止其他所有事件。这个问题很容易解决。只需创建新方法killAllEvents(),在其中植入如下代码:

protected function killAllEvents():void
{
if(_primaryKeyCode)
dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, _previousPrimaryKeyCode));

if(_secondaryKeyCode > 0)
dispatchEvent(new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, _previousSecondaryKeyCode));
}

在resetThumb()方法中将其设置成调用状态,就在你移除事件处理器之后。你的resetThumb()方法应该呈此状态:

protected function resetThumb():void
{
removeEventListener(Event.ENTER_FRAME, onThumbDrag);

killAllEvents();

_thumb.stopDrag();
_thumb.x = 0;
_thumb.y = 0;

就是这样。若你现在进行测试,你会发现,当操纵杆以任何方向移动时,事件就会被调遣,如果你的拇指从控制器上移开,事件就停止传播。

总结

在这部分文章内容里,我们主要谈论如何轻松通过虚拟控制器模拟键盘输入,然后进行调遣,这样任何注意这些事件的外部对象就能够在接收到事件时做出反应。(本文为游戏邦/gamerboom.com编译,拒绝任何不保留版权的转载,如需转载请联系:游戏邦

Controllers For Touch Based Devices (pt.2)

By Mike Jones

In the first part of this article you saw how to put together the basic design and functional ‘building blocks’ that allowed you to drag the thumb stick of the controller around the orbit of the surround and return it back to the centre point in the controller once you released it. As the example below shows:

If you’ve not read the first part of this article yet, I suggest you go and have a read through it now (I’ll wait :p)

Hello… Is This Thing On?

With the ‘run off’ boundary in place all that is left to do is dispatch events to let the ‘outside world’ know what the controller is doing. As I mentioned in the first part of this article, I opted to just map keystrokes to the controller as most web-based Flash games tend to concentrate on keyboard controls over mouse movement (in some instances this is partly to do with the fact that the Flash runtime doesn’t provide support for Mouselook).

Now this sounds like a simple process. After all there are four arrow keys therefore I can just map those to Up, Down, Left, and Right on my controller. However that’s fine if I just want 4-way joystick control, (think Dig-Dug or Mr. Doo). However, most modern platformers tend to support 8-way movement at the very least. This poses a bit of a problem as it means you need to map combinations of key presses – for example Up and Left or Down and Right. This is painless when using a physical keyboard as the user just presses those keys in combination and they respond accordingly. We’ll have to emulate that and that means you need to do a bit more work in how you determine what your virtual controller is dispatching in the way of emulated key presses.

Mapping The Keys

The first thing to do is map the four arrow keys. That way you know that you are dispatching the events based on the position of the thumb stick. To do this you need to add in a simple internal loop (or tick if you prefer) that just updates the information about which key input you are emulating. So if you were to push the to the top you would like want to dispatch an event that represents the UP key being pressed for example.

Inverting Controls

One thing you may wish to implement in a future enhancement is allowing the user to invert the Y-axis of your controller (Up / Down). This is generally useful for games that relate to the flying of air- (or space-) based craft using a pitch and yaw approach. Therefore, as in a real aircraft, pushing up on the controller would in fact make the craft move down (or descend) and pulling the controller down would make it move up (or ascend).

You’re going to need another method to handle the checking and dispatching of the emulated key presses. So create a new protected method named dispatchKeyCombo() and put a call to it at the very bottom of the onThumbDrag() method. You should now have something that looks similar to the code below (note I’ve removed the main bulk of the code in the onThumbDrag() method for brevity):

Now every time the user moves the thumb stick and the onThumbDrag() method is invoked it will automatically invoke the dispatchKeyCombo() method as well. With the stub method in place let’s set about adding in the initial logic and event dispatching. The first thing you need to do is determine where the thumb stick is in relation to the surround. You may recall that in the onThumbDrag() method you had a variable named _degrees that stored the current positive or negative position of the thumb stick in degrees. At the time I skipped over its use and promised to explain its purpose later on. Well, now’s the time. You need the degree values so that you can use the current degree rotation as a basis for mapping the thumb stick location to the arrow keys.

Remember you are just adding in 4-way joystick support at this point. To achieve this you need to check what the value of the _degrees variable is and if it is equal to the required value for each of the four directions (Up, Down, Left and Right) you can dispatch the event. Based on the current setup, the degree values for each of the four thumb stick positions would be: Right = 0, Down = 90, Left = 180 and Up = -90. Now that you know what the values are it is a simple process of adding in the logical conditions to determine what values need to be dispatched.

In theory this is exactly what you need. However if you test this in debug mode you’ll see that actually hitting that single value when moving the thumb stick is very difficult as you need to be very precise – it’s tricky with a Mouse imagine how hard it would be if you were using your thumb… The obvious course of action is to make use of a range of values to determine the position of the thumb stick. This way you can create ‘zones’ that relate to Up, Down, Left and Right. Below is the updated code that now uses zones to determine where the thumb stick is. Notice that the conditions are a little more complex as we are checking to see if the thumb stick is between values (some deal with both positive and negative values).

If you test this version in Debug mode you’ll see the traces are produced in a more consistent way – obviously you can tweak the range to vary the precision of the thumb stick output. However as you are targeting touch based devices don’t try and make the range too as user’s thumbs aren’t that precise – especially when they are in the heat of a fire fight.

Now that you have the basic structure in place you can move on to the next step. Mapping the keyboard input values to those of your thumb stick’s position. ActionSCript provides constants for all of the common key values, making implementing the inputs easy. Before you add any key input code to the dispatchKeyCombos() method you’ll need to declare four new variables. These are instance variables not method variables so just place them under all of the other instance variables at the top of the class.

As with most things you don’t have to worry about all of them at this point in time; I’ll explain each one’s purpose as we add additional functionality. The only one you need to concern yourself with at this point is _primaryKeyCode, within this variable you’re going to store the current keyboard key code.

First up, replace each of the trace() statements with a reference to the _primaryKeyCode variable. Depending on which direction you are looking to monitor you can then assign the relevant keyboard input constant. Once these are in place you just need to dispatch the updated value of _primaryKeyCodeas the keyCode property of a new KeyboardEvent() as you can see in the following code block:

The updated virtual controller is below, (I’ve added in an external event handler so you can see the current direction output in a text field above it)*.

*I’ve also set the alpha on the red boundary to 0 (zero) so it is no longer visible.

Expanding the Scope

Now that you have the basic structure for dispatching code let’s expand it so the virtual controller code allows you to use the controller as an 8-way controller as opposed to the 4-way you currently have. Considering that under the hood the controller is mapping to emulated keyboard events, dealing with the additional angles within your controller raises an additional requirement.

Remember those additional variables I made you declare: _primaryKeyCode, _secondaryKeyCode, and so on? Well, you are going to use another of those now – _secondaryKeyCode. Moving the thumb stick in the primary positions (as the code currently supports) requires only a single keyboard event to be dispatched. Moving the thumb stick to these off axis angles requires you to dispatch two keyboard events – for example if you move the thumb stick halfway between Up and Right you’re going to have to dispatch key codes that represent an Up Arrow key press as well as a Right Arrow key press.

Let’s look at the revised code and break down what is going on with the addition of the second event dispatcher and the inclusion of the new checks for those additional ‘zones’ that provide 8-way controller support.

You’ll notice that there have been a few changes to the dispatchKeyCombo() method. The biggest change is the one I mentioned prior to this code block: I’ve added support for key input mapping in relation to the full movement of the thumb stick, not just when it is moved Up, Down, Left, or Right. Secondly there is now a reference to the variable _secondaryKeyCode. This is where the application stores the secondary key input code. As I mentioned earlier if you push the thumb stick up and right then from a key input perspective you need to dispatch a KeyboardEvent() for both the Up key and the Right key. By default the _secondaryKeyCode variable is reset to 0 (zero) at the beginning of the method and only gets updated should the user move the virtual controller to a position that requires two key code values.

The last part is to add a check to see if the _secondaryKeyCode variable value is greater than 0 (zero) – if it is then dispatch the second KeyboardEvent().

Only one thing is left to do, and then the method will be finished. You may have noticed that you are dispatching KeyboardEvent.KEY_DOWN events, but how do you let any object listening to your controller know when you’ve changed direction. Well you need to dispatch the KeyboardEvent.KEY_UP event. This is where those final two variable come in. They are: _previousPrimaryKeyCode and _previousSecondaryKeyCode. These are used to store the (as the name implies) previous key codes dispatched. However to avoid unnecessary event dispatching they are only triggered if the new values for both the primary and secondary key codes have changed, like so:

If the user changes the position of the thumb stick then the KeyboardEvent.KEY_UP event for the relevant input is dispatched. Because there’s a lot going on in this method, I’ve included the complete version below so you can see how it flows:

So far the examples have been tested in the browser or on the desktop – however, the intention is that this controller will work on a touch based device (the title gives it away a bit :p). That said, if you were to put this on a device now it wouldn’t work.

Why? Well it’s because you need to tell your game that it is using multitouch events so it knows how to handle them. Now you could place this code within the virtual controller – making sure it always enables the multitouch events, or you can keep it externalized and place it in the actual game. Personally I tend to put this in the constructor of my controllers, mainly because in the heat of coding I tend to forget to put the multitouch code in and then sit their dumbfounded when it fails to work on the device. Obviously this could be conceived as repetitious if I have more than one controller (dual controllers, additional buttons etc), but it’s not a big bit of code and once it’s initialized, setting it again won’t cause any real additional overhead.

So in this final step just paste this code in to the constructor of your virtual controller just above where you added the event handlers and you are done.

It’s worth pointing out that you need to use the MultitouchInputMode.TOUCH_POINT event as you are just monitoring for the press and release on the screen. If you needed to track multiple inputs so you could perform gestures (pinch zoom for example) then you’d need to use the MultitouchInputMode.GESTURE event instead. For controllers I would suggest you avoid mixing them otherwise you will get undesirable side effects.

Tidying Up

The last thing you need to do is tidy up a few loose strings. While your controller now dispatches the correct events if you remove your thumb from the controller they continue to get dispatched. The simple reason is that there is no catch all event to kill all of the events should the user remove their thumb from the controller. This is an easy fix. Just create a new method called killAllEvents() and within it place the following code:

Now place a call to it from within the resetThumb() method, right after you remove the event handler. Your resetThumb() method should now look like this:

That’s it. If you test it now you’ll see the events are dispatched when the thumb stick is moved in any direction and if you remove your thumb from the controller the events will stop being broadcast.

Summary

In the final part of this article you have seen how you can easily emulate keyboard inputs through the virtual controller and dispatch them so that any external object listening for these events can react when they are received.

If you want to see this controller in action check out my Pushbutton engine article on integrating controls with Pushbutton Engine.(Source:flashgen


上一篇:

下一篇: