side-scrolling tutorials?

Blitz3D Forums/Blitz3D Beginners Area/side-scrolling tutorials?

ErikT(Posted 2003) [#1]
Anyone know about any good 2d side-scrolling tutorials? I want to move entities around and have a background image move along relative to the entities position. If an entity moves to one edge of the screen, that entity should be prevented from moving outside the screen but instead move the background (and the other entities) backwards to simulate camera movement. I've tried to work something smart out on my own but I'm mathematically challenged; this stuff makes my head hurt. Checked the code archives but didn't see anything relevant there. Any pointers or help would be much appreciated.


semar(Posted 2003) [#2]
An easy but effective way to achieve 2D scrolling, is the use of 'Origin' command.

Origin x,y sets an x,y offset where the subsequent graphic commands will be drawn with.

In more detail, if you have a sprite that attempt to move after the upper left edge of the screen, then you could:

- draw the sprite at 0,0

- use origin command, and set the new offset for the next drawing commands; the amount of the x,y offset, is given by the x,y speed that you want to use to move your sprite - which is the same speed the backround would move at.

- draw the other stuff, for example background, and the other sprites; their drawing position will be automatically affected by the offsets set with the Origin command; that means, they will be translated in relation to the main sprite.

Hope this helps,
Sergio.


Who was John Galt?(Posted 2003) [#3]
The multilayer scrolling demo that comes with Blitz is worth a look - hack it apart to your hearts delight. I have a nice little function that detects collisions between sprites and a tile map I'll post if u want.


Neo Genesis10(Posted 2003) [#4]
Try something like the following (depending on how you set up your maps, of course).

Const TILESIZE = 32
Global tiles = LoadAnimImage("tiles.bmp", TILESIZE, TILESIZE, 0, 16)

Type platform
	Field x,y
	Field frame
End Type

; The offsets say how far left or down the map has been scrolled

Function DrawMap( Xoffset, Yoffset )

	; Cycle through each platform created
	For p.platform = Each platform
		x = p\x - Xoffset
		y = p\y - Yoffset

		; Check if tile is visible (on-screen)
		If (x > -TILESIZE) And (x < GraphicsWidth())
			If (y > -TILESIZE) And (y < GraphicsHeight())
				; If visible, draw it
				DrawBlock tiles, p\x - Xoffset, p
			EndIf
		EndIf
	Next

End Function
Adding to the offsets in this example will scroll the screen right and down (it is assumed that the offset of 0, 0 is the top-left corner of the map). Using Origin is not recommended as it affects all drawing commands including viewports. This means if you were to put a heads up display in the game, it would scroll with the map. It also means you're "drawing" stuff which isnt onscreen which can slow the game down.


ErikT(Posted 2003) [#5]
Hey, thanks a lot. I managed to produce a working piece of code by myself, but it's kludgy and ugly as hell so I think I'll just re-write the whole thing.

@ 0DFEx: That would be great. Thanks.


Who was John Galt?(Posted 2003) [#6]

Function draw_block_map(x,y)	
	bmap_blocktlx=x/bmap\tileSide	;Index of top left block that needs pasting
	bmap_blocktly=y/bmap\tileSide	;Index of top right block
	If bmap_blocktlx<0 Then bmap_blocktlx=0
	If bmap_blocktly<0 Then bmap_blocktly=0
	bmap_drawxpos=bmap_blocktlx*bmap\tileSide-x
	bmap_offy=bmap_blocktly*bmap\tileSide-y
	bmap_drawypos=bmap_offy
		
	bmap_lx_max=bmap_blocktlx+bmap\screenxblksminus1
	bmap_ly_max=bmap_blocktly+bmap\screenxblksminus1
		
	If bmap_lx_max>bmap\blocksx-1 Then bmap_lx_max=bmap\blocksx-1
	If bmap_ly_max>bmap\blocksy-1 Then bmap_ly_max=bmap\blocksy-1
		
	For bmap_lx=bmap_blocktlx To bmap_lx_max
		For bmap_ly=bmap_blocktly To bmap_ly_max
			DrawBlock bmap_blocks,bmap_drawxpos,bmap_drawypos,block_map(bmap_lx,bmap_ly)
			bmap_drawypos=bmap_drawypos+bmap\tileSide
		Next
		bmap_drawypos=bmap_offy
		bmap_drawxpos=bmap_drawxpos+bmap\tileSide
	Next
End Function

Function dotMapCollide(dotx,doty) ; Must have a global 'dot' graphic defined
	bmap_blocktlx=dotx/bmap\tileSide	;x index of block dot is in
	bmap_blocktly=doty/bmap\tileSide	;y index of block dot is in
	Select (bmap_blocktlx>-1 And bmap_blocktlx<bmap\blocksx And bmap_blocktly>-1 And bmap_blocktly<bmap\blocksy)
	Case 0
		Return 0
	Case 1
		Return ImagesCollide(dot,dotx,doty,0,bmap_blocks,bmap_blocktlx*bmap\tileSide,bmap_blocktly*bmap\tileSide,block_map(bmap_blocktlx,bmap_blocktly))
	End Select
End Function

Function imMapCollide(image,x,y,frame) ;optimiZE!!!!!!!!!!!
	;imtlx=x-ImageXHandle(image)
	;imtly=y-ImageYHandle(image)
	;imbrx=imtlx+ImageWidth(image)
	;imbry=imtly+ImageHeight(image)
	
	;blocktlx=imtlx/bmap\tileSide
	;blocktly=imtly/bmap\tileSide
	;blockbrx=imbrx/bmap\tileSide
	;blockbry=imbry/bmap\tileSide
	
	col=0
	;For bx=blocktlx To blockbrx
	;	For by=blocktly To blockbry
	;		If ImagesCollide (image,x,y,frame,bmap_blocks,bx*bmap\tileSide,by*bmap\tileSide,block_map(bx,by)) Then col=1	
	;	Next
	;Next
	Return col
End Function



There you go - you'll have to do a bit of figuring out to work it into a running piece of software. Designed only to work with square map blocks as it stands. May need a few globals defining. block_map array holds the tile values. You have collision testing for both points and images with the terrain. Can't remember why the image map collision was all commented out - it will probs work if you uncomment it.


Tri|Ga|De(Posted 2003) [#7]
Hi

I've made this Mappy tutorial

Link.