日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Delphi开发Android用虚拟摇杆VirtualJoystic

發(fā)布時(shí)間:2023/12/14 Android 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Delphi开发Android用虚拟摇杆VirtualJoystic 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Delphi11新鮮出爐后一直沒有去試用,最近幾天有空下了個(gè)Lite版來(lái)玩,發(fā)現(xiàn)編譯速度快了很多,編譯后的尺寸也變小了一些,前些時(shí)候在github上看到一個(gè)Delphi無(wú)引擎版的小游戲,決定調(diào)試一下,目前Windows下運(yùn)行正常,像這個(gè)樣子:

安卓下暫時(shí)沒有運(yùn)行起來(lái),界面是這個(gè)樣子:

?使用的MouseDown和MouseUp事件驅(qū)動(dòng),也就是說(shuō)按左、右的時(shí)候,沒法跳,所以想著改造一下,整個(gè)虛擬搖桿來(lái)操控,于是有了這一篇博文(順便吐槽一下Delphi11有時(shí)編輯器會(huì)完全消失,歡迎頁(yè)面也一起消失了)。

一、首先順便弄一下,做個(gè)搖桿的樣子,和按鍵的樣子:

二、搖桿在屏幕左半邊,按鍵在屏幕右半邊,也就是說(shuō)點(diǎn)擊屏幕左半邊任意一點(diǎn)就是?搖桿的中心位置,然后滑動(dòng)觸控點(diǎn),一通計(jì)算得到方向,同時(shí)兼顧右邊的按鍵觸控即可。

單元代碼如下(網(wǎng)上其他的方法太復(fù)雜難懂,下面主要就3個(gè)方法2個(gè)事件):

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//計(jì)算八方向下當(dāng)前搖桿的方向Result := A2C8[0];for I := 1 to 7 doif (A >= A2D8[I-1]) and (A < A2D8[I]) thenbeginResult := A2C8[I];exit;end;endelsebegin//計(jì)算四方向下當(dāng)前搖桿的方向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//假設(shè)屏幕左半邊只能用來(lái)操作搖桿,按鍵必須在屏幕右半邊//不能使用MouseDown\MouseMove\MouseUp事件+Touch事件的方式//因?yàn)榈谝粋€(gè)觸控的點(diǎn)會(huì)被當(dāng)成Mouse事件,也就是說(shuō)先按按鍵的話,搖桿就操作不了//所以要使用OnTouch事件進(jìn)行多點(diǎn)觸控//另外OnTouch事件有個(gè)特點(diǎn),有觸控時(shí)才觸發(fā),若只操作搖桿再松開的話則無(wú)事件觸發(fā)//也不能用MouseUp來(lái)觸發(fā),因?yàn)橹挥械谝粋€(gè)點(diǎn)松開時(shí)才發(fā)觸發(fā)MouseUp,若一直按差按鍵//再滑動(dòng)搖桿,則搖桿松開也沒法產(chǎn)生事件使搖桿復(fù)位//解決方案:用joyCenter.Tag作為標(biāo)志,當(dāng)屏幕左半邊有點(diǎn)觸發(fā)時(shí)Tag=1,設(shè)定一個(gè)Timer//在0.5秒內(nèi)歸0,下一個(gè)OnTouch事件中仍有這個(gè)點(diǎn),則再次執(zhí)行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//一次最多觸發(fā)一個(gè)按鍵(搖桿由Mouse事件觸發(fā)了)else if KeyOk thenContinue;//遍歷按鍵for J := 0 to Length(FBtns) - 1 dobegin//計(jì)算按鍵半么(按鍵是圓的)R := System.Math.Min(Round(FBtns[J].Width / 2), Round(FBtns[J].Height / 2));//檢測(cè)觸控點(diǎn)是否在按鈕區(qū)域內(nèi)if PtInCircle(pt, FBtns[J].Position.Point.Round + Point(R, R), R) thenbeginKeyOk := True;//TODO 執(zhí)行按鍵操作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('原點(diǎn):(%.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軸正方向?yàn)?度,X軸順時(shí)針為0~180度,逆時(shí)針為0~-180角//所以+360度 => X軸順時(shí)針0~360,(A+90)%360 => 調(diào)整為正北為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;//使用極坐標(biāo)公式 x = r*cos(a), y = r*sin(a)通過角度、半徑計(jì)算出虛擬搖桿球的位置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('遠(yuǎn)點(diǎn):(%.0f, %.0f),方位角:%d°,強(qiáng)度:%.0f%%,方向:%s', [pt.X, pt.Y, A, r/mr*100, c]); end;procedure TForm7.JoyUp; begin//搖桿復(fù)位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.

最終效果是這個(gè)樣子(HUAWEI P20):

?完整工程含APK《下載地址》

總結(jié)

以上是生活随笔為你收集整理的Delphi开发Android用虚拟摇杆VirtualJoystic的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。