如何通过电脑手柄玩安卓手游?

环境工具

系统archlinux

手柄 北通360, usb

安卓手机 小米11

游戏 流行群侠传

步骤

手机要打开开发者调试, 并通过usb连接测试

不属于此次重点, 可自行搜索, 通过命令行adb
devices测试输出,说明连接成功

安装scrcpy

此工具用来在电脑端远程操作手机, 并且该软件开源, 而且使用还算流畅

sudo pacman -S scrcpy

在手机电脑正常连接的情况下, 直接启动改程序即可

测试键盘控制

通过键盘测试游戏中一些主要操作的对应按键, 后续跟手柄进行绑定

键盘

  1. 前后左右(wsad)

  2. 轻击(h)

  3. 重击(j)

  4. 技能1(u)

  5. 技能2/3(i)

    随从技能也会一起被放出去,真刺激

  6. 闪避(k)

  7. 怒气(p)

  8. 换武器(l)

编写手柄键盘按键映射程序

这里要注意, 按键使用的是keyboard组件, 测试使用pyautogui会出现连点的情况

"""
通过python + adb + scrcpy的方式,实现手柄玩安卓手机游戏

# Released by rdb under the Unlicense (unlicense.org)
# Based on information from:
# https://www.kernel.org/doc/Documentation/input/joystick-api.txt

# 参考
https://blog.csdn.net/Enderman_xiaohei/article/details/88050036?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-9-88050036-blog-109139735.pc_relevant_3mothn_strategy_recovery&spm=1001.2101.3001.4242.6&utm_relevant_index=12

https://blog.csdn.net/dhjabc_1/article/details/117444998

使用:
linux下需要使用管理员身份运行(触发按键需要), 否则运行报错

sudo python xx.py

"""
import pygame
# 键盘
import keyboard
import pyautogui
import time

# 鼠标, 没啥用了
# from pymouse import PyMouseMeta
# m = PyMouseMeta()


