tile scrolling map (diablo 2 like)

Blitz3D Forums/Blitz3D Beginners Area/tile scrolling map (diablo 2 like)

i want to create some similar game to diablo 2 exp and i am writing the story right now and i have license for blitzmax so i decided to ask first...

what would be a best choice blitzplus, blitz3d or blitzmax? and why?

please consider the question is in 2D or isometric game, not 3D.

Thanks.

matt.

I would suggest blitzmax. OOP will make things easier to understand.

Just a minute and I'll give you some code.

Ok to start you out here is a simple 2D camera system that will let you have multiple viewports each able to zoom in and out.
Global CameraList:TList = CreateList()

Type TCamera
	Field WorldX:Float
	Field WorldY:Float
	Field TargetX:Float
	Field TargetY:Float
	Field ViewX:Float
	Field ViewY:Float
	Field ViewWidth:Float
	Field ViewHeight:Float
	Field ViewZoom:Float
	
	Function Create:TCamera (_WorldX:Float, _WorldY:Float,_ViewX:Float, _ViewY:Float, _ViewWidth:Float, _ViewHeight:Float)
		Local Camera:TCamera = New TCamera
		Camera.WorldX = _WorldX
		Camera.WorldY = _WorldY
		Camera.SetView(_ViewX, _ViewY, _ViewWidth, _ViewHeight)
		Camera.ViewZoom = 1.0
		CameraList.AddLast(Camera)
		If Debug.Enabled Debug.Console.Output("Camera Created",[255,255,255])
		Return Camera
	End Function
	
	Method Cls()
		Local ClsColor:Int [3]
		GetClsColor ClsColor[0],ClsColor[1],ClsColor[2]
		SetColor ClsColor[0],ClsColor[1],ClsColor[2]
		DrawRect ViewX, ViewY,ViewWidth,ViewHeight
	End Method
	
	
	Method SetView(_ViewX:Float, _ViewY:Float, _ViewWidth:Float, _ViewHeight:Float)
		ViewX = _ViewX
		ViewY = _ViewY
		ViewWidth = _ViewWidth
		ViewHeight = _ViewHeight
	End Method

	Method CenterOnPosition(_X:Float, _Y:Float, _Speed:Float = 1.0)
		TargetX = -_X * ViewZoom + (ViewX + (ViewWidth / 2))
		TargetY = -_Y * ViewZoom + (ViewY + (ViewHeight / 2))
		WorldX :+ (TargetX - WorldX) * (_Speed * ViewZoom)
		WorldY :+ (TargetY - WorldY) * (_Speed * ViewZoom) 
	End Method
	
	Method Shake(_Strength:Float)
		WorldX :+ Rnd(-_Strength,_Strength) * ViewZoom
		WorldY :+ Rnd(-_Strength,_Strength) * ViewZoom
	End Method
	
End Type

