small collision problem
-
ChebbyShabby
- Enthusiast

- Posts: 121
- Joined: Mon Jun 26, 2006 10:47 am
small collision problem
i've written a code for making a sprite jump (check it out here: http://www.MailFreeOnline.com/uploader/02ABDBBE.zip). however, the collision is all horribly wrong -- the sprite stands through the platforms, and not on top.
can anyone help?
can anyone help?
It's simply that you are increasing grav by .5 each time the square drops and so after a while it is dropping by several pixels at a time.
When it finally makes contact with a platform it is dropping by a few pixels and so ends up buried, as it were.
Either change the position of the platforms so that they lie on boundaries that will avoid the problem or change the gravity effect to compensate.
When it finally makes contact with a platform it is dropping by a few pixels and so ends up buried, as it were.
Either change the position of the platforms so that they lie on boundaries that will avoid the problem or change the gravity effect to compensate.
-
ChebbyShabby
- Enthusiast

- Posts: 121
- Joined: Mon Jun 26, 2006 10:47 am
Using your code, when you press space to jump your square moves up by :
9.5 pixels then 9, 8.5, 8, 7.5, 7, 6.5, 6, 5.5, 5, 4.5, 4, 3.5, 3, 2.5, 2, 1.5, 1, .5 which comes to 95 pixels and then starts to drop by:
.5, 1, 1.5, 2 etc
so each platform has to be 95 pixels above each other minus .5 or minus 1.5 or minus 3 or minus 5
You have to add up the gravity drops to find where the next platform can be.
The only problem is of course that your Y variable is not a float so moving by half pixels will result in rounding errors.
9.5 pixels then 9, 8.5, 8, 7.5, 7, 6.5, 6, 5.5, 5, 4.5, 4, 3.5, 3, 2.5, 2, 1.5, 1, .5 which comes to 95 pixels and then starts to drop by:
.5, 1, 1.5, 2 etc
so each platform has to be 95 pixels above each other minus .5 or minus 1.5 or minus 3 or minus 5
You have to add up the gravity drops to find where the next platform can be.
The only problem is of course that your Y variable is not a float so moving by half pixels will result in rounding errors.
If you use separate sprites for each platform and do a collision test between your block and the platforms then when you are falling due to gravity and land on/in a platform you raise your blocks y co-ord to the same y co-ord as the block you hit before flipping the screen.
That way you will always land on a platform whatever its distance apart from the others.
That way you will always land on a platform whatever its distance apart from the others.
-
ChebbyShabby
- Enthusiast

