how would u...(bout collisions)

Blitz3D Forums/Blitz3D Beginners Area/how would u...(bout collisions)

Apollonius(Posted 2004) [#1]
This is for BlitzPlus,

If u draw squares on ur screen, green,blue and one yellow(player) everything 32x32. And you want the blue squares to collide with the yellow(player) and stop it when it hit it... u need to make somekind of area like inbetween x,y to x,y if it hits that spot which would be a blue square then stop the command to move the yellow thing forward or something,

could anyone help me? a mini-simple example would help alot! Thannk yooou~


soja(Posted 2004) [#2]
There are ready-made examples for imagescollide, rectscollide, imagesoverlap, rectsoverlap. Something like that is what you want.


Apollonius(Posted 2004) [#3]
nah I doubt they're exactly what I want oh well I'll try to do this one on my own...


I prolly can succeed with my extended knowledge of BP! hahaha lol <dies>

they all require an image which i dont want to use


WolRon(Posted 2004) [#4]
This does not require an image!

RectsOverlap (rect1 X,rect1 Y,rect1 Width,rect1 Height,rect2 X,rect2 Y,rect2 Width,rect2 Height)
Parameters
rect1 X = rectangle 1 x location
rect1 Y = rectangle 1 y location
rect1 Width = rectangle 1 width
rect1 Height = rectangle 1 height
rect2 X = rectangle 2 x location
rect2 Y = rectangle 2 y location
rect2 Width = rectangle 2 width
rect2 Height = rectangle 2 height

Description
This command will take two rectangular locations on the screen and see if they overlap. You will need to know the x, y, width, and height of both regions to test.

I'm still trying to find a real good logical use for this command with all the other collision commands available to you like ImagesOverlap, ImagesCollide, ImageRectOverlap, and ImageRectCollide. My guess is that this is the absolute fastest possible collision method available and useful to those wishing to write their own collision routines.

Unlike the other collision commands, there is no image to detect a collision with - simply one rectangular location overlapping another. You could probably use this command instead of the ImageRectOverlap command, as they are really basically doing the same thing (and I betcha this is faster).

This would be useful for very easy-going 'Monkey Island' games to check the position of your pointer against a screen location (or 'hot spot') when pixel perfect accuracy (heck, image graphics in general) are not really needed.


Neo Genesis10(Posted 2004) [#5]
Here is a piece of code I did for someone else who recently asked me this very question. The code is for Blitz 2D, but all the commands work perfectly well in B+. All the images are created by the program, so no external files are needed.

Use the cursor keys to move the man around and check for collisions. Its commented as well, so you should be able to figure out how it works.
Graphics 640, 480
SetBuffer BackBuffer()

Global man = CreateImage(32, 48)
Global tile = CreateImage(32, 32, 4)

; This just creates the images needed. Nothing collision related.
CreateImages

; This is where we create types to store our map information

Type map_tile
	Field block_type	; 0 - Passable, 1 - Unpassable
	Field graphic
End Type

; Here we create a 2D array to represent the map. Think of the first
; and second subscripts as the  X and Y coordinates.

Dim map.map_tile(30, 20)

; This loads in a basic map for the example
CreateMap

; Here we create offsets for drawing

Global Xoffset, Yoffset

Main
EndGraphics
End

Function Main()

	quit = False
	
	playerX = 64
	playerY = 80
	
	ClsColor 0, 0, 255
	
	; Here is the main game loop
	
	While quit = False
	
		; Everytime a key is hit, the collision check function ensures
		; that moving in that direction wont cause an impact. If it doesnt
		; the player moves.
	
		If KeyDown(200)
;			Stop
			If CheckCollision(playerX, playerY - 4) = False
				playerY = playerY - 4
			EndIf
		EndIf
		
		If KeyDown(208)
			If CheckCollision(playerX, playerY + 4) = False
				playerY = playerY + 4
			EndIf
		EndIf
		
		If KeyDown(203)
			If CheckCollision(playerX - 4, playerY) = False
				playerX = playerX - 4
			EndIf
		EndIf
		
		If KeyDown(205)
			If CheckCollision(playerX + 4, playerY) = False
				playerX = playerX + 4
			EndIf
		EndIf	
	
		; This simply offsets the screen to keep our man centered
	
		If (playerX - Xoffset) < (GraphicsWidth() / 3)
			Xoffset = Xoffset - 4
		EndIf
		
		If (playerY - Yoffset) < (GraphicsHeight() / 3)
			Yoffset = Yoffset - 4
		EndIf
		
		If (playerX - Xoffset) > ((GraphicsWidth() / 3) * 2)
			Xoffset = Xoffset + 4
		EndIf
		
		If (playerY - Yoffset) > ((GraphicsHeight() / 3) * 2)
			Yoffset = Yoffset + 4
		EndIf
	
		Cls
		DrawMap
		DrawImage man, (playerX - Xoffset), (playerY - Yoffset)
		Flip
	Wend

End Function

Function CheckCollision(x, y)

	; Since our man is larger than most tiles, we need to check all four corners.
	; For this reason I will use a For loop.

	For i = 1 To 6
	
		nx = x
		ny = y
	
		Select i
		Case 2
			nx = x + 31
		Case 3
			ny = y + 47
		Case 4
			nx = x + 31
			ny = y + 47
		Case 5
			ny = y + 24
		Case 6
			nx = x + 31
			ny = y + 24
		Case 5
			
		End Select
	
	
		; The following converts the x and y coords into an actual map array position
		tx = Floor(nx / 32)
		ty = Floor(ny / 32)
		
		; Important to ensure we dont try checking outside the array boundaries
		If tx >= 30 Or tx < 0 Then Return True
		If ty >= 20 Or ty < 0 Then Return True
		
		; Check which block we are moving into
		Select map(tx, ty)\block_type

		Case 0						; PASSABLE
			
			; Do nothing, since the player can pass through
			
		Case 1						; UNPASSABLE
			Return True		; Tell the main loop the player has bumped something
		End Select
	
	Next
	
	Return False

End Function

Function CreateImages()

	SetBuffer ImageBuffer(man)
	ClsColor 255, 255, 255
	Cls
	Color 0, 0, 0
	Oval 7, 0, 16, 16, False
	Line 1, 17, 30, 17
	Line 15, 16, 15, 32
	Line 15, 32, 0, 48
	Line 15, 32, 31, 48
	
	MaskImage man, 255, 255, 255
	
	For i = 1 To 4
		Select i
		Case 1
			ClsColor 255, 255, 255
		Case 2
			ClsColor 0, 0, 255
		Case 3
			ClsColor 0, 255, 0
		Case 4
			ClsColor 255, 0, 0
		End Select
		
		SetBuffer ImageBuffer(tile, i-1)
		Cls
	Next
	
	ClsColor 255, 255, 255
	SetBuffer BackBuffer()

End Function

Function CreateMap()

	Restore mapdata
	For y = 0 To 19
		For x = 0 To 29
		
			; Create a new map tile
			map.map_tile(x, y) = New map_tile
			Read map(x,y)\block_type
			
			; Just for the example, we are using the same frame number as the
			; block type
			map(x,y)\graphic = map(x,y)\block_type
			
		Next
	Next


End Function

Function DrawMap()

	tx = Floor(Xoffset / 32)
	ty = Floor(Yoffset / 32)
	
	; This gets the number of odd pixels we need to offset drawing by
	PXoffset = Xoffset - (tx * 32)
	PYoffsey = Yoffset - (ty * 32)
	
	If tx < 0 tx = 0
	If ty < 0 ty = 0
	If tx >= 30 tx = 29
	If ty >= 20 ty = 19
	
	For x = tx To (tx + 19)
		For y = ty To (ty + 15)
			If y < 20 And x < 30
				
				; Heres where we get the actual drawing coordinates
				dx = (x * 32) - Xoffset
				dy = (y * 32) - Yoffset
				
				DrawImage tile, dx, dy, map(x,y)\graphic

			EndIf
		Next
	Next

End Function

.mapdata
Data 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
Data 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,1
Data 1, 0, 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,1
Data 1, 0, 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,1
Data 1, 0, 1 ,1 ,1 ,1 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,1
Data 1, 0, 1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,1
Data 1, 0, 1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,1
Data 1, 0, 1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,1 ,1 ,0 ,0 ,1
Data 1, 0, 1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,1
Data 1, 0, 1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,1
Data 1, 0, 1 ,1 ,1 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,1
Data 1, 0, 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,0 ,0 ,1 ,0 ,0 ,1
Data 1, 0, 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1
Data 1, 0, 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1
Data 1, 0, 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1
Data 1, 0, 1 ,1 ,1 ,1 ,1 ,1 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1
Data 1, 0, 0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1
Data 1, 0, 0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1
Data 1, 0, 0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1
Data 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1



Apollonius(Posted 2004) [#6]
Neo that code is pretty nice but in B+ I don't see the square u hit with the little character I only see a blue bg


Neo Genesis10(Posted 2004) [#7]
Substitute the created images for your own loaded versions and it'll work perfectly. I believe this has something to do with how B+ deals with buffers.


Ross C(Posted 2004) [#8]
*RossC smacks Kaisuo with the lazy stick*

:P