Delphi11新鲜出炉后一直没有去试用,最近几天有空下了个Lite版来玩,发现编译速度快了很多,编译后的尺寸也变小了一些,前些时候在github上看到一个Delphi无引擎版的小游戏,决定调试一下,目前Windows下运行正常,像这个样子:

安卓下暂时没有运行起来,界面是这个样子:

使用的MouseDown和MouseUp事件驱动,也就是说按左、右的时候,没法跳,所以想着改造一下,整个虚拟摇杆来操控,于是有了这一篇博文(顺便吐槽一下Delphi11有时编辑器会完全消失,欢迎页面也一起消失了)。

一、首先顺便弄一下,做个摇杆的样子,和按键的样子:

二、摇杆在屏幕左半边,按键在屏幕右半边,也就是说点击屏幕左半边任意一点就是 摇杆的中心位置,然后滑动触控点,一通计算得到方向,同时兼顾右边的按键触控即可。

单元代码如下(网上其他的方法太复杂难懂,下面主要就3个方法2个事件):

unit Unit7;interfaceusesSystem.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects,FMX.Gestures, FMX.ExtCtrls, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Ani,FMX.Memo.Types, FMX.ScrollBox, FMX.Memo, System.Math, FMX.Layouts;typeTForm7 = class(TForm)Label1: TLabel;Label2: TLabel;chk8Dir: TCheckBox;Memo1: TMemo;Layout1: TLayout;Circle1: TCircle;Circle2: TCircle;Circle3: TCircle;Circle4: TCircle;joyBorder: TCircle;joyCenter: TCircle;tmrJoyUp: TTimer;Label0: TLabel;procedure chk8DirChange(Sender: TObject);procedure FormTouch(Sender: TObject; const Touches: TTouches;const Action: TTouchAction);procedure FormCreate(Sender: TObject);procedure tmrJoyUpTimer(Sender: TObject);privateFStartPt: TPointF;FBtns: TArray<TCircle>;function CalcDirection(A: integer): Char;procedure JoyDown(X, Y: Single);procedure JoyMove(X, Y: Single);procedure JoyUp;{ Private declarations }public{ Public declarations }end;varForm7: TForm7;implementation{$R *.fmx}varA2D8: array [0..7] of Integer = (23, 68, 112, 158, 203, 248, 293, 338);A2C8: array [0..7] of Char = ('↑', '↗', '→', '↘', '↓', '↙', '←', '↖');A2D4: array [0..3] of Integer = (45, 135, 225, 315);A2C4: array [0..3] of Char = ('↑', '→', '↓', '←');function TForm7.CalcDirection(A: integer): Char;
varI: integer;
beginif chk8Dir.IsChecked thenbegin//计算八方向下当前摇杆的方向Result := A2C8[0];for I := 1 to 7 doif (A >= A2D8[I-1]) and (A < A2D8[I]) thenbeginResult := A2C8[I];exit;end;endelsebegin//计算四方向下当前摇杆的方向Result := A2C4[0];for I := 1 to 3 doif (A >= A2D4[I-1]) and (A < A2D4[I]) thenbeginResult := A2C4[I];exit;end;end;
end;procedure TForm7.chk8DirChange(Sender: TObject);
beginif chk8dir.IsChecked thenchk8dir.Text := '八方向'elsechk8dir.Text := '四方向';
end;procedure TForm7.FormCreate(Sender: TObject);
begin//初始化摇杆按键SetLength(FBtns, 4);FBtns[0] := Circle4;FBtns[1] := Circle3;FBtns[2] := Circle2;FBtns[3] := Circle1;{$IFDEF Android}FullScreen := True;{$ENDIF}Label0.Text := Format('屏幕:%d x %d', [Width, Height]);
end;procedure TForm7.FormTouch(Sender: TObject; const Touches: TTouches;const Action: TTouchAction);
varI, J, R: Integer;JoyOk, KeyOk: Boolean;pt: TPoint;
begin//假设屏幕左半边只能用来操作摇杆,按键必须在屏幕右半边//不能使用MouseDown\MouseMove\MouseUp事件+Touch事件的方式//因为第一个触控的点会被当成Mouse事件,也就是说先按按键的话,摇杆就操作不了//所以要使用OnTouch事件进行多点触控//另外OnTouch事件有个特点,有触控时才触发,若只操作摇杆再松开的话则无事件触发//也不能用MouseUp来触发,因为只有第一个点松开时才发触发MouseUp,若一直按差按键//再滑动摇杆,则摇杆松开也没法产生事件使摇杆复位//解决方案:用joyCenter.Tag作为标志,当屏幕左半边有点触发时Tag=1,设定一个Timer//在0.5秒内归0,下一个OnTouch事件中仍有这个点,则再次执行Tag=1JoyOk := False;KeyOk := False;memo1.Lines.BeginUpdate;memo1.Lines.Clear;for I := 0 to length(Touches) - 1 dobeginpt := Touches[I].Location.Round;memo1.Lines.Add(Format('(%.3d, %.3d)', [pt.X, pt.Y]));if pt.X < Width/2 thenbeginif JoyOk thenContinue;JoyOk := True;tmrJoyUp.Enabled := False;if joyCenter.Tag = 1 thenJoyMove(pt.X, pt.Y)elseJoyDown(pt.X, pt.Y);tmrJoyUp.Enabled := True;end//一次最多触发一个按键(摇杆由Mouse事件触发了)else if KeyOk thenContinue;//遍历按键for J := 0 to Length(FBtns) - 1 dobegin//计算按键半么(按键是圆的)R := System.Math.Min(Round(FBtns[J].Width / 2), Round(FBtns[J].Height / 2));//检测触控点是否在按钮区域内if PtInCircle(pt, FBtns[J].Position.Point.Round + Point(R, R), R) thenbeginKeyOk := True;//TODO 执行按键操作FBtns[J].StopPropertyAnimation('fill.color');FBtns[J].Fill.Color := TAlphaColors.Chartreuse;FBtns[J].AnimateColor('fill.color', TAlphaColors.Aliceblue, 0.5);end;end;end;memo1.Lines.EndUpdate;
end;procedure TForm7.JoyDown(X, Y: Single);
beginif X >= Layout1.Width/2 thenExit;if X < joyBorder.Width/2 thenExit;if Y > Layout1.Height-joyBorder.Height/2 thenExit;joyBorder.Position.X := X - joyBorder.Width / 2;joyBorder.Position.Y := Y - joyBorder.Height / 2;joyCenter.Position.X := (joyBorder.Width - joyCenter.Width) / 2;joyCenter.Position.Y := (joyBorder.Height - joyCenter.Height) / 2;if joyCenter.Tag = 0 thenbeginFStartPt.X := X;FStartPt.Y := Y;end;joyCenter.Tag := 1;Label1.Text := Format('原点:(%.0f, %.0f)', [FStartPt.X, FStartPt.Y]);
end;procedure TForm7.JoyMove(X, Y: Single);
varpt: TPointF;I, A: Integer;r, mr, aa: Single;c: Char;
beginpt.X := X;pt.Y := Y;aa := pt.Angle(FStartPt);//弧度//弧度*180/PI => X轴正方向为0度,X轴顺时针为0~180度,逆时针为0~-180角//所以+360度 => X轴顺时针0~360,(A+90)%360 => 调整为正北为0度A := Round(360 + aa*180/3.1415926 + 90) mod 360;r := pt.Distance(FStartPt);//最大半径要减去摇杆球的半么mr := joyBorder.Width/2 - joyCenter.Width/2;if r > mr thenr := mr;//使用极坐标公式 x = r*cos(a), y = r*sin(a)通过角度、半径计算出虚拟摇杆球的位置joyCenter.Position.X := joyBorder.Width/2 + r*Cos(aa) - joyCenter.Width/2;joyCenter.Position.Y := joyBorder.Height/2 + r*Sin(aa) - joyCenter.Height/2;C := CalcDirection(A);Label2.Text := Format('远点:(%.0f, %.0f),方位角:%d°,强度:%.0f%%,方向:%s', [pt.X, pt.Y, A, r/mr*100, c]);
end;procedure TForm7.JoyUp;
begin//摇杆复位joyCenter.Tag := 0;joyCenter.Position.X := (joyBorder.Width - joyCenter.Width) / 2;joyCenter.Position.Y := (joyBorder.Height - joyCenter.Height) / 2;
end;procedure TForm7.tmrJoyUpTimer(Sender: TObject);
begintmrJoyUp.Enabled := False;JoyUp;memo1.Lines.Clear;
end;end.

