Game question

Game development specific discussions.
Provoni
Posts: 393
Joined: Jan 05, 2014 12:33
Location: Belgium

Game question

Postby Provoni » Feb 16, 2014 17:17

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!
pilot703
Posts: 8
Joined: Feb 16, 2014 12:40

Re: Game question

Postby pilot703 » Feb 16, 2014 17:29

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
TJF
Posts: 3609
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: Game question

Postby TJF » Feb 16, 2014 17:50

rdc
Posts: 1725
Joined: May 27, 2005 17:22
Location: Texas, USA
Contact:

Re: Game question

Postby rdc » Feb 17, 2014 2:25

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.

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.
Provoni
Posts: 393
Joined: Jan 05, 2014 12:33
Location: Belgium

Re: Game question

Postby Provoni » Feb 17, 2014 15:59

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
rdc
Posts: 1725
Joined: May 27, 2005 17:22
Location: Texas, USA
Contact:

Re: Game question

Postby rdc » Feb 17, 2014 21:31

It is really the only way to do it. Any programs that shows a portion of a map or graphics is using this technique.
anonymous1337
Posts: 5494
Joined: Sep 12, 2005 20:06
Location: California

Re: Game question

Postby anonymous1337 » Feb 18, 2014 18:57

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.
NeonMoonshine
Posts: 3
Joined: Feb 07, 2014 19:30

Re: Game question

Postby NeonMoonshine » Feb 19, 2014 3:45

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:

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
c-sanchez
Posts: 128
Joined: Dec 06, 2012 0:38

Re: Game question

Postby c-sanchez » Feb 19, 2014 13:37

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?
dodicat
Posts: 6799
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Game question

Postby dodicat » Feb 21, 2014 0:37

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:

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
 
Lachie Dazdarian
Posts: 2338
Joined: May 31, 2005 9:59
Location: Croatia
Contact:

Re: Game question

Postby Lachie Dazdarian » Jun 04, 2014 23:36

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...
TESLACOIL
Posts: 1769
Joined: Jun 20, 2010 16:04
Location: UK
Contact:

Re: Game question

Postby TESLACOIL » Jun 05, 2014 20:33

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.

Return to “Game Dev”

Who is online

Users browsing this forum: No registered users and 4 guests