FreeBASIC Games Directory Forum
 Welcome, Guest. Please login or register. May 26, 2013, 02:27:19 AM 1 Hour 1 Day 1 Week 1 Month Forever Login with username, password and session length 11.5.2013 - Added a webpage for the latest FBGD competition.13.3.2013 - Members registrations temporary disabled. For all membership requests, please email me: lachie13@yahoo.com 30.11.2012 - The ninth issue of BASIC Gaming is out! Read it here: http://games.freebasic.net/forum/index.php?topic=560.022.11.2012 - Be sure to check our currently running annual FBGD game making competition. This year's theme is SEASONS OF THE YEAR, 300 \$ first place prize, and the competition runs till 18th of February. Link: http://games.freebasic.net/forum/index.php?topic=559.0

Pages: 1 [2]
 Author Topic: How to create "sliding off tiles" effect?  (Read 3997 times)
KristopherWindsor
Forum Sage

Gender:
Posts: 363

The Thirsty Smiley

 « Reply #15 on: January 21, 2008, 05:45:23 PM »

I don't know vectors (yet).

I think they are just lines with decimal coordinates.
 Logged

dabooda
Forum Howler

Gender:
Posts: 122

 « Reply #16 on: January 22, 2008, 09:20:36 AM »

Great topic and great practice for me. I was currently working on this issue for my new game and this is what I have come up with. Keep in mind all my stuff is standard size(16x16) but hopefully someone might get some use out of this. It only checks two points in the direction your heading and the sprite will slide off the tile only if its already hanging about 4 pixels off of it to begin with. Here's my code, hope it helps.

'Simple demo to demonstrate tile sliding
'Note all my tiles are set up 16x16, this makes for easier and quicker reading
'For one I can use bit shifting instead of multiplication and division
'Note you could apply this to 32x32 or 64x64 just as well

'Include
#Include "fbgfx.bi"

'Variables
Dim Shared As Integer man_x, man_y 'Main sprites positions
Dim Shared As UByte map(0 To 39, 0 To 29) 'My block reading map
Dim Shared As Integer key_up, key_down, key_right, key_left 'used for storing keys states

'Subs(defined at end of code)
Declare Sub move_up(ByRef x As Integer, ByRef y As Integer)
Declare Sub move_down(ByRef x As Integer, ByRef y As Integer)
Declare Sub move_left(ByRef x As Integer, ByRef y As Integer)
Declare Sub move_right(ByRef x As Integer, ByRef y As Integer)

'Some constants
Const As UByte block = 1 'will be considered blocking
Const As UByte walk = 0 'can be walked on
Const As Integer block_number = 20 'change for more or less blocks
Const As Integer rate = 5 'change to slow down program or speed up

'Set up my screen
ScreenRes 640, 480, , , 0

Randomize Timer

'Set up map(You can ignore this all it does is set up temp map)
Dim As Integer x, y

'clear map to block
For y = 0 To 29
For x = 0 To 39
map(x, y) = block
Next
Next

'now clear out for walk
For y = 1 To 28
For x = 1 To 38
map(x, y) = walk
Next
Next

'now we can randomly place blocks on map
For x = 1 To block_number
map((Rnd*37)+1, (Rnd*27)+1) = block
Next

'Set up mans Position on map
man_x = (Rnd*37)+1: man_y = (Rnd*27)+1 'initial position
map(man_x, man_y) = walk 'clear the map at position
man_x = man_x Shl 4: man_y = man_y Shl 4 'Set up coordinates(16x16)

'Finally we can draw the map
For y = 0 To 464 Step 16
For x = 0 To 624 Step 16
If map(x Shr 4, y Shr 4) = block Then
Line (x, y) - (x+15, y+15), 15, bf
EndIf
Next
Next

'Main Loop
Dim key_null As String 'used to clear key buffer
Do

'Clear Man Sprite(And yes its the blue box)
Line (man_x, man_y) - (man_x+15, man_y+15), 0, b

'Get input
key_up = MultiKey(fb.SC_UP)
key_down = MultiKey(fb.SC_DOWN)
key_left = MultiKey(fb.SC_LEFT)
key_right = MultiKey(fb.SC_RIGHT)

'clear buffer
key_null = InKey\$

'Check input and move accordingly
If key_up Then move_up(man_x, man_y)
If key_down Then move_down(man_x, man_y)
If key_left Then move_left(man_x, man_y)
If key_right Then move_right(man_x, man_y)

'Redraw man at new position
Line (man_x, man_y) - (man_x+15, man_y+15), 3, b

'Sleep for a bit
Sleep rate, 1

