科技: 人物 企业 技术 IT业 TMT
科普: 自然 科学 科幻 宇宙 科学家
通信: 历史 技术 手机 词典 3G馆
索引: 分类 推荐 专题 热点 排行榜
互联网: 广告 营销 政务 游戏 google
新媒体: 社交 博客 学者 人物 传播学
新思想: 网站 新书 新知 新词 思想家
图书馆: 文化 商业 管理 经济 期刊
网络文化: 社会 红人 黑客 治理 亚文化
创业百科: VC 词典 指南 案例 创业史
前沿科技: 清洁 绿色 纳米 生物 环保
知识产权: 盗版 共享 学人 法规 著作
用户名: 密码: 注册 忘记密码?
    创建新词条
科技百科
  • 人气指数: 6563 次
  • 编辑次数: 1 次 历史版本
  • 更新时间: 2012-05-29
明天
明天
发短消息
相关词条
电子游戏AI
电子游戏AI
游戏设计七大常量
游戏设计七大常量
游戏设计认知
游戏设计认知
任天堂游戏设计原理
任天堂游戏设计原理
平衡游戏内部经济系统
平衡游戏内部经济系统
游戏5大设计方法
游戏5大设计方法
游戏开发者12个诀窍
游戏开发者12个诀窍
游戏视觉风格
游戏视觉风格
创造虚拟感7大原则
创造虚拟感7大原则
基于数据设计游戏
基于数据设计游戏
推荐词条
希拉里二度竞选
希拉里二度竞选
《互联网百科系列》
《互联网百科系列》
《黑客百科》
《黑客百科》
《网络舆情百科》
《网络舆情百科》
《网络治理百科》
《网络治理百科》
《硅谷百科》
《硅谷百科》
2017年特斯拉
2017年特斯拉
MIT黑客全纪录
MIT黑客全纪录
桑达尔·皮查伊
桑达尔·皮查伊
阿里双十一成交额
阿里双十一成交额
最新词条

热门标签

微博侠 数字营销2011年度总结 政务微博元年 2011微博十大事件 美国十大创业孵化器 盘点美国导师型创业孵化器 盘点导师型创业孵化器 TechStars 智能电视大战前夜 竞争型国企 公益型国企 2011央视经济年度人物 Rhianna Pratchett 莱恩娜·普莱契 Zynga与Facebook关系 Zynga盈利危机 2010年手机社交游戏行业分析报告 游戏奖励 主流手机游戏公司运营表现 主流手机游戏公司运营对比数据 创建游戏原型 正反馈现象 易用性设计增强游戏体验 易用性设计 《The Sims Social》社交亮 心理生理学与游戏 Kixeye Storm8 Storm8公司 女性玩家营销策略 休闲游戏的创新性 游戏运营的数据分析 社交游戏分析学常见术语 游戏运营数据解析 iPad风行美国校园 iPad终结传统教科书 游戏平衡性 成长类型及情感元素 鸿蒙国际 云骗钱 2011年政务微博报告 《2011年政务微博报告》 方正产业图谱 方正改制考 通信企业属公益型国企 善用玩家作弊行为 手机游戏传播 每用户平均收入 ARPU值 ARPU 游戏授权三面观 游戏设计所运用的化学原理 iOS应用人性化界面设计原则 硬核游戏 硬核社交游戏 生物测量法研究玩家 全球移动用户 用户研究三部曲 Tagged转型故事 Tagged Instagram火爆的3大原因 全球第四大社交网络Badoo Badoo 2011年最迅猛的20大创业公司 病毒式传播功能支持的游戏设计 病毒式传播功能 美国社交游戏虚拟商品收益 Flipboard改变阅读 盘点10大最难iPhone游戏 移动应用设计7大主流趋势 成功的设计文件十个要点 游戏设计文件 应用内置付费功能 内置付费功能 IAP功能 IAP IAP模式 游戏易用性测试 生理心理游戏评估 游戏化游戏 全美社交游戏规模 美国社交游戏市场 全球平板电脑出货量 Facebook虚拟商品收益 Facebook全球广告营收 Facebook广告营收 失败游戏设计的数宗罪名 休闲游戏设计要点 玩游戏可提高认知能力 玩游戏与认知能力 全球游戏广告 独立开发者提高工作效率的100个要点 Facebook亚洲用户 免费游戏的10种创收模式 人类大脑可下载 2012年最值得期待的20位硅谷企业家 做空中概股的幕后黑手 做空中概股幕后黑手 苹果2013营收 Playfish社交游戏架构

触屏游戏虚拟操纵杆 发表评论(0) 编辑词条

目录

触屏设备制作游戏虚拟操纵杆的教程编辑本段回目录

在编译本篇教程所提供的源文件之前,你需要先下载GreenSock的TweenLite(AS3)库类到你的项目文件夹的“greensock”子文件夹中。(这点将在第18步骤中详细讨论到)。

以下便是我们将努力创造出的最终结果:

virtual joystick for touch devices(from active.tutsplus)

virtual joystick for touch devices(from active.tutsplus)

步骤1:创造一个新的AS3文件

让我们开始在Flash Professional CS5中创造一个新的AS3文件。

new_document(from active.tutsplus)

new_document(from active.tutsplus)

