《Genesis-3D开源游戏引擎--横版格斗游戏制作教程08:虚拟键盘实现》--本系列完结
8.虚拟键盘实现
概述:
硬键盘就是物理键盘,平时敲的那种。软键盘是虚拟的键盘,不是在键盘上,而是在"屏幕"上。虚拟按键就是虚拟键盘的一部分,根据功能需求,提供部分按键效果的UI可操控按钮,尤其是在平板电脑、触控手机上,虚拟按键得到了更多的应用。在触控平台上的游戏,一部分通过手指在屏幕上相应的滑动产生相应的指令;还有一部分增设虚拟按键,完成对游戏的操控。
实现原理:
UI基本制作->功能实现
实现方法:
步骤1:
按照7UI的制作方法,完成UI的制作,最终效果图,如8-1-1所示。左侧为摇杆按钮,为双侧的BUTTON,一层做摇杆的底部按钮背景,一层与用户交互发生相应事件。右侧围控制攻击和跳跃的按钮。

图8-1-1
步骤2:
脚本实现按钮功能。
初始化虚拟按键UI。
public void Init()
{
//注册攻击按钮layout文件
GUI.RegisterLayout(_attackWindowName, @"Layout\AttackButton.layout", false, true);
//注册按钮点击事件 1.layout名字 2.控件名字 3.回调函数 4.事件控制类型
GUI.UIWidget.SetEventMouseButtonClick(_attackWindowName, "AttackBtn", OnAttackBtnClick, EventControl.Add);
//注册跳跃按钮layout文件
GUI.RegisterLayout(_jumpWindowName, @"Layout\JumpButton.layout", false, true);
//注册按钮点击事件 1.layout名字 2.控件名字 3.回调函数 4.事件控制类型
GUI.UIWidget.SetEventMouseButtonClick(_jumpWindowName, "JumpBtn", OnJumpBtnClick, EventControl.Add);
//根据屏幕尺寸设定按钮位置
IntSize screenSize = GUI.GetScreenSize();
IntPoint AtkBtnUIpos = new IntPoint((int)(screenSize.width - GUI.UIWidget.GetSize(_attackWindowName, "_Main").width * 2.5f),
(int)(screenSize.height - GUI.UIWidget.GetSize(_attackWindowName, "_Main").height * 1.2f));
IntPoint JumpBtnUIpos = new IntPoint((int)(screenSize.width - GUI.UIWidget.GetSize(_attackWindowName, "_Main").width * 1.2f),
(int)(screenSize.height - GUI.UIWidget.GetSize(_attackWindowName, "_Main").height * 1.2f));
GUI.UIWidget.SetPosition(_attackWindowName, "_Main", AtkBtnUIpos);
GUI.UIWidget.SetPosition(_jumpWindowName, "_Main", JumpBtnUIpos);
}
//攻击点击回调函数
private void OnAttackBtnClick(FString sender)
{
Logic.IputMgr.Instance.Attack_N(Code.J);
}
//跳跃点击回调函数
private void OnJumpBtnClick(FString sender)
{
Logic.IputMgr.Instance.Jump();
}
虚拟摇杆类
public class AndroidJoystick
{
public void Init()
{
GUI.RegisterLayout(_joystickWindowName, @"Layout\JoyStickBtn.layout", false, true);
//注册按钮按下事件
GUI.UIWidget.SetEventMouseButtonPressed(_joystickWindowName, "JoystickBtn", OnJSBtnPressed, EventControl.Add);
//注册按钮抬起事件
GUI.UIWidget.SetEventMouseButtonReleased(_joystickWindowName, "JoystickBtn", OnJSBtnReleased, EventControl.Add);
//注册按钮的拖拽事件
GUI.UIWidget.SetEventMouseDrag(_joystickWindowName, "JoystickBtn", OnJSBtnDrag, EventControl.Add);
//注册按钮的Tick事件
GUI.UIWidget.SetEventTick(_joystickWindowName, "JoystickBtn", Tick, EventControl.Add);
IntSize screenSize = GUI.GetScreenSize();
IntPoint JoystickBtnUIpos = new IntPoint((int)(GUI.UIWidget.GetSize(_joystickWindowName, "_Main").width * 0.2f),
(int)(screenSize.height - GUI.UIWidget.GetSize(_joystickWindowName, "_Main").height * 1.5f));
GUI.UIWidget.SetPosition(_joystickWindowName, "_Main", JoystickBtnUIpos);
GUI.SetLayoutVisible(_joystickWindowName, true);
jsBtnPos = GUI.UIWidget.GetPosition(_joystickWindowName, "JoystickBtn");
_isCtrl = false;
}
private void OnJSBtnDrag(FString sender, int value, int value2, MouseButton btn)
{
if (lastX == -)
{
lastX = value;
}
//跟上一帧作比较,大于0为右移,小于0为左移
int xOffset = value - lastX;
if (xOffset > )
{
Debug.Dbgout("IsRightSlide");
IntPoint JoystickBtnUIpos = new IntPoint(, jsBtnPos.top);
//移动按钮位置
GUI.UIWidget.SetPosition(_joystickWindowName, "JoystickBtn", JoystickBtnUIpos);
Logic.LogicMgr.Instance.SetDirection(Logic.Direction.Forward);
Logic.LogicMgr.Instance.CurPlayer.State = Logic.CharacterState.Running;
}
else if (xOffset < )
{
Debug.Dbgout("IsLeftSlide");
IntPoint JoystickBtnUIpos = new IntPoint(, jsBtnPos.top);
//移动按钮位置
GUI.UIWidget.SetPosition(_joystickWindowName, "JoystickBtn", JoystickBtnUIpos);
Logic.LogicMgr.Instance.SetDirection(Logic.Direction.Backward);
Logic.LogicMgr.Instance.CurPlayer.State = Logic.CharacterState.Running;
}
lastX = value;
lastY = value2;
}
private void OnJSBtnPressed(FString sender, int value, int value2, MouseButton btn)
{
//控制控件是否被操作
_isCtrl = true;
Debug.Dbgout("isCtrl");
}
private void OnJSBtnReleased(FString sender, int value, int value2, MouseButton btn)
{
//控制控件是否被操作
_isCtrl = false;
Debug.Dbgout("Released");
}
private void Tick(FString sender, float gameTime, float frameTickTime)
{
if (!_isCtrl)
{
//在非操作状态,设置为初始状态
GUI.UIWidget.SetPosition(_joystickWindowName, "JoystickBtn", jsBtnPos);
if (Logic.LogicMgr.Instance.CurPlayer.State == Logic.CharacterState.Running)
{
Logic.LogicMgr.Instance.CurPlayer.State = Logic.CharacterState.Idle;
}
}
}
引擎官方网站:http://www.genesis-3d.com.cn/
官方论坛:http://bbs.9tech.cn/genesis-3d/
官方千人大群:59113309 135439306
YY频道-游戏开发大讲堂(完全免费,定期开课):51735288
Genesis-3D开源游戏引擎:游戏起源,皆因有我!!!
《Genesis-3D开源游戏引擎--横版格斗游戏制作教程08:虚拟键盘实现》--本系列完结的更多相关文章
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程:简介及目录》(附上完整工程文件)
介绍:讲述如何使用Genesis-3D来制作一个横版格斗游戏,涉及如何制作连招系统,如何使用包围盒实现碰撞检测,软键盘的制作,场景切换,技能读表,简单怪物AI等等,并为您提供这个框架的全套资源,源码以 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程04:技能的输入与检测》
4.技能的输入与检测 概述: 技能系统的用户体验,制约着玩家对整个游戏的体验.游戏角色的技能华丽度,连招的顺利过渡,以及逼真的打击感,都作为一款游戏的卖点吸引着玩家的注意.开发者在开发游戏初期,会根据 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程01: 资源导入》
1. 资源导入 概述: 制作一款游戏需要用到很多资源,比如:模型.纹理.声音和脚本等.通常都是用其它相关制作资源软件,完成前期资源的收集工作.比如通常用的三维美术资源,会在Max.MAYA等相应软件中 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程07:UI》
概述: UI即User Interface(用户界面)的简称.UI设计是指对软件的燃机交互.操作逻辑.界面美观的整体设计.好的UI设计不仅可以让游戏变得更有品位,更吸引玩家,还能充分体现开发者对游戏整 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程06:技能播放的逻辑关系》
6.技能播放的逻辑关系 技能播放概述: 当完成对技能输入与检测之后,程序就该对输入在缓存器中的按键操作与程序读取的技能表信息进行匹配,根据匹配结果播放相应的连招技能. 技能播放原理: 按键缓存器中内容 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程05:技能读表》
5.技能读表 技能读表概述: 技能读表,作为实现技能系统更为快捷的一种方式,被广泛应用到游戏开发中.技能配表,作为桥梁连接着游戏策划者和开发者在技能实现上的关系.在游戏技能开发中,开发者只需要根据策划 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程03:碰撞检测》
3.碰撞检测 碰撞检测的概述: 碰撞在物理学中表现为两粒子或物体间极端的相互作用.而在游戏世界中,游戏对象在游戏世界自身并不受物理左右,为了模拟真实世界的效果,需要开发者为其添加属性,以模拟真实事件的 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程02:关键帧动画导入与切割》
2. 关键帧动画导入与切割 动画的分割与导入概述: 在游戏当中,游戏角色在不同状态下会有不同的动作,这些动作在引擎里相当于一段段的动画片段.当导入模型资源的时候,连同模型动画都会一并导入到引擎中.开发 ...
- Beat 'Em Up Game Starter Kit (横版格斗游戏) cocos2d-x游戏源代码
浓缩精华.专注战斗! 游戏的本质是什么?界面?养成?NoNo! 游戏来源于对实战和比赛的模拟,所以它的本源就是对抗.就是战斗! 是挥洒热血的一种方式! 一个游戏最复杂最难做的是什么?UI?商城? ...
随机推荐
- android 从assets和res中读取文件
1. 相关文件夹介绍 在Android项目文件夹里面,主要的资源文件是放在res文件夹里面的.assets文件夹是存放不进行编译加工的原生文件,即该文件夹里面的文件不会像xml,java文件被预编译, ...
- JUnit + Spring + Hibernate 集成测试,无法通过的问题
使用JUnit测试DAO层.由于不能破坏数据现场,故所有的测试类都继承了Spring测试框架下的 org.springframework.test.AbstractTransactionalDataS ...
- 详细记录python的range()函数用法
使用python的人都知道range()函数很方便,今天再用到他的时候发现了很多以前看到过但是忘记的细节.这里记录一下range(),复习下list的slide,最后分析一个好玩儿的冒泡程序. 这里记 ...
- [原]Water Water Search Problems' Set~Orz【updating...】
[HDU] [POJ] 作者:u011652573 发表于2014-4-30 10:39:04 原文链接 阅读:30 评论:0 查看评论
- YTU 2617: B C++时间类的运算符重载
2617: B C++时间类的运算符重载 时间限制: 1 Sec 内存限制: 128 MB 提交: 284 解决: 108 题目描述 C++时间类的运算符重载 定义一个时间类Time,其数据成员为 ...
- 在blade中定义一个可以被模版使用的变量
laravel的blade中的数据一般由控制器传入,但是有没有什么办法临时在blade模版中创建并且被blade所使用吗? 答案是肯定的,不过语法稍微复杂一点 {{-- */$variableAvai ...
- Codeforces 377 A Maze【DFS】
题意:给出n*m的矩阵,矩阵由'.'和'#'组成,再给出k,表示需要在'.'处加k堵墙,使得剩下的'.'仍然是连通的 先统计出这个矩阵里面总的点数'.'为sum 因为题目说了一定会有一个解,所以找到一 ...
- Android 源代码自动编译packages/apps
/*************************************************************************** * Android 源代码自动编译packag ...
- MySQL的性能调优工具:比mysqlreport更方便的tuning-primer.sh
年初的时候收藏过一篇关于mysqlreport的报表解读,和内置的show status,和show variables相比mysqlreport输出一个可读性更好的报表:但Sundry MySQL提 ...
- ecshop 文章列表页调用描述信息啊
1.打开 includes/lib_article.php文件 将 $sql = 'SELECT article_id, title, author, add_time, file_url, open ...