View Screens

BlitzMax Forums/BlitzMax Beginners Area/View Screens

Joe90bigrat90(Posted 2011) [#1]
How would i go about having to view screens on the screen that scroll when the player moves.
Do i need to draw a massive bitmap for the screen (say double in width of screen and double of height in screen.
So say player 1 moves right viewscreen 1 moves to the right and i guess it shows more of the bitmap.

Just curious as to how this is done.

Thankyou

Kind Regards

Joe


Sloan(Posted 2011) [#2]
I did a tutorial a while back about parallax scrolling that you might find useful:

Parallax scrolling simulates the real-world effect of closer-to-you moving objects moving faster than objects further away. If you are on a train for example, you see the ground whizzing away from you, but the mountains in the distance hardly move.

In order to simulate this in a computer game, we move foreground objects faster than background objects. The effect is quite stunning, and was used a lot in the days of the Amiga.

Graphics 640, 480, 16
HideMouse()
Incbin "crackice.png"
Incbin "dreamscape.png"
Incbin "moon.jpg"


Sets up the graphics and includes the image files into the binary executable.

Type TBackDrop

   	Field speed:Float
   	Field x:Float
   	Field y:Int
   	Field width:Int
   	Field img:TImage

   	Method Update()
      	 x = x - speed
  	
      	 If x < -width
       	 x = 0
      	 End If 
   	End Method


   	Method Draw()
    	 DrawImage(img, x, y)
      	 If x < -(width-640)
       	 DrawImage(img, x+width, y)
      	 End If 
   	End Method

   	Function Create:TBackDrop(nx:Int, ny:Int, ..
      	 width:Int, speed:Float, imgFile:String)
      	 Local o:TBackDrop = New TBackDrop
         	 o.speed = speed
         	 o.x = nx
         	 o.y = ny
         	 o.width = width
         	 o.img = LoadImage(imgfile)	
   	
         	 Return o
   	End Function
End Type


The TBackDrop type has been created to allow the easy creation of a moving background image. We will use two of these Types to create the parallax scrolling effect.

Local Scroll1:TBackDrop = TBackDrop.Create(0, 224, ..
         1024, .2, "incbin::dreamscape.png")
Local Scroll2:TBackDrop = TBackDrop.Create(0, 224, ..
         1024, .5, "incbin::crackice.png")
Local Moon:TImage = LoadImage("incbin::moon.jpg")


Now we create the objects. Notice that we use the Type name to create an object. This is because Functions are accessible only by using the UDT's name.

While Not KeyHit(KEY_ESCAPE)

   	Scroll1.Update()
   	Scroll2.Update()

   	Cls
   	DrawImage(Moon, 0, 0)
   	Scroll1.Draw()
   	Scroll2.Draw()
   	Flip

Wend


In the main loop, we update the respective backgrounds and then draw them to the screen. This is repeated until the user presses the ESCAPE key. And then...

Local t:Int = MilliSecs()
Local v:Int = 255

While v > 0
   	If MilliSecs()> t+25
     	 t = MilliSecs()
     	 SetColor(v, v, v)
     	 v = v - 5
   	End If 

   	Cls
   	DrawImage(Moon, 0, 0)
   	Scroll1.Draw()
   	Scroll2.Draw()
   	Flip

Wend


Once the user presses the escape key, we still draw the screen, but we add a nice fade out effect. This is achieved by using SetColor. By lowering the values for the red, green and blue components, we can darken the images displayed. This is because SetColor affects every draw operation performed after it.

Full code and graphics are available in this zip archive.


Midimaster(Posted 2011) [#3]
there are two kinds of "moving background", one of them is the real world image sloan is talking about. A more simple way is to have tiles or small strips that represent a part of the world.

here is an example:

SuperStrict
Graphics 600,400
Global BackGround:TImage[100] , Position%
'
' this is only to simulate a set of 100 background strips:
' you will replace this with a set of (3-100) images
'     For i%=0 to 99
'          BackGround[i]=Loadimage(....
'     Next
'
		Local NewRandom#, LastRandom#, i%
		LastRandom=250
		SeedRnd MilliSecs()
		For I% = 0 To 99
			'sky
			SetColor 0,0,55
			DrawRect 0,0,10,300
			'stars
			SetColor 255,255,255
			For Local j%=0 To 5
				Plot Rand(0,10),Rand(0,300)
			Next
			'gras
			SetColor 0,55,0
			DrawRect 0,300,10,400
			'mountain
			SetColor 111,111,111
			NewRandom = Rnd(LastRandom-10,LastRandom+10)
			If NewRandom>300 Then NewRandom=300
			Print NewRandom
			If I=99 Then NewRandom=250
			Local tri#[]=[0.0,300.0 , 10.0,300.0 , 10.0,NewRandom , 0.0,LastRandom]
			DrawPoly Tri
			SetColor 255,255,255
			LastRandom = NewRandom
			BackGround[i]=CreateImage(10,400,DYNAMICIMAGE)
			GrabImage BackGround[i],0,0
		Next


' here is the main program:

Global WorldWidth%=1000
Global NumberOfStrips%=100
Global StripWidth%=10
Repeat
	Cls
	Position = (Position+1) Mod WorldWidth
	Print Position
	For Local i%=0 To NumberOfStrips-1
		Local ImagePos% = -Position + i*StripWidth
		If ( ImagePos > -StripWidth ) And ( ImagePos<600 )
			DrawImage Background[i] , ImagePos, 0
		EndIf
		If ( WorldWidth+ImagePos > -StripWidth ) And ( WorldWidth+ImagePos < 600 )
			DrawImage Background[i] , WorldWidth+ImagePos , 0
		EndIf
	Next		
	Flip 
Until KeyHit(Key_Escape)



Joe90bigrat90(Posted 2011) [#4]
wow thanks it looks stunning doesnt it although i dont think ill be writing any programs like this.

Well an idea i had was to draw an overhead view screen so youre looking above the player. nothing 3d just 2d so player moves in different directions the screen scrolls. I dont know if you remember a game called Extreme Violence on the Amiga. It was only a simple game but i want to be able to draw 2 view screens next to each other looking down ont he players. Left viewscreen player 1 and right player 2.
I guess i could use this code to achieve this effect.

thanks a lot.


xlsior(Posted 2011) [#5]
Keep in mind that there are limits on the size of a single image that you can load -- most videocards won't handle anything larger than 4096x4096, and older cards may have smaller limits.

Depending on the size of your image, you may need to chop it up into several smaller tiles for maximum compatibility. (eg. 512x512, or 1024x1024)


Midimaster(Posted 2011) [#6]
You can also change the "strips" (10x800pix) to "tiles" (100x100pix). This would be better, if you scroll in X and Y direction.

If your background is a painted picture, you may divide it into tiles of 100x100 pixels.

If your background repeats often. (e.g. forest) you should read about "tile based games". In this model there is no need of pre-painting all. But the game will "compose" the background from several basic tiles on the fly. So you can construct a "infinite" world

SuperStrict
Graphics 600,400
Global tiles:TImage[20,20] , PositionX% , PositionY%
'
' this is only to simulate a set of 400 tiles:
' you will replace this with a set of  tiles of your images
'     For i%=0 to 19
'        For j%=0 to 19
'          Tiles[i,j]=Loadimage(....
'        Next
'     Next
'
		Local NewRandom#, LastRandom#, i% , j%
		LastRandom=250
		SeedRnd MilliSecs()
		For I% = 0 To 19
			For j% = 0 To 19
				Cls
				SetColor Rand(200),Rand(100,200),Rand(200)
				DrawRect 0,0,100,100
				Tiles[i,j]=CreateImage(100,100,DYNAMICIMAGE)
				GrabImage Tiles[i,j],0,0
			Next
		Next


' here is the main program:

Global WorldWidth%=1000
Global NumberOfTiles%=20
Global StripWidth%=100
Repeat
	Cls
	PositionX = (PositionX+1) Mod WorldWidth
	PositionY = (PositionY+1) Mod WorldWidth
	Print PositionX
	For Local i%=0 To NumberOfTiles-1
		Local ImagePosX% = -PositionX + i*StripWidth
		If ( ImagePosX > -StripWidth ) And ( ImagePosX<600 )
			
			For Local j%=0 To NumberOfTiles-1
				Local ImagePosY% = -PositionY + j*StripWidth
				If ( ImagePosY > -StripWidth ) And ( ImagePosX<600 )
					DrawImage Tiles[i,j] , ImagePosX, ImagePosY
				EndIf
			Next
		EndIf
	Next		
	Flip 
Until KeyHit(Key_Escape)


Last edited 2011


ima747(Posted 2011) [#7]
just an FYI regarding chopping things into smaller segments. If possible it's best to keep them power of 2 dimensions (i.e. 8, 16, 32, 64, 128, etc.) since almost all implementations will upscale the images to pow2 anyway when stored on the card, using less wastes a little vram which can add up. Further if possible it's best to keep them pow2 squared (as in 8x8 not 8x16), as older and very low end cards require this and again, you'll be wasting space on those systems if you do less.

Sometimes the mental savings of being able to do simpler math makes the vram savings a non issue, but if you're already going to be slicing and dicing you might as well get the most bang for your buck :0)