feat: add smooth delay for KeySteeringWheel

This commit is contained in:
AkiChase 2025-03-19 11:03:43 +08:00
parent 615e08cb7e
commit 06855046e6
15 changed files with 191 additions and 70 deletions

View File

@ -495,12 +495,13 @@ function closeWS() {
</NSpace>
</NFlex>
<NDataTable
max-height="120"
:max-height="150"
:columns="tableCols"
:data="availableDevice"
:row-props="tableRowProps"
:pagination="false"
:bordered="false"
style="margin-bottom: 32px"
/>
<NDropdown
placement="bottom-start"

View File

@ -21,6 +21,7 @@ import {
KeySwipe as KeyMappingKeySwipe,
KeySight as KeyMappingKeySight,
KeyFire as KeyMappingKeyFire,
KeyCancelSkill,
} from "../../tools/keyMappingConfig";
import { useGlobalStore } from "../../store/global";
import { DropdownOption, NDropdown, useDialog, useMessage } from "naive-ui";
@ -28,6 +29,7 @@ import { onBeforeRouteLeave } from "vue-router";
import { useKeyboardStore } from "../../store/keyboard";
import { useI18n } from "vue-i18n";
import { useRotation } from "../../tools/hooks";
import { asType } from "../../tools/tools";
const { t } = useI18n();
const store = useGlobalStore();
@ -97,35 +99,42 @@ function onAddButtonSelect(
posX: addButtonPos.value.x - 70,
posY: addButtonPos.value.y - 30,
pointerId: 2, // default skill and fire pointerId
};
} as any;
if (type === "Tap") {
asType<KeyTap>(keyMapping);
keyMapping.pointerId = 3;
(keyMapping as KeyTap).time = 80;
keyMapping.time = 80;
} else if (type === "Swipe") {
asType<KeyMappingKeySwipe>(keyMapping);
keyMapping.pointerId = 3;
(keyMapping as KeyMappingKeySwipe).pos = [
{ x: keyMapping.posX, y: keyMapping.posY },
];
(keyMapping as KeyMappingKeySwipe).intervalBetweenPos = 100;
keyMapping.pos = [{ x: keyMapping.posX, y: keyMapping.posY }];
keyMapping.intervalBetweenPos = 100;
} else if (type === "SteeringWheel") {
asType<KeyMappingSteeringWheel>(keyMapping);
keyMapping.pointerId = 1;
(keyMapping as unknown as KeyMappingSteeringWheel).key = {
keyMapping.key = {
left: "NONE1",
right: "NONE2",
up: "NONE3",
down: "NONE4",
};
(keyMapping as unknown as KeyMappingSteeringWheel).offset = 100;
keyMapping.offset = 100;
keyMapping.smoothDelay = 0;
keyMapping.delayStepLength = 25;
} else if (type === "DirectionalSkill") {
(keyMapping as unknown as KeyDirectionalSkill).range = 30;
asType<KeyDirectionalSkill>(keyMapping);
keyMapping.range = 30;
} else if (type === "CancelSkill") {
asType<KeyCancelSkill>(keyMapping);
keyMapping.note = t("pages.KeyBoard.addButton.CancelSkill");
} else if (type === "Observation") {
asType<KeyMappingObservation>(keyMapping);
keyMapping.pointerId = 4;
(keyMapping as unknown as KeyMappingObservation).scale = 0.6;
keyMapping.scale = 0.6;
} else if (type === "Macro") {
delete (keyMapping as any).pointerId;
(keyMapping as unknown as KeyMacro).macro = {
delete keyMapping.pointerId;
asType<KeyMacro>(keyMapping);
keyMapping.macro = {
down: null,
loop: null,
up: null,
@ -137,9 +146,10 @@ function onAddButtonSelect(
return;
}
}
asType<KeyMappingKeySight>(keyMapping);
keyMapping.pointerId = 0;
(keyMapping as unknown as KeyMappingKeySight).scaleX = 0.5;
(keyMapping as unknown as KeyMappingKeySight).scaleY = 0.5;
keyMapping.scaleX = 0.5;
keyMapping.scaleY = 0.5;
} else if (type === "Fire") {
for (const mapping of store.editKeyMappingList) {
if (mapping.type === "Fire") {
@ -147,10 +157,11 @@ function onAddButtonSelect(
return;
}
}
delete (keyMapping as any).key;
(keyMapping as unknown as KeyMappingKeyFire).scaleX = 0.5;
(keyMapping as unknown as KeyMappingKeyFire).scaleY = 0.5;
(keyMapping as unknown as KeyMappingKeyFire).drag = false;
delete keyMapping.key;
asType<KeyMappingKeyFire>(keyMapping);
keyMapping.scaleX = 0.5;
keyMapping.scaleY = 0.5;
keyMapping.drag = false;
} else return;
keyboardStore.edited = true;
store.editKeyMappingList.push(keyMapping as KeyMapping);

View File

@ -14,9 +14,14 @@ import {
NInputNumber,
} from "naive-ui";
import { CloseCircle, Settings } from "@vicons/ionicons5";
import { KeyCommon, KeyMacro, KeyMacroList } from "../../tools/keyMappingConfig";
import {
KeyCommon,
KeyMacro,
KeyMacroList,
} from "../../tools/keyMappingConfig";
import { useKeyboardStore } from "../../store/keyboard";
import { useI18n } from "vue-i18n";
import { configKeyCommon } from "./config";
const props = defineProps<{
index: number;
@ -154,8 +159,8 @@ function showSetting() {
const keyboardElement = document.getElementById(
"keyboardElement"
) as HTMLElement;
const maxWidth = keyboardElement.clientWidth - 150;
const maxHeight = keyboardElement.clientHeight - 300;
const maxWidth = keyboardElement.clientWidth - configKeyCommon.settingW;
const maxHeight = keyboardElement.clientHeight - configKeyCommon.settingH;
settingPosX.value = Math.min(keyMapping.value.posX + 25, maxWidth);
settingPosY.value = Math.min(keyMapping.value.posY - 25, maxHeight);
@ -206,6 +211,8 @@ function showSetting() {
:style="{
left: `${settingPosX}px`,
top: `${settingPosY}px`,
width: `${configKeyCommon.settingW}px`,
height: `${configKeyCommon.settingH}px`,
}"
>
<NH4 prefix="bar">{{
@ -305,8 +312,6 @@ function showSetting() {
flex-direction: column;
padding: 10px 20px;
box-sizing: border-box;
width: 150px;
height: 300px;
border-radius: 5px;
border: 2px solid var(--light-color);
background-color: var(--bg-color);

View File

@ -13,6 +13,7 @@ import {
import { CloseCircle, Settings } from "@vicons/ionicons5";
import { KeyFire } from "../../tools/keyMappingConfig";
import { useKeyboardStore } from "../../store/keyboard";
import { configKeyFire } from "./config";
const props = defineProps<{
index: number;
@ -77,8 +78,8 @@ function showSetting() {
const keyboardElement = document.getElementById(
"keyboardElement"
) as HTMLElement;
const maxWidth = keyboardElement.clientWidth - 200;
const maxHeight = keyboardElement.clientHeight - 430;
const maxWidth = keyboardElement.clientWidth - configKeyFire.settingW;
const maxHeight = keyboardElement.clientHeight - configKeyFire.settingH;
settingPosX.value = Math.min(keyMapping.value.posX + 40, maxWidth);
settingPosY.value = Math.min(keyMapping.value.posY - 40, maxHeight);
@ -144,6 +145,8 @@ function changeDragSetting() {
:style="{
left: `${settingPosX}px`,
top: `${settingPosY}px`,
width: `${configKeyFire.settingW}px`,
height: `${configKeyFire.settingH}px`,
}"
>
<NH4 prefix="bar">{{ $t("pages.KeyBoard.KeyFire.fire") }}</NH4>
@ -194,8 +197,6 @@ function changeDragSetting() {
flex-direction: column;
padding: 10px 20px;
box-sizing: border-box;
width: 200px;
height: 430px;
border-radius: 5px;
border: 2px solid var(--light-color);
background-color: var(--bg-color);

View File

@ -5,6 +5,7 @@ import { NIcon, NButton, NFormItem, NInput, NH4, NInputNumber } from "naive-ui";
import { Eye, CloseCircle, Settings } from "@vicons/ionicons5";
import { KeyObservation } from "../../tools/keyMappingConfig";
import { useKeyboardStore } from "../../store/keyboard";
import { configKeyObservation } from "./config";
const props = defineProps<{
index: number;
@ -69,8 +70,8 @@ function showSetting() {
const keyboardElement = document.getElementById(
"keyboardElement"
) as HTMLElement;
const maxWidth = keyboardElement.clientWidth - 150;
const maxHeight = keyboardElement.clientHeight - 300;
const maxWidth = keyboardElement.clientWidth - configKeyObservation.settingW;
const maxHeight = keyboardElement.clientHeight - configKeyObservation.settingH;
settingPosX.value = Math.min(keyMapping.value.posX + 40, maxWidth);
settingPosY.value = Math.min(keyMapping.value.posY - 40, maxHeight);
@ -122,6 +123,8 @@ function showSetting() {
:style="{
left: `${settingPosX}px`,
top: `${settingPosY}px`,
width: `${configKeyObservation.settingW}px`,
height: `${configKeyObservation.settingH}px`,
}"
>
<NH4 prefix="bar">{{ $t("pages.KeyBoard.Observation.observation") }}</NH4>
@ -158,8 +161,6 @@ function showSetting() {
flex-direction: column;
padding: 10px 20px;
box-sizing: border-box;
width: 150px;
height: 300px;
border-radius: 5px;
border: 2px solid var(--light-color);
background-color: var(--bg-color);

View File

@ -5,6 +5,7 @@ import { NIcon, NButton, NFormItem, NInput, NH4, NInputNumber } from "naive-ui";
import { CloseCircle, Settings } from "@vicons/ionicons5";
import { KeySight } from "../../tools/keyMappingConfig";
import { useKeyboardStore } from "../../store/keyboard";
import { configKeySight } from "./config";
const props = defineProps<{
index: number;
@ -69,8 +70,8 @@ function showSetting() {
const keyboardElement = document.getElementById(
"keyboardElement"
) as HTMLElement;
const maxWidth = keyboardElement.clientWidth - 200;
const maxHeight = keyboardElement.clientHeight - 380;
const maxWidth = keyboardElement.clientWidth - configKeySight.settingW;
const maxHeight = keyboardElement.clientHeight - configKeySight.settingH;
settingPosX.value = Math.min(keyMapping.value.posX + 40, maxWidth);
settingPosY.value = Math.min(keyMapping.value.posY - 40, maxHeight);
@ -132,6 +133,8 @@ function showSetting() {
:style="{
left: `${settingPosX}px`,
top: `${settingPosY}px`,
width: `${configKeySight.settingW}px`,
height: `${configKeySight.settingH}px`,
}"
>
<NH4 prefix="bar">{{ $t('pages.KeyBoard.KeySight.sight') }}</NH4>
@ -176,8 +179,6 @@ function showSetting() {
flex-direction: column;
padding: 10px 20px;
box-sizing: border-box;
width: 200px;
height: 380px;
border-radius: 5px;
border: 2px solid var(--light-color);
background-color: var(--bg-color);

View File

@ -18,6 +18,7 @@ import {
KeyTriggerWhenPressedSkill,
} from "../../tools/keyMappingConfig";
import { useKeyboardStore } from "../../store/keyboard";
import { configKeySkill } from "./config";
const props = defineProps<{
index: number;
@ -184,8 +185,8 @@ function showSetting() {
"keyboardElement"
) as HTMLElement;
// setting
const maxWidth = keyboardElement.clientWidth - 220;
const maxHeight = keyboardElement.clientHeight - 430;
const maxWidth = keyboardElement.clientWidth - configKeySkill.settingW;
const maxHeight = keyboardElement.clientHeight - configKeySkill.settingH;
settingPosX.value = Math.min(keyMapping.value.posX + 40, maxWidth);
settingPosY.value = Math.min(keyMapping.value.posY - 40, maxHeight);
updateRangeIndicator(keyboardElement);
@ -258,6 +259,8 @@ function updateRangeIndicator(element?: HTMLElement) {
:style="{
left: `${settingPosX}px`,
top: `${settingPosY}px`,
width: `${configKeySkill.settingW}px`,
height: `${configKeySkill.settingH}px`,
}"
>
<NH4 prefix="bar">{{ $t("pages.KeyBoard.KeySkill.skill") }}</NH4>
@ -373,8 +376,6 @@ function updateRangeIndicator(element?: HTMLElement) {
flex-direction: column;
padding: 10px 20px;
box-sizing: border-box;
width: 220px;
height: 430px;
border-radius: 5px;
border: 2px solid var(--light-color);
background-color: var(--bg-color);

View File

@ -5,6 +5,7 @@ import { KeySteeringWheel } from "../../tools/keyMappingConfig";
import { NButton, NFormItem, NH4, NIcon, NInput, NInputNumber } from "naive-ui";
import { CloseCircle, Move, Settings } from "@vicons/ionicons5";
import { useKeyboardStore } from "../../store/keyboard";
import { configKeySteeringWheel } from "./config";
const props = defineProps<{
index: number;
@ -79,8 +80,8 @@ function showSetting() {
const keyboardElement = document.getElementById(
"keyboardElement"
) as HTMLElement;
const maxWidth = keyboardElement.clientWidth - 179;
const maxHeight = keyboardElement.clientHeight - 300;
const maxWidth = keyboardElement.clientWidth - configKeySteeringWheel.settingW;
const maxHeight = keyboardElement.clientHeight - configKeySteeringWheel.settingH;
settingPosX.value = Math.min(
keyMapping.value.posX + offset.value + 10,
@ -182,6 +183,8 @@ function showSetting() {
:style="{
left: `${settingPosX}px`,
top: `${settingPosY}px`,
width: `${configKeySteeringWheel.settingW}px`,
height: `${configKeySteeringWheel.settingH}px`,
}"
>
<NH4 prefix="bar">{{
@ -194,6 +197,24 @@ function showSetting() {
@update:value="keyboardStore.edited = true"
/>
</NFormItem>
<NFormItem :label="$t('pages.KeyBoard.SteeringWheel.smoothDelay')">
<NInputNumber
v-model:value="keyMapping.smoothDelay"
:min="0"
:placeholder="$t('pages.KeyBoard.SteeringWheel.smoothDelayPlaceholder')"
@update:value="keyboardStore.edited = true"
/>
</NFormItem>
<NFormItem :label="$t('pages.KeyBoard.SteeringWheel.delayStepLength')">
<NInputNumber
v-model:value="keyMapping.delayStepLength"
:min="10"
:placeholder="
$t('pages.KeyBoard.SteeringWheel.delayStepLengthPlaceholder')
"
@update:value="keyboardStore.edited = true"
/>
</NFormItem>
<NFormItem :label="$t('pages.KeyBoard.setting.pointerID')">
<NInputNumber
v-model:value="keyMapping.pointerId"
@ -219,8 +240,6 @@ function showSetting() {
flex-direction: column;
padding: 10px 20px;
box-sizing: border-box;
width: 170px;
height: 300px;
border-radius: 5px;
border: 2px solid var(--light-color);
background-color: var(--bg-color);

View File

@ -14,6 +14,7 @@ import { Analytics, CloseCircle, Settings } from "@vicons/ionicons5";
import { useKeyboardStore } from "../../store/keyboard";
import { KeySwipe } from "../../tools/keyMappingConfig";
import { useI18n } from "vue-i18n";
import { configKeySwipe } from "./config";
const props = defineProps<{
index: number;
@ -90,8 +91,8 @@ function showSetting() {
const keyboardElement = document.getElementById(
"keyboardElement"
) as HTMLElement;
const maxWidth = keyboardElement.clientWidth - 150;
const maxHeight = keyboardElement.clientHeight - 380;
const maxWidth = keyboardElement.clientWidth - configKeySwipe.settingW;
const maxHeight = keyboardElement.clientHeight - configKeySwipe.settingH;
settingPosX.value = Math.min(keyMapping.value.posX + 40, maxWidth);
settingPosY.value = Math.min(keyMapping.value.posY - 40, maxHeight);
@ -190,6 +191,8 @@ function swipeTrackClickHandler(event: MouseEvent) {
:style="{
left: `${settingPosX}px`,
top: `${settingPosY}px`,
width: `${configKeySwipe.settingW}px`,
height: `${configKeySwipe.settingH}px`,
}"
>
<NH4 prefix="bar">{{ $t("pages.KeyBoard.Swipe.swipe") }}</NH4>
@ -293,8 +296,6 @@ function swipeTrackClickHandler(event: MouseEvent) {
flex-direction: column;
padding: 10px 20px;
box-sizing: border-box;
width: 150px;
height: 380px;
border-radius: 5px;
border: 2px solid var(--light-color);
background-color: var(--bg-color);

View File

@ -0,0 +1,39 @@
export const configKeyCommon = {
settingW: 150,
settingH: 300,
};
export const configKeyFire = {
settingW: 200,
settingH: 430,
};
export const configKeyMacro = {
settingW: 200,
settingH: 300,
};
export const configKeyObservation = {
settingW: 150,
settingH: 300,
};
export const configKeySight = {
settingW: 200,
settingH: 380,
};
export const configKeySkill = {
settingW: 220,
settingH: 430,
};
export const configKeySteeringWheel = {
settingW: 170,
settingH: 470,
};
export const configKeySwipe = {
settingW: 150,
settingH: 380,
};

View File

@ -252,7 +252,11 @@
},
"SteeringWheel": {
"steeringWheel": "SteeringWheel",
"offset": "Offset"
"offset": "Offset",
"smoothDelay": "Smooth Delay",
"delayStepLength": "Delay StepLength",
"smoothDelayPlaceholder": "Set 0 to disable smooth delay",
"delayStepLengthPlaceholder": "Smooth delay step length"
},
"KeySight": {
"sight": "Front sight",

View File

@ -252,7 +252,11 @@
},
"SteeringWheel": {
"steeringWheel": "键盘行走",
"offset": "偏移"
"offset": "偏移",
"smoothDelay": "平滑延迟",
"delayStepLength": "延迟步长",
"smoothDelayPlaceholder": "0则禁用平滑延迟",
"delayStepLengthPlaceholder": "平滑延迟的步长"
},
"KeySight": {
"sight": "准星",

View File

@ -32,8 +32,12 @@ import {
AndroidMetastate,
} from "../frontcommand/android";
import { UIEventsCode } from "../frontcommand/UIEventsCode";
import { sendInjectKeycode, sendSetClipboard } from "../frontcommand/controlMsg";
import {
sendInjectKeycode,
sendSetClipboard,
} from "../frontcommand/controlMsg";
import { NonReactiveStore } from "../store/noneReactiveStore";
import { asType } from "./tools";
function clientxToPosx(clientx: number) {
return clientx < 70
@ -515,19 +519,20 @@ function addDirectionalSkillShortcuts(
// add shortcuts for steering wheel
function addSteeringWheelKeyboardShortcuts(
key: wheelKey,
key: WheelKey,
relativeSize: { w: number; h: number },
// pos relative to the mask
posX: number,
posY: number,
offset: number,
pointerId: number
pointerId: number,
delay?: { smoothDelay: number; delayStepLength: number }
) {
let loopFlag = false;
let curPosX = 0;
let curPosY = 0;
posX = Math.round((posX / relativeSize.w) * store.screenSizeW);
posY = Math.round((posY / relativeSize.h) * store.screenSizeH);
let loopFlag = false;
let curPosX = posX;
let curPosY = posY;
// calculate the end coordinates of the eight directions of the direction wheel
let offsetHalf = Math.round(offset / 1.414);
@ -570,8 +575,29 @@ function addSteeringWheelKeyboardShortcuts(
let newPos = calculatedPosList[newPosIndex];
if (newPos.x === curPosX && newPos.y === curPosY) return;
curPosX = newPos.x;
curPosY = newPos.y;
// TODO add config in KeySteeringWheel.vue
if (delay) {
const { smoothDelay, delayStepLength } = delay;
let movePosX = curPosX;
let movePosY = curPosY;
curPosX = newPos.x;
curPosY = newPos.y;
const delayTimes = Math.floor(smoothDelay / delayStepLength);
const deltaX = Math.floor((newPos.x - movePosX) / delayTimes);
const deltaY = Math.floor((newPos.y - movePosY) / delayTimes);
for (let i = 0; i < delayTimes; i++) {
movePosX += deltaX;
movePosY += deltaY;
await touchX(TouchAction.Move, pointerId, movePosX, movePosY);
await sleep(delayStepLength);
}
} else {
curPosX = newPos.x;
curPosY = newPos.y;
}
// move to the direction
await touchX(TouchAction.Move, pointerId, newPos.x, newPos.y);
};
@ -584,7 +610,7 @@ function addSteeringWheelKeyboardShortcuts(
downKeyMap.get(key.down) === false
) {
// all wheel keys has been released
for (const k of ["left", "right", "up", "down"]) {
for (const k of ["left", "right", "up", "down"] as const) {
// only delete the valid key
loopDownKeyCBMap.delete(key[k]);
upKeyCBMap.delete(key[k]);
@ -592,13 +618,13 @@ function addSteeringWheelKeyboardShortcuts(
// touch up
await touchX(TouchAction.Up, pointerId, curPosX, curPosY);
// recover the status
curPosX = 0;
curPosY = 0;
curPosX = posX;
curPosY = posY;
loopFlag = false;
}
};
for (const k of ["left", "right", "up", "down"]) {
for (const k of ["left", "right", "up", "down"] as const) {
addShortcut(
key[k],
async () => {
@ -618,13 +644,12 @@ function addSteeringWheelKeyboardShortcuts(
}
}
interface wheelKey {
type WheelKey = {
left: string;
right: string;
up: string;
down: string;
[key: string]: string;
}
};
// add baisc click shortcuts
function addClickShortcuts(key: string, pointerId: number) {
@ -1359,9 +1384,6 @@ function execLoopCB() {
if (loopFlag) requestAnimationFrame(execLoopCB);
}
// change ts type
function asType<T>(_val: any): asserts _val is T {}
function applyKeyMappingConfigShortcuts(
keyMappingConfig: KeyMappingConfig
): boolean {
@ -1377,7 +1399,13 @@ function applyKeyMappingConfigShortcuts(
item.posX,
item.posY,
item.offset,
item.pointerId
item.pointerId,
item.smoothDelay === 0
? undefined
: {
smoothDelay: item.smoothDelay,
delayStepLength: item.delayStepLength,
}
);
break;
case "DirectionalSkill":
@ -1513,6 +1541,7 @@ function applyKeyMappingConfigShortcuts(
}
}
// Wrapping of the touch action
async function touchX(
action: TouchAction,
pointerId: number,
@ -1520,7 +1549,7 @@ async function touchX(
posY: number,
time?: number
) {
await touch({
return touch({
action,
pointerId,
screen: {

View File

@ -15,6 +15,8 @@ export interface KeySteeringWheel extends KeyBase {
down: string;
};
offset: number;
smoothDelay: number;
delayStepLength: number;
}
export interface KeyDirectionalSkill extends KeyBase {

View File

@ -41,3 +41,5 @@ export async function cleanAfterimage() {
export function openWebsite(url: string) {
shellOpen(url);
}
export function asType<T>(_val: any): asserts _val is T {}