Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Scrolling maps (Not 100% Working)
#1
Difficulty: Medium 3/5
Credits : Missunderstood , Verrigan

This tutorial will show you how to modify a vanilla copy of Mirage Source 3.0.3/3.0.7 to put in scrolling maps. This has only been tested on vanilla Mirage Source 3.0.3/3.0.7, and is not guaranteed to work with your code.

Me : Krloz tested it on a blank MSE and it worked but with the bug mentioned on the bottom

With my version of scrolling maps, the player will always be in the center tile of the screen. (Or 1 left/1 up from center, depending on how big you make your maps. x = 8, y = 6 on standard vanilla 3.0.3/3.0.7) Any tile that is off the map will be filled with black.

Files to Modify
[*]modGameLogic.bas

Each portion of this tutorial is broken up by file, which is how I intend to break down every tutorial I post on this forum, even in cases such as this one that we only modify one file. If enough people want to see this in action before making changes, I may put up a temporary (vanilla) server/client..
Anyways.. Let's begin.

modGameLogic.bas
ModGameLogic is where the game handles all of the imagery that you see in the game. I'm going to show you from the top of the file to the bottom.

In Sub GameLoop()
Replace this code:

Code:
' Release DC
        Call DD_BackBuffer.ReleaseDC(TexthDC)


        ' Get the rect for the back buffer to blit from
        With rec
            .top = 0
            .Bottom = (MAX_MAPY + 1) * PIC_Y
            .Left = 0
            .Right = (MAX_MAPX + 1) * PIC_X
        End With

        ' Get the rect to blit to
        Call DX.GetWindowRect(frmMirage.picScreen.hWnd, rec_pos)
        With rec_pos
            .Bottom = .top + ((MAX_MAPY + 1) * PIC_Y)
            .Right = .Left + ((MAX_MAPX + 1) * PIC_X)
        End With

        ' Blit the backbuffer
        Call DD_PrimarySurf.Blt(rec_pos, DD_BackBuffer, rec, DDBLT_WAIT)

With this code

Code:
' Release DC
        Call DD_BackBuffer.ReleaseDC(TexthDC)
        
        Dim MapXOffset As Integer, MapYOffset As Integer
        Dim PXOffset As Long, PYOffset As Long
        Dim bRec As RECT, tRec As RECT
        
        MapXOffset = Int(MAX_MAPX / 2) - GetPlayerX(MyIndex)
        MapYOffset = Int(MAX_MAPY / 2) - GetPlayerY(MyIndex)
        PXOffset = Player(MyIndex).XOffset
        PYOffset = Player(MyIndex).YOffset
        
        ' Get the rect for the back buffer to blit from
        If MapYOffset < 0 Then
          rec.top = Abs(MapYOffset) * PIC_Y
          rec.Bottom = (MAX_MAPY + 1) * PIC_Y
        Else
          rec.top = 0
          rec.Bottom = PIC_Y * ((MAX_MAPY + 1) - MapYOffset)
        End If
        If MapXOffset < 0 Then
          rec.Left = Abs(MapXOffset) * PIC_X
          rec.Right = (MAX_MAPX + 1) * PIC_X
        Else
          rec.Left = 0
          rec.Right = PIC_X * ((MAX_MAPX + 1) - MapXOffset)
        End If
        
        ' Get the rect to blit to
        Call DX.GetWindowRect(frmMirage.picScreen.hWnd, tRec)
        If MapYOffset < 0 Then
          rec_pos.top = tRec.top
        Else
          rec_pos.top = tRec.top + MapYOffset * PIC_Y
        End If
        rec_pos.Bottom = rec_pos.top + (rec.Bottom - rec.top)
        If MapXOffset < 0 Then
          rec_pos.Left = tRec.Left
        Else
          rec_pos.Left = tRec.Left + MapXOffset * PIC_X
        End If
        rec_pos.Right = rec_pos.Left + (rec.Right - rec.Left)
        
        ' Handle player movement offsets.
        If GetPlayerY(MyIndex) = Int(MAX_MAPY / 2) And PYOffset > 0 Then
          rec.top = rec.top + PYOffset
          rec_pos.Bottom = rec_pos.Bottom - PYOffset
        ElseIf GetPlayerX(MyIndex) = Int(MAX_MAPX / 2) And PXOffset > 0 Then
          rec.Left = rec.Left + PXOffset
          rec_pos.Right = rec_pos.Right - PXOffset
        Else
          If rec.Left = 0 Then
              rec_pos.Left = rec_pos.Left - PXOffset
              rec.Right = rec.Right + PXOffset
          End If
          If rec.Right = PIC_X * (MAX_MAPX + 1) Then
              rec_pos.Right = rec_pos.Right - PXOffset
              rec.Left = rec.Left + PXOffset
          End If
          If rec.top = 0 Then
              rec_pos.top = rec_pos.top - PYOffset
              rec.Bottom = rec.Bottom + PYOffset
          End If
          If rec.Bottom = PIC_Y * (MAX_MAPY + 1) Then
              rec_pos.Bottom = rec_pos.Bottom - PYOffset
              rec.top = rec.top + PYOffset
          End If
        End If
        
        'Fill in unfilled horizontal portions of the map with black.
        If MapYOffset < 0 Then
          bRec.top = rec_pos.Bottom
          bRec.Bottom = tRec.Bottom
        Else
          bRec.Bottom = rec_pos.top
          bRec.top = tRec.top
        End If
        bRec.Left = tRec.Left
        bRec.Right = bRec.Left + (PIC_X * (MAX_MAPX + 1))
        
        Call DD_PrimarySurf.BltColorFill(bRec, 0)
        
        'Fill in unfilled vertical portions of the map with black.
        bRec.top = tRec.top
        bRec.Bottom = tRec.top + (PIC_Y * (MAX_MAPY + 1))
        If MapXOffset < 0 Then
          bRec.Left = rec_pos.Right
          bRec.Right = tRec.Right
        Else
          bRec.Right = rec_pos.Left
          bRec.Left = tRec.Left
        End If
        
        Call DD_PrimarySurf.BltColorFill(bRec, 0)
        
        ' Blit the backbuffer
        Call DD_PrimarySurf.Blt(rec_pos, DD_BackBuffer, rec, DDBLT_WAIT)