Loop Until MultiKey(fb.SC_ESCAPE)

End 0

'My subs(I will only comment heavily up, for the rest
'of the subs are the same principle, just different
'directions
Sub move_up(ByRef x As Integer, ByRef y As Integer)
'Variables needed for checking both corners(only two corners needed)
'fp and sp are map checks, fs and ss are slide checks
Dim As UByte fp, sp 'map checks for each corner
Dim As Integer fs, ss 'slide checks for each corner

'Find first and second map points
fp = map( (x Shr 4), ((y - 1) Shr 4) )
sp = map( ((x + 15) Shr 4), ((y - 1) Shr 4) )

'Find slide results, note it only slides if man
'is off tile by at least 4 pixels
fs = ((x And 15) Shr 2)
ss = (((x + 15) And 15) Shr 2)

'Check to see if both are blocked
If fp = block And sp = block Then Exit Sub 'no point in checking

'Check for walks
If fp = walk And sp = walk Then
y-=1: Exit Sub 'move up
End If

'Only check for slide if left and right aren't pressed
If key_left Or key_right Then Exit Sub

'Now we can check for slides
If fp = walk And sp = block And ss < 3 Then
x-=1 'slide left
ElseIf fp = block And sp = walk And fs > 0 Then
x+=1 'slide right
EndIf
'If none of these checks are true then
'it is safe to assume that man is within
'tiles bounds
End Sub

Sub move_down(ByRef x As Integer, ByRef y As Integer)
'Move down is almost identical to move up, so
'one could merge the two but for ease and readability
'I have seperated them
Dim As UByte fp, sp 'map checks
Dim As Integer fs, ss 'slide checks

'find map coordinates
fp = map( (x Shr 4), ((y + 16) Shr 4) )
sp = map( ((x + 15) Shr 4), ((y + 16) Shr 4) )

'Find slides(same as move up)
fs = ((x And 15) Shr 2)
ss = (((x + 15) And 15) Shr 2)

'Check for full block
If fp = block And sp = block Then Exit Sub

'check for walks
If fp = walk And sp = walk Then
y+=1: Exit Sub 'move down
End If

'only check slide if right or left isn't pressed
If key_right Or key_left Then Exit Sub

'check slides
If fp = walk And sp = block And ss < 3 Then
x-=1 'move left
ElseIf fp = block And sp = walk And fs > 0 Then
x+=1 'move right
EndIf

End Sub

Sub move_left(ByRef x As Integer, ByRef y As Integer)
'Move left is a little different, but same principle
Dim As UByte fp, sp 'map checks
Dim As Integer fs, ss 'slide checks

'find map coordinates
fp = map( ((x - 1) Shr 4), (y Shr 4) )
sp = map( ((x - 1) Shr 4), ((y + 15) Shr 4) )

'find slides(with the y now)
fs = ((y And 15) Shr 2)
ss = (((y + 15) And 15) Shr 2)

'check for full block
If fp = block And sp = block Then Exit Sub

'check for walks
If fp = walk And sp = walk Then
x-=1: Exit sub 'move left
EndIf

'check for up and down key
If key_up Or key_down Then Exit Sub

'check for slides
If fp = walk And sp = block And ss < 3 Then
y-=1 'slide up
ElseIf fp = block And sp = walk And fs > 0 Then
y+=1 'slide down
EndIf

End Sub

Sub move_right(ByRef x As Integer, ByRef y As Integer)
'move right is same as move left, again you could easily merge the two
Dim As UByte fp, sp 'map checks
Dim As Integer fs, ss 'slide checks

'find map points
fp = map( ((x + 16) Shr 4), (y Shr 4) )
sp = map( ((x + 16) Shr 4), ((y + 15) Shr 4) )

'find slides
fs = ((y And 15) Shr 2)
ss = (((y + 15) And 15) Shr 2)

'Check for full block
If fp = block And sp = block Then Exit Sub

'check for walks
If fp = walk And sp = walk Then
x+=1: Exit sub 'move right
EndIf

'check for up and down key
If key_up Or key_down Then Exit Sub

'check for slides
If fp = walk And sp = block And ss < 3 Then
y-=1 'slide up
ElseIf fp = block And sp = walk And fs > 0 Then
y+=1 'slide down
EndIf

End Sub

I only heavily commented the move_up sub but the rest work the same just different directions, also you can combine move_up and move_down as well as move_right and move_left easily. Again this is simplified and for standard sized tiles, but maybe the technique could be incorporated in other engines. The good thing about this is no decimals are used and neither is multiplication or division.