And here is a tile map system for you.
Global Tiles:TImage [1]
Type TTileMap
	Field Name:String
	Field TileSize:Float
	Field Depth:Int
	Field Width:Int
	Field Height:Int

	Field Data:Int [,,]
	
	Function CreateBlank:TTileMap (_Name:String, _Depth:Int, _Width:Int, _Height:Int, _TileSize:Int = 32)
		Local o:TTileMap = New TTileMap
			o.Name = _Name
			o.TileSize = _TileSize
			o.Depth = _Depth
			o.Width = _Width
			o.Height = _Height
			o.Data = New Int[_Depth, _Width, _Height]
			o.Clear()
		Return o
	End Function
	
	Function CreateFromFile:TTileMap (_File:String)
		Local o:TTileMap = New TTileMap
			o.Load(_File)
		Return o
	End Function
	
	Method LimitCameraToMapBounds(_Camera:TCamera)
		If _Camera.WorldX < -(Width*(TileSize * _Camera.ViewZoom)) + (_Camera.ViewX + _Camera.ViewWidth)
			_Camera.WorldX = -(Width*(TileSize * _Camera.ViewZoom)) + (_Camera.ViewX + _Camera.ViewWidth)
		End If
		If _Camera.WorldY < -(Height*(TileSize *_Camera.ViewZoom)) + (_Camera.ViewY + _Camera.ViewHeight)
			_Camera.WorldY = -(Height*(TileSize * _Camera.ViewZoom)) + (_Camera.ViewY + _Camera.ViewHeight)
		End If
		If _Camera.WorldX > _Camera.ViewX Then _Camera.WorldX = _Camera.ViewX
		If _Camera.WorldY > _Camera.ViewY Then _Camera.WorldY = _Camera.ViewY
	End Method

	Method Load (_File:String)
		Local In:tStream = ReadStream(_File)
		If Not In
			Return False 
		End If
		Name = ReadString(In,16)
		TileSize = Readint(In)
		Depth = Readint(In)
		Width = Readint(In)
		Height = Readint(In)
		Data = New Int[Depth, Width, Height]
		For Local d:Int = 0 To Depth - 1
			For Local x:Int = 0 To Width - 1
				For Local y:Int = 0 To Height - 1
					Data [d,x,y] = Readint(In)
				Next
			Next
		Next
		CloseStream In
	End Method
	
	Method Save (_File:String)
		Local Out:tStream = WriteStream(_File)
		If Not Out
			Return False 
		End If
		WriteString (Out,Name[..16])
		WriteInt (Out,TileSize)
		WriteInt (Out,Depth)
		WriteInt (Out,Width)
		WriteInt (Out,Height)
		For Local d:Int = 0 To Depth - 1
			For Local x:Int = 0 To Width - 1
				For Local y:Int = 0 To Height - 1
					WriteInt(Out,Data [d,x,y])
				Next
			Next
		Next
		CloseStream Out
	End Method
	
		
	Method Clear()
		For Local d:Int = 0 To Depth - 1
			For Local x:Int = 0 To Width - 1
				For Local y:Int = 0 To Height - 1
					Data [d,x,y] = 0
				Next
			Next
		Next
	End Method

	Method Fill(_Depth:Int, _TileIndex:Int)
		For Local x:Int = 0 To Width - 1
			For Local y:Int = 0 To Height - 1
				Data [_Depth,x,y] = _TileIndex
			Next
		Next
	End Method

	Method ScreenToMapCoords(_Camera:TCamera,_ScreenX:Float, _ScreenY:Float, _MapX:Float Var, _MapY:Float Var)
		If  _ScreenX < _Camera.ViewX Or _ScreenX > _Camera.ViewX + _Camera.ViewWidth Or _ScreenY < _Camera.ViewY Or _ScreenY > _Camera.ViewY + _Camera.ViewHeight Then
			_MapX = -1
			_MapY = -1
			Return False
		EndIf
		If _Camera.WorldX > 0 Then
			_MapX = (_ScreenX - _Camera.WorldX)
		Else
			_MapX = (-_Camera.WorldX + _ScreenX)
		EndIf
		If _Camera.WorldY > 0 Then
			_MapY = (_ScreenY - _Camera.WorldY)
		Else
			_MapY = (-_Camera.WorldY + _ScreenY)
		EndIf
		Return True
	End Method
	
	Method ScreenToMapCell(_Camera:TCamera,_ScreenX:Float, _ScreenY:Float, _MapCellX:Int Var, _MapCellY:Int Var)
		Local _MapX:Float
		Local _MapY:Float
		ScreenToMapCoords(_Camera,_ScreenX, _ScreenY, _MapX, _MapY)
		If _MapX <0 Or _MapX > Width * (TileSize * _Camera.ViewZoom) Or _MapY < 0 Or _MapY > Height * (TileSize * _Camera.ViewZoom) Then
			_MapCellX = -1
			_MapCellY = -1
		Else
			_MapCellX = _MapX / (TileSize * _Camera.ViewZoom)
			_MapCellY = _MapY / (TileSize * _Camera.ViewZoom)
		EndIf
	End Method
	
	Method MapToMapCell(_Camera:TCamera,_MapX:Float, _MapY:Float, _MapCellX:Int Var, _MapCellY:Int Var)
		If _MapX < 0 Or _MapX > Width * (TileSize * _Camera.ViewZoom) Or _MapY < 0 Or _MapY > Height * (TileSize * _Camera.ViewZoom) Then
			_MapCellX = -1
			_MapCellY = -1
		Else
			_MapCellX = _MapX / (TileSize * _Camera.ViewZoom)
			_MapCellY = _MapY / (TileSize * _Camera.ViewZoom)
		EndIf
	End Method
	
	Method MapCellToScreenCoords(_Camera:TCamera,_MapX:Float, _MapY:Float, _ScreenX:Float Var, _ScreenY:Float Var)
		_ScreenX = _Camera.WorldX + (TileSize * _Camera.ViewZoom) * _MapX
		_ScreenY = _Camera.WorldY + (TileSize * _Camera.ViewZoom) * _MapY
	End Method

	Method MapToScreenCoords(_Camera:TCamera,_MapX:Float, _MapY:Float, _ScreenX:Float Var, _ScreenY:Float Var)
		_ScreenX = (_MapX * _Camera.ViewZoom) + _Camera.WorldX
		_ScreenY = (_MapY * _Camera.ViewZoom) + _Camera.WorldY
	End Method
		
	Method Render(_Camera:TCamera,_Depth:Int = 0)
		Local ScreenX:Float
		Local ScreenY:Float
		For Local MapX = 0 To Width - 1
			ScreenX = MapX * (TileSize * _Camera.ViewZoom) + _Camera.WorldX
			If ScreenX + (TileSize * _Camera.ViewZoom) >= _Camera.ViewX And ScreenX <= _Camera.ViewX + _Camera.ViewWidth Then
				For Local MapY = 0 To Height - 1
					ScreenY = MapY * (TileSize * _Camera.ViewZoom) + _Camera.WorldY
					If ScreenY + (TileSize * _Camera.ViewZoom) >= _Camera.ViewY And ScreenY <= _Camera.ViewY + _Camera.ViewHeight Then
						Local TileIndex:Int = Data[_Depth, MapX, MapY]
						If TileIndex < 0 TileIndex = 0
						If TileIndex > Tiles.Length - 1 TileIndex = 0
						If Tiles[TileIndex] = Null
							If TileIndex <> 0 Print "Error: Tile does not exist: #"+TileIndex
							Continue
						End If
						SetScale _Camera.ViewZoom,_Camera.ViewZoom
						DrawImage Tiles[TileIndex],ScreenX, ScreenY
						SetScale 1,1
					EndIf
				Next
			EndIf
		Next
	End Method
	
	Method RenderGrid(CurrentCamera:TCamera)
		Local _Size:Float = TileSize * CurrentCamera.ViewZoom
		For Local _X:Float = 0 To Width
			DrawLine _X*_Size+CurrentCamera.WorldX,CurrentCamera.WorldY,_X*_Size+CurrentCamera.WorldX,CurrentCamera.WorldY+(Height*_Size)
		Next
		For Local _Y:Float = 0 To Height
			DrawLine CurrentCamera.WorldX,_Y*_Size+CurrentCamera.WorldY,CurrentCamera.WorldX+(Width*_Size), _Y*_Size+CurrentCamera.WorldY
		Next
	End Method
	
End Type

Let me know if you have questions.

wow man! this is great! you are very nice to share this with us!

you now, for me this is very new and i dont know much about OOP, but i will try to start coding mannualy your posted code with blitzmax today.

many, many thanks!

matt.