Hey all,
I'm considering to make a game a la Starcraft, Warcraft I,II.
Let's say I have a map 1000 by 1000 and the screen displays a 120 by 80 or so and I have lots of units and structures on the map. Do I redraw the map (by adjusting the map coordinates) every time I move the screen? How is this actually done in a decent game, that is my question. I don't need code, just some pointers on how to program a "map" game with lots of units that performs well, also on slow machines.
Thanks!
Game question
Re: Game question
I don't know if this is the perfect solution, but you can slice the map up into small maps, that will have their own value.
Tell the program to run for example 13, wich is one of those slices. Then wen you walk into another piece of map, tell the program to run 14
Tell the program to run for example 13, wich is one of those slices. Then wen you walk into another piece of map, tell the program to run 14
Re: Game question
In my Deep Deadly Dungeon game I had maps larger than the view area. What you need to do is to create a viewport and display that on the screen. Here is the code I used to create a viewport.
As you can see it is quite simple. I first get the player coordinates and subtract half the viewport width and height (w, h). This puts the player in the center of the viewport. I then check for boundary conditions. If the viewport goes off the edge of the map, I reset the coords to the edge of the map. After I create the viewport, I use the coords to draw the map.
This just maps the viewport to the actual map tile array. The map is 80 by 80 tiles while the viewport is 79 by 43. When the map is drawn the player will be in the center of the screen unless they are at the edges. As they move around the map is redrawn each time and gives the appearance of scrolling.
Code: Select all
'get the view coords
i = player.pcoord.x - (w / 2)
j = player.pcoord.y - (h / 2)
If i < 0 Then i = 0
If j < 0 Then j = 0
If i + w > dunw - 1 Then i = dunw - w - 1
If j + h > dunh - 1 Then j = dunh - h - 1
As you can see it is quite simple. I first get the player coordinates and subtract half the viewport width and height (w, h). This puts the player in the center of the viewport. I then check for boundary conditions. If the viewport goes off the edge of the map, I reset the coords to the edge of the map. After I create the viewport, I use the coords to draw the map.
Code: Select all
For x = 0 To w
For y = 0 To h
If levels.isseen(i + x, j + y) = True Then
If levels.map(i + x, j + y) = mfloor Then
If levels.tmaptype = cavern Then
Get tmap,(96, 0) - (111, 15), tp
ElseIf levels.tmaptype = dungeon Then
If levels.mapscheme Then
Get tmap,(80, 0) - (95, 15), tp
Else
Get tmap,(112, 0) - (127, 15), tp
End If
End If
Put (x * 16, y * 16), tp, PSet
...
This just maps the viewport to the actual map tile array. The map is 80 by 80 tiles while the viewport is 79 by 43. When the map is drawn the player will be in the center of the screen unless they are at the edges. As they move around the map is redrawn each time and gives the appearance of scrolling.
Re: Game question
Hey rdc,
Yeah, that's actually how I'm doing it right now. I was just wondering if this was the right way... considering I'm gonna have allot of units etc on my screen.
Thanks
Yeah, that's actually how I'm doing it right now. I was just wondering if this was the right way... considering I'm gonna have allot of units etc on my screen.
Thanks
Re: Game question
It is really the only way to do it. Any programs that shows a portion of a map or graphics is using this technique.
-
- Posts: 5494
- Joined: Sep 12, 2005 20:06
- Location: California
Re: Game question
This kind of thing can be optimized using the following psuedo-algorithm:
* Get the width/height of tiles and player location.
* Render tiles in a for loop where x = (player-x rounded to tile-width - screen-width / 2) to (player-x rounded to tile-width + screen-width / 2)
* and y is similarly done.
This way, even with super-large maps, you don't need a for loop between 0 and x-max, and 0 and y-max, but instead between x-visible-start to x-visible-end and y-visible-start to y-visible-end. So basically, only up to 18 x 18 tiles at a time, for example. (Let's say it's a 16x16 tile screen, but we need to account for partial clipping on each axis.)
I hope that makes sense.
* Get the width/height of tiles and player location.
* Render tiles in a for loop where x = (player-x rounded to tile-width - screen-width / 2) to (player-x rounded to tile-width + screen-width / 2)
* and y is similarly done.
This way, even with super-large maps, you don't need a for loop between 0 and x-max, and 0 and y-max, but instead between x-visible-start to x-visible-end and y-visible-start to y-visible-end. So basically, only up to 18 x 18 tiles at a time, for example. (Let's say it's a 16x16 tile screen, but we need to account for partial clipping on each axis.)
I hope that makes sense.
-
- Posts: 3
- Joined: Feb 07, 2014 19:30
Re: Game question
That's similar to how I'm doing it in the engine I'm currently making.
I set up a camera object which has values for it's center position on the map, it's scale for zooming in and out, and it's viewport coordinates to render on the screen. The camera has functions to determine the visible tile coordinates at the corners of the viewport. In the draw sub, I simply loop between the values returned by those functions.
Here is how my camera and drawing functions work. I don't know if this is a good way to do it or not, but it seems to work. The rendering loop is the sub at the bottom of this code:
I set up a camera object which has values for it's center position on the map, it's scale for zooming in and out, and it's viewport coordinates to render on the screen. The camera has functions to determine the visible tile coordinates at the corners of the viewport. In the draw sub, I simply loop between the values returned by those functions.
Here is how my camera and drawing functions work. I don't know if this is a good way to do it or not, but it seems to work. The rendering loop is the sub at the bottom of this code:
Code: Select all
Type Sys_Position
As Integer id
Declare Function tilex (x As Integer) As Integer
Declare Function tiley (y As Integer) As Integer
Declare Function xOff (x As Integer) As Integer
Declare Function yOff (y As Integer) As Integer
End Type
Type Sys_Camera
As Integer id, X, Y
As Integer view_X0, view_Y0, view_X1, view_Y1
As Single scale
Declare Function view_Width() As Single
Declare Function view_Height() As Single
Declare Function X0() As Integer
Declare Function X1() As Integer
Declare Function Y0() As Integer
Declare Function Y1() As Integer
Declare Function screenX0() As Integer
Declare Function screenY0() As Integer
Declare Sub draw_Map(Map() As Integer)
End Type
Function Sys_Position.tilex (x As Integer) As Integer
Return x / TILE_WIDTH
End Function
Function Sys_Position.tiley (y As Integer) As Integer
Return y / TILE_HEIGHT
End Function
Function Sys_Position.xOff (x As Integer) As Integer
Dim As Integer offset
offset = x Mod TILE_WIDTH
If offset < 0 Then Return TILE_WIDTH + offset
Return offset
End Function
Function Sys_Position.yOff (y As Integer) As Integer
Dim As Integer offset
offset = y Mod TILE_HEIGHT
If offset < 0 Then Return TILE_HEIGHT + offset
Return offset
End Function
Function Sys_Camera.view_Width() As Single
Return (This.view_X1 - This.view_X0) / This.scale
End Function
Function Sys_Camera.view_Height() As Single
Return (This.view_Y1 - This.view_Y0) / This.scale
End Function
Function Sys_Camera.X0() As Integer
Return This.X - (This.view_Width / 2)
End Function
Function Sys_Camera.Y0() As Integer
Return This.Y - (This.view_Height / 2)
End Function
Function Sys_Camera.X1() As Integer
Return This.X + (This.view_Width / 2)
End Function
Function Sys_Camera.Y1() As Integer
Return This.Y + (This.view_Height / 2)
End Function
Function Sys_Camera.screenX0() As Integer
Return This.view_X0 - ((Position.xOff(This.X0())) * This.scale)
End Function
Function Sys_Camera.screenY0() As Integer
Return This.view_Y0 - ((Position.yOff(This.Y0())) * This.scale)
End Function
Sub Sys_Camera.draw_Map(Map() As Integer)
Dim As Integer ix, iy, scrX0, scrY0, scrX1, scrY1
scrX0 = This.screenX0()
scrY0 = This.screenY0()
For ix = Position.tilex(This.X0()) To Position.tilex(This.X1())
For iy = Position.tiley(This.Y0()) To Position.tiley(This.Y1())
scrX1 = scrX0 + (scale*TILE_WIDTH)
scrY1 = scrY0 + (scale*TILE_HEIGHT)
If ix>=0 And iy>=0 And ix<=UBound(Map, 1) And iy<=UBound(Map, 2) Then
If Map(ix,iy) <> 0 Then
'////////////// DRAW TILE FROM (scrX0, scrY0) to (scrX1, scrY1)
EndIf
EndIf
scrY0 += scale * TILE_HEIGHT
Next
scrY0 = This.screenY0()
scrX0 += scale * TILE_WIDTH
Next
End Sub
Re: Game question
A game like starcraf and run (like Starcraft) on machines with limited resources?
this is one of my favorite RTS, and works perfectly on the pc 256 mb of ram I have...
I know I'm off topic, but Might show you an image of what you've done?
this is one of my favorite RTS, and works perfectly on the pc 256 mb of ram I have...
I know I'm off topic, but Might show you an image of what you've done?
Re: Game question
I haven't written many games, and none of this sort.
However it is easy enough to capture a whole screen in an storage array and re-draw the screen by a mapping macro.
A kind of view port.
(I have used pset, probably faster by direct screen pixels, but the example is probably of no use to you any how)
VIZ:
However it is easy enough to capture a whole screen in an storage array and re-draw the screen by a mapping macro.
A kind of view port.
(I have used pset, probably faster by direct screen pixels, but the example is probably of no use to you any how)
VIZ:
Code: Select all
Type Point
As Integer x,y
As Uinteger col
End Type
#define map(a,b,x,c,d) ((d)-(c))*((x)-(a))/((b)-(a))+(c)
#define r(f,l) int(Rnd*((l+1)-(f))+(f))
Dim Shared As Integer xres,yres
Screeninfo xres,yres
Screenres xres,yres,32
Dim As Any Ptr image=Imagecreate(xres,yres,Rgb(0,0,0))
For n As Integer=1 To 100
Circle image,(r(0,xres),r(0,yres)),r(10,50),Rgb(Rnd*255,Rnd*255,Rnd*255),,,,f
Next n
Draw String image,(200,100),"HELLO"
Redim As Point p(xres+1,yres+1)
For y As Integer=0 To yres
For x As Integer=0 To xres
p(x,y)=Type<Point>(x,y,Point(x,y,image))'store
Next x
Next y
Sub fillbox(a() As Point,x1 As Integer,y1 As Integer,x2 As Integer,y2 As Integer)
Dim As Integer xpos,ypos
For y As Integer=0 To yres
For x As Integer=0 To xres
xpos=map(0,xres,a(x,y).x,x1,x2)
ypos=map(0,yres,a(x,y).y,y1,y2)
Pset(xpos,ypos),a(x,y).col
Next x
Next y
End Sub
Dim As Integer mx,my
Dim As Integer boxW,boxH
boxW=xres/4
boxH=yres/4
Do
Screenlock
Cls
Put(0,0),image,Pset
Getmouse mx,my
fillbox(p(),mx,my,(mx+boxW),(my+boxH))
Line(mx,my)-(mx+boxW,my+boxH),Rgb(200,0,0),b
Screenunlock
Sleep 1,1
Loop Until Len(Inkey)
Imagedestroy image
Sleep
-
- Posts: 2338
- Joined: May 31, 2005 9:59
- Location: Croatia
- Contact:
Re: Game question
I re-coded this old scrolling engine by Relsoft that clips the area to be drawn of any sized map: http://lachie.phatcode.net/fbscroll.php
I think it might be useful to you.
There was a more elaborate engine I started developing based on it, but kinda abandoned it soon: http://lachie.phatcode.net/screenbyscreen.php
Pitty. It looks fun from this time distance. Hrm...
I think it might be useful to you.
There was a more elaborate engine I started developing based on it, but kinda abandoned it soon: http://lachie.phatcode.net/screenbyscreen.php
Pitty. It looks fun from this time distance. Hrm...
Re: Game question
Ive made mods/edits of quite a few RTS games. A lot of CPU load comes from things like path finding, collision detection etc
You can design the game from the outset to reduce the number of things that happen. Fewer units, slower rates of fire. OPEN RA has a debug mode and it gives you a real time graph a CPU activity for various elements.
OpenRA
http://www.openra.net/
One of the best RTS game ever created.( a lot of design factors just right) and the original ran on a 100mhz Pentium.
You can design the game from the outset to reduce the number of things that happen. Fewer units, slower rates of fire. OPEN RA has a debug mode and it gives you a real time graph a CPU activity for various elements.
OpenRA
http://www.openra.net/
One of the best RTS game ever created.( a lot of design factors just right) and the original ran on a 100mhz Pentium.
Who is online
Users browsing this forum: No registered users and 4 guests