2017-04-11 71 views
1

我在建设SDL2申请macOS使用C++。我需要一些“基本”滚动的应用程序(如网页浏览器)。我通过使用SDL_MouseWheel事件来实现这个功能,该功能为我提供了一个功能齐全的“类似于窗口”的滚动功能。我使用的是MacBook Pro和我想带触控板的功能。Smooth(Inertial)使用SDL2滚动?

简单地说,我要求一个更好的滚动算法(MacBook的触控板滚动,惯性滚动

我了解SDL_MultiGesture事件,但我真的不知道如何把事情放在一起来实现我想要的结果。

+0

问题似乎有点模糊和范围广泛。你可以缩小它的范围,也许举一个你现在有什么样的例子,并解释你想如何改变行为? – paddy

+0

我想实现使用SDL2的惯性滚动(可能与SDL_MultiGesture),我想要一些帮助或例子。 –

回答

1

好的,这是问题的答案。首先,你将不得不手动完成它。 我也假设你知道SDL2和C++。
*注意:我只在Y轴上滚动(如果你愿意的话,你可以这样做)。

首先,我们需要一些变量:

int scrolling;    // flag (scrolling or not) 
int scroll_sensitivity = 40; // how fast we want to scroll 
double scroll_Y = 0;   // current scrolling amount (on Y-Axis) 
double scroll_acceleration;  // scrolling speed 
double scroll_friction = 0.001; // how fast we decelerate 
double scroll_prev_pos;   // previous event's position 

之后,你将需要处理的SDL_MultiGesture事件:

case SDL_MULTIGESTURE:{ 
    if(event.mgesture.numFingers == 2){ 
    if(scrolling == 0){ 
     scrolling = 1; 
     scroll_prev_pos = event.mgesture.y; 
    } else{ 
     double dy = event.mgesture.y - scroll_prev_pos; 
     scroll_acceleration = dy * 40; 
     scroll_prev_pos = event.mgesture.y; 
     scrolling = 1; 
    } 
    } 
    break; 
} 

而且,我们需要停止滚动的SDL_FingerDown事件:

case SDL_FINGERDOWN:{ 
    scrolling = 0; 
    break; 
} 

接下来,我们要更新scroll_Y(把它放在你的“更新”函数中):

if(scrolling){ 
    if(scroll_acceleration > 0) scroll_acceleration -= scroll_friction; 
    if(scroll_acceleration < 0) scroll_acceleration += scroll_friction; 
    if(abs(scroll_acceleration) < 0.0005) scroll_acceleration = 0; 
    scroll_Y += scroll_sensitivity * scroll_acceleration; 
    // Here you have to set your scrolling bounds i.e. if(scroll_Y < 0) scroll_Y = 0; 
} 

最后,我们要根据我们的滚动值呈现:

SDL_Rect rect = {some_x, some_y + scroll_Y, some_w, some_h}; 
SDL_RenderCopy(renderer, some_texture, NULL, &rect); 

这就是它!
我有一个完全可行的应用程序与上面的代码,所以我100%肯定这是按预期工作。如果你有任何问题(因为它不是真正的代码,它更像是一个算法)与我联系。正如我之前提到的,我假定您已经知道SDL和C++已经够好了,所以我相信您能够理解实现。 此外,我知道这个解决方案可以变得更好,所以如果你有任何添加/改变,只要说出来!

祝您有个美好的一天!

2

我遇到了同样的问题,事实证明SDL opts out of momentum scroll events通过关闭用户默认系统中的AppleMomentumScrollSupported默认值。

您可以在您的应用程序中使用Objective-C++的以下位置重新打开它,并且您的SDL_MouseWheel事件将变得平滑。

NSDictionary *appDefaults = [[NSDictionary alloc] initWithObjectsAndKeys: 
          [NSNumber numberWithBool:YES], @"AppleMomentumScrollSupported", 
          nil]; 
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; 
[appDefaults release];