I've been wondering. How are they done? Not just specifically vb.net, but really in general. Are they stored in a file, then read and stored into an array? If so, the bigger the map, I sure the performace gets pretty bad.
There are ways to get the same/good performance regardless of the size of the map. For instance you can divide the map into equally sized blocks, only a few of which are shown at any one time (ofc the camera is restricted, so the user never knows this). But yes - they are commonly stored in a file. Some games/utilities/programs generate them from scratch using semi-random procedures and/or fractal generation, but once units/resources/cities etc. are placed on the map, you will ofc need to save it.
For older civ style games (typically strategy type chess-like maps) with relatively small maps of textured tiles, there is no need to divide the map. You can easily get a satisfactory framerate with the entire map loaded.
In truth, a mature man who uses hair-oil, unless medicinally , that man has probably got a quoggy spot in him somewhere. As a general rule, he can't amount to much in his totality. (Melville: Moby Dick)
FYI I managed to make a method where the world can be as big as you want with zero slowdown in my game Bosskillers, a 2D rpg. How i did it was only render what you see. Take a look at this pseudo code:
Code:
Const TILE_WIDTH As Long = 32
Const TILE_HEIGHT As Long = 24
Coordinates.X = Int(-(Map.Position.X) / TILE_WIDTH)
Coordinates.Y = Int(-(Map.Position.Y) / TILE_HEIGHT) 'converts your position into tile coordinates
'This here allows the world to be as gigantic as you want with zero slow down like 5000x5000 for example. Only draws what is on screen.
X1 = Coordinates.X
Y1 = Coordinates.Y
X2 = Coordinates.X + Map.Screen_Tile_Width 'Number of tiles on screen at once for one row
Y2 = Coordinates.Y + Map.Screen_Tile_Height 'Number of tiles on screen at once for one column
If X2 <= 0 Then X2 = 0
If Y2 <= 0 Then Y2 = 0
If Y2 >= Map.Height - 1 Then Y2 = Map.Height - 1
If X2 >= Map.Width - 1 Then X2 = Map.Width - 1
If X1 <= 0 Then X1 = 0
If Y1 <= 0 Then Y1 = 0
If X1 >= X2 Then X1 = X2
If Y1 >= Y2 Then Y1 = Y2
For Y = Y1 To Y2
For X = X1 To X2
If Running = True Then
If Not ((Map.Position.X + ((TILE_WIDTH * X) + TILE_WIDTH) < R.Left) Or (Map.Position.X + ((TILE_WIDTH * X)) > R.Right) Or (Map.Position.Y + ((TILE_HEIGHT * Y) + TILE_HEIGHT) < R.Top) Or (Map.Position.Y + ((TILE_HEIGHT * Y)) > R.Bottom)) Then
Draw_Tile
End If
Next X
Next Y
Think of it as being a small rectangular magnifine glass over a gigantic enormous sized map (your huge 2x2 array of textures as tiles). No matter where you are, the loops only itterate the number of tiles you can see on screen. Also as you move your character, it moves the map position the opposite direction the character is moving. Like if you move right, the map goes left. If you move up the map moves down. So the huge gigantic map moves seemlessly, regardless of its size.
Hey Jacob, I know it's been a while since I've posted to this thread, but I wanted to ask you a question. I took your example and applied it to my situation, here is my code:
Code:
Option Strict On
Option Explicit On
Public Class Form1
Private map(49, 49) As Panel
Private viewedMap(8, 8) As Panel
Private currentpos As Point
Private Sub loadmap()
'1 - Grass
'2 - Water
'3 - Rock
'4 - Dirt
Dim delim() As String = {Environment.NewLine}
Dim str() As String = My.Resources.map.Split(delim, StringSplitOptions.RemoveEmptyEntries)
For y As Integer = 0 To str.Count - 1
For x As Integer = 0 To str(y).Length - 1
Dim i As Integer = CInt(str(y).Substring(x, 1))
Dim pnl As New Panel
With pnl
.Size = New Size(10, 10)
.Tag = i.ToString
Select Case i
Case 1
.BackColor = Color.Green
Case 2
.BackColor = Color.Blue
Case 3
.BackColor = Color.Gray
Case 4
.BackColor = Color.Brown
End Select
End With
map(x, y) = pnl
Next
Next
End Sub
Private Sub movemap()
Dim x, y As Integer 'Current position
x = currentpos.X
y = currentpos.Y
Me.Controls.Clear()
Dim locx As Integer = 0
Dim locy As Integer = 0
For col As Integer = x - 4 To x + 4
For row As Integer = y - 4 To y + 4
viewedMap(locx, locy) = map(col, row)
If col = x AndAlso row = y Then
viewedMap(locx, locy).BorderStyle = BorderStyle.FixedSingle
Else
viewedMap(locx, locy).BorderStyle = BorderStyle.None
End If
locx += 1
If locx = 9 Then
locx = 0
locy += 1
End If
Next
Next
For col1 As Integer = 0 To 7
For row1 As Integer = 0 To 7
viewedMap(col1, row1).Location = New Point(col1 * 10, row1 * 10)
Me.Controls.Add(viewedMap(col1, row1))
Next
Next
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Call loadmap()
currentpos = New Point(5, 13)
Call movemap()
End Sub
Private Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
If e.KeyCode = Keys.Left Then
currentpos.Y -= 1
ElseIf e.KeyCode = Keys.Right Then
currentpos.Y += 1
ElseIf e.KeyCode = Keys.Up Then
currentpos.X -= 1
ElseIf e.KeyCode = Keys.Down Then
currentpos.X += 1
End If
Call movemap()
End Sub
End Class
And that works, however... whenever I call movemap(), it appears as if the whole map has been inverted. But if I don't worry about calling move map and add all the panels in loadmap, the map appears as it should. Any thoughts on this?
I rushed an example in vb.net but try this. The only problem with my rushed example is that I'm use to vb6, so there is some rendering issues such as the screen not clearing. but if you know how to do it, you got one solid tile engine to build off of. Personally I prefer using DirectX over vb's slow graphical routines. I maintain a solid 60 FPS that way.
And don't change the way I coded it. Theres a reason why it works. You are moving the X1s, Y1s, X2s and Y2s as though you are moving a magnifine glass. It draws only within your window. Which makes massive size maps possible. Im talking World of Warcraft / Grand Theft Auto sizes if not bigger. I tested it on my map editor as well and made worlds 10000 by 10000. Takes a while to load the map though, like maybe 30 sec to a min depending how large your map is. The larger the map the longer it loads. The shorter the map the faster it loads. The maps dont have to be squared either. You can make em rectangular as well.
Last edited by Jacob Roman; Feb 28th, 2013 at 02:20 AM.