DaBooda out...
 Logged

Baa...Baa...Bang! F&#K! I'm Wool!
Lachie Dazdarian
Double dipper
Forum Sage

Gender:
Posts: 1195

 « Reply #17 on: January 22, 2008, 04:15:59 PM »

This is cool dabooda. I'll explore it this weekend and see if I can implement it in my screen by screen scrolling engine.

Kris, I know what vectors are. And can use some basic vectors math. I'm just having huge problems applying any other math that basic +,-,/,* in programming. I find it difficult to "see" how something like vector math can be applied to solve a certain problem and properly use it to get the desired result. A fact I shouldn't be proud of, I know. I must educate myself.
 Logged

"Things like Basic and Free Basic provide much-needed therapy and a return to sanity and a correct appreciation of people. The arrogant folk really hate a word like 'Basic' - fine, and good riddance." ~ pragmatist
notthecheatr
Global Moderator
Forum Sage

Gender:
Posts: 351

Who's the guy from 21 Jump Street?

 « Reply #18 on: January 22, 2008, 04:52:21 PM »

Vectors are good for things like velocity, acceleration, even direction and position.  It's basically just a way to bundle x and y (and z, if it's 3d) components into one variable (a UDT) and manipulate them as a packaged deal, rather than separately.  One of the things you might work with is converting between polar and cartesian coordinates - that is, between <angle, radius> and <x, y>.  Vectors are mostly useful as a way of thinking about things;  I don't usually even bother to make a whole vector class, just a UDT with x and y (always as Single or even Double - much more useful than integers).

Examples:
-Motion:  Add the velocity vector to the position vector.
-Time-based motion:  Multiply the velocity vector by the time differential before adding it to the position
-Acceleration:  Add the acceleration vector to the velocity vector.
etc.

These are basic things;  conversion between polar and cartesian coordinates will take trig functions.  There are various other things you do with them, too.  Only really complex physics engines would bother to go beyond this stuff, though.  I can't think of a lot of other things to do with them.
 Logged

The funniest thing happened yesterday.
cha0s
Recruit

Posts: 23

 « Reply #19 on: February 19, 2008, 11:38:01 PM »

The method I used for collision in mine was simply using the X, Y coordinates to access a linear map buffer, and check if there was or wasn't collision enabled in that tile quadrant. You know, like "if( map( loc_x + loc_y * map_width ).collision = TRUE ) then"
 Logged
Leonheart
Guest
 « Reply #20 on: February 20, 2008, 03:10:44 AM »

If someone want create complex 3D engine or game they should learn and know about vector. It's enable the engine to render prespective image and texture mapping on poligon.

I'm simplify the vector definition in my brain. Vector is 2D/3D coordinate relativly from original point like zero point (0,0,0).

Hey! That was a good idea!
How about make a new section in this forum. How about 2D/3D engine tutorial section eh?
Of course since me (or anyone) difficult to found good book for explain that such bunch things.

- 2D - 3D - Vector - vector math - Ray tracing - texture mapping - lighting - mesh - effect - shading
- light scatter - photon map - motion - animation

whoops to many!!!!
 Logged
Lachie Dazdarian
Double dipper
Forum Sage

Gender:
Posts: 1195

 « Reply #21 on: February 20, 2008, 04:30:47 AM »

Erm...just put these sort of things in the Game Dev or Programming section. I'm pretty sure we don't need a separate sub-forum for a specific group of tutorials.
 Logged

"Things like Basic and Free Basic provide much-needed therapy and a return to sanity and a correct appreciation of people. The arrogant folk really hate a word like 'Basic' - fine, and good riddance." ~ pragmatist
hd_
Recruit

Posts: 35

 « Reply #22 on: February 23, 2008, 10:40:17 PM »

I would have done it the same way as Dr_D. The magic of circle-line and sphere-plane collisions is knowing how to get the normal of the line/plane. The normal of a 2d line is:
nx=(y2-y1)
ny=-(x2-x1)

To make it a unit vector:
m=sqr(nx^2+ny^2)
nx/=m
ny/=m

where (x1,y1) and (x2,y2) are the two points that form the line segment.

(The normal is the vector perpendicular to the line. To be useful, it should be a unit vector)

Then it's just a simple matter of pushing the circle away from the line, in the direction of (nx,ny) by the distance from the line and the circle. One trap you may fall into is that so far I have only described circle-line collisions. You need to do some extra magic to do circle-line segment collisions. Then after that you will notice that the circle can sink into two lines which form a sharp V :O I haven't bothered figuring out how to solve that part yet
 Logged
Pages: 1 [2]