class JoyToKey:
    """
    将手柄映射到键盘输入上
    """

    def exec(self, joystick, event):
        # 可能的joystick行为: JOYAXISMOTION JOYBALLMOTION JOYBUTTONDOWN JOYBUTTONUP JOYHATMOTION
        # if event.type == pygame.JOYBUTTONUP:
        #     print("Joystick button released.")
        # ********************键盘按键********************
        if event.type == pygame.KEYDOWN:
            # print(pygame.key.get_pressed())
            pass
            # event.key 表示键盘按键的值,比如k 的值是107, 回车键的值是13,等
            # self.toggle_show_fps(event.key)
        elif event.type == pygame.KEYUP:
            # print(pygame.key.get_pressed())
            pass

        # ********************手柄操作********************
        elif event.type == pygame.JOYBUTTONDOWN:
            # 检测到手柄上的键按下
            # print("Joystick button pressed.")
            if joystick.get_button(7) == 1:
                # 手柄start键 --> 键盘中的回车键。
                keyboard.press('enter')
            if joystick.get_button(0) == 1:
                # 手柄A键 --> 键盘的k键,也就是对应跳(闪)的功能。
                keyboard.press('k')
            if joystick.get_button(2) == 1:
                # 手柄X键 --> 键盘u
                keyboard.press('u')
            if joystick.get_button(1) == 1:
                # 手柄B键 --> 键盘i
                keyboard.press('i')
            if joystick.get_button(3) == 1:
                # 手柄Y键 --> 键盘p
                keyboard.press('p')
            if joystick.get_button(4) == 1:
                keyboard.press('h')
            if joystick.get_button(5) == 1:
                # 手柄又键 --> 键盘l(换武器)
                # keyboard.press('l')
                keyboard.press('j')
        elif event.type == pygame.JOYBUTTONUP:
            # print("Joystick button release.")
            if joystick.get_button(7) == 0:
                # 手柄start键 --> 键盘中的回车键。
                keyboard.release('enter')
            if joystick.get_button(0) == 0:
                # 手柄A键 --> 键盘的k键,也就是对应跳(闪)的功能。
                keyboard.release('k')
            if joystick.get_button(2) == 0:
                # 手柄X键 --> 键盘u
                keyboard.release('u')
            if joystick.get_button(1) == 0:
                # 手柄B键 --> 键盘i
                keyboard.release('i')
            if joystick.get_button(3) == 0:
                # 手柄Y键 --> 键盘p
                keyboard.release('p')
            if joystick.get_button(4) == 0:
                keyboard.release('h')
            if joystick.get_button(5) == 0:
                # 手柄又键 --> 键盘l(换武器)
                # keyboard.release('l')
                # 攻击键容易连点
                keyboard.release('j')

        # 攻击键
        elif event.type == pygame.JOYAXISMOTION:
            # print("Joystick axis pressed.")
            if joystick.get_axis(2) > 0:
                # 手柄左x --> 键盘h
                # 注意: 这里需要让手柄, pygame来控制按压和释放, 如果用pyautogui, keydown每次会触发很多按压,(连点)
                # 还是用这个保险
                keyboard.press('h')
            if joystick.get_axis(5) > 0:
                # 手柄右x --> 键盘j
                keyboard.press('j')
            if round(joystick.get_axis(1)) < 0:
                # 前
                keyboard.press('w')
            if round(joystick.get_axis(1)) > 0:
                # 后
                keyboard.press('s')
            if round(joystick.get_axis(0)) < 0:
                # 左
                keyboard.press('a')
            if round(joystick.get_axis(0)) > 0:
                # 右
                keyboard.press('d')

            # 释放
            # print("Joystick axis released.")
            # print("s", joystick.get_axis(1))
            if joystick.get_axis(2) < 0:
                # 手柄左x --> 键盘h
                keyboard.release('h')
            if joystick.get_axis(5) < 0:
                # 手柄右x --> 键盘j
                keyboard.release('j')
            if round(joystick.get_axis(0)) == 0:
                # 释放左右
                keyboard.release('a')
                keyboard.release('d')
            if round(joystick.get_axis(1)) == 0:
                # 释放前后
                keyboard.release('w')
                keyboard.release('s')

            # 摇杆转向
            # 当前鼠标光标位置, 固定位置, 不单独获取了
            # x, y = pygame.mouse.get_pos()
            x, y = 482, 305
            pyautogui.moveTo(x, y)
            # 1. 设置当前鼠标光标位置, 放中间或偏右
            # 2. 根据摇杆变化, 利用pyautogui进行拖拽
            # 3, 4为遥感的横/纵向变化
            if joystick.get_axis(3) != 0 or joystick.get_axis(4) != 0:
                # 将当前光标位置的东西向下移动100个像素点,在拖动的过程中按住鼠标左键。
                # >> > pyautogui.drag(100, 0, button='left')
                # 一样的问题, 连点
                # pyautogui.drag(int(round(joystick.get_axis(4))), int(round(joystick.get_axis(3))), button='left')
                print(y+int(round(joystick.get_axis(4))), x+int(round(joystick.get_axis(3))))

                # 使用pymouse实现上述payautogui的拖拽
                # x, y = pygame.mouse.get_pos()
                # m.press(x, y)
                # x1 = x + joystick.get_axis(3)
                # y1 = y + joystick.get_axis(4)
                # m.move(x1, y1)
                # m.release(x1, y1)


if __name__ == '__main__':
    pygame.init()

    # 初始化joystick
    pygame.joystick.init()

    # 得到joystick的数量
    joystick_count = pygame.joystick.get_count()
    print("Number of joysticks: {}".format(joystick_count))

    # 之考虑一个手柄
    joystick = pygame.joystick.Joystick(0)
    # 按键映射对象
    joyToKey = JoyToKey()

    # -------- 程序主循环 -----------
    # 保持循环直到用户点击关闭按钮
    done = False
    while not done:
        # 事件处理的步骤
        # 手柄事件触发
        for event in pygame.event.get():
            # 如果用户触发了关闭事件
            if event.type == pygame.QUIT:
                # 设置我们做了这件事的标志,所以我们就可以退出循环了
                done = True
            else:
                joyToKey.exec(joystick, event)

    # 关闭窗口并退出.
    pygame.quit()

程序运行

程序使用的是keyboard组件, 在linux下运行时需要sudo

sudo python 北通360-流行群侠传手游.py

此时在scrcpy界面, 通过手柄即可控制手机进行游戏操作, 并且流畅性也还可以

说明

只是为了提高下游戏的趣味性, 其它操作可自行发掘

摇杆目前无法适应

摇杆转向跟鼠标适配未实现, 事件刷新太快, 暂时未想到好方法进行转换

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容