123
-=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- (c) WidthPadding Industries 1987 0|722|0 -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=-
Socoder -> Blitz -> Proper Collsions

Page : 1 2 Next
Prev
Mon, 25 Jun 2007, 15:13
Blitz3Dman
I am writing a tile based top down game. I haven't the slightest idea how I'd go about doing collisions.

Help?

-=-=-
There are 10 kinds of people in this world -

( Insert 16 remarks about to what extent people know hex here )
Mon, 25 Jun 2007, 15:26
JL235
I presume this is 2d, other then that some more information would be very useful.

Is this a collision between two images? If so use either the ImagesOverlap or ImagesCollide functions. Full details on how these work and their differences can be found in the Command Reference.

You can also calculate a collision from given positions, widths and height of the two objects your colliding. But if their images, use the Blitz commands.
Mon, 25 Jun 2007, 15:32
Blitz3Dman
Ok, I shall clarify.

I am doing 2d, and I bet I know every collision DETECTING technique in the book. Or at least almost. What I can't figure out is how to use the information to keep the player back. A while back in a completely different game (I was programming to find out how to do collisions but I never could) I tried if you're facing north, force the player south a bit, and the like. But if you changed keys quickly enough, youd end up facing south, but still colliding with the wall you can only run into going north. So you start being forced north.

-=-=-
There are 10 kinds of people in this world -

( Insert 16 remarks about to what extent people know hex here )
Mon, 25 Jun 2007, 16:48
Nolan
I am doing 2d, and I bet I know every collision DETECTING technique in the book.


Well, what have you read so far... the prologue?

-=-=-
nolandc.com
Mon, 25 Jun 2007, 16:55
f4ktor
Write yourself an pixel color intersection detection routine. As accurate as possible in 2D.
Mon, 25 Jun 2007, 17:01
Blitz3Dman
...

I suppose I meant the command reference. Nothing on collisions like that in the command reference, unfortunately.

GAH I know how to detect, just not how to stop the player.

ImagesCollide
ImagesOverlap
ImageRectsOverlap
RectsOverlap
Find distance
Find out if two boxes overlap
but f4ctor's suggestion wouldn't work in this case.

-=-=-
There are 10 kinds of people in this world -

( Insert 16 remarks about to what extent people know hex here )
Mon, 25 Jun 2007, 17:54
JL235
f4aktor Write yourself an pixel color intersection detection routine. As accurate as possible in 2D.

What exactly is that?

So your problem is that you don't know how to interpret that there has been a collision, and so not move into a wall?

Well, here is some pseudo code which should explain it to you.

- Receive input, (let's presume the 'move left' button has been pressed)

- store a copy of the players x and y co-ordinates, and add on the amount to move based on the input given (so moving left would be something like 'playerXCopy = playerX + 5, playerYCopy = playerY + 0' (he's moved 5 places horizontally, 0 vertically))

- use 'imagesOvelapping' to check a collision between the player and the other things in the world. The locations used are the copy of the players location (for the players image) and the co-ordinate of the object being checked against.

- if there is no collision, set the players location to the players copied location used in the collision.

- if there is a collision, do nothing (i.e. do not move the player).

Is this really the problem? Genuinely, it sounds a little trivial. You could model your program in real life. If your moving forward whilst blindfolded and you felt a wall in front of you, to avoid colliding you simply stop moving. You don't take a step forward and then one back, you just don't move forward.
Mon, 25 Jun 2007, 18:36
Blitz3Dman
Thanks, I'll have to try it tomorrow, though, it's kinda late here and I'm too tired to code.

-=-=-
There are 10 kinds of people in this world -

( Insert 16 remarks about to what extent people know hex here )
Tue, 26 Jun 2007, 01:22
Dabz
Linky:-

myweb.tiscali.co.uk/mdplasteringservices/Dizzy.zip

Shows how to do Dizzy (the egg) movement, with x amount of frames up and x amount of frames across.

But, this shows collision detection using ReadPixelFast (Walking up hills etc)

When doing tile based games, I either use bit-shifting and/or Pixel checking.

I find this far better than using Blitz's built in commands.

Dabz


-=-=-
Intel Core i5 6400 2.7GHz, NVIDIA GeForce GTX 1070 (8GB), 8Gig DDR4 RAM, 256GB SSD, 1TB HDD, Windows 10 64bit
Tue, 26 Jun 2007, 02:04
JL235
You use bit-shifting, could you explain further? Why do you find it better? What is the idea or technique behind your bit-shifting collision detection? Could you also post code? With explanation?
Tue, 26 Jun 2007, 09:51
Forklift_Fred
I am also intrigued by this pixel method but I'm guessing from the code, that is a BlitzPlus example

Sorry, I might be able to pick out the relevant parts but it's a bit heavy on Canvas, Gadget, and Event functions for it to be workable in B3D

(Actually, for all I know it could be BlitzMax but you see my problem)

-=-=-
Come rain or shine...
Tue, 26 Jun 2007, 10:38
JL235
I presume the pixel-checking is just a simple case of checking the pixel(s) at the edge or the centre of the egg, when moving If it's the colour of land, you don't move there (maybe go in the other direction), otherwise you do.

But I don't get the bit-shifting bit.

As it happens I made a per-pixel collision detection routine a few weeks ago. First in C# using Managed DirectX and then translated it to Java using Java's Graphics classes. What was interesting though was that instead of checking every pixel of the area that overlaps in order (i.e. line by line reading left to right, up to down), I checked from the outside of the area to the inside. This meant all edges were checked first, and I found in the majority of cases it was faster (although if the collision is at the top of the area or the centre of the area that overlaps it's a bit slower).
Tue, 26 Jun 2007, 11:27
Dabz
I usually use bit-shifting for drawing the tilemap, and collisions for tetris/columns type games, such as the one I posted on the showcase.

The reason I prefer bit-shifting, is because, it keeps me in tune with the 'gridness' of the tilemap. As in, it helps me think of the array in code, as what should appear on the screen. Instead of working on numbers from 0-640 or 0-480, I can just use numbers from 0-19 or 0-14 (Using 32*32 bitmaps) and bit shift them across to form the big numbers.

This also means, that if I want to check on the right hand side of the player for say, a wall, I would just use:-


If tileBank((playerTileX+1),playerTileY = WALL
playerTileX = playerTileX - 1
End if


Or this:-

Graphics 640,480,16,2

;Setback buffer, just in case you are
;using B3D to run the app
SetBuffer BackBuffer()

;Setup misc variables and constants
Const MAP_WIDTH = 20
Const MAP_HEIGHT = 15

Const WALL_BLOCK = 1 ;Red block

;Setup tileGrid array and load a grid into it
Dim tileGrid(MAP_WIDTH,MAP_HEIGHT)

Restore GridData

For loopy = 0 To MAP_HEIGHT-1
For loopx = 0 To MAP_WIDTH-1
Read tileGrid(loopx,loopy)
Next
Next

;Player variables, simply x and y positions
Global playerX = 1
Global playerY = 1


Repeat
Cls

DrawGrid()
MovePlayer()
DrawPlayer()

Color 255,255,255
Text 0,0,"Arrow keys to move blue block"

Flip
Until KeyHit(1)

;Simple draw with a rect stuff
Function DrawPlayer()
Color 0,0,255
Rect playerX Shl 5,playerY Shl 5,32,32
End Function

;Standard movement stuff
Function MovePlayer()
If KeyHit(200) ;Up
If tileGrid(playerX,playerY-1) <> WALL_BLOCK
playerY = playerY - 1
End If
End If

If KeyHit(208) ;Down
If tileGrid(playerX,playerY+1) <> WALL_BLOCK
playerY = playerY + 1
End If
End If

If KeyHit(203) ;Left
If tileGrid(playerX-1,playerY) <> WALL_BLOCK
playerX = playerX - 1
End If
End If

If KeyHit(205) ;Right
If tileGrid(playerX+1,playerY) <> WALL_BLOCK
playerX = playerX + 1
End If
End If
End Function

;This is less complicated when using bitmap image tiles loaded
;using LoadAnimImage, if we had these, we would just simply put:-
;
;DrawImage tiles,loopx shl 5, loopy shl 5, tileGrid(loopx,loopy)
;
;in the nested loop, Instead of the select...case statements.
;
;When we look at the normal byte sequence of bits, which are represented as
;below (which you will probably recognise):-
;
;128,64,32,16,8,4,2,1
;
;By shifting left, say the value 2 by 5 (Blitz: 2 Shl 5), we end up with a value of 64,
;like this:-
;
;128,64,32,16,8 ,4 ,2 ,1
;0 0 0 0 0 0 1 0 <---Starting value (2)
;----Shifting value above------
;0 0 0 0 0 1 0 0 1
;0 0 0 0 1 0 0 0 2
;0 0 0 1 0 0 0 0 3
;0 0 1 0 0 0 0 0 4
;0 1 0 0 0 0 0 0 5

;So looking at that, we can draw our grid to the screen using two For...Next
;loops below, and by making each block 32*32, we get a nice even spread when
; Bit-shifting them by 5!

Function DrawGrid()
For loopy = 0 To MAP_HEIGHT-1
For loopx = 0 To MAP_WIDTH-1
Select tileGrid(loopx,loopy)
Case WALL_BLOCK
Color 255,0,0
Rect (loopx Shl 5),(loopy Shl 5),32,32
End Select
Next
Next
End Function
;Grid data, obviously
.GridData
Data 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,1
Data 1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1
Data 1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,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,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1
Data 1,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,0,0,0,0,0,0,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,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

;If we need to convert screen coordinates back to our grid, we shift the bits right, much like above e.g.
;
; Print 64 shr 5


Simple as that!

I'll do a pixel one too, probably tonight!

BTW Bit-shifting is MUCH faster than using Step 32 in a For..Next loop, so if anyone mentions the command Step, go away!

Oh, and heres another little thing I wrote that uses bit-shifting:-

www.syntaxbomb.com/forum/index.php?action=dlattach;topic=297.0;attach=86

maDenathorn

EDIT: The formatting is terrible, sorry, I had it set out all nice too!

-=-=-
Intel Core i5 6400 2.7GHz, NVIDIA GeForce GTX 1070 (8GB), 8Gig DDR4 RAM, 256GB SSD, 1TB HDD, Windows 10 64bit
Tue, 26 Jun 2007, 12:02
JL235
So your using the bit-shifting to enable you to have 1 position equate to 32 pixels?

Although bit-shifting may be far faster then using a for/next loop, a for/next loop is far quicker to understand when reading and understanding the code, which has far greater benefits in a project.

I also wouldn't really use the fact bit-shifting is faster as a real benefit (for the majority of occasions), because a for/next loop is far from slow. It's written in a different language so it's not such a fair comparison. After profiling my RTS (which is written in Java) I find that during the mainloop; 72% of the time is spent drawing all units and buildings, whilst only 1.5% of the time is spent iterating over the 600 units and 6 buildings.

But still, the idea of using bit-shifting is brilliant and I might use it myself in the future. Although I'd probably wrap it up into a function.

It would be so useful if there was a Blitz profiler.
Tue, 26 Jun 2007, 14:00
Dabz
Or 16 pixels (shl 4), or 8 pixels (shl 3) etc etc

I do actually use it for collision detection, here, it helps we check the collision easily, but when I need to convert screen coordinates back into a tilemap coordinate e.g. when a player moves by 1 pixel, I just shift all the bits right to bring it back down, something like:-

If tileMap(playerX,(playerY shr 5)+1) = WALL

Where playerY contains a normal screen coordinate, and playerX contains a tilemap coordinate (like the example I posted a couple of posts above)

Basically, its my way, and as you suggested, that Step 32 might seem easier to read... But if there is a speedier way of doing something, I'll use it!

Just like arrays are faster than types, but I wouldnt dream of basing a tilemap in a type... It's not right! lol

And it doesnt really take people long to get their heads round bit-shifting, I mean, I found Types harder to understand when first learning Blitz allllll them years ago!

maDenathorn

-=-=-
Intel Core i5 6400 2.7GHz, NVIDIA GeForce GTX 1070 (8GB), 8Gig DDR4 RAM, 256GB SSD, 1TB HDD, Windows 10 64bit
Tue, 26 Jun 2007, 14:51
JL235
It's not so much 'what is bit-shifting' which I see as making the code harder to understand, it's just when you see 'for i = 1 to 10 step 2' you know exactly what it will do, without thinking at all.

If I see '32 << 4' I instinctively know it's '32 bit-shifted 4 places to the left', but then I have to think what the answer is. There is that extra small step.

It may only take a second longer, but reading one piece of code instinctively and thinking for a second on the other (and then keeping that in mind) makes a big difference, especially with code you've never seen before (or not for a long time).

Don't get me wrong, I'm not trying to say your idea is wrong or anything, in fact I really like it. But this is why I would wrap it into a function. So you'd read 'times32 n' instead of 'n << 5'. As bit-shifting isn't always used specifically for multiplying by 32 (like it could be used for converting a hexadecimal colour into it's components), seeing 'times32' tells the reader more about what that code does. Then you then only need to see the real mechanics if you chose to peer deeper behind the code.
Tue, 26 Jun 2007, 14:52
Blitz3Dman
Hm, Dabz... err.. madenathorn, there are [code] [/code] commands here.

Thanks for the help, I will have to code it sometime.
Not in a coding mood. Oh well. Maybe when my mind can be taken off my stomach.

-=-=-
There are 10 kinds of people in this world -

( Insert 16 remarks about to what extent people know hex here )
Tue, 26 Jun 2007, 20:56
magicman
I just make the tiles types, that seems to work.
Tue, 26 Jun 2007, 20:57
Forklift_Fred
Bit Shifting isn't something I'd progressed to but I get the concept (thanks for the refresher). I think it's the applications of it that have lost me in the past. I'm still not sure how it fits into collision detection so I eagerly await you next example

Are there benefits of using Shl 5 rather than *32? Or am I missing the point? Shl 5 sounds clever but is that all it is? Like using big words rather than simple English because it's better.

-=-=-
Come rain or shine...
Tue, 26 Jun 2007, 21:21
hyruleknight
well you could just use the imageoverlap command to see if it hit hit the tile and if you want to make tiles that have different collision sectors you can just use smaller tiles and use the simple solution.

of course having collision sectors would make it easier to use in a map editer and are not very hard to do, you just need a few extra if statements to find which sector(s) your guy is touching. i'd say 4 sectors are sufficient for most games, remember though each block has to evenly divided into 4 smaller ones.

anymore than 4 sections is a waste of time

-=-=-
i like green haired girls...
Wed, 27 Jun 2007, 00:51
JL235
@Forklift_Fred: Bit-shifting is very cheap. Even cheaper then simple addition.
Wed, 27 Jun 2007, 01:42
Dabz
As DiablosDevil says, it's cheap... If you want to optimize your code that little bit more, then use it!

There's a time and a place for any command in Blitz or programming as a whole.

As I mentioned before, bit-shifting is great for tetris/columns type games e.g.



Thats taken from a new project of mine in Max, a psuedo tetris game with a funky twist.

But that small snatch of code there controls the falling tile, if it hits the bottom of the grid, it stops, if it sees another tile in front of it, it stops, and if there is a tile where the new tile begins, it ends the game.

Thats the collision detection.

I learned all this stuff from a tutorial years ago from a blitzer called Vic-e-babes... It caused some agro back then too ('Bit-shifting' V 'Step incrementer'), which to be honest, I'll never understand why. I think he got that much grief, he withdrew the tutorial, which is a shame really, as it had some really good optimizing techniques in there.

Dabz








-=-=-
Intel Core i5 6400 2.7GHz, NVIDIA GeForce GTX 1070 (8GB), 8Gig DDR4 RAM, 256GB SSD, 1TB HDD, Windows 10 64bit
Wed, 27 Jun 2007, 03:03
JL235
But one big problem I can see with using bit-shifting is what if you want to change the tile size? Ok the different bits represent powers of 2, but what if you wanted to set the tile size to 48?. It would be better to have a constant, say TILE_SIZE = 32, and place all calculations around this. Then by simply changing the value of TILE_SIZE, all collision detection and conversions from pixel positions to array positions still work, as they could all run their calculations based on that constant.

That's another reason why I'd wrap the bit-shifting into it's own function. If you wanted to change it so shift 4 places instead of 5, you'd only have to change it once if it's wrapped up into a function. The alternative would be to change every occasion that 'shr 5' appears to 'shr 4', which could potentially lead to bugs if you missed one.
Wed, 27 Jun 2007, 09:05
Dabz


ta-da!

Dabz

P.S. I'm a massive columbo fan!

-=-=-
Intel Core i5 6400 2.7GHz, NVIDIA GeForce GTX 1070 (8GB), 8Gig DDR4 RAM, 256GB SSD, 1TB HDD, Windows 10 64bit
Wed, 27 Jun 2007, 17:50
Trooper David
P.S. I'm a massive columbo fan!


LOL So typical Dabz. I was checking over your code, AND it looks familiar too me. Is it the same one we did in chat room at Syntaxbomb? Then came the columbo comment LOL

-=-=-
Hi
Wed, 27 Jun 2007, 23:50
Dabz
Same technique Dave mate!

Nice to see you... hehehe

maDenathorn

-=-=-
Intel Core i5 6400 2.7GHz, NVIDIA GeForce GTX 1070 (8GB), 8Gig DDR4 RAM, 256GB SSD, 1TB HDD, Windows 10 64bit
Page : 1 2 Next
Prev