- Posts: 121
- Joined: Mon Jun 26, 2006 10:47 am
done that (with little experience). now, the code runs VERY slow. where have i gone wrong?
Code: Select all
InitKeyboard()
InitSprite()
Global Y = 0
Global accel.f = 10
Global Grav.f = 0
#Eraser = 0
#Platform = 1
Structure Platform
id.w
x.l
y.l
EndStructure
NewList Platform.Platform()
If OpenScreen(640, 480, 32, "Eraser")
LoadSprite(#Eraser, "C:\Square.bmp")
LoadSprite(#Platform, "C:\Square.bmp")
x = 30
SetFrameRate(60)
Repeat
FlipBuffers()
ClearScreen(RGB(0,0,0))
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Space)
If accel = 10: start = 1: EndIf
EndIf
If start = 1
accel-0.5
Y-accel
If accel = 0: start = 0: EndIf
EndIf
AddElement(Platform())
ResetList(Platform())
While NextElement(Platform())
For i = 0 To 5
DisplayTransparentSprite(#Platform, 30+(20*i), 400)
Next
Wend
DisplayTransparentSprite(#Eraser, x, Y)
If start = 0
Grav-0.5
For i = 0 To 5
If SpriteCollision(#Eraser, x, Y, #Platform, 30+(20*i), 400)
Grav = 0
accel = 10
EndIf
Next i
EndIf
Y-Grav
If KeyboardPushed(#PB_Key_Left)
x-5
EndIf
If KeyboardPushed(#PB_Key_Right)
x+5
EndIf
Until KeyboardPushed(#PB_Key_Escape)
EndIf
End- Kaeru Gaman
- Addict

- Posts: 4826
- Joined: Sun Mar 19, 2006 1:57 pm
- Location: Germany
Code: Select all
InitKeyboard()
InitSprite()
Global Y = 0
Global accel.f = 10
Global Grav.f = 0
#Eraser = 0
If OpenScreen(640, 480, 32, "Eraser")
LoadSprite(#Eraser, "c:\Square.bmp")
For n=1 To 5
LoadSprite(n, "c:\Square.bmp") ;<------------ load 5 platforms
Next
x = 30
SetFrameRate(60)
Repeat
FlipBuffers()
ClearScreen(RGB(0,0,0))
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Space)
If accel = 10: start = 1: EndIf
EndIf
If start = 1
accel-0.5
Y-accel
If accel = 0: start = 0: EndIf
EndIf
For i = 1 To 5
DisplayTransparentSprite(i, 30+(20*i), 400-i*50) ;<------ display 5 platform
Next
DisplayTransparentSprite(#Eraser, x, Y)
If start = 0
Grav-0.5
For i = 1 To 5
If SpriteCollision(#Eraser, x, Y, i, 30+(20*i), 400-i*50) ;<---- check collisions
Grav = 0
accel = 10
y=400-i*50-15; <-------------- this is the y position of the block - height
EndIf ; so that we sit on top
Next i
If y>400 ; <-------------------- this stops us falling out the bottom of the screen
grav=0
accel=10
EndIf
EndIf
Y-Grav
If KeyboardPushed(#PB_Key_Left)
x-5
EndIf
If KeyboardPushed(#PB_Key_Right)
x+5
EndIf
Until KeyboardPushed(#PB_Key_Escape)
EndIf
End
This is probably the way I would go as well. It gives you more control over how the collisions occur.Kaeru Gaman wrote: additionally, I would rather use coordinate-checks than the SpriteCollision-command...
Using the code I posted above, you can see that even if you just touch the side of a block then you are put above it. That's because SpriteCollision just checks that you hit and not how you hit.
-
ChebbyShabby
- Enthusiast

- Posts: 121
- Joined: Mon Jun 26, 2006 10:47 am
thanks to both of you. one quick question:
isn't this a bit unnecessary, as i could just load the sprite only once and use it several times?
Code: Select all
For n=1 To 5
LoadSprite(n, "c:\Square.bmp") ;<------------ load 5 platforms
Next took your advice; replaced the SpriteCollision function with this, which detects collision only if the player is on top of the platform:additionally, I would rather use coordinate-checks than the SpriteCollision-command...
Code: Select all
If x < (30+(20*i))+16 And x+16 > (30+(20*i)) And Y+16 > 400-i*50 And Y < (400-i*50)+1if i ever decide to make a level editor, won't this be mandatory?so what's the use of the structure?
You could use copysprite to make more than one of the same sprite or you have to load individual sprites if they are different.
I should of used copysprite in the example, I was just bashing something out quickly.
It wouldn't be mandatory to use a structure. It's up to you how you would handle the data.
Edit. I see your point about reusing a sprite and you are probably right.
I should of used copysprite in the example, I was just bashing something out quickly.
It wouldn't be mandatory to use a structure. It's up to you how you would handle the data.
Edit. I see your point about reusing a sprite and you are probably right.
-
ChebbyShabby
- Enthusiast

- Posts: 121
- Joined: Mon Jun 26, 2006 10:47 am
so, for example, if i had a level file that saves as simply x and y coordinates of different platforms*, how would i go about displaying them without a structure?
*e.g.
00034
00400
00064
00400
(first line is the x coordinate, line after that is the y coordinate and it keeps repeating, so that the value of x is all the odd numbers, while the value of y is all the even numbers)
EDIT: lol i just realised that this is fairly simple. still, some experienced advice would be nice
*e.g.
00034
00400
00064
00400
(first line is the x coordinate, line after that is the y coordinate and it keeps repeating, so that the value of x is all the odd numbers, while the value of y is all the even numbers)
EDIT: lol i just realised that this is fairly simple. still, some experienced advice would be nice
You were nearly there.
You could have a file like this
05;number of platforms in level
100;x of first platform
300;y of first platform
10;number of sprite to display
200;x of second platform
250;y of second platform
4;number of sprite to display
etc
Just read in the first number to know how much more data is needed.
You can of course use structures if that is the way you are happiest with.
You could have a file like this
05;number of platforms in level
100;x of first platform
300;y of first platform
10;number of sprite to display
200;x of second platform
250;y of second platform
4;number of sprite to display
etc
Just read in the first number to know how much more data is needed.
You can of course use structures if that is the way you are happiest with.
-
ChebbyShabby
- Enthusiast

- Posts: 121
- Joined: Mon Jun 26, 2006 10:47 am
ah. you see sprites won't be necessary, as the plaforms themselves will be invisible; instead, a bitmap background is shown, with the platform boxes simulating the ground in this background, so a simple x,y file will work. also, i can use the Eof() function to find how many lines there are in the level and divide it by 2 to get the number of platforms.
my only problem now is reading it. how do i create an array with odd numbers and one with even?
my only problem now is reading it. how do i create an array with odd numbers and one with even?
Code: Select all
Platforms=10
Dim x.w(platforms)
Dim y.w(platforms)
For n=1 To platforms
Read x(n)
Read y(n)
Next
file=OpenFile(1,"c:\Level1")
For n=1 To platforms
WriteWord(1,x(n))
WriteWord(1,y(n))
Next
CloseFile(1)
DataSection
Data.w 100,100
Data.w 200,300
Data.w 300,400
Data.w 400,200
Data.w 500,100
Data.w 600,300
Data.w 700,400
Data.w 800,200
Data.w 100,200
Data.w 200,100
EndDataSection
MessageRequester("","Click ok to load")
file=OpenFile(1,"c:\Level1")
For n=1 To platforms
x(n)=ReadWord(1)
Debug x(n)
y(n)=ReadWord(1)
Debug y(n)
Next
CloseFile(1)
Good idea about drawing the platforms into the background. Might be a bit hard if you are doing a level editor, unless you keep a blank background and keep over printing onto it and then save it under a different name.