如何在VB6中流畅地制作这个角色的动画

发布于 2024-12-05 11:57:51 字数 2751 浏览 1 评论 0原文

好吧,我有了这个角色,我希望它能顺利移动。我有一个由 6 个精灵驱动的行走动画,这就是动画现在的运行方式:

首先,我有一个 KeyDown 子组件:

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)

...

Select Case KeyCode

    Case vbKeyLeft: 'move left
        MoveLeft Character, Speed

    Case vbKeyRight: 'move right
        MoveRight Character, Speed

    Case vbKeyUp: 'jump
        Jump Character

    Case vbKeyDown:
        Duck Character

End Select

...

End Sub

然后,当按下向右或向左箭头键时,Select 会触发 MoveLeft/MoveRight 函数。

Public Function MoveRight(Character As Image, Speed As Integer)
SaveSetting "MLP", "Game", "direction", "right"
Character.Left = Character.Left + Speed
    Select Case GetSetting("MLP", "Game", "right_animation", 0)
        Case 0:
            Character.Picture = LoadPicture(App.Path & "\images\characters\" & GetSetting("MLP", "Game", "pony", "twilight") & "\sprite_27.gif")
            SaveSetting "MLP", "Game", "right_animation", 1
        Case 1:
            Character.Picture = LoadPicture(App.Path & "\images\characters\" & GetSetting("MLP", "Game", "pony", "twilight") & "\sprite_28.gif")
            SaveSetting "MLP", "Game", "right_animation", 2
        Case 2:
            Character.Picture = LoadPicture(App.Path & "\images\characters\" & GetSetting("MLP", "Game", "pony", "twilight") & "\sprite_29.gif")
            SaveSetting "MLP", "Game", "right_animation", 3
        Case 3:
            Character.Picture = LoadPicture(App.Path & "\images\characters\" & GetSetting("MLP", "Game", "pony", "twilight") & "\sprite_30.gif")
            SaveSetting "MLP", "Game", "right_animation", 4
        Case 4:
            Character.Picture = LoadPicture(App.Path & "\images\characters\" & GetSetting("MLP", "Game", "pony", "twilight") & "\sprite_31.gif")
            SaveSetting "MLP", "Game", "right_animation", 5
        Case 5:
            Character.Picture = LoadPicture(App.Path & "\images\characters\" & GetSetting("MLP", "Game", "pony", "twilight") & "\sprite_32.gif")
            SaveSetting "MLP", "Game", "right_animation", 0
    End Select
End Function

只有其中之一的功能,因为两者是相同的。现在,我想在这里添加 100MS 的延迟。我发现了一个暂停功能:

Public Function Pause(Milliseconds As Single)
Dim T As Single, t2 As Single
T = GetTickCount(): t2 = GetTickCount()
Do Until t2 - T >= Milliseconds
    t2 = GetTickCount(): Sleep 1: DoEvents
Loop
End Function

这个暂停功能效果很好,但由于某种原因在这种情况下不起作用。我尝试过在Form_KeyDown Select中触发函数之前暂停,我在每张图片更改之前尝试过,我在每张图片更改后尝试过,我在MoveRight/MoveLeft中的Select之前尝试过,但它们都不会产生动画,就像角色只是滑动而没有精灵变化/动画一样。可能是什么问题以及如何解决这个问题?

如果你想知道它在没有像我在这里发布的代码那样的暂停的情况下做了什么,它有动画,但速度非常快,你可以注意到精灵的变化,它看起来有动画,但不平滑,它运行得很快。

Okay, so I have this character, and I want it to smoothly move. I have it's walking animation powered with 6 sprites, and this is how the animation is functioning right now:

First, I have a KeyDown sub:

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)

...

Select Case KeyCode

    Case vbKeyLeft: 'move left
        MoveLeft Character, Speed

    Case vbKeyRight: 'move right
        MoveRight Character, Speed

    Case vbKeyUp: 'jump
        Jump Character

    Case vbKeyDown:
        Duck Character

End Select

...

End Sub

The Select then triggers the MoveLeft/MoveRight funcitons when they press right or left arrow keys.

Public Function MoveRight(Character As Image, Speed As Integer)
SaveSetting "MLP", "Game", "direction", "right"
Character.Left = Character.Left + Speed
    Select Case GetSetting("MLP", "Game", "right_animation", 0)
        Case 0:
            Character.Picture = LoadPicture(App.Path & "\images\characters\" & GetSetting("MLP", "Game", "pony", "twilight") & "\sprite_27.gif")
            SaveSetting "MLP", "Game", "right_animation", 1
        Case 1:
            Character.Picture = LoadPicture(App.Path & "\images\characters\" & GetSetting("MLP", "Game", "pony", "twilight") & "\sprite_28.gif")
            SaveSetting "MLP", "Game", "right_animation", 2
        Case 2:
            Character.Picture = LoadPicture(App.Path & "\images\characters\" & GetSetting("MLP", "Game", "pony", "twilight") & "\sprite_29.gif")
            SaveSetting "MLP", "Game", "right_animation", 3
        Case 3:
            Character.Picture = LoadPicture(App.Path & "\images\characters\" & GetSetting("MLP", "Game", "pony", "twilight") & "\sprite_30.gif")
            SaveSetting "MLP", "Game", "right_animation", 4
        Case 4:
            Character.Picture = LoadPicture(App.Path & "\images\characters\" & GetSetting("MLP", "Game", "pony", "twilight") & "\sprite_31.gif")
            SaveSetting "MLP", "Game", "right_animation", 5
        Case 5:
            Character.Picture = LoadPicture(App.Path & "\images\characters\" & GetSetting("MLP", "Game", "pony", "twilight") & "\sprite_32.gif")
            SaveSetting "MLP", "Game", "right_animation", 0
    End Select
End Function

Only one of the functions because both are identical. Now, I want to add a delay in here, of 100MS. I have a pause function I found:

Public Function Pause(Milliseconds As Single)
Dim T As Single, t2 As Single
T = GetTickCount(): t2 = GetTickCount()
Do Until t2 - T >= Milliseconds
    t2 = GetTickCount(): Sleep 1: DoEvents
Loop
End Function

And this pause function works great, but not in this case for some reason. Ive tried putting the pause before the function is triggered in the Form_KeyDown Select, I've tried it before each picture is changed, I've tried it after each picture is changed, I've tried it before the Select in MoveRight/MoveLeft, but they all result in no animation, like the character just slides with no sprite change/animation. What could be the problem and how can I fix this?

If you are wondering what it does with no Pause like the code I posted here, it animates but really fast, you can notice the sprite changes and it looks animated but its not smooth, it goes way to fast.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

放低过去 2024-12-12 11:57:51

看起来每秒的帧数是由 key_down 触发的速率或键盘重复速度/速率和延迟决定的。您可以使用一些我不知道的 VB 代码来调整应用程序中的延迟(但我相信您可以搜索)。

但如果我这样做,我会使用“游戏循环”。对于一个简单的解决方案,您需要:

  • Timer 组件及其 Tick 事件,设置为 33ms 间隔,作为
  • moveleft、moveright 的游戏循环全局布尔标志。
  • 全局 int 毫秒_elasped。
  • keydown 和 keyup 的功能是设置和清除 moveleft 和 moveright 标志。

在 keydown 函数中,专门设置/清除 moveleft 或 moveright 标志。

在timer_tick()子函数中,检查moveleft的标志,如果设置了,则通过x = x + speed * timer.interval来为角色设置动画。,同时让角色对象知道如何已经过去了很多 milliseconds_elpased,因此它将显示正确的帧本身。对 moveright 执行类似操作。

计时器将以timer.interval (FPS)的速率刷新动画;而角色的动画独立于 FPS,因为它使用 milliseconds_elpased 来确定它应该处于哪一帧。

It looks like your frame per second is powered by the rate at which key_down is fired, or the keyboard repeat speed/rate and delay. You can adjust that delay in your application by using some VB code that I do not know off my head (but you can search I believe).

But if I were doing it, I will use a "Game Loop". for a simplistic solution, you need:

  • Timer component and its Tick event, set to 33ms interval, to act as the Game Loop
  • global boolean flags for moveleft, moveright.
  • global int milliseconds_elasped.
  • The keydown and keyup functions to set and clear the moveleft and moveright flags.

In the keydown function, set/clear the moveleft or moveright flags exclusively.

In the timer_tick() Sub, check the flag for moveleft, if it is set, animate the character by x = x + speed * timer.interval., at the same time let the character object know how much milliseconds_elpased has passed so that it will display the correct frame itself. Do the similar for moveright.

The timer will refresh the animation at the rate timer.interval (FPS); while the character animates independant of the FPS as it uses the milliseconds_elpased to determine which frame it should be at.

何必那么矫情 2024-12-12 11:57:51

我最终也是最成功的解决方案是杰克和我的结合。

首先,我使用了 Jake 的计时器想法,其次,我没有使用图像,而是使用了 Wmode 设置为透明的 Flash 图像。我不会循环浏览图像,而是循环浏览 1 帧 SWF 文件,这些文件渲染得更加美丽且无闪烁!以下是新 Select Case 的体验:

Select Case CurrentState
        Case 0:
            Character.LoadMovie 0, App.Path & "\swf\twilight\walk_1.swf"
            CurrentState = 1
        Case 1:
            Character.LoadMovie 0, App.Path & "\swf\twilight\walk_2.swf"
            CurrentState = 2
        Case 2:
            Character.LoadMovie 0, App.Path & "\swf\twilight\walk_3.swf"
            CurrentState = 3
        Case 3:
            Character.LoadMovie 0, App.Path & "\swf\twilight\walk_4.swf"
            CurrentState = 4
        Case 4:
            Character.LoadMovie 0, App.Path & "\swf\twilight\walk_5.swf"
            CurrentState = 5
        Case 5:
            Character.LoadMovie 0, App.Path & "\swf\twilight\walk_6.swf"
            CurrentState = 0
End Select

另外,如果您注意到的话,我不再使用 Save/GetSetting 以及全局公共变量来提高效率,这是 Deanna 建议的。谢谢大家,我们在实现这个答案的过程中都提供了帮助。

My final and most successful solution was a combination of both Jake's and mine.

First, I used Jake's Timer idea, and secondly, instead of using images, I used a flash image with Wmode set to transparent. Instead of cycling through images, i would cycle through 1-framed SWF files which rendered much more beautifully and flicker-free! Here is a taste of the new Select Case:

Select Case CurrentState
        Case 0:
            Character.LoadMovie 0, App.Path & "\swf\twilight\walk_1.swf"
            CurrentState = 1
        Case 1:
            Character.LoadMovie 0, App.Path & "\swf\twilight\walk_2.swf"
            CurrentState = 2
        Case 2:
            Character.LoadMovie 0, App.Path & "\swf\twilight\walk_3.swf"
            CurrentState = 3
        Case 3:
            Character.LoadMovie 0, App.Path & "\swf\twilight\walk_4.swf"
            CurrentState = 4
        Case 4:
            Character.LoadMovie 0, App.Path & "\swf\twilight\walk_5.swf"
            CurrentState = 5
        Case 5:
            Character.LoadMovie 0, App.Path & "\swf\twilight\walk_6.swf"
            CurrentState = 0
End Select

Also if you notice, I am no longer using Save/GetSetting, and a global public variable to improve efficiency, which was suggested by Deanna. Thank you everyone, we all helped in the process of achieving this answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文