I couldn't help but create an account on here when I saw that the only tutorial for creating animated map tiles required server side changes and sent packets to the client constantly. I'm going to start putting in some useful tutorials here but I'll start with this one for now. Questions and comments are always welcome. Warning! These changes will force you to delete all of your server maps since it changes the maximum number of layers on a map. If someone knows of a way to create a tool to automatically parse in extra layers into an existing saved map then please make one. This is for 2 frame animations of type Mask and Fring. I will explain how to modify this at the end of the tutorial but keep this in mind as you read through. I don't claim to have the same baseline code as everyone else so if my sub names look different than yours then forgive me. Also I don't plan on putting up any pictures but I tried to be descriptive enough so that you wouldn't need them. If my code snippets have terrible looking spacing then I'm sorry, but hopefully you can just copy/paste them. == Server Side == This change is only to save maps. No animation handling is done on the server. Open modEnumerations and find ``` Public Enum MapLayer ``` Before Layer_Count add these to the enumeration ``` MaskAnim FringeAnim ``` Your enumeration should now look similar to this ``` ' Layers in a map Public Enum MapLayer Ground = 1 Mask Mask2 Fringe Fringe2 MaskAnim FringeAnim ' Make sure Layer_Count is below everything else Layer_Count End Enum ``` Simple right? You are now done with server side changes == Client Side == Open frmEditor_Map and bring to the top fraLayers. You should see five radio buttons and the caption for the last one should be Fringe2 and will be named optLayer(5). Copy/Paste one of these radio buttons or create a new one and name it optLayer and set the index to 6, hence it will be called optLayer(6). Change the caption to read M.Anim (Mask Animation). Create another radio button the same way and name it optLayer with an index of 7 so it will show as optLayer(7). Change the caption to read F. Anim (Fringe Animation). Now for the actual code changes. Do the exact same thing you did on the server to the client. Open modEnumerations and add to the same fields to the same enumeration so it looks similar to this ``` Public Enum MapLayer Ground = 1 Mask Mask2 Fringe Fringe2 MaskAnim FringeAnim ' Make sure Layer_Count is below everything else Layer_Count End Enum ``` Your MapLayer enumeration on the server and client should be identical. Now for the part that does the real work. Open up modDirectDraw7 and find this sub ``` Public Sub BltMapTile(ByVal x As Long, ByVal y As Long) ``` In that sub you will see a block of code that looks like this or similar. Pay attention to where I added some comment lines that say "Paste New Code Here" ``` With Map.Tile(x, y) For i = MapLayer.Ground To MapLayer.Mask2 ' skip tile? If (.Layer(i).Tileset > 0 And .Layer(i).Tileset 0 Or .Layer(i).y > 0) Then ' sort out rec rec.top = .Layer(i).y * PIC_Y rec.Bottom = rec.top + PIC_Y rec.Left = .Layer(i).x * PIC_X rec.Right = rec.Left + PIC_X ' render Call Engine_BltFast(ConvertMapX(x * PIC_X), ConvertMapY(y * PIC_Y), DDS_Tileset(.Layer(i).Tileset), rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) End If Next '################### '## Paste New Code Here ## '################### End With ``` Where I put the "Paste New Code Here", paste this code ``` If GetTickCount Mod 1000 < 500 Then ' skip tile? If (.Layer(MapLayer.MaskAnim).Tileset > 0 And .Layer(MapLayer.MaskAnim).Tileset 0 Or .Layer(MapLayer.MaskAnim).y > 0) Then ' sort out rec rec.top = .Layer(MapLayer.MaskAnim).y * PIC_Y rec.Bottom = rec.top + PIC_Y rec.Left = .Layer(MapLayer.MaskAnim).x * PIC_X rec.Right = rec.Left + PIC_X ' render Call Engine_BltFast(ConvertMapX(x * PIC_X), ConvertMapY(y * PIC_Y), DDS_Tileset(.Layer(MapLayer.MaskAnim).Tileset), rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) End If End If ``` This will create an animation layer above your Mask2 layer. For every full second, your normal mask or mask2 tile will remain for the entire second, but the mask animation layer will appear on top of (covering) your normal mask tile for the first half of the second, hence making a two frame animation. At the end I will go into more details on how to change the timing and add more animation frames. Go to the next sub, which should be this ``` Public Sub BltMapFringeTile(ByVal x As Long, ByVal y As Long) ``` You will do the exact same thing here as in the previous sub but you will replace MaskAnim with FringeAnim. Paste the following code after "Next" and before "End While" ``` If GetTickCount Mod 1000 < 500 Then ' skip tile? If (.Layer(MapLayer.FringeAnim).Tileset > 0 And .Layer(MapLayer.FringeAnim).Tileset 0 Or .Layer(MapLayer.FringeAnim).y > 0) Then ' sort out rec rec.top = .Layer(MapLayer.FringeAnim).y * PIC_Y rec.Bottom = rec.top + PIC_Y rec.Left = .Layer(MapLayer.FringeAnim).x * PIC_X rec.Right = rec.Left + PIC_X ' render Call Engine_BltFast(ConvertMapX(x * PIC_X), ConvertMapY(y * PIC_Y), DDS_Tileset(.Layer(MapLayer.FringeAnim).Tileset), rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) End If End If ``` This will do the same thing as the Mask Animation above, but instead of being a Mask tile above Mask2, it will be a Fringe tile above the Fringe2 layer. == How to Use== To use this is simple. First create your map as you would without animations. A good map to start with is one with a body of water in it. Pick a tile on your existing map that you want to animate. Open your map editor and select the tile that you want to be the first frame of your animation. This tile should be similar but slightly different than your existing tile that you want to animate. A water tile is a good one to start with. Select your new layer radio button with the caption M. Anim. Place the tile. You should now see the tile flash in half second intervals on top of your normal Mask tile creating a 2 frame, one second animation. I use this primarily for water, but also for blowing grass For fringe animations do the exact same thing as with mask animations but use the fringe radio button on top of a normal Fringe tile. I like to use these for flames on torches and flags or windmills. == How to Modify == To change the rate at which the frames change simply find this line in both subs that you modified ``` If GetTickCount Mod 1000 < 500 Then ``` Change the 1000 to your new time (1000 = 1 second) and change the 500 to be half of whatever your new animation time is. So if you want a very slow animation that takes 2 seconds, your code would look like this ``` If GetTickCount Mod 2000 < 1000 Then ``` If you want to modify the number of animation frames I recommend changing the number of animation frames to even numbers like 4 (that should be plenty). If you do odd numbers like 3 or 5 then if you try to do an animation with only 2 frames then it will look choppy, but with 4 frames you can just use the same tile for frames 1 and 3 and the other tile for frames 2 and 4 and it will still look good. I will assume you are going for 4 animation frames. If not then read between the lines to figure it out. If you can't do that on your own then just stick with the 2 frame tutorial. To change the animation frame number go to the enum on the server and client and add new enum values for Mask and Fringe like this ``` ' Layers in a map Public Enum MapLayer Ground = 1 Mask Mask2 Fringe Fringe2 MaskAnim MaskAnim2 MaskAnim3 FringeAnim FringeAnim2 FringeAnim3 ' Make sure Layer_Count is below everything else Layer_Count End Enum ``` Remember to change the enum on the server and client side so they are identical. Also remember that your normal mask or fringe layer makes up one of the animation frames so your number of animation layers will be the number of animation frames minus 1. Open frmEditor_Map and add new radio buttons for the new animation frames. Make sure your Mask buttons come first and have index values 6 to 8 and your Fringe buttons come last and have index values 9 to 11. In the first sub in the location where I said to "Paste New Code Here", paste this code instead. ``` If GetTickCount Mod 1000 < 250 Then ' skip tile? If (.Layer(MapLayer.MaskAnim).Tileset > 0 And .Layer(MapLayer.MaskAnim).Tileset 0 Or .Layer(MapLayer.MaskAnim).y > 0) Then ' sort out rec rec.top = .Layer(MapLayer.MaskAnim).y * PIC_Y rec.Bottom = rec.top + PIC_Y rec.Left = .Layer(MapLayer.MaskAnim).x * PIC_X rec.Right = rec.Left + PIC_X ' render Call Engine_BltFast(ConvertMapX(x * PIC_X), ConvertMapY(y * PIC_Y), DDS_Tileset(.Layer(MapLayer.MaskAnim).Tileset), rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) End If Else If GetTickCount Mod 1000 < 500 Then ' skip tile? If (.Layer(MapLayer.MaskAnim2).Tileset > 0 And .Layer(MapLayer.MaskAnim2).Tileset 0 Or .Layer(MapLayer.MaskAnim2).y > 0) Then ' sort out rec rec.top = .Layer(MapLayer.MaskAnim2).y * PIC_Y rec.Bottom = rec.top + PIC_Y rec.Left = .Layer(MapLayer.MaskAnim2).x * PIC_X rec.Right = rec.Left + PIC_X ' render Call Engine_BltFast(ConvertMapX(x * PIC_X), ConvertMapY(y * PIC_Y), DDS_Tileset(.Layer(MapLayer.MaskAnim2).Tileset), rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) End If Else If GetTickCount Mod 1000 < 750 Then ' skip tile? If (.Layer(MapLayer.MaskAnim3).Tileset > 0 And .Layer(MapLayer.MaskAnim3).Tileset 0 Or .Layer(MapLayer.MaskAnim3).y > 0) Then ' sort out rec rec.top = .Layer(MapLayer.MaskAnim3).y * PIC_Y rec.Bottom = rec.top + PIC_Y rec.Left = .Layer(MapLayer.MaskAnim3).x * PIC_X rec.Right = rec.Left + PIC_X ' render Call Engine_BltFast(ConvertMapX(x * PIC_X), ConvertMapY(y * PIC_Y), DDS_Tileset(.Layer(MapLayer.MaskAnim3).Tileset), rec, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY) End If End If ``` For the Fringe paste the same thing where the fringe code would go but change all the MaskAnim to FringeAnim (there are 21 in all, 7 for each frame). If you want to change the frame rate of this 4 frame animation then change 1000 to whatever you want your new animation time to be (1000 = 1 second). Divide that number by your number of frames and that is how much to increment by when you change the 250, 500, and 750 values I put here. So for a 2 second animation use 2000 and 500, 1000, 1500 for your values. That should do it. If you have any questions or comments feel free to leave them.