Free Web Hosting Provider - Web Hosting - E-commerce - High Speed Internet - Free Web Page
Search the Web

   

vbProgramming
Tutorials - Bit String Flicking

 
       
vbProgramming Home :: vbProgramming Forums :: Tutorials :: Contact :: Links 

This tutorial will teach you Bit String Flicking, one of the more complicated ways to do
collision detection. Bit String Flicking uses binary to do collision detection. Since this
is a complicated tutorial, there will not be any graphics used, but graphics can be easily
implemented if needed.

 

 

 

Binary!!!
This tutorial is the most complicated one yet - which is why we're not gonna use graphics, although you could easily
implement them into your program if you wish. The scary thing about this tutorial is that we're gonna use binary(don't
worry if you dont know what binary is/how it works, ill explain everything you need to know about binary for this tutorial.

Well, the first thing you just might want to know is that binary numbers are represented through 0's and 1's. Nowadays, we use the decimal system (DEC means 10, there's 10 different numbers in the decimal system: 0 through 9). Similarily, Binary uses 2 numbers (BI means 2, there's 2 different numbers that you can use: 0 and 1)

Well how do you count numbers using binary? Well let's start with 0.
(Left= Decimal and Right = Binary)

0 0
1 1
2 10
3 11
4 100

Do you see the pattern? For the next number in binary, you just try to form the next bigget number possible using 0's
and 1's. For example, after 3 (11) why does it go to 4 (100)? Becuase using 0's and 1's you cant really form another higher double digit number using 0's and 1's. (By the way, if you have "all 1's" then you add a digit. For example,
7 is 111. Since you have "all 1's" you have to add a digit: 8 is 1000.

Knowing the binary numbers isnt important (for this tutorial). There's only 1 important thing you have to notice:
2^X results in a "1" on the left side of a binary number, followed by X 0's(WOAH that sounded confusing.. i cant think of any other way of explaining - so here's an example)

1(2^0)   = 1
2(2^1)   = 10
4(2^2)   = 100
8(2^3)
  = 1000
16(2^4) = 10000

OK, so i said this:
"2^X results in a "1" on the left side of a binary number, followed by X 0's"
Substitute in numbers for X
"2^3 results in a "1" on the left side of a binary number, followed by 3 0's" = 1 followed by 3 0's = 1000.

Eh? Another way of looking at it is this:

" 2^X results in a 1 in the Xth digit" (in this explanation, you're not concerned about the 0's but rather the position of
- Just a quick note, the "first" digit is considered to be the 0th digit.

4(2^2)   = 100

Look at the above example, see how the 1 is on the 2nd digit(remember that the rightmost digit is the 0th digit).

This is an important concept which we'll use later in this tutorial. It might strike you as pointless right now, but why would I spend 5 min typing this if we're not really going to use it? :p.

Oh by the way, open MS Calculator (Start -> Run -> Calc) to convert from decimal to binary (you need to go to View | Scientific)

Binary Operators
The most basic operators we're going to talk about are these 2:

And
Or

You might be wodnering why a boolean check (If Walking And Running - for example) be used with binary? This is becuase VB.NET uses binary to check whether they both are true (stunned eh?).

We'll talk about booleans soon. For now let's worry about And-ing and Or-ing the binary numbers.
This might seem strange, but you can And numbers.

If 2 And 3 Then
'why the heck are we anding 2 and 3
End If

How do we And numbers? We gotta And their binary counterparts.

AND
1 1 = 1
0 0 = 0
0 1 = 0
1 0 = 0

Scroll back up to view this "table" (aka Truth Table). Let's And 2 and 3

            10
 AND  11
-------------
            10

You might be wondering how on earth i got that. Look above at the Truth Table for And. I set the problem up similar to an addition problem. Now I just use the Truth Table. The first column has 2 numbers, 0 and 1. I look at the Truth Table and see that 0 and 1 produce 0. So I write that down. I do the same for the 2nd column (1 and 1), and write down 1.

We see that it produces 10 (in binary of course). We know that 10 is the same as 2 in decimal. Let's prove that we got the right result. Go to VB.NET, create a new project called Bit String Flicking and in form1_Load type in
MessageBox.Show(2 And 3)

You should get "2" when the form loads. Heh heh heh. Weird.
Ok, just note this down:
True =  1
False = 0

OK, look at this logically (dont use binary yet)

If True And True then
messagebox.show ("this will always execute")
End If

(Think about it as like .. "If Walking And Running Then", pretend Walking and Running are both True)
Obviously, each time you execute the if statement, it'll messagebox that.

Same holds true for False:

If False and False then
MessageBox.show("This will always execute")
End If

ex:
If Happy = False And Glad = False Then
Messagebox.show("sad") ' DONT ASK LOL!
End If

Now look back up at the truth table, you should see a connection. Remmeber 0 = false and 1 = true.
0 AND 0 = 1 ' if the "if" statement 'gets back a 1' then it'll execute whats in between If and End If.
1 AND 1 = 1
0 AND 1 = 0
1 AND 0 = 0

Can't you kinda see how that works?

----

OK, now let's experiment with OR

If Running Or Walking Then
'Messagebox.show("He's moving")
End If

Or requires only one side to be True in order for it to execute the messagebox. If both are true it'll still execute. Only if both are false, it wont execute. Here's a Truth Table for Or:

OR
0 0 = 0
1 1 = 1
1 0 = 1
0 1 = 1

See how that works? Let's try an example:
MessageBox.Show(2 Or 3)

       10
OR 11
---------
       11

(oh by the way, for those of you who are just skimming this tutorial, "messagebox.show(2 or 3)" wont 'pick and choose' which to display - 2 or 3 :p)

We see that 11 in binary = 3 in decimal - so obviously it will display 3 each time.

Using it in our program
OK so we learned all this binary stuff. In order for this to be worthwhile, we have to use this in our program.
There's a couple things i want to point out before starting. An Integer has 64 bits. this means that it can hold 64 binary "digits". So the number 1 in binary for an integer would really look like this:

00000000000000000000000000000000000000000000001... never mind :p, there's 63 0's followed by a 1.

If you wish, you could dim an Int32 or an Int16 (which hold 32 and 16 bits, respectively).

Here's what we're goign to do. We're going to use binary for collision. How? we're goign to store each tile of the map into a bit (a 0 or a 1). In our case, 1 means that the tile is occupied, and 0 means that the tile is free.

Pretend we're using an imaginary Integer type called Int4 - it doesnt exist (just for simplicity so that i dont really have to spend time drawing 0's) - pretend our map is 4 by 4.


