defender type screen wrap

Blitz3D Forums/Blitz3D Beginners Area/defender type screen wrap

Bremer(Posted 2003) [#1]
I'm making a game where the screen needs to wrap like in the old Defender game. I have fair success putting the player and enemies on screen, but on the point where it wraps there is a void where it won't draw anything.

What would be a good way of dealing with this type of game setup?


smilertoo(Posted 2003) [#2]
have an overlap area at the join.


Bremer(Posted 2003) [#3]
overlap area? everything is placed dynamically, that is, i check if anything is within the area that is 400 before or after the player and then draws it. But at the place where it goes from zero to 10000 or the other way it doesen't work. I hope that made sense.


_PJ_(Posted 2003) [#4]
You will need an overlap if the program is looking, say, 400 in front and the map is 10000 units wide, nothing after 9600 will be drawn, because you've run out of map. However, If you ensure that when the player reaches 9600 travelling one way, or 400 travelling the other, the position resets, and match the landscape from 9600 to 10000 to the same as 0 to 400, it should work.


Anthony Flack(Posted 2003) [#5]
if it's less than 400 in front, draw it at x,y
if it's more than 9600 behind, draw it at x+10000,y

or something like that.


Bremer(Posted 2003) [#6]
I just can't seem to get this to work. I decided that the screen is 10000 pixels wide and the enemies are supposed to wrap around when they reach either 0 to 9999. The screenlocation does the same, but I can't seem to find out how to translate that into placing the images correctly depending whether or not they are within the 800 pixels that stars at screenlocation. Its quite fustrating, but I guess that its back to the thinking box for a while.


Foppy(Posted 2003) [#7]
I have written a small demo here that uses a technique similar to what Anthony describes. Well I guess the idea is the same on some level, while coding I noticed that this can indeed be quite tricky to figure out. Using a piece of paper and a pen really helps, and even then you have to turn the music off (well I had to).

The important code is in the main function. It checks if a ship is close enough to the player, if so it is drawn. This is the normal case. If the difference between the two is big however, it could be that it is so big because they are both near the edge of the world, on opposite sides. This means they are in fact *close* to each other as the world wraps around! So, if the difference is *big enough*, the ship is also drawn.

In that last case you have to do a bit more work to compute *where* to draw the ship on the screen ("drawOffset"); my program uses 2 different computations based on whether the ship is to the right or to the left of the player.

To be able to see what is going on I added a radar, just like in Defender (more or less). This is really necessary to check if everything works as intended. ;) The three lines on the radar represent the area you can see; the center line is the player position. Reminds me of Falcon Patrol II too... ti ti ti ti de li tiii, ti de li etc. The player moves to the right automatically.

; #########
; constants
; #########

Const SCREENWIDTH  = 800
Const SCREENHEIGHT = 600
Const WORLDWIDTH   = 3500
Const SHIPCOUNT    = 20
Const SCROLLSPEED  = 2


; ######################
; program initialization
; ######################

Graphics(SCREENWIDTH,SCREENHEIGHT)
SetBuffer(BackBuffer())
SeedRnd(MilliSecs())


; #######
; globals
; #######

Global g_playerX


; #########
; SHIP type
; #########

Type SHIP
	Field f_x
	Field f_y
End Type


; ######################
; radar drawing function
; ######################

Function drawRadar()
	; draw radar background
	Color(0,0,200)	
	Rect(0,0,WORLDWIDTH/10,SCREENHEIGHT/10,True)
	
	; plot ships
	Color(255,255,255)
	For ship.SHIP = Each SHIP
		Plot(ship\f_x/10,ship\f_y/10)
	Next
	
	; plot line at player position
	Color(200,200,200)
	Line(g_playerX/10,0,g_playerX/10,SCREENHEIGHT/10)
	
	; compute left and right screen border position, maybe wrap
	leftBorder = g_playerX-SCREENWIDTH/2
	If (leftBorder < 0) Then
		leftBorder = leftBorder + WORLDWIDTH
	End If
	rightBorder = g_playerX+SCREENWIDTH/2
	If (rightBorder > WORLDWIDTH) Then
		rightBorder = rightBorder - WORLDWIDTH
	End If
	
	; draw left and right border on radar
	Color(175,175,175)
	Line(leftBorder/10,0,leftBorder/10,SCREENHEIGHT/10)
	Line(rightBorder/10,0,rightBorder/10,SCREENHEIGHT/10)
End Function


; #################
; main program loop
; #################

; create ships first
For i = 1 To SHIPCOUNT
	ship.SHIP = New SHIP
	ship\f_x  = Rand(0,WORLDWIDTH)
	ship\f_y  = Rand(0,SCREENHEIGHT)
Next

; player starts in center of world
g_playerX = WORLDWIDTH/2

; loop until player presses escape
While(Not(KeyHit(1)))

	Cls

	; get screen position of player -> always center of screen
	drawPlayerX = SCREENWIDTH/2
	
	; draw line representing player
	Color(0,255,0)
	Line(drawPlayerX,0,drawPlayerX,SCREENHEIGHT)

	; draw ships
	Color(255,255,255)
	For ship.SHIP = Each SHIP
	
		; compute offset compared to player position (distance of going from player to ship)
		offset = ship\f_x - g_playerX
	
		; default is not to draw
		draw = False
		
		; if absolute difference is smaller than screen width...
		If (Abs(offset) <= SCREENWIDTH) Then
			
			; draw at offset
			drawOffset = offset
			draw       = True
		
		; if absolute difference is big enough so that wrapping occurs...
		Else If (Abs(offset) > (WORLDWIDTH-SCREENWIDTH)) Then
		
			; compute drawing-offset based on player position and ship position
			If (ship\f_x > g_playerX) Then
				drawOffset = -g_playerX - (WORLDWIDTH-ship\f_x)
			Else
				drawOffset = ship\f_x + (WORLDWIDTH-g_playerX)
			End If
			draw = True
		
		End If
		
		; finally, draw (if visible) using computed drawing-offset
		If (draw) Then
			Oval(drawPlayerX+drawOffset,ship\f_y,5,5,True)	
		End If
	Next
	
	; draw the radar
	drawRadar()
	
	Flip

	; move the player to the right, maybe wrap
	g_playerX = g_playerX + SCROLLSPEED
	If (g_playerX > WORLDWIDTH) Then
		g_playerX = 0
	End If
Wend

Delete Each SHIP

End



robleong(Posted 2003) [#8]
I used an overlap for my Defensor game, so I would recommend it too!


Bremer(Posted 2003) [#9]
While I wasn't able to use the code provided by Foppy directly it did stear me in the right direction, and now I know how useful the abs() command is. Thank you for your input. Now I can get on with the rest of the game. I have 4 different enemy types working already and all the bullet code is done, so now I'll start working on the paralaxing surface graphics and later some more enemy types. I just hope that I can create some graphics for it that is nice to look at because while I might be able to code, I'm not that great in the graphics department :-)

Thanks again,