In Sub EditorMouseDown
Replace this code:

Code:
Public Sub EditorMouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
Dim x1, y1 As Long

    If InEditor Then
        x1 = Int(x / PIC_X)
        y1 = Int(y / PIC_Y)

With this code :

Code:
Public Sub EditorMouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
  Dim x1, y1 As Long

  If InEditor Then
    x1 = Int(x / PIC_X) + (Player(MyIndex).x - Int(MAX_MAPX / 2))
    y1 = Int(y / PIC_Y) + (Player(MyIndex).y - Int(MAX_MAPY / 2))



In Sub PlayerSearch
Replace this code:

Code:
Sub PlayerSearch(Button As Integer, Shift As Integer, x As Single, y As Single)
Dim x1 As Long, y1 As Long

    x1 = Int(x / PIC_X)
    y1 = Int(y / PIC_Y)

with this

Code:
Sub PlayerSearch(Button As Integer, Shift As Integer, x As Single, y As Single)
  Dim x1 As Long, y1 As Long

  x1 = Int(x / PIC_X) + (Player(MyIndex).x - Int(MAX_MAPX / 2))
  y1 = Int(y / PIC_Y) + (Player(MyIndex).y - Int(MAX_MAPY / 2))
This section added on April 4th
Delete this code:

Code:
' Blit the text they are putting in
        Call DrawText(TexthDC, 0, (MAX_MAPY + 1) * PIC_Y - 20, MyText, RGB(255, 255, 255))
        
        ' Draw map name
        If Map.Moral = MAP_MORAL_NONE Then
              Call DrawText(TexthDC, Int((MAX_MAPX + 1) * PIC_X / 2) - (Int(Len(Trim(Map.Name)) / 2) * 8), 1, Trim(Map.Name), QBColor(BrightRed))
        Else
              Call DrawText(TexthDC, Int((MAX_MAPX + 1) * PIC_X / 2) - (Int(Len(Trim(Map.Name)) / 2) * 8), 1, Trim(Map.Name), QBColor(White))
        End If
        
        ' Check if we are getting a map, and if we are tell them so
        'If GettingMap = True Then
        '    Call DrawText(TexthDC, 50, 50, "Receiving Map...", QBColor(BrightCyan))
        'End If

Under this code:

Code:
' Blit the backbuffer
        Call DD_PrimarySurf.Blt(rec_pos, DD_BackBuffer, rec, DDBLT_WAIT)

Add this code:

Code:
' Blit the text they are putting in
        TexthDC = frmMirage.picScreen.hdc
        Call DrawText(TexthDC, 0, (MAX_MAPY + 1) * PIC_Y - 20, MyText, RGB(255, 255, 255))
        
        ' Draw map name
        If Map.Moral = MAP_MORAL_NONE Then
              Call DrawText(TexthDC, Int((MAX_MAPX + 1) * PIC_X / 2) - (Int(Len(Trim(Map.Name)) / 2) * 8), 1, Trim(Map.Name), QBColor(BrightRed))
        Else
              Call DrawText(TexthDC, Int((MAX_MAPX + 1) * PIC_X / 2) - (Int(Len(Trim(Map.Name)) / 2) * 8), 1, Trim(Map.Name), QBColor(White))
        End If
        
        ' Check if we are getting a map, and if we are tell them so
        'If GettingMap = True Then
        '    Call DrawText(TexthDC, 50, 50, "Receiving Map...", QBColor(BrightCyan))
        'End If

Quote: his tutorial has been tested in vanilla 3.0.3/3.0.7, and works great. I'm sure there are other ways to do this, and maybe even cleaner ways, but it works great for me. Smile Feel free to post any suggestions/questions/gripes.

Remember that this was made for vanilla 3.0.3/3.0.7, so make sure you remember that if you apply this to your already modified client.. You may need to add/change this code a bit to work with a modified client.

[Edit]
I redid this code from scratch today. You don't have to mess with any of the blt subroutines anymore. As you can see, the code has shrunk quite a bit, and I added some more comments... It's a little simpler than the last code I had, but you will still need to make changes to it to match your source. The description of what the code does still applies, so I didn't change any of that. Pretty much all I changed was the code, and this message. Tongue

Enjoy!

[Edit Again]
Modified some of the description, and confirmed that this code works in 3.0.7 as well.

