small collision problem

Advanced game related topics
ChebbyShabby
Enthusiast
Enthusiast
Posts: 121
Joined: Mon Jun 26, 2006 10:47 am

small collision problem

Post by ChebbyShabby »

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?
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

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.
ChebbyShabby
Enthusiast
Enthusiast
Posts: 121
Joined: Mon Jun 26, 2006 10:47 am

Post by ChebbyShabby »

thank you very much. i think i've used the sleezy method of displaying levels and faced the consequences :oops:

are there any mathematical calculations for finding the boundries where it is safe to make contact? or is there a simple way?
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

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.
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

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.
ChebbyShabby
Enthusiast
Enthusiast
Posts: 121
Joined: Mon Jun 26, 2006 10:47 am

Post by ChebbyShabby »

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
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

seems you infinitely add Platform-Elements, one each loop...
further, you dont seem to use the coordinates of the platform anywhere,
so what's the use of the structure?

additionally, I would rather use coordinate-checks than the SpriteCollision-command...
oh... and have a nice day.
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

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
Try this bit of code. :)
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Kaeru Gaman wrote: additionally, I would rather use coordinate-checks than the SpriteCollision-command...
This is probably the way I would go as well. It gives you more control over how the collisions occur.

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
Enthusiast
Posts: 121
Joined: Mon Jun 26, 2006 10:47 am

Post by ChebbyShabby »

thanks to both of you. one quick question:

Code: Select all

  For n=1 To 5 
    LoadSprite(n, "c:\Square.bmp") ;<------------ load 5 platforms 
  Next 
isn't this a bit unnecessary, as i could just load the sprite only once and use it several times?
additionally, I would rather use coordinate-checks than the SpriteCollision-command...
took your advice; replaced the SpriteCollision function with this, which detects collision only if the player is on top of the platform:

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)+1
so what's the use of the structure?
if i ever decide to make a level editor, won't this be mandatory?
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

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.
ChebbyShabby
Enthusiast
Enthusiast
Posts: 121
Joined: Mon Jun 26, 2006 10:47 am

Post by ChebbyShabby »

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 :lol:
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

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.
ChebbyShabby
Enthusiast
Enthusiast
Posts: 121
Joined: Mon Jun 26, 2006 10:47 am

Post by ChebbyShabby »

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?
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

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)
Simple file commands.

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.
Post Reply