在属性面板中找到文件设置,并确保文件的规格为(550×400),背景颜色为 (#000000) ,如下图所示:

document_properties(from active.tutsplus)

document_properties(from active.tutsplus)

在属性面板上将文件的类名设置为“com.MyApp”。这是我们所创造并用来代表主要应用的类。我们也将在之后创造其它针对于操纵杆的类,从而使我们能够只使用几行代码便将操纵杆添加到任何其它应用中。

将文件另存为“JoystickApp.fla”。

步骤2:创造文件类

document_class(from active.tutsplus)

document_class(from active.tutsplus)

现在,点击类名旁边的铅笔图标从而触发出编辑类。因为本来并不存在类,所以我们必须去创造它们。

edit_document_class(from active.tutsplus)

edit_document_class(from active.tutsplus)

当我们需要选择软件去编辑类定义时,我们可以选择Flash Professional。这时候你将能够看到新的类定义预填充在新的ActionScript文件中:

package com {       import flash.display.MovieClip;       public class MyApp extends MovieClip {           public function MyApp() {             // constructor code         }     }   }

将其保存在子文件夹“\com\”中与.fla 文件相同的文件夹中,并命名为“MyApp.as”。需要注意的是你可以自己设定文件夹的名称和结构。而文件夹结构的设置可以参考你的AS包的结构。

步骤3:绘制基本的操纵杆和把手

在这个步骤中我们将绘制出一套基本的圆圈以代表操纵杆。而在之后的步骤中我们将进一步优化我们的用户界面(UI)以让其更加具有吸引力。首先我们需要在.fla 文件中画出一个圆圈。并设置其属性为宽:160,高:160,颜色: #CCCCCC,其位置为横坐标:100,纵坐标:300。

将这个圆圈转变成一个MovieClip,并将其命名为“操纵杆”。在转变过程中选择一个定位点作为中心。

将MovieClip“操纵杆”放置在如下平台的左下方。(这只是用于参考)。我们将在之后的步骤中从“MyApp”类中动态地添加MovieClip到平台上。

circle_joystick_movieclip(from active.tutsplus)

circle_joystick_movieclip(from active.tutsplus)

在平台上绘制另外一个更小的圆圈,设置其宽为50px,高为50px。同样地将这个圆圈转变为新的MovieClip并命名为“操纵杆把手”。如下图将其放置于“操纵杆”MovieClip之上。

joystickKnob_movieclip(from active.tutsplus)

joystickKnob_movieclip(from active.tutsplus)

这便是我们完成所有阶段后能够看到的基本版操纵杆。我们将其安置在如上图的位置上。既然我们明确了操纵杆的外表,我们便可以开始为其撰写脚本了。现在你便可以在这个平台上删除这两个MovieClip了。

步骤4:将UI与定制类绑定

现在让我们将我们所创造的UI与它们的定制类维系在一起。打开程序库并右击“操纵杆”MovieClip。选择“属性”。

在“输出行动脚本”的复选框中打勾。将你的类名改为“com.controls.Joystick”。我们将在“com”文件夹中创建一个子文件夹,并在“com.controls”包中设置与控制相关的代码。

joystick_mc_class(from active.tutsplus)

joystick_mc_class(from active.tutsplus)

点击类名旁边的铅笔图标,如果需要打开编辑器就选择“Flash Professional”。这时候我们便创造出了一个名为.as的文件,其类名为“操纵杆”,并且是“MovieClip类的扩展。

在另外的“操纵杆把手”MovieClip中重复相同的过程。提供类名“com.controls.JoystickKnob”。

将两个类文件分别保存为“操纵杆.as”和“操纵杆把手.as”。

此时你的程序库将如下所示,即拥有两个MovieClip并附属于它们各自的定制类上:

library(from active.tutsplus)

library(from active.tutsplus)

步骤5:操纵杆把手类

我们根据操纵杆的位置去设置把手的起点。如此我们便能够在把手被拖曳到其它任何位置时更好地找到其最初的位置。

为此,我们将在“操纵杆把手”类中使用两个简单的属性。

package com.controls {       import flash.display.MovieClip;       public class JoystickKnob extends MovieClip {         private var _origin_x:Number;         private var _origin_y:Number;                  public function JoystickKnob() {             // constructor code         }     }   }

让我们先写下获取和设定方法,并以此读出或写下“ _origin_x”和“ _origin_y”属性。在“操纵杆把手”类中添加以下方法:

public function get origin_x():Number {     return _origin_x; }   public function set origin_x(o_x:Number):void {     _origin_x = o_x; }   public function get origin_y():Number {     return _origin_x; }   public function set origin_y(o_y:Number):void {     _origin_y = o_y; }

明确一开始的函数名中不会包含“_”(下划线),因为我们希望外部类的名字为“origin_x”和“origin_y”。

步骤6:基本的操纵杆类

让我们开始添加参数到“操纵杆”类的构造函数中。我们将添加2种参数,分别是“left_margin:Number”和“bottom_margin:Number”。如此我们便能够在实例化MovieClip时将操纵杆设置在任何一个位置上。

随后,我们将在“操纵杆”类的私有变量中分配这两个参数。你所设置的代码需如下:

package com.controls {       import flash.display.MovieClip;       public class Joystick extends MovieClip {         private var my_x:Number;         private var my_y:Number;           public function Joystick(margin_left:Number, margin_bottom:Number) {             my_x = margin_left;             my_y = margin_bottom;         }     }   }

现在我们需要编写“初始化()”方法以设置屏幕上的操纵杆位置。我们将在这个方法上添加“操纵杆把手”MovieClip。这个方法中包含了一个“事件”类型的参数,而我们将在一分钟后才涉及到这一参数。

在你添加“操纵杆把手”MovieClip之前我们需要在这个类中输入“操纵杆把手”类。添加以下输入代码:

import com.controls.JoystickKnob;

既然我们已经输入了“操纵杆把手”类,我们便需要在你的类中申明一个代表把手的变量:

private var knob:JoystickKnob;

现在,将以下函数添加到你的类中:

private function init(e:Event=null):void {     this.x = my_x + this.width / 2;     this.y = stage.stageHeight – my_y – this.height / 2;       knob = new JoystickKnob();     knob.x = 0;     knob.y = 0;       knob.origin_x = 0;     knob.origin_y = 0;       addChild(knob);       // knob.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);     // stage.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);       knob.buttonMode = true; }

正如你所看到的,基于构造函数能够接受的边际范围我们已经在平台上添加了“把手”,并且将“操纵杆”MovieClip设置于平台上了。除此之外我们还在“把手”和“平台”上添加了一些事件监听器,分别是“MOUSE_DOWN”和“MOUSE_UP”。之后我们需要在类中写下“mouseDown()”和“mouseReleased()”方法,使我们能够拖放把手。现在我们监听器添加了注释;而与此同时也不要忘记取消在方法之后的两行内容的批注。

既然平板电脑/触屏设备中的MouseEvent.<EVENT_NAMES>转变成了碰触事件,我们便能够使用鼠标去取代碰触行动了。

现在我们需要从构造函数中调用这一方法。但是比起盲目地调用方法,通过实践去检查现有的“平台”并调用它会更加合适。如果此时“操纵杆”MovieClip的“平台”属性还未进行初始化,我们便需要在明确了“平台”属性后调用init()方法。因此我们需要基于下述方法调用init()(在你的构造函数中添加以下内容):

if (stage) {     init(); } else {     addEventListener(Event.ADDED_TO_STAGE,init); }

我们需要删除之前添加的事件监听器。所以让我们在(最初的)init()方法中添加以下内容:

if (hasEventListener(Event.ADDED_TO_STAGE)) {     removeEventListener(Event.ADDED_TO_STAGE,init); }

步骤7:在平台上添加操纵杆

在我们执行这一代码并核查输出之前,我们需要从“MyApp”类中实例化“操纵杆”类。在你的“MyApp”类构造函数中添加以下代码。同时输入“操纵杆”类并申明一个能够代表“操纵杆”MovieClip的属性。所以此时你的“MyApp”类应该如下所示:

package com {       import flash.display.MovieClip;     import com.controls.Joystick;       public class MyApp extends MovieClip {         private var joystick:Joystick;           public function MyApp() {             joystick = new Joystick(30, 30);             addChild(joystick);         }     } }

现在你便能够执行并测试应用。你需要在你的平台上动态地添加“操纵杆”MovieClip,并在左边和下部位置留出30px的空间以传递构造函数。以下是SWF的截图:

swf_joystick_placement(from active.tutsplus)

swf_joystick_placement(from active.tutsplus)

步骤8:在把手上添加互动作用

现在是时候在“操纵杆把手”MovieClip中添加互动作用了,使得我们能够在操纵杆周长内拖动把手。在“操纵杆”类中取消我们之前所添加的两个事件监听器批注。现在我们需要为“把手”编写“mouseDown()”和“mouseReleased()”方法。

我们需要在mouseDown()方法中添加startDrag() 方法。通过设置属性而明确“操纵杆”MovieClip的范围。同时也不要忘记输入类“flash.geom.Rectangle”和“flash.events.MouseEvent”。

private function mouseDown(event:MouseEvent):void {     knob.startDrag(false,new Rectangle( -  this.width / 2, -  this.height / 2,this.width,this.height)); }

现在mouseReleased()便是一个简单的stopDrag()。随后我们需要添加更多代码以激活把手回到其“origin_x”和“origin_y”(游戏邦注:初始位置)。现在只要你释放鼠标,它便能够快速回到这一初始点上。

private function mouseReleased(event:MouseEvent):void {     knob.stopDrag();       knob.x = knob.origin_x;     knob.y = knob.origin_y; }

此时你便能够执行操纵杆的基本互动作用了。编译并运行!它将如下所示:

virtual joystick(from active.tutsplus)

virtual joystick(from active.tutsplus)

步骤9:检测把手的移动

让我们在操纵杆上尝试并检查“把手”的移动,并明确我们将如何基于自上而下的视图精灵去使用它。

当我们能够四处拖曳把手时,我们便需要基于操纵杆去明确把手的位置。修改精灵。我们将在之后创造一个精灵;而现在我们只需要设置把手位置的参数值即可。

在拖曳时明确把手的位置,我们还需要涵括一个ENTER_FRAME方法。在“操纵杆”类中添加以下代码:

private function knobMoved(event:Event):void {     trace(knob.x + “, ” + knob.y); }

在mouseDown()方法中的startDrag()之前添加ENTER_FRAME事件监听器:

private function mouseDown(event:MouseEvent):void {     this.addEventListener(Event.ENTER_FRAME, knobMoved);     knob.startDrag(false,new Rectangle( -  this.width / 2, -  this.height / 2,this.width,this.height)); }

我们并不想一直运行着ENTER_FRAME方法,因为这么做非常耗成本。因此我们打算只在拖曳动作开始时添加监听器,并在调用stopDrag()方法时立刻删除监听器。在运行stopDrag()之后添加removeEventListener:

if (this.hasEventListener(Event.ENTER_FRAME)) {     this.removeEventListener(Event.ENTER_FRAME, knobMoved); }

编译并运行SWF以进行测试。在输出窗口中读取参数值。

步骤10:对齐把手

因为我们面向的是触屏设备,所以用户在此体验不到控制的物理感触。所以有可能用户只是碰触到把手的外部,并尝试着去拖动操纵杆。所以我们根本不可能期待用户能精确地碰触并拖动把手。为了克服这一问题,我们必须想办法将把手对齐到用户碰触于操纵杆的点上。

也就是我们将在这个步骤中将“把手”的MovieClip与“操纵杆”所发生的碰触点对齐在一起。

在“操纵杆”类中添加以下私有方法:

private function snapKnob(event:MouseEvent):void {     knob.x = this.mouseX;     knob.y = this.mouseY;     mouseDown(null); }

在上述代码中,我们将“把手”的MovieClip纵坐标和横坐标等同于“操纵杆”的MovieClip的鼠标相对横坐标和纵坐标。我们同时也将调用mouseDown(null)方法开始拖曳过程。

我们将通过添加事件监听器而调用这一方法。让我们在init()方法中进行实践。围绕着事件监听器调用mouseDown()方法。在init()方法中添加以下代码:

this.addEventListener(MouseEvent.MOUSE_DOWN, snapKnob); knob.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown); stage.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);

根据上述代码,当“操纵杆”MovieClip获得MOUSE_DOWN事件后,它便能够调用snapKnob()方法。转而,这一方法能够把“把手”的MovieClip对齐到用户所碰触的位置上。随后调用mouseDown(null)方法,我们将推动startDrag()过程以让玩家感觉自己好像真的在碰触把手。

步骤11:创造一个主角MovieClip

既然我们的基本操纵杆已经能够有效运行了,我们便需要根据“把手”的位置参数值创造一个“主角”MovieClip以开始移动操纵杆。

现在打开.fla文件并绘制一个圆圈,如下所示。将其转变为MovieClip并再次使用定位点。将MovieClip命名为“主角”。然后设置其属性:宽为30px,高为30px,颜色为#0099CC。

在将圆圈转变为MovieClip的同时将其导出到行动脚本中,并将其类名命为“com.Hero”。

export_hero_mc(from active.tutsplus)

export_hero_mc(from active.tutsplus)

下图便是将圆圈转变为MovieClip的样子。

hero_mc(from active.tutsplus)

hero_mc(from active.tutsplus)

现在我们便能够从平台上删除MovieClip,因为我们将从“MyApp”类中将“主角”MovieClip动态地添加到平台上。

在你导出带有定制类名“com.Hero”的MovieClip后,不要忘记创建一个新的类文件并将其保存在“com”文件夹中。

步骤12:在平台上添加主角

让我们打开“MyApp.as”并动态地添加“主角”MovieClip。因为我们已经从“JoystickApp.fla”程序库中导出了“主角”的MovieClip,所以我们现在只需要打开“MyApp.as”,导入“com.Hero”类并申明一个新的属性“主角”,然后在实例化“操纵杆”MovieClip之前添加以下代码。你的“MyApp”类应该如下:

package com {       import flash.display.MovieClip;     import com.controls.Joystick;     import com.Hero;       public class MyApp extends MovieClip {         private var joystick:Joystick;         private var hero:Hero;           public function MyApp() {             hero = new Hero();             hero.x = stage.stageWidth/2;             hero.y = stage.stageHeight/2;             addChild(hero);               joystick = new Joystick(30, 30);             addChild(joystick);         }     } }

你可以注意到我们已经将MovieClip对齐在平台中央了。此时如果你编译并运行SWF,你便能够看到平台中央的“主角”MovieClip。

步骤13:将“主角”MovieClip转移到操纵杆类中

现在,为了能够在“操纵杆”MovieClip中访问“主角”MovieClip,我们需要使用一个简单的方法将“主角”MovieClip连同“margin_left”和“margin_bottom”属性转移到“操纵杆”MovieClip的构造函数中。

打开“com.controls.Joystick”类。输入“com.Hero” 类并在构造函数中添加第三个参数,如下:

public function Joystick(margin_left:Number, margin_bottom:Number, hero_mc:Hero) {

现在,既然我们希望能够在这个类中访问这一参数,我们就需要在此创造一个名为“主角”的私有变量:

private var hero:Hero;

随后,将我们刚刚添加的第三个参数转移到构造函数中的变量中,如下:

hero = hero_mc;

最后一步便是从“MyApp”类中将“主角”MovieClip转移到“操纵杆”MovieClip中(游戏邦注:并同时进行实例化)。将第三个参数添加到“操纵杆”MovieClip的构造参数中。

joystick = new Joystick(30, 30, hero);

此时我们便能够在平台上通过“操纵杆”MovieClip访问“主角”的MovieClip了。

步骤14:主角类

让我们准备一个“主角”类以移动“操纵杆”MovieClip。我们应该创造如下的基本类:

package com {       import flash.display.MovieClip;        public class Hero extends MovieClip {                  public function Hero() {           }     } }

在类中添加以下属性。我们应该在移动过程中使用这些属性。

package com {       import flash.display.MovieClip;        public class Hero extends MovieClip {         private var walk_speed = 2;           public var move_left:Boolean = false;         public var move_up:Boolean = false;         public var move_right:Boolean = false;         public var move_down:Boolean = false;           public function Hero() {           }     } }

因为属性是不需要加以说明的,所以你必须理解它们的用途。让我们前进到下个步骤并开始创造“主角”MovieClip的动画。

我们所添加的四个布尔属性是用于明确主角的移动方向。我们将通过“操纵杆”的类明确这些属性是正确还是错误。但是在此之前,让我们先准备具有移动能力的“主角”类。

在“主角”类中添加一个名为“heroMove()”的空白方法。

private function heroMove(event:Event):void {   }

我们将通过一个ENTER_FRAME事件监听器调用这一方法。在这一类的构造函数中添加事件监听器。

public function Hero() {     this.addEventListener(Event.ENTER_FRAME, heroMove); }

再一次需要记住输入一般类,如“flash.events.Event”等。

步骤15:理解把手的移动

现在,我们需要在“主角”类中调用“heroMove()” 方法以处理ENTER_FRAME事件。我们将在此核查4个布尔变量并相对应地移动主角。不过在此之前,我们还需要在“操纵杆”类中添加一个特殊的代码。所以让我们打开“操纵杆.as”文件并调用“knobMoved()”。

我们在方法中设置了跟踪语句,以此追踪“把手”MovieClip的横坐标和纵坐标位置。使用如下代码替换你的跟踪语句,你的“knobMoved()”方法 应该是:

private function knobMoved(event:Event):void {     // LEFT OR RIGHT     if (knob.x > 20) {         hero.move_right = true;         hero.move_left = false;     } else if (knob.x < -20) {         hero.move_right = false;         hero.move_left = true;     } else {         hero.move_right = false;         hero.move_left = false;     }       // UP OR DOWN     if (knob.y > 20) {         hero.move_down = true;         hero.move_up = false;     } else if (knob.y < -20) {         hero.move_down = false;         hero.move_up = true;     } else {         hero.move_down = false;         hero.move_up = false;     } }

上述代码是用于分离“左或右”和“上或下”移动相关代码,因为这里不存在让主角向左和右或向上和下移动的情节。所以我们便基于“把手”的MovieClip的横坐标和纵坐标(并围绕着“操纵杆”MovieClip的中心位置)将“主角”MovieClip的4个方向变量设置为正确或错误。

根据下图我们便能够更容易明白这一逻辑:

joystick_area_overview(from active.tutsplus)

joystick_area_overview(from active.tutsplus)

上图的2条红色虚线交汇在(0,0)或“起始点”或“操纵杆”MovieClip的“定位点”上。

而4个红色虚线框则代表“主角”能够移动“把手”的纵坐标和横坐标范围。红色虚线框中的文本则代表着方向。

蓝色矩形代表的是简单的方向,在此碰触点/把手只能朝着一个方向移动。

图像中间那个40×40 px的方形(灰色)代表的是一个槽区,即如果在此移动“把手”MovieClip也不会发生任何变化。这个槽区提供给用户能够容纳得下小指的空间,并且当用户碰触这块区域时也不会影响游戏的发展。因为在触屏设备中用户不能感受到任何物理界面,所以这种槽区更是非常必要(至少对于某些基本的游戏来说)——除非游戏拥有一个超级敏感的操纵杆。

以下是分离“左或右”的情况:

joystick_area_leftright(from active.tutsplus)

joystick_area_leftright(from active.tutsplus)

以下是分离“上和下”的情况:

joystick_area_updown(from active.tutsplus)

joystick_area_updown(from active.tutsplus)

步骤16:创造主角动画

现在,我们需要在“主角”类中调用“heroMove()” 方法以处理ENTER_FRAME事件。我们将在此核查4个布尔变量并相对应地移动主角。

在“heroMove()”方法中包含以下代码让我们能够根据基本的把手移动去移动“主角”MovieClip。

private function heroMove(event:Event):void {     if (move_left) {         this.x -= walk_speed;     }     if (move_up) {         this.y -= walk_speed;     }     if (move_right) {         this.x += walk_speed;     }     if (move_down) {         this.y += walk_speed;     } }

最后,记得在“操纵杆”类的“mouseReleased()”方法中将4个布尔变量重置为“错误的”。如果忘记了这个步骤“,“主角”MovieClip将在停止拖曳把手时继续运动着(游戏邦注:这是通过ENTER_FRAME事件基于“主角”类中的“heroMove()”方法所触发的)。

此时你的SWF应该如下:

virtual joystick (from active.tutsplus)

virtual joystick (from active.tutsplus)

继续前进并向下移动操纵杆把手。

步骤17:主角循环和方向

我们一直在尝试着创造出一款拥有自上而下视图以及一个能够到处走动的角色的游戏。虽然没有华丽的图像和动画,但是我们仍希望根据主角的移动创造出主角的方向或循环。如此我们便需要在.fla文件中添加一个额外的内容到“主角”MovieClip中(即一个像鼻子一样的形状)。

打开程序库中的“主角”标记,并添加一个小圆圈以代表“鼻子”。下图便是这一“鼻子”的放大版本及其MovieClip的实际尺寸视图。

hero_nose(from active.tutsplus)

hero_nose(from active.tutsplus)

现在让我们改变“主角”类中的“主角”MovieClip的“循环”属性。打开“主角”类,在“heroMove()”方法的开端添加以下代码:

private function heroMove(event:Event):void {     if (move_left && move_up) {         this.rotation = -45;     } else if (move_right && move_up) {         this.rotation = 45;     } else if (move_left && move_down) {         this.rotation = 225;     } else if (move_right && move_down) {         this.rotation = 135;     } else if (move_right) {         this.rotation = 90;     } else if (move_left) {         this.rotation = -90;     } else if (move_up) {         this.rotation = 0;     } else if (move_down) {         this.rotation = 180;     }       if (move_left) {         this.x -= walk_speed;     }     if (move_up) {         this.y -= walk_speed;     }     if (move_right) {         this.x += walk_speed;     }     if (move_down) {         this.y += walk_speed;     } }

在上述代码中我们已经核查了所有的8个方向,并相应地循环了“主角”MovieClip。现在编译并运行代码,你便能够看到如下场景:

virtual joystick (from active.tutsplus)

virtual joystick (from active.tutsplus)

这便是操纵杆和主角的基本行为。

步骤18:添加TweenLite支持

在这个步骤中我们将掌握TweenLite程序库是如何运行的,以及我们可以如何轻松地将其整合到我们的演示内容中以获得更棒的动画效果。

我们选择使用GreenSock所开发的TweenLite程序库。这是一种较为简单的动画引擎,开发者能够快速掌握它;并且它对于动画性能的影响也非常小。

打开网站http://www.greensock.com/tweenlite/并点击右边的“Download AS3”按钮。

阅读并接受相关条款,一旦完成了下载你便拥有了greensock-as3.zip。

将其解压到一个文件夹中。

在解压后的文件夹中找到“com”文件夹,导航到“com”文件夹中。

你需要找到一个名为“greensock”的子文件夹。这便是我们所需要的文件夹。

现在有两种方法能够帮助你在自己的项目中使用这一程序库。

将这一文件夹复制到你的项目文件夹中,或者将其动态链接至你的项目中。

动态链接具有一个优点,即你可以在不同项目的常见位置上使用相同的文件夹。而如果你选择将“greensock”文件夹复制到你的项目文件夹中,你便只能够在这一项目中使用它。如果你仍坚持将这一文件夹用于其它项目中,那么当引擎本身的漏洞得到了修改或者出现了新的功能时,你便需要面向不同的项目去更新你的本地文件夹。

不过不管怎样,在这一项目中我们最终选择了复制文件夹到我们的项目位置上。

将“greensock”文件夹复制到你的项目“com”文件夹中。以下图像将帮助你更好地理解“greensock”文件夹的最终位置:

greensock_folder(from active.tutsplus)

greensock_folder(from active.tutsplus)

现在,我们将输出创造把手动画所需要的类。打开“操纵杆.as”文件,并添加以下输入代码:

import com.greensock.*;

步骤19:创造把手动画

让我们为把手创造一个简单的动画,即更好地表现出它从触动到回到起始点的这一过程。我们需要在“操纵杆.as”文件中完成这一操作。

将以下方法添加到类中:

private function mover():void {     TweenLite.to(knob, 0.5, {x: knob.origin_x, y:knob.origin_y}); }

在方法“mouseReleased()”的最后添加函数调用到“mover()”:

mover();

切记在“mouseReleased()”方法中删除以下两行内容:

knob.x = knob.origin_x knob.y = knob.origin_y;

现在,尝试着拖曳把手并离开中心处。你将会看到如下swf格式的动画:

virtual joystick (from active.tutsplus)

virtual joystick (from active.tutsplus)

步骤20:把手反弹效果

因为操纵杆能够将把手拉回起始点的位置,所以我们需要在此添加一个自然的反弹效果。幸运的是使用TweenLite引擎能够帮助我们节省许多不必要的工作。

我们只需要打开“操纵杆.as”文件并输入TweenLite类包以创造出释放效果:

import com.greensock.easing.*;

TweenLite所支持的一种性能将帮助我们定义动画的类型。从我们的例子来看,也就是我们所需要的反弹效果。所以我们需要在“TweenLite.to()”方法中包含“释放”属性,如下:

TweenLite.to(knob, 0.5, {x: knob.origin_x, y:knob.origin_y, ease:Bounce.easeOut});

漏洞

你将能够在上面的SWF中发现一个小故障或漏洞。基于动画的原因,如果你快速轻拍把手并放开它,它便不会有任何反应。而当你快速轻拍多次把手时,那么第一次轻拍所触发的动画便会持续下去。TweenLite将迫使“把手”回到起始点位置。

改善

为了解决这一问题,我们需要在用户轻拍于“操纵杆”MovieClip时强制停止动画的运行。而这就需要我们获得能够代表动画的标识符。

所以我们便开始创造“TweenLite”的标识符(变量)。即我们需要在“操纵杆”类中创造这一新变量:

private var knob_tween:TweenLite;

现在,我们使用“TweenLite.to()”所执行的动画将被定义为这一属性。我们还需要适当地调整动画的陈述。删除对于静态方法“to()”的调用,并将其改为:

knob_tween = new TweenLite(knob, 0.5, {x: knob.origin_x, y:knob.origin_y, ease:Bounce.easeOut

新属性。“knob_tween”是我们用于强制停止动画的一种方法。来到“mouseDown()”方法并在方法的前端添加以下陈述:

if (knob_tween) {     knob_tween.kill(); }

测试并将下图的SWF与之前的进行比较。快速轻拍“操纵杆”MovieClip。并观察行为发生的改变。

这里包括了操纵杆的最终行为。

步骤21:重新设计操纵杆

直至现在,我们只使用了2种颜色的圆圈去表示操纵杆和把手。我并不打算在这一部分教程中过分讲究,因为这是一种主观设计,每个人都能够发挥自己的创造性。我将列举出一些能够适应这一逻辑并加强游戏体验与外观的例子。

例子1(截图)

example_1(from active.tutsplus)

example_1(from active.tutsplus)

例子2(截图)

example_2(from active.tutsplus)

example_2(from active.tutsplus)

例子3(截图)

example_3(from active.tutsplus)

example_3(from active.tutsplus)

步骤22:最终代码

我们将在此回顾每个.as文件的最终代码:

MyApp.as

package com {       import flash.display.MovieClip;     import com.controls.Joystick;     import com.Hero;       public class MyApp extends MovieClip {         private var joystick:Joystick;         private var hero:Hero;           public function MyApp() {             hero = new Hero();             hero.x = stage.stageWidth/2;             hero.y = stage.stageHeight/2;             addChild(hero);               joystick = new Joystick(30, 30, hero);             addChild(joystick);         }     } }

操纵杆把手.as

package com.controls {       import flash.display.MovieClip;       public class JoystickKnob extends MovieClip {         private var _origin_x:Number;         private var _origin_y:Number;                  public function JoystickKnob() {         }           public function get origin_x():Number {             return _origin_x;         }           public function set origin_x(o_x:Number):void {             _origin_x = o_x;         }           public function get origin_y():Number {             return _origin_x;         }           public function set origin_y(o_y:Number):void {             _origin_y = o_y;         }     } }

主角.as

package com {       import flash.display.MovieClip;     import flash.events.Event;       public class Hero extends MovieClip {         private var walk_speed = 2;           public var move_left:Boolean = false;         public var move_up:Boolean = false;         public var move_right:Boolean = false;         public var move_down:Boolean = false;           public function Hero() {             this.addEventListener(Event.ENTER_FRAME, heroMove);         }           private function heroMove(event:Event):void {             if (move_left && move_up) {                 this.rotation = -45;             } else if (move_right && move_up) {                 this.rotation = 45;             } else if (move_left && move_down) {                 this.rotation = 225;             } else if (move_right && move_down) {                 this.rotation = 135;             } else if (move_right) {                 this.rotation = 90;             } else if (move_left) {                 this.rotation = -90;             } else if (move_up) {                 this.rotation = 0;             } else if (move_down) {                 this.rotation = 180;             }               if (move_left) {                 this.x -= walk_speed;             }             if (move_up) {                 this.y -= walk_speed;             }             if (move_right) {                 this.x += walk_speed;             }             if (move_down) {                 this.y += walk_speed;             }         }     } }

操纵杆.as

package com.controls {       import flash.events.Event;     import flash.display.MovieClip;     import flash.events.MouseEvent;     import flash.geom.Rectangle;       import com.controls.JoystickKnob;     import com.Hero;       import com.greensock.*;     import com.greensock.easing.*;       public class Joystick extends MovieClip {         private var my_x:Number;         private var my_y:Number;           private var knob:JoystickKnob;         private var hero:Hero;           private var knob_tween:TweenLite;           public function Joystick(margin_left:Number, margin_bottom:Number, hero_mc:Hero) {             my_x = margin_left;             my_y = margin_bottom;             hero = hero_mc;               if (stage) {                 init();             } else {                 addEventListener(Event.ADDED_TO_STAGE,init);             }         }           private function init(e:Event=null):void {             if (hasEventListener(Event.ADDED_TO_STAGE)) {                 removeEventListener(Event.ADDED_TO_STAGE,init);             }               this.x = my_x + this.width / 2;             this.y = stage.stageHeight – my_y – this.height / 2;               knob = new JoystickKnob();             knob.x = 0;             knob.y = 0;               knob.origin_x = 0;             knob.origin_y = 0;               addChild(knob);               this.addEventListener(MouseEvent.MOUSE_DOWN, snapKnob);             knob.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);             stage.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);               knob.buttonMode = true;         }           private function snapKnob(event:MouseEvent):void {             knob.x = this.mouseX;             knob.y = this.mouseY;             mouseDown(null);         }           private function mouseDown(event:MouseEvent):void {             if (knob_tween) {                 knob_tween.kill();             }             this.addEventListener(Event.ENTER_FRAME, knobMoved);             knob.startDrag(false,new Rectangle( -  this.width / 2, -  this.height / 2,this.width,this.height));         }           private function knobMoved(event:Event):void {             // LEFT OR RIGHT             if (knob.x > 20) {                 hero.move_right = true;                 hero.move_left = false;             } else if (knob.x < -20) {                 hero.move_right = false;                 hero.move_left = true;             } else {                 hero.move_right = false;                 hero.move_left = false;             }               // UP OR DOWN             if (knob.y > 20) {                 hero.move_down = true;                 hero.move_up = false;             } else if (knob.y < -20) {                 hero.move_down = false;                 hero.move_up = true;             } else {                 hero.move_down = false;                 hero.move_up = false;             }         }           private function mouseReleased(event:MouseEvent):void {             knob.stopDrag();               hero.move_left = false;             hero.move_up = false;             hero.move_right = false;             hero.move_down = false;               if (this.hasEventListener(Event.ENTER_FRAME)) {                 this.removeEventListener(Event.ENTER_FRAME, knobMoved);             }               mo

ver();         }           private function mover():void {             knob_tween = new TweenLite(knob, 0.5, {x: knob.origin_x, y:knob.origin_y, ease:Bounce.easeOut});         }     }

步骤27:总结

本篇教程是关于如何通过添加屏幕控制而创造出一款触屏游戏。

而不同游戏类型也将需要有所针对地改变主角的移动逻辑。例如自上而下视角的汽车控制(停车场类游戏),平台游戏/横向卷轴游戏,益智游戏以及其它休闲游戏。

游戏邦注:原文发表于2011年2月2日,所涉事件和数据均以当时为准。(本文为游戏邦/gamerboom.com编译,作者:Hemanth Sharma )

Creating a Virtual Joystick for Touch Devices

Hemanth Sharma on Feb 2nd 2011

Prerequisite

Before you can compile the source files provided with this tutorial, download GreenSock’s TweenLite library for AS3 into the “greensock” subfolder in your project folder. (Discussed in Step 18).

Final Result Preview

Let’s take a look at the final result we will be working towards:

If you have a touch enabled device that supports Flash, open this page in it and try it out! Otherwise, use the mouse to drag the joystick or click the button.

Step 1: Create a New AS3 Document

Let us begin by creating a new AS3 Document in Flash Professional CS5.

Go to the Document Settings in the Properties panel and make sure the document size (550×400) and background color (#000000) are as shown in the below image:

On the Properties panel, specify a document class name of “com.MyApp“. This is the class that we will create that will represent the main application (more info here). We are going to create other classes specific to the joystick later so we can include the joystick in any other application with a couple of lines of code.

Save the file as “JoystickApp.fla”.

Step 2: Create the Document Class

Now, click on the pencil icon beside the Class name that will trigger the editing of that class. Since there is no class, we will have to create it.

When asked to choose the software that you want to use to edit the class definition, choose Flash Professional. You should see the new class definition pre-populated in a new ActionScript file:

Save this .as file as “MyApp.as” in the same folder as the .fla file under the subfolders “\com\”. Note that you may give your own names and folder structures. The structure of the folder refers to the structure of your AS package.

Step 3: Drawing the Basic Joystick and Knob

In this step, we will draw a basic set of circles to represent our Joystick. In later steps, we shall enhance the UI to fit our jazzy needs. Go ahead a draw a circle on the stage of your .fla file. Give it the following properties. Width: 160, Height: 160, Color: #CCCCCC. Place it at x: 100, y: 300.

Convert this circle to a MovieClip and name the MovieClip “Joystick“. Also don’t forget to choose the registration point as center while converting ().

Place the MovieClip “Joystick” on stage in the bottom left corner as shown in the image below. This is just for a reference. We will add the MovieClips dynamically on the stage from “MyApp” class later.

Draw another circle (smaller) on the stage with the values Width: 50px, Height: 50px. Convert the same to a new MovieClip and name it “JoystickKnob“. Place it on top of the “Joystick” MovieClip as shown in the below image.

This is how the basic version of Joystick will look like once we complete all the steps. We will dynamically place it in the position shown above. Now that we have an idea of how it would look, let’s go ahead and write the script for the same. You may now delete the two MovieClips from the stage.

Step 4: Tie the UI to the Custom Classes

Let us now tie the UI we drew to their custom classes. Go to Library and right-click on the “Joystick” MovieClip. Choose “Properties”.

Check the check box that says “Export for ActionScript”. Change your Class name to “com.controls.Joystick”. We will create a subfolder in the “com” folder and have code related to controls in the “com.controls” package.

Click on the pencil icon beside your Class name. Choose “Flash Professional” if asked for the editor. A new .as file is created with the class name “Joystick“, extended from the “MovieClip” class.

Repeat the same process for the other MovieClip “JoystickKnob“. Provide the class name “com.controls.JoystickKnob”.

Save the two class files as “Joystick.as” and “JoystickKnob.as” respectively.

This is how your library should look, with the two MovieClips attached to their custom classes:

Step 5: Joystick Knob Class

It is recommended to set the Knob’s origin with respect to the Joystick. This will help us to bring back the Knob to its initial location once the knob is dragged elsewhere and released.

For this, we will use two simple properties in the “JoystickKnob” class.

Let us now write the getter and setter methods to read and write the _origin_x and _origin_y properties. Add the following methods in the “JoystickKnob” class.

Observe that the function names are not having “_” (underscore) in the beginning of their names. This is because we just wanted the names to external classes to be origin_x and origin_y.

Step 6: Basic Joystick Class

Let us start by adding parameters to the constructor of the “Joystick” class. We will accept 2 parameters – left_margin:Number and bottom_margin:Number. This will help us place the Joystick wherever we want when we instantiate the MovieClip.

Later, we shall assign the two parameters to the private variables of “Joystick” class. Your code should look similar to this:

We now need to write the “initialize()” method to set the position of the Joystick on screen. We will also add the “JoystickKnob” MovieClip dynamically in this method. This method contains an “Event” type parameter. Don’t worry about it just yet. We will come to it in a minute.

Right before you add the “JoystickKnob” MovieClip dynamically, we need to import the “JoystickKnob” class into this class. Add the following import statement:

Now that we have imported the “JoystickKnob” class, declare a variable in your class to represent the knob.

Now, add the following function to your class.

As you can see, we have positioned the “Joystick” MovieClip on stage according to the margins the constructor accepted and we have added the “knob” on the stage. We have also added some event listeners to the “knob” and “stage” for MOUSE_DOWN and MOUSE_UP respectively. We shall write the methods mouseDown() and mouseReleased() later in the class to enable the dragging and dropping of the knob. The event listeners are currently commented out; DO NOT FORGET to uncomment the two lines after we write the methods.

Note that the MouseEvent.<EVENT_NAMES> translate to touch events on a touch tablet/device. So it is completely OK to use mouse events in place of touch.

We need to now call this method from the constructor. Instead of calling the method blindly, it is a good practice to check for the existence of “stage” and only then call this. If the “stage” property for “Joystick” MovieClip is not yet initialized by this time (which is a corner case), the init() method needs to get called after it can determine the “stage” property. Hence we call the init() method in the below shown manner (add this set of lines inside your constructor):

We shouldn’t forget to remove the added EventListener. Hence let’s add a couple of lines inside the (beginning of) init() method:

Step 7: Add Joystick to the Stage

Before we execute this code and check the output, we need to instantiate the “Joystick” class from inside the “MyApp” class. Add the following code to your constructor of the “MyApp” class. Also import the “Joystick” class and declare a property to represent the “Joystick” MovieClip. So your “MyApp” class should look like this at this time:

You may now execute and test the app. This would just dynamically add the “Joystick” MovieClip on the stage leaving 30px margin on the left and bottom as passed to the constructor. Here is the screenshot of the SWF:

Step 8: Adding Interaction to Knob

Now is the time to add interaction to the “JoystickKnob” MovieClip, make it draggable around the Joystick’s perimeter. In the “Joystick” class, uncomment the two event listeners that we commented before. We shall now write the mouseDown() and mouseReleased() methods for the “knob“.

We will just add a startDrag() method inside the mouseDown() method. Give the properties to specify the boundary of the “Joystick” MovieClip. Don’t forget to import the classes flash.geom.Rectangle and flash.events.MouseEvent (if you haven’t).

mouseReleased() is a simple stopDrag() for now. We shall add more code later to “animate” back the knob to its “origin_x” and “origin_y“. Right now, it just snaps back when you release the mouse.

You may now execute the basic interaction of the Joystick. Compile and run! Here is how it should behave:

Step 9: Detecting Knob Movement

Let us try and detect the “knob” movement in the Joystick and determine how we want to use it for a simple top-down view sprite.

When the “knob” is being dragged around, we need to read the position of it with respect to the “Joystick” MovieClip and modify the sprite. We shall create a sprite later. For now, let us just read the value of the knob’s position.

To read the position of the knob while dragging, we need to include an ENTER_FRAME method. Add the below method to the “Joystick” class:

Add the ENTER_FRAME event listener just before the startDrag() happens inside the mouseDown() method:

We don’t want the ENTER_FRAME method to be running all the time. This could prove costly. Hence, we will add the listener only when dragging starts and remove the listener as soon as we stopDrag(). Add the removeEventListener right after stopDrag().

Compile and execute the SWF now to test this out. Read the values in the output window.

Step 10: Snapping the Knob

Since it is the Touch Screens that we are trying to target, there is no physical feel of the controls. Hence, there is a clear possibility that the user might just touch outside the knob and try to drag the joystick around. It is unfair and inconvenient to expect the user to precisely touch and drag the knob. To overcome this confusion, it is a good idea to snap the knob to the place where the touch happens on the Joystick.

In this step, we will snap the “knob” MovieClip to the point on the “Joystick” where the actual touch might happen.

In the “Joystick” class, add the following private method:

In the above code, we are setting the “knob” MovieClip’s x and y coordinates to “Joystick” MovieClip’s mouseX and mouseY coordinates. We are also calling the mouseDown(null) method to start the dragging process.

This method will be called by adding an event listener. Let’s do that in the init() method. Right around the event listener that calls the mouseDown() method. Add the following line in the init() method:

According to the code above, as soon as the “Joystick” MovieClip (“this“) gets a MOUSE_DOWN event, it calls the snapKnob() method. Inturn, this method snaps “knob” MovieClip to the touched position. Later, calling the mouseDown(null) method, we force the startDrag() process so the user feels he has touched the knob.

Step 11: Creating a Hero MovieClip

Now that we have the basic Joystick working, we need to create a “Hero” MovieClip to start moving it according to the “knob” position values.

Move to the .fla file for now and draw a circle, as shown below. Convert it to MovieClip and use the center registration point () again. Give the MovieClip the name “Hero“. You may choose to give the properties – Width: 30px, Height: 30px, Color: #0099CC.

Also, export to ActionScript while converting to MovieClip and give it the class name “com.Hero“.

This is how the MovieClip will look once it is converted.

We should now remove the MovieClip from stage as we will add the “Hero” MovieClip dynamically on stage from the “MyApp” class.

After you have exported the MovieClip with the custom class name “com.Hero”, don’t forget to create the new class file and save it in the “com” folder.

Step 12: Adding Hero to the Stage

Let us open “MyApp.as” and add the “Hero” MovieClip dynamically. Since we have exported “Hero” MovieClip from the Library of “JoystickApp.fla”, open “MyApp.as”, import “com.Hero” class and declare a new property “hero” and add the following code before the “joystick” MovieClip is instantiated in the constructor. This is how your “MyApp” class should look like:

Note that we have also aligned the MovieClip to center of the stage. If you compile and run the SWF, you should see the “hero” MovieClip in the center of the stage.

Step 13: Passing Hero MovieClip to Joystick Class

Now, for the “joystick” MovieClip to access “hero” MovieClip that’s added to the stage, we shall use an easy method of passing “hero” MovieClip to the constructor of “joystick” MovieClip along with the “margin_left” and “margin_bottom” properties.

Open the “com.controls.Joystick” class. Import “com.Hero” class and add a third parameter to the constructor as shown below:

Now, since we want this parameter to be accessed across this class, we will create a private variable called “hero” in this class:

Later, assign the third parameter we just passed to this variable inside the constructor as shown below.

The final step is to pass the “hero” MovieClip from “MyApp” class after it’s added, to the “joystick” MovieClip while it is being instantiated. Add (pass) the third parameter to the “joystick” MovieClip’s constructor.

At this point, the “hero” MovieClip on stage is accessible from the “joystick” MovieClip.

Step 14: Hero Class

Let us prepare the “Hero” class to be able to move around as dictated by the “joystick” MovieClip. We should have created a basic class by now that looks like this:

Add the following properties to the class. We shall make use of them during the movement.

As the properties are self explanatory, you must have understood what they are used for. Let’s move on to the next step and start animating the “hero” MovieClip.

The four Boolean properties we added are used to determine which direction the Hero is supposed to move. We will set these properties to true or false through the “Joystick” class. Before we do that, let us prepare “Hero” class with the capability to move.

Add an empty method called “heroMove()” in the “Hero” class.

We shall call this method through an ENTER_FRAME event listener. Add the event listener in the constructor of this class.

Again, please don’t forget to import generic classes like “flash.events.Event“, etc.

Step 15: Understanding Knob Movement

Now, we have asked the “heroMove()” method in the “Hero” class to be called on ENTER_FRAME event. This is where we will check the 4 Boolean variables and move the Hero accordingly. But before we do that, let us add the specific code in the “Joystick” class. Open the “Joystick.as” file and go to the method called “knobMoved()“.

We have the trace statement in the method that traces the x and y coordinates of the “knob” MovieClip. Replace the trace statement with the following highlighted lines and your “knobMoved()” method should look like this:

What we have done in the above code is to separate the “Left or Right” and “Up or Down” movement related code as there won’t be any scenario where the Hero would move left and right or move up and down. So, we set the “hero” MovieClip’s 4 direction variables to true or false based on the x and y positions of the “knob” MovieClip with respect to the center of the “joystick” MovieClip.

The below figure will explain the simple logic:

The figure above shows the 2 red dashed lines intersecting in the center that represents the (0,0) or “origin” or “registration point” of the “joystick” MovieClip.

The 4 red shaded boxes represent the area in which the x and y values of the “knob” MovieClip will be passed to the “hero” MovieClip. Also the text on the red shaded boxes represent the directions.

The blue rectangles represent one simple direction. While the touch/knob is here, it just orders to move in one direction.

Also observe the 40×40 px square (gray) in the center. They represent the gutter area where if the “knob” MovieClip is moved, nothing happens. This gutter area is to provide a little finger movement on the screen when touched without disturbing the game’s behavior. Since there is no physical surface for the user to feel, this gutter area is required, at least for some basic games, unless the game is supposed to be ultra sensitive to the Joystick.

Let us look at the “Left or Right” break-up:

Here is the “Up and Down” break-up:

Step 16: Animating Hero

Now, we have asked the “heroMove()” method in the “Hero” class to be called on ENTER_FRAME event. This is where we will check the 4 Boolean properties of “hero” MovieClip and move it accordingly.

Go ahead and include the following statements in the “heroMove()” method to make the “hero” MovieClip move according to basic knob movement.

Lastly, don’t forget to reset the 4 Boolean variables to “false” in the “mouseReleased()” method of the “Joystick” Class. Failing to do so will result in constant motion of the “hero” MovieClip even while not dragging the knob (this is triggered from the “heroMove()” method from “Hero” class through ENTER_FRAME event).

This is how your SWF should behave:

Go ahead and move the Joystick Knob below.

Step 17: Hero Rotation & Direction

We are trying to have a top-down view game with a person depicted walking around. Keeping the complex artwork and animation apart, we would at least want to cover the direction or rotation of the Hero according to his movement. For this, we will make a slight addition to the “hero” MovieClip in the .fla file. We will add something that looks like a nose.

Open the “Hero” symbol in the Library and add a small circle that will represent the nose. Below is the zoomed in version of the object being drawn inside the “Hero” symbol and beside it is the actual size view of the MovieClip.

Let us now change the “rotation” property of the “hero” MovieClip in the “Hero” class. Open the “Hero” class and add the following code in the beginning of the “heroMove()” method:

In the above code, we have made checks for all 8 directions and rotated the “hero” MovieClip accordingly. Compiling and running your code now should result in the following:

This concludes the basic behavior of the Joystick and Hero.

Step 18: Add TweenLite Support

In this step, we shall understand how TweenLite library works and how easily we can incorporate it in our demo so we can get a little better effect for animations.

We will choose to use a library called TweenLite developed by GreenSock. This is a very light weight tweening engine that is quick for a developer and has less impact on performance of your animations.

Go to http://www.greensock.com/tweenlite/ and click on the “Download AS3″ button on the right side.

Read and accept the terms and conditions and once the download is done, you must have greensock-as3.zip.

Extract it to a folder.

Find the “com” folder inside the extracted folder. Navigate to inside the “com” folder.

You should find a subfolder by name “greensock”. This is the folder we need.

Now, there are 2 common ways of setting this library up for use in your projects.

Copy this folder to your project folder.
OR

Link it dynamically from where ever it is to your project.
Linking dynamically has an advantage. You can end up using the same folder that exists on some other common location in many different projects. If you choose to copy the “greensock” folder into your project’s folder, you will be able to use it only in that project. Doing this eventually for other project may lead to duplicates of GreenSock library and if the engine itself is released with bug fixes or new features, you will need to update your local folders for many different projects.

However, for this project, we will just copy the folder to our project’s location.

Copy the “greensock” folder to the “com” folder of your project. The below image should help you understand the final location of the “greensock” folder.

Now, we shall import the classes that we require to start animating the Knob. Open the “Joystick.as” file and add this import statement:

Step 19: Animating the Knob

Let us add a simple animation to the Knob when it is released and needs to come back to its origin. This is done in the “Joystick.as” file.

Add the following method to the class:

Now, add the function call to “mover()” in the method “mouseReleased()” at the end:

Don’t forget to REMOVE the following 2 lines in the “mouseReleased()” method:

Now, try dragging the knob and releasing it away from the center. Notice the animation in the below swf:

Step 20: Knob Bounce Effect

Since a Joystick brings back the knob to its origin, it also adds a natural rebound effect. Luckily, we have very less work to do to achieve this using TweenLite.

Open the “Joystick.as” and Import a package of TweenLite that enables the easing effects:

There is a property supported by TweenLite that will allow you to define the type of animation. In our case, it is the Bounce effect we need. So, go ahead and include the property “ease” in the “TweenLite.to()” method as shown below:

Test the below SWF:

The Bug

You must be able to find a small glitch or bug in the above SWF. If you rapidly try to tap “around” the knob and release it, the knob doesn’t respond. This is because of the animation. By the time you rapidly tap more than once, the animation that got triggered from the first tap isn’t over. Without the animation complete, TweenLite is forcing the “knob” to animate back to its origin.

The Fix

To fix this, we need to force-stop the animation when there is a tap on the “joystick” MovieClip. To be able to stop an animation forcibly, we need to get the identifier that represents the tween/animation we are doing.

We start by creating an identifier (variable) of type “TweenLite”. Create this new variable in “Joystick” class:

Now, the animation we are performing using “TweenLite.to()” should be assigned to be identified by this property we created. We need to do a slight change to the tween statement. Remove the call for “to()” static method and change it to the following:

The new property, “knob_tween” is the one we use to force-stop the animation. Go to the method “mouseDown()” and add the following statements in the beginning of the method:

Test and compare the SWF below to the previous one. Tap rapidly on the “joystick” MovieClip. Notice the change in behavior.

This covers the final behavior of Joystick.

Step 21: Joystick Re-design

Till now, we simply used 2 flat colored circles to represent a Joystick and Knob. I won’t elaborate this section of the tutorial as it is subjective and has no limits to how creative it can become. I will show you some example designs that can be adapted into this logic to enhance the experience and look of your game.

Example 1 (screenshot)

Example 2 (screenshot)

Example 3 (screenshot)

Step 22: Final Code

We shall review the final code for your reference of each .as file below.

MyApp.as

JoystickKnob.as

Hero.as

Joystick.as

Step 27: Conclusion

This was a basic tutorial on how to make your games touch-devices-ready by adding an on-screen control.

Additionally, different types of games would need changes in the Hero movement logic. Some examples include top-down view car control (parking lot type game), platform game / side-scrolling game, puzzles, and other casual games. Hope you had fun learning to create this Virtual Joystick.

For more tutorials, tips on Flash development for devices and improvisations on the above code, visit http://www.hsharma.com/tech.(source:active.tutplus+

→如果您认为本词条还有待完善,请 编辑词条

词条内容仅供参考,如果您需要解决具体问题
(尤其在法律、医学等领域),建议您咨询相关领域专业人士。
2

标签: 触屏游戏虚拟操纵杆 触屏设备制作游戏虚拟操纵杆的教程 触屏设备制作游戏虚拟操纵杆

收藏到: Favorites  

同义词: 暂无同义词

关于本词条的评论 (共0条)发表评论>>

对词条发表评论

评论长度最大为200个字符。