Also noticed a "bug" with on-screen display of typed text (It scrolls, too).. Something for you to fix on your own. Smile (I'm going to use a text box Tongue)

[Modified Difficulty]
Edited post to show actual difficulty, which I forgot to change with the new code. I chose medium because it isn't hard at all, but some people want to scroll larger maps than the picscreen, which is going to take more coding. Others want to have it stop scrolling when you reach the edge, which is more coding as well. So medium seemed right to me. Smile

[Edited on 4/4/05]
Added the changes required to print the map name and the text a user is typing in the proper position, rather than having it scroll with the map.


The only bug I see is when u use 25+ X,Y's the player moves out of the screen and you wont be avaible to see your char still messing to see how to fix it
Reply
#2
Sync didn't do it, he just moved it to the old forum, Also credit verrigan, its modified(and Improved Smile ) from his version.

There may be some bugs, I have them fixed in my sources, so if you encounter them, let me know and i'll be able to fix it.
Reply
#3
Well yes I made my maps bigger but I just cant get it working because the char wont go in the middle of screen for example

maps
X = 30
Y = 25
__________________
|  |
|   |
| |
| |
| |
|  |
|________________X|
Reply
#4
uhh...thats never been an error I have encountered...It seems like you might have done something wrong. This halfs the map_x and y to get the middle, so changing the map size wouldn't through it off. It uses the constants, not fixed values.(I might have used 32 instead of pic_x in some places though, not sure)
Reply
#5
it would just round it. I wouldn't think it wouldn't through it off by several tiles.
Reply
#6
No, having it odd, throws it off by only 1 tile. He messed with something else, apparently.

No clue what it could be, unless he hasn't resized his picscreen. Which would put it down there, if it wasn't the exact size of the maps and such.
Reply
#7
Idk.. Map size is at default and I dont know how to fix this xD I might redo this
Reply
#8
I'm using it in my source. You really only need to re-dim some stuff, and pass off the x and y offsets to the subs that blit things and what not.
Reply
#9
The thing... is that I dont know how to reDim , gilgamesch told me to reDim but Idk how xDD I guess I have to rip it off kite's wind wisper Tongue
Reply
#10
http://fuckinggoogleit.com Smile
Reply
#11
Lol, it's not hard. I had some help with it, but after seeing how it's done, it's really not that hard.

Here is an example:

Code:
ReDim SMaps(Size).Tile(0 To MAX_MAPX, 0 To MAX_MAPY)

Which goes in:

Code:
Sub iLoadMap

Of course, there are more places that this is needed, well, not this exact redim, but I'm sure you guys get the point.
Reply
#12
I made the maps stop scrolling when they get to certain point but the characters "jump" the animations wont be working... Im still working on fixing this but Im not a pro yet xD as for the rediming im not going to do yet since im trying to make the scrolls stop in a certain point
Reply
#13
If this is Misunderstood's tut, then it already stops, if there is no map attached.
Reply
#14
This one dont stops... theres no loading of surrounding maps or anything else it just scrolls
Reply
#15
Okay, then add this code, somewhere in gameloop:

Code:
If Map.Up = 0 Then
              If MapYOffset > 0 Or (MapYOffset = 0 And GetPlayerDir(MyIndex) = DIR_DOWN) Then
                  MapYOffset = 0
                  PYOffset = 32
              End If
        End If
        If Map.Down = 0 Then
              If MapYOffset < 0 Or (MapYOffset = 0 And GetPlayerDir(MyIndex) = DIR_UP) Then
                  MapYOffset = 0
                  PYOffset = 32
              End If
        End If
        If Map.Left = 0 Then
              If MapXOffset > 0 Or (MapXOffset = 0 And GetPlayerDir(MyIndex) = DIR_RIGHT) Then
                  MapXOffset = 0
                  PXOffset = 32
              End If
        End If
        If Map.Right = 0 Then
              If MapXOffset < 0 Or (MapXOffset = 0 And GetPlayerDir(MyIndex) = DIR_LEFT) Then
                  MapXOffset = 0
                  PXOffset = 32
              End If
         End If

This will make it stop scrolling, if there is no map linked in any direction.
Reply
#16
Just read through quickly but it doesn't seem anyone explained this:

When you change the values for MAX_MAPX and MAX_MAPY you also need to resize picScreen.

So, if you changed it to this:

MAX_MAPX = 25
MAX_MAPY = 30

then you need to do this:

25x32=800 'Multiply MAX_MAPX by the width of your tiles
30x32=960 'Multiply MAX_MAPY by the height of your tiles

Change the height and width of your picScreen to those values:

picScreen.height = 960
picScreen.width = 800

For those of you who don't know how to do this... open up frmMirage. Left click on picScreen. In the attributes list, look for height and width and change to these values.

Otherwise the character sprites disappear as a result of walking on tiles that exist but can't be seen. I assume that's why you would be losing the sprites and not getting any compiler errors.
Reply
#17
>.> I see then I need the same picscreen size as my maps... so I cant have bigger maps than my own screen? =(
Reply
#18
You can. Its very easy, but you need to figure out what to modify yourself.
Its easy if you understand the tutorial Smile. If you don't understand...then of course it might be hard.
Reply
#19
I imagine you can make it bigger that your maps, I just know that it for sure cuts off the right and bottom tiles and and anything else that is supposed to be blt'd to the screen if your picScreen is too small width or height wise.


EDIT: I'll test it and post results


RESULTS:

Well I tested simply drawing a map, running the game, walking to the edges of the screen etc. It works like it's supposed to.

I then resized the picScreen to "unofficially" add another row of tiles... I could not walk on those tiles. Making the picScreen smaller does exactly what I said it would. The character appears to walk off the screen, but with a long name, you can see that is simply walking onto the tiles that are there, but cannot be seen as a result of the picScreen being too small.

I tried drawing a map on the "unoffically" added tiles, and the map editor will not allow drawing.

So all-in-all, my tests only proved what I allready know. Changing the size of picScreen only effects what is displayed, and what is not. The variable checking that was added to the source code prevents any errors from occuring, so what's why your character would be disappearing off the screen without any real debug info. In the compiler's eyes, there is nothing wrong with the code, and since the tile exists in code, it will place the character on them anyways, even though the tile cannot be visually seen.

Now with the scrolling maps, as said above... if you know how to modify it slightly, you can have bigger maps than your picScreen, you just need to know how to display them... and unfortunately I don't lol.

I hope this helps explain some things for you.
Reply
#20
Since it is not 100% working, im moving it under requests for now Smile Don't want to get people's hopes up Smile
Reply
#21
Ok shannara...
@topic...

I tried messing with code all I could is blting the char on center of screen ( +2y of the center but I could.. ) except I couldnt made it to work properly when I try to map and everything the char still working as if its lost on the map[/quote]
Reply


Forum Jump:


Users browsing this thread: 4 Guest(s)