开发者

How to smoothly animate this character in VB6

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", 开发者_如何学C"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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