1

我正在 SDL 中构建一个简单的游戏。我经历了无数的教程,我显然错过了一些东西,因为它仍然完全忽略了我的操纵杆

在我的构造函数中

SDL_JoystickEventState(SDL_ENABLE);
joystick = SDL_JoystickOpen(0);

在我的更新中,我正在调用一个测试来检查我是否真的初始化了操纵杆

if (SDL_NumJoysticks() <= 0)
{
done = true;
}

这也是我的播放器更新

void World::playerMovement()
{
    SDL_Event event;

    while (SDL_PollEvent (&event))
    {
        switch (event.type)
        {
            case SDL_QUIT:
                done = true;
                break;
            case SDL_JOYAXISMOTION:
                if ( ( event.jaxis.value < -3200 ) || (event.jaxis.value > 3200 ) )
                {
                    test = true;
                }
                    break;
        }
   }
}

测试只是一个布尔值,一旦为真将意味着我的敌人开始产卵。我还检查了 main

if (SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) < 0)
{
    fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
    done = true;
}

当我运行游戏时,它会正常加载,但无论我移动操纵杆多少,它都不会将 test 设置为 true。

我还尝试在 while poll 事件循环中使用以下内容。

if (event.type == SDL_JOYAXISMOTION)
{
if(SDL_JoystickGetAxis(joystick, 1) > 0)
{
test = true;
}
}

有什么想法是我错过的吗?

4

7 回答 7

2

我认为 emartel 拥有确保 SDL_joystick 正常工作的最佳答案。

World::playerMovement() 什么时候发生?您的程序的整体流程很难从这些片段中确定。

我很高兴与您分享我用于处理操纵杆的代码,该代码跟踪:多个操纵杆、已删除死区的轴缩放 [-1,1] 以及按住按钮。

以下是如何将其用作主循环的一部分的片段:

// FIXME: SDL needs to be initialized before we get here.

JoystickManager Joy;
Joy.Initialize();
double deadzone = 0.02;

// Main loop.
bool done = false;
while( ! done )
{
    // Keep the list of joysticks up-to-date.
    Joy.FindJoysticks();

    // Handle all user input.
    SDL_Event event;
    while( SDL_PollEvent( &event ) )
    {
        // Let the JoystickManager track events relevant to it.
        Joy.TrackEvent( &event );

        // FIXME: Handle single-press events here (next target, etc).
        // Don't handle button-held-down events like firing (see below).

        if( event.type == SDL_QUIT )
            done = true;
    }

    // Read joystick 0 analog axes.
    double roll = Joy.Axis( 0, 0, deadzone );
    double pitch = Joy.Axis( 0, 1, deadzone );
    double yaw = Joy.Axis( 0, 3, deadzone );
    double throttle = Joy.AxisScaled( 0, 2, 1., 0., 0., deadzone );

    // Read joystick 0 buttons held down.
    bool firing = Joy.ButtonDown( 0, 0 );

    // FIXME: Update game objects and draw graphics.
}
于 2013-02-01T22:11:00.803 回答
2

我在 SDL2 中发现了一个奇怪的行为:

如果没有事件放入队列,请尝试在 SDL_Init 调用之前添加以下内容:

SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS,"1");
于 2016-01-27T22:04:10.843 回答
1

您确定joystick指向有效的操纵杆吗?

您声明您正在使用它Constructor...在您初始化 SDL 之前是否碰巧调用了该构造函数SDL_INIT_JOYSTICK?如果您的播放器是全局变量,则可能会发生这种情况。

确保按顺序:

  • 通过将其添加到您的SDL_Initwith| SDL_INIT_JOYSTICK或调用来初始化 Joystick 子系统SDL_InitSubSystem(SDL_INIT_JOYSTICK);
  • 查看SDL_NumJoysticks() > 0
  • 获取操纵杆 0:joystick = SDL_JoystickOpen(0);
  • 启用事件:SDL_JoystickEventState(SDL_ENABLE);
  • 处理您的事件SDL_PollEvent
  • 在程序结束时,关闭游戏杆: SDL_JoystickClose(joystick);

此外,确保在 Windows 中正确检测到操纵杆并正确报告其输入。

于 2013-01-27T18:29:12.147 回答
0

看起来您的 SDL 初始化不正确。

代替

SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK)

SDL_Init(SDL_INIT_EVERYTHING)
于 2013-04-12T12:52:04.537 回答
0

如果您调用SDL_NumJoysticks以获取连接的控制器数量,然后调用SDL_JoystickOpen它在您的游戏循环之前返回一个操纵杆标识符,那么您将收到SDL_JOYAXISMOTION事件。

例如

int num_joy;
num_joy = SDL_NumJoysticks();
printf("%d joysticks found\n", num_joy);
for(int i = 0; i < num_joy; i++)
{
    SDL_Joystick *joystick = SDL_JoystickOpen(i);
    printf("Joystick name: %s\n", SDL_JoystickName(joystick));
}

SDL_Event event;
bool quit = false;
// Game loop
while(!quit)
{
    // event loop
    while(SDL_PollEvent(&event))
    {
        if (event.type == SDL_JOYAXISMOTION)
        {
            printf("Joystick______EVENT!\n");
        }
        // etc.....
        

请参阅https://wiki.libsdl.org/SDL_JoystickName

于 2020-07-18T15:20:32.703 回答
0

这是 SDL 1.2 还是 2.0?就我而言,2.0 SDL_PollEvent(&event) 实际上并没有在事件结构中放入任何数据。在那次通话之后,我不得不使用 SDL_JoystickGetAxis(joystick_id, axis) 和朋友来获取数据。

因此,在您的情况下,请尝试将 SDL_JoystickGetAxis 调用移出事件类型的 if-test。

于 2015-10-26T13:51:32.870 回答
-1

我不知道这对你有什么帮助,但我知道 pygame 支持操纵杆。pygame 是 SDL 库的 python 端口。如果一切都失败了,我想你总是可以在 python 中编写那段特定的代码。

于 2013-01-27T03:21:18.253 回答