最终效果是这个样子(HUAWEI P20):

完整工程含APK《下载地址》

Delphi开发Android用虚拟摇杆VirtualJoystic相关推荐

  1. 尝鲜delphi开发android/ios_环境搭建

    Delphi这又老树发新枝了,开始做终端程序开发了,这个东西的准确名字是:RAD Studio XE5,可以使用delphi和c++ builder进行终端开发. 我尽可能讲啰嗦一些,免得回头被人问. ...

  2. 《Delphi XE6 android 编程入门教程》推荐

    近5.6年已经没有看见关于delphi的新技术的书出来了(看来在国内delphi的使用量确实很低了), 高勇同学最近出了一本<Delphi XE6 android 编程入门教程>,上周刚拿 ...

  3. 微信小程序之蓝牙开发虚拟摇杆

    文章用于学习记录 文章目录 前言 一.App Inventor 二.uni-app 三.微信小程序 3.1 示例&应用 3.2 服务值与特征值 3.3 控制指令 3.4 测试 3.5 十六进制 ...

  4. delphi android 蓝牙,Android实例-Delphi开发蓝牙官方实例解析(XE10+小米2+小米5)

    [实例简介] 2.保证无毒 3.简单,方便,实用 4.实例可以自行改用 5.如有非法,本人无法律责任,由改动代码人负责! 6.需要更多本人作品,查找标签"朱建强" 7.请下载,杀毒 ...

  5. 二丶Android如何自定义一个可移动的飞行虚拟摇杆?

    摘要: 上次我们自定义了一个固定位置摇杆,此摇杆无法调整杆量,且位置固定,这次我们就来定义一个可以自由调整杆量和变换位置的虚拟摇杆. 下面就写一下需要实现此虚拟摇杆的步骤: 一丶初始化资源 我们需要美 ...

  6. DELPHI XE Android 开发笔记

    DELPHI XE Android 开发笔记 第一次编译时,设定android SDK: F:\RAD Studio XE6\PlatformSDKs\adt-bundle-windows-x86-2 ...

  7. Delphi 开发跨平台 Android / iOS 程序的多语言

    使用 Delphi 的 FireMonkey 框架,开发跨平台的程序,可以做到一个源码,编译成 Windows, Mac OS, Android, iOS,甚至是 Linux 上面运行的程序. 简单说 ...

  8. Cocos2d-x虚拟摇杆控制精灵上下左右运动----之游戏开发《赵云要格斗》(1)

      这里是Evankaka的博客,欢迎大家前面讨论与交流------      转载请注明出处http://blog.csdn.net/evankaka/article/details/4204350 ...

  9. cocos2dx游戏开发学习——虚拟摇杆(8方向)讲解

    写这篇博客的目的主要是记录一下 虚拟摇杆的实现过程.虚拟摇杆一般分文四方向和八方向,也主要根据项目需求来决定.直接进入主题吧. 先上效果图: 方向的思路分析 看图,说先我们可以将8个方向在坐标系中画出 ...

  10. 开发Android必知的工具

    程序开发有时候非常依赖使用的开发工具,好的完备的开发工具可以让开发人员的工作效率有大幅度的提高.开发Android也是如此,大家可能都离不开Eclipse或Android Studio这些工具,但他们 ...

最新文章

  1. 面向对象设计领域的OCP原则
  2. DDR的前世与今生(一)
  3. Python中使用requests和parsel爬取喜马拉雅电台音频
  4. 剥开比原看代码(十七):比原是如何显示交易的详细信息的?
  5. python输入三个整数、输出最大的数_题目:使用Python编程,输入三个整数x,y,z,请把这三个数由小到大输出...
  6. php点击弹出文字代码,js实现鼠标点击页面弹出自定义文字效果
  7. 第 14 章 程序员常用 10 种算法
  8. 桌面版应用_【Nordic博文分享系列】开发你的第一个NCS(Zephyr)应用程序
  9. log4j.dtd_Eclipse log4j.xml –无法将log4j.dtd验证为XML定义
  10. 安装php项目后图片路径不对,解决织梦CMS栏目绑定二级域名后图片不显示,路径错误办法...
  11. mysql内容_mysql 的基本内容
  12. 20210729 线性增长条件和全局Lipschitz条件的关系
  13. IOS逆向学习之路之iPod touch4 越狱心得
  14. PHP京东商城爬取网页乱码问题解决
  15. 多目标跟踪算法中之图匹配——匈牙利算法和KM算法详解
  16. go语言的类型之间的相互转化和float保留小数时的四舍五入
  17. 元宇宙来了,用好名字好概念赋能中国制造国际营销的初步构想
  18. 《Python程序设计与算法基础教程(第二版)》江红 余青松,第十章课后习题答案
  19. PHPExcel导出Excel基本操作,实现设置字体、合并单元格、加粗等功能
  20. Java子类访问父类私有变量的思考

热门文章

  1. IBM Rhapsody 报错找不到 VC11 目录的解决方法
  2. php 将日期转换时间戳,php怎么将日期转换为时间戳?
  3. idea 谷歌翻译
  4. 创建数据库常用SQL语句
  5. Android系统QFIL刷机流程
  6. “跟着吴恩达老师入门机器学习”学习笔记(二)
  7. hitool java_第三章:使用HiTool下载程序
  8. mysql varbinary blob_MySQL BIT、BINARY、VARBINARY、BLOB(二进制类型)
  9. java ojdbc14 查询数据表,Oracle10g JDBC ojdbc14 DATE类型hibernate查询时分秒问题
  10. linux下编译opendds,求教OpenDDS的交叉编译!