Dim line1 as int4
Dim line2 as int4
Dim line3 as int4
Dim line4 as int4

by default, integers are 0. So before setting up our tiles, the map would look like this in binary:

0000 'line1
0000 'line2
0000 'line3
0000 'line4

First of all, there's something we need to fix: Rather than 'dimming' 4 lines, we might as well use an array:

Dim line(3) as Int4 'remember, the 0 counts as an element so there's 4 elements.

Pretend there's an object at tile (0,0).

All we gotta do is this:
Line(0) = 2^0

Let me explain :p.
We know that 2^0 is 0001 in binary. (assuming that we're using "int4's, there would be 3 0's behind the 1
        0000
OR  0001
-------------
        0001

So our map would look like this

0001 'line(1)
0000 'line(2)
0000 'line(3)
0000 'line(4)

(Hey by the way, don't worry about the 1 being in the top right hand corner even though the object is in the top left hand corner - ill explain that later - it turns out that it doesn't really matter)

The formula for setting a bit is this
Line(y) = 2^(x)
Since our x and y's are 0 and 0, we just plugin 0 and 0.

Now how do we check for collision?
We just 'And' it!

If line(0) And (2 ^ 0) Then
MessageBox.Show("Collided" )
End If

The formula for checking for collision is this:
If line(y) And (2 ^ x) Then

How does that work?
We know that line(y) = 0001. 2^0 would give us 0001
            0001
AND   0001
----------------
           1111

Yup, it tests out ok. So it'll display a MessageBox saying Collided.

Now about the whole 'the 1 is in the top right corner but the object is in the top left". Here's why it doesn't matter. The binary number doesnt matter. We're just inputing X and the Y coordinates into the formula and it'll check out ok or not. When we input 0 for X in the "And (2^X), X is really in the top left hand corner in your game, but the line() array stores it in the top right. Its no big problem - the X is still the same, its just reverse. The only time it'll create a problem is when you step back and try to write out the binary numbers - just know that it's reverse, that's all :p.

Also, the only reason i used "Int4" was becuase it would save typing space (its easier than typing 60 extra 0's. In our program we're going to use Integers

Creating our program
This will be short and quick, since we typed in the majority of the code earlier.

Dim GameField(5) As Integer
'Set the guy's coordinates to (5,5) by default
Dim x As Integer = 5
Dim y As Integer = 5


In form1_load type this in

GameField(0) = (2 ^ 0 Or 2 ^ 1) ' (0,0) and (0,1) arent passable


Create this function:

Public Sub CheckForCollision(ByVal x As Integer, ByVal y As Integer)

    If GameField(y) And (2 ^ x) Then '(0,0)
      MessageBox.Show("collided")
    End If

End Function


Now go to form1_keydown

Select Case e.KeyCode
   Case Keys.Left
      x -= 1
   Case Keys.Right
      x += 1
   Case Keys.Down
      y += 1
   Case Keys.Up
      y -= 1
End Select


Me.Text = "(" & x & "," & y & ")" 'Display the guy's X and Y coordinates, tricky syntax
CheckForCollision(x,y)

Now run the program. use form1's .Text to help you find out where the guy is, walk to tiles (0,0) and (0,1) and see what happens.

That's basically it for this tutorial. (I told you i'd try to keep it simple by avoiding graphics)
My thoughts about Bit String Flicking for Collision Detection:
I dont like it :p. I tend to beleive that it makes matters a little more confusing. However, this is an extremely fast way of testing for collision. It's good to know I guess.

If you guys have any questions, please post em at the forums. If needed, ill add more explanations for this tutorial.

Note: One main source I used to help me was the book ".NET Game Programming with DirectX 9.0" (Highly Recommended)

The Source Code for this tutorial is located here: (OK there's no source for this tut :p)You can also locate this by logging in to vbProgramming Forums and going to:
Tutorials > Tutorial Source Code > Source Code