Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[TUT] Robin's Amazing Package Map Animations in EO 2.0


Mondo
 Share

Recommended Posts

Hello,

This is my second tutorial so I haven't practiced this enough, I might still mess up. 

Anyhow, I never found complete Map Animations Tutorial on the forums and certainly found no information about it except for (again) a quick suggestion from Robin on how to place the sprite animations in the map and again some comments from other programmers regarding this already being done on Robin's Amazing Package.

Robin's Map Animation does not overload the server/client with network traffic, it just sends the map once, which includes all the animations in it, and they're all handled on client side.

So I spent a couple hours again hacking the Amazing Package code looking for what I needed to make this work on EO 2.0 and now that I found it I thought I'd share it with the EO community.

As always, credits for this superb piece of software engineering go to Robin Perris, author of Robin's Amazing Package ([http://www.touchofdeathforums.com/smf/index.php/topic,74117.0.html](http://www.touchofdeathforums.com/smf/index.php/topic,74117.0.html)) where I grabbed the Map Animation code from.

On that note I invite again you to review Robin's bundle, its filled with tons of lessons and good stuff lying there ready for the grabbing if you are patient enough to look for it.

Try not just to copy paste what you see, and go a step further and try to understand what the code actually does.

Disclaimer: Please keep in mind this is a crude implementation and may probably need some major tweaking, again i hope it will help anyone who is looking for simple map animations and can't find how to make'em work.

What you'll need:

VB6 Enterprise Edition
EO 2.0 Source Code.
The ability to DEBUG, set a breakpoint and follow steps.
Skills to use the "find" function, or have a good eye for the nested code.
Tons, and tons, and tons of patience.

So again lets get messy…

**ON SERVER SIDE**

**STEP1\. On modTypes in Type TileRec**

Find:

```
    DirBlock As Byte

```Add BELOW That:

```
    Animation As Long

```
**STEP 2\. On modHandleData in HandleMapData**

Find:

```
            Map(mapNum).Tile(x, y).DirBlock = Buffer.ReadByte

```Add BELOW That:

```
' MAP ANIMATION HACK
            Map(mapNum).Tile(x, y).Animation = Buffer.ReadLong
' MAP ANIMATION HACK

```
**STEP 3\. On modServerTCP in MapCache_Creat**

Find:

```
                Buffer.WriteByte .DirBlock

```Add BELOW that:

```
' MAP ANIMATION HACK
                Buffer.WriteLong .Animation
' MAP ANIMATION HACK

```
**ON CLIENT SIDE**

**STEP 1\. on ModTypes un Public Type TileRec**

Find:

```
    DirBlock As Byte

```
Add BELOW that:

```
' MAP ANIMATION HACK
    Animation As MapAnimRec
' MAP ANIMATION HACK

```
Before the Public Type TileRec add the following code:

```
' MAP ANIMATION HACK
Public Type MapAnimRec
    Animation As Long
    Timer(0 To 1) As Long
    FrameIndex(0 To 1) As Long
End Type
' MAP ANIMATION HACK

```
**STEP 2\. On modHandleData in HandleMapData**

Find:

```
            Map.Tile(x, y).DirBlock = Buffer.ReadByte

```
Add BELOW that:

```
' MAP ANIMATION HACK
            Map.Tile(x, y).Animation.Animation = Buffer.ReadLong
' MAP ANIMATION HACK

```
**STEP 3\. on ModDirectDraw7 add a new routine**

```
' MAP ANIMATION HACK
Public Sub BltMapAnimation(ByVal x As Long, ByVal y As Long, ByVal layer As Long)
    Dim animNum As Long
    Dim Sprite As Integer
    Dim sRECT As DxVBLib.RECT
    Dim dRECT As DxVBLib.RECT
    Dim i As Long
    Dim width As Long, height As Long
    Dim FrameCount As Long

    animNum = Map.Tile(x, y).Animation.Animation

    If animNum = 0 Or animNum > MAX_ANIMATIONS Then Exit Sub
    Sprite = Animation(animNum).Sprite(layer)

    If Sprite < 1 Or Sprite > NumAnimations Then Exit Sub

    FrameCount = Animation(animNum).Frames(layer)

    AnimationTimer(Sprite) = GetTickCount + SurfaceTimerMax

    If DDS_Animation(Sprite) Is Nothing Then
        Call InitDDSurf("animations\" & Sprite, DDSD_Animation(Sprite), DDS_Animation(Sprite))
    End If

    ' total width divided by frame count
    width = DDSD_Animation(Sprite).lWidth / FrameCount
    height = DDSD_Animation(Sprite).lHeight

    sRECT.top = 0
    sRECT.Bottom = height
    sRECT.left = (Map.Tile(x, y).Animation.FrameIndex(layer)) * width
    sRECT.Right = sRECT.left + width

    x = ConvertMapX(x * 32) + 16 - (width / 2)
    y = ConvertMapY(y * 32) + 16 - (height / 2)

    ' Clip to screen
    If y < 0 Then

        With sRECT
            .top = .top - y
        End With

        y = 0
    End If

    If x < 0 Then

        With sRECT
            .left = .left - x
        End With

        x = 0
    End If

    If y + height > DDSD_BackBuffer.lHeight Then
        sRECT.Bottom = sRECT.Bottom - (y + height - DDSD_BackBuffer.lHeight)
    End If

    If x + width > DDSD_BackBuffer.lWidth Then
        sRECT.Right = sRECT.Right - (x + width - DDSD_BackBuffer.lWidth)
    End If

    Call Engine_BltFast(x, y, DDS_Animation(Sprite), sRECT, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
End Sub
' MAP ANIMATION HACK

```
**STEP 4\. On modDirectDraw7 modify Render_Graphics function add call to BltMapAnimation**

Right after:

```
    ' Blit out the items

```
And Before

```
'draw animations

```
Add the following code:

```
' MAP ANIMATION HACK
    ' draw low-level map animations this is layer 0 (BELOW PLAYER)
    For x = 0 To Map.MaxX
        For y = 0 To Map.MaxY
            BltMapAnimation x, y, 0
        Next
    Next
' MAP ANIMATION HACK

```
Then Find:

```
    ' animations
    If NumAnimations > 0 Then

```

Add ABOVE that:

```
' MAP ANIMATION HACK
    ' draw low-level map animations this is layer 1 above the player.
    For x = 0 To Map.MaxX
        For y = 0 To Map.MaxY
            BltMapAnimation x, y, 1
        Next
    Next
' MAP ANIMATION HACK

```
**STEP 5\. On ModGameLogic add routine**

```
' MAP ANIMATION HACK
Public Sub CheckMapAnim(ByVal x As Long, ByVal y As Long)
    Dim animNum As Long
    Dim layer As Long
    Dim loopTime As Long
    Dim FrameCount As Long

    animNum = Map.Tile(x, y).Animation.Animation

    ' if it doesn't exist then exit sub
    If animNum = 0 Or animNum > MAX_ANIMATIONS Then Exit Sub

    For layer = 0 To 1
        loopTime = Animation(animNum).loopTime(layer)
        FrameCount = Animation(animNum).Frames(layer) -1 ' This is to prevent an odd flicker in the animations.

        ' make sure we don't have an extra frame
        If Map.Tile(x, y).Animation.FrameIndex(layer) = 0 Then Map.Tile(x, y).Animation.FrameIndex(layer) = 1

        If Map.Tile(x, y).Animation.Timer(layer) + loopTime <= GetTickCount Then
            ' out of range?
            If Map.Tile(x, y).Animation.FrameIndex(layer) >= FrameCount Then
                Map.Tile(x, y).Animation.FrameIndex(layer) = 0 ' Because we do have frame 0 on animations, don't we?
            Else
                Map.Tile(x, y).Animation.FrameIndex(layer) = Map.Tile(x, y).Animation.FrameIndex(layer) + 1
            End If
            Map.Tile(x, y).Animation.Timer(layer) = GetTickCount
        End If
    Next
End Sub
' MAP ANIMATION HACK

```
**Step 6\. On modGameLogic modify routine GameLoop**

Add the following code on the top of the routine

```
Dim x as long
Dim y as long

```
Then Find :

```
            tmr25 = Tick + 25

```

Add ABOVE that:

```
            ' MAP ANIMATION HACK
            For x = 0 To Map.MaxX
                For y = 0 To Map.MaxY
                    CheckMapAnim x, y
                Next
            Next
            ' MAP ANIMATION HACK

```

**STEP 7\. On modGameEditors in function MapEditorMouseDown**

Find:

```
                        setDirBlock Map.Tile(CurX, CurY).DirBlock, CByte(i), Not isDirBlocked(Map.Tile(CurX, CurY).DirBlock, CByte(i))
                        Exit Sub
                    End If
                End If
            Next

```
Add BELOW that:

```
' MAP ANIMATION HACK
        ElseIf frmEditor_Map.optAnim.Value Then
            ' set the animation on that tile
            Map.Tile(CurX, CurY).Animation.Animation = frmEditor_Map.lstAnimation.ListIndex + 1
        End If
' MAP ANIMATION HACK

```
Note that you'll have an extra END IF after… remove it.

Find:

```
                .Data3 = 0
            End With

```
Add BELOW that:

```
' MAP ANIMATION HACK
        ElseIf frmEditor_Map.optAnim.Value Then
            Map.Tile(CurX, CurY).Animation.Animation = 0
        End If
' MAP ANIMATION HACK

```
Note that you'll have an extra END IF after this… remove it.

**STEP 8\. on ModGameEditors in MapEditorInit**

Find:

```
    ' Error handler
End Sub

```
Add ABOVE that:

```
' MAP ANIMATION HACK
    ' populate the anim list
    frmEditor_Map.lstAnimation.Clear
    For i = 1 To MAX_ANIMATIONS
        frmEditor_Map.lstAnimation.AddItem i & ": " & Animation(i).Name
    Next
    frmEditor_Map.lstAnimation.ListIndex = 0
' MAP ANIMATION HACK

```
**STEP 9\. On frmEditor_Map add a new routines:**

```
' MAP ANIMATION HACK
Private Sub cmdAnimClear_Click()
Dim x As Long, y As Long
    For x = 0 To Map.MaxX
        For y = 0 To Map.MaxY
            Map.Tile(x, y).Animation.Animation = 0
        Next
    Next
End Sub

Private Sub cmdAnimFill_Click()
Dim x As Long, y As Long
    For x = 0 To Map.MaxX
        For y = 0 To Map.MaxY
            Map.Tile(x, y).Animation.Animation = lstAnimation.ListIndex + 1
        Next
    Next
End Sub

Private Sub optAnim_Click()
    fraAnimation.Visible = True
End Sub
' MAP ANIMATION HACK

```

On Sub OptBlock_Click() Find :

```
End Sub
```
Add ABOVE that:

```
' MAP ANIMATION HACK
    fraAnimation.Visible = False
' MAP ANIMATION HACK
```
On Sub OptLayer_Click() Find :

```
    ' Error handler
    Exit Sub
```
Add ABOVE that:

```
' MAP ANIMATION HACK
    fraAnimation.Visible = False
' MAP ANIMATION HACK
```
On Sub optAttribs_Click() Find :

```
    ' Error handler
    Exit Sub
```
Add ABOVE that:

```
' MAP ANIMATION HACK
    fraAnimation.Visible = False
' MAP ANIMATION HACK
```
**STEP 10\. MODIFY FORM frmEditor_Map**

You're looking to get something that will look like this.

![](http://www.touchofdeathforums.com/smf/index.php?action=dlattach;topic=79806.0;attach=20963;image)

Add a Radio button inside fraType frame call the RadioButton optAnim, set Caption to "Animation". you'll need to move stuff around to make room for this.
Add a new Frame on the form, call it FraAnimation, set Caption to "Animation", set it on top of the picback picturebox
Inside fraAnimation add the following controls.
Add a ListBox, name it lstAnimation
Add a Button, name it cmdAnimFill, set Caption to "Fill"
Add a Button, name it cmdAnimClear, set Caption to "Clear"
Add a Label, name it LabelAnimInstr, set Caption to "Select an animation from the list then place it on the map. Loop count will be ignored and the animation will continiously play. To close this box, simply select 'Layers', 'Attributes' or 'Block'."

Set compiler to 350° and cook until done…

**_The How's and Why's…_**

So what we did here on the server side was:

Modify the TileRec and add support for the Animation

Modify the HandleMapData routine to read the message from the client that includes the animations.

Modify the MapCache_Create routine to Write the message to the client that includes the animations.

On the Client side we did:

Modify the TileRec and add support for the Animation, and added a MapAnimRec to store animation data for the map.

Modified the HandleMapData to read the message from the server where we get the Animation data.

Added a routine to DirectDraw that Builds the Map Animation (BltMapAnimation)

Modified the Render_Graphics routine to add the looks to Build the map animations for the two layers, below the player, and above the player.

Added a new routine to the GameLogic that would check the map animations (checkAnimMap) and this one is in charge of moving forward the frames for each sprite animation on the map.

Modified the GameLoop Routine to include a couple declarations and a call to the CheckAnimMap function for each tile, this way we make the sprites animate.

Modified the MapEditorMouseDown so it knows what to do when we click the right or left mouse button and we are on the optAnim checkbox.

Modified the MapEditorInit to make it load the Map Editor Animation list with all the goodies from the animations.

And finally modified the Map Editor form, adding controls that we needed, and the code behind those controls.

Again, if you have questions I'll be happy to try and answer them. If you have any problems retry all the steps in the tutorial a couple times, and if you run into some severe problems I'll do my best to assist you, but be reminded that **this tutorial is delivered AS-IS**… It might not work for you, but then again if you tweak it enough it just might.

Hope this is useful for you all! :)

Cheers!
Link to comment
Share on other sites

@Riftguy:

> So will this store the animations client side so the server does not bombard the client with packets constantly?

Yes sir, they're only sent once when the map is read… after that they're stored in the local map and just replayed.
Link to comment
Share on other sites

@tslusny:

> Do you tested this? becouse this code has some mess with frames for me and when i tryied to change frames on animation in animation editor my pcs graphic card crashed….. so i think u dont tested it :confused:

Really, what mess did you find in the frames? Coz the tutorial only asked to create ONE new frame, and edit an existing one and all this it had to be done on frmedit_map, I never touched a thing in the animation editor…

So if its crashing on you I'd suggest rolling back the changes or going back to a backup and running through the tutorial again.

If you need assistance please provide printscreens of the errors, or error numbers and descriptions and the module, routine and line of code where you get the error.

cheers
Link to comment
Share on other sites

@tslusny:

> i tried it another time and my server just freeze when i add animation to map, do you tested this if it really works? i think there is infinite loop or something like that

I have it working on my on EO 2.0 and works quite well, even if the whole map is filled with animations… I think you need to set up a break point in the bltmapanimation routine and start debugging from there...
Link to comment
Share on other sites

Minor correction to routine BltMapAnimation.

```
FrameCount = 15 ' Animation(animNum).Frames(layer)
```
Should be:

```
FrameCount = Animation(animNum).Frames(layer)
```
I hard coded 15 frames to test, forgot to uncomment.

The Fix already reflected in the tutorial.
Link to comment
Share on other sites

@or3o:

> Do you by chance know how to edit  the maps files so ya dont have to delete all you maps?

Sorry unfortunately I have no clue on how to do that… I'd suggest Commenting Server Step 3\. hence you don't read the animation attribute (nor will it mess up when it tries to render)...

Once the map is in memory you save it again, this WILL write the Animation record in each tile... Do this for all your maps and then uncomment the Step 3.

Its a long shot but it might just work...
Link to comment
Share on other sites

@tslusny:

> this totorial still not working for me

My friend, I told you before, you need to provide error number, error description, module, and subroutine or function as well as where the program breaks if you expect me to provide assistance…

Just saying that it doesn't work for you does not get you any closer to making it work.
Link to comment
Share on other sites

@tslusny:

> i said before no error popups im on windows 7 and it just white the server window and shows window with option to debug or close exe

I'm on Windows 7 too, and my VB6 does not crash and ask for a debug… are you running this from Visual Basic 6, or are you just running the Eclipse Origins.exe ?
Link to comment
Share on other sites

  • 2 weeks later...
  • 1 month later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...