News:

PlayBASIC2DLL V0.99 Revision I Commercial Edition released! - Convert PlayBASIC programs to super fast Machine Code. 

Main Menu

kevin, a problem I cant work out!

Started by RaverDave, February 03, 2006, 03:14:13 AM

Previous topic - Next topic

RaverDave

Hi!
the rebound code and such hasnt changed atall, so the problem has always been there!
What happens is alot of times (too many to be able to make it pass) the brick doesnt get destroyed yet the ball still rebound, this really should be impossible but maybe there is a logical error I am missing again!! Just to refresh your memory here is part of the function!

PlayBASIC Code: [Select]
Function Move_Ball(ThisBall,ThisMap,ThisLevel)
; Calc the New X & Y positions of the ball....
NewX# =Balls(ThisBall).Xpos + Balls(ThisBall).SpeedX
NewY# =Balls(ThisBall).Ypos + Balls(ThisBall).SpeedY
; Get the WIDTH and HEIGHT OF our ball.
; While At the moment this might be a bit of extra overkill, in the future
; you might decide that the balls can be different sizes.
Width = Balls(ThisBall).width
Height= Balls(ThisBall).Height
; ==============================================================
; Collision -Check If this Movement will hit the Level
; ===========================================================
If CheckMapImpact(ThisMap,ThisLevel,balls(b).xpos,balls(b).ypos,NewX#,NewY#,Width,Height)
; If there was impact with the map, then read our
; new position back.
NewX=GetMapImpactX()
NewY=GetMapImpactY()
NewX#=NewX
NewY#=NewY
TileWidth=GetMapBlockWidth(ThisMap)
TileHeight=GetMapBlockHeight(ThisMap)
TileX=NewX/TileWidth
TileY=NewY/Tileheight
If GetMapImpactLeft()
;Print "Impact occured on the LEFT side"
balls(thisball).speedx=balls(thisball).speedx *-1
If (TileX-1)>-1
For lp=TileY To (NewY+HEight-1)/TileHeight
If PeekLevelTile(ThisMap,ThisLevel,TileX-1,lp)<>0 And hitdat(tilex-1,lp)<>10
hitdat(tilex-1,lp)=hitdat(tilex-1,lp)-1
Inc score
;balls(thisball).speedx=balls(thisball).speedx *-1
balls(thisball).hitside=1
checked=0
SetCursor 320,10
If hitdat(tilex-1,lp)=0
PokeLevelTile ThisMap,ThisLevel,TileX-1,lp,0
Dec tilenum
EndIf
If powerdat(tilex-1,lp)<>0
s$="Wooohoooo!!!"
EndIf
EndIf
Next
EndIf
EndIf





RaverDave

Man, why oh why does the paste knack up my lovely indentation??!

RaverDave

#2
I have a feeling its to do with changing its direction before a value check is done!! And if I recall the change direction bit was put where it is now to avoid the ball going straight through the bricks in the case of a collision happening to more than 1 brick at once, which worked fine but has caused this problem of a rebound with no destruction sometimes!

RaverDave

#3
I have tried the method again of  having the rebound code after the check loops! so within the check loop I set a field within the ball type to 1, But after I watched a few balls bouncing around for half an hour i noticed an oddity of a ball getting stuck on a brick, just stopping dead, only to move again after another ball destroys that brick!! !I just cant win!! One way some bricks arent destroyed sometimes and the other way balls stop dead!
Something is fundamentally wrong with this whole system!
For what its worth here is the whole function, with a few changes.


Function Move_Ball(ThisBall,ThisMap,ThisLevel)
; Calc the New  X & Y positions of the ball....
NewX# =Balls(ThisBall).Xpos  +  Balls(ThisBall).SpeedX
NewY# =Balls(ThisBall).Ypos  +   Balls(ThisBall).SpeedY
; Get the WIDTH and HEIGHT OF our ball.  
; While At the moment this might be a bit of extra overkill, in the future
; you might decide that the balls can be different sizes.  
Width = Balls(ThisBall).width
Height= Balls(ThisBall).Height
; ==============================================================
; Collision -Check If this Movement will hit the Level
; ===========================================================
If CheckMapImpact(ThisMap,ThisLevel,balls(b).xpos,balls(b).ypos,NewX#,NewY#,Width,Height)  
; If there was impact with the map, then read our
; new position back.
NewX=GetMapImpactX()
NewY=GetMapImpactY()
NewX#=NewX
NewY#=NewY
TileWidth=GetMapBlockWidth(ThisMap)
TileHeight=GetMapBlockHeight(ThisMap)
TileX=NewX/TileWidth  
TileY=NewY/Tileheight
If GetMapImpactLeft()
;Print "Impact occured on the LEFT side"
;balls(thisball).speedx=balls(thisball).speedx *-1
 If (TileX-1)>-1
   For  lp=TileY To (NewY+HEight-1)/TileHeight
     If PeekLevelTile(ThisMap,ThisLevel,TileX-1,lp)<>0
      balls(thisball).hitleft=1
      If hitdat(tilex-1,lp)<>10
       hitdat(tilex-1,lp)=hitdat(tilex-1,lp)-1
       Inc score
        checked=0
         SetCursor 320,10
         If hitdat(tilex-1,lp)=0
          PokeLevelTile ThisMap,ThisLevel,TileX-1,lp,0
          Dec tilenum
         EndIf
       If powerdat(tilex-1,lp)<>0
         s$="Wooohoooo!!!"
     EndIf
    EndIf
     EndIf
   Next
 EndIf
EndIf
If GetMapImpactRight()
;balls(thisball).speedx=balls(thisball).speedx *-1
 If (TileX+1)=<GetLevelWidth(ThisMap,ThisLevel)
  For  lp=TileY To (NewY+HEight-1)/TileHeight
    If PeekLevelTile(ThisMap,ThisLevel,TileX+1,lp)<>0
     balls(thisball).hitright=1
     If hitdat(tilex+1,lp)<>10
       hitdat(tilex+1,lp)=hitdat(tilex+1,lp)-1
       s$=Str$(hitdat(tilex+1,lp))
       Inc score
     checked=0
       If hitdat(tilex+1,lp)=0
          PokeLevelTile ThisMap,ThisLevel,TileX+1,lp,0
          Dec tilenum
       EndIf
       SetCursor 320,10
       If powerdat(tilex+1,lp)<>0
          s$="Wooohoooo!!!"
     EndIf
    EndIf
   EndIf
  Next
 EndIf
EndIf
If GetMapImpactTop()
;balls(thisball).speedy=balls(thisball).speedy * -1
 If (TileY-1)>-1
  For  Xlp=TileX To (NewX+Width-1)/TileWidth
   If PeekLevelTile(ThisMap,ThisLevel,xlp,TileY-1)<>0
    balls(thisball).hittop=1
    If hitdat(xlp,tiley-1)<>10
     hitdat(xlp,tiley-1)=hitdat(xlp,tiley-1)-1
     Inc score
     If powerdat(xlp,tiley-1)<>0
         s$="Wooohoooo!!!"
     EndIf
     If hitdat(xlp,tiley-1)=0
        PokeLevelTile ThisMap,ThisLevel,xlp,TileY-1,0
        Dec tilenum
     EndIf
    EndIf
   EndIf
  Next
 EndIf
EndIf
If GetMapImpactBot()
;balls(thisball).speedy=balls(thisball).speedy * -1
 If (TileY+1)=<GetLevelHeight(ThisMap,ThisLevel)
  For Xlp=TileX To (NewX+Width-1)/TileWidth
     If PeekLevelTile(ThisMap,ThisLevel,Xlp,TileY+1)<>0
      balls(thisball).hitbottom=1
      If hitdat(xlp,tiley+1)<>10
       hitdat(xlp,tiley+1)=hitdat(xlp,tiley+1)-1
       checked=0
        Inc score
     If hitdat(xlp,tiley+1)=0
        PokeLevelTile ThisMap,ThisLevel,Xlp,TileY+1,0
          Dec tilenum
       EndIf
       If powerdat(Xlp,tiley+1)<>0
          s$="Wooohoooo!!!"
     EndIf
    EndIf
   EndIf
  Next
 EndIf
EndIf
EndIf

If balls(thisball).hittop=1
balls(thisball).hittop=0
balls(thisball).speedy=balls(thisball).speedy * -1
EndIf
If balls(thisball).hitbottom=1
balls(thisball).hitbottom=0
balls(thisball).speedy=balls(thisball).speedy * -1
EndIf

If balls(thisball).hitleft=1
balls(thisball).hitleft=0
balls(thisball).speedx=balls(thisball).speedx *-1
EndIf  
If balls(thisball).hitright=1
balls(thisball).hitright=0
balls(thisball).speedx=balls(thisball).speedx *-1
EndIf    



;  Set the balls New Position

balls(ThisBall).xpos=NewX#
balls(ThisBall).ypos=NewY#

EndFunction

Tracy

My less-than-stellar suggestion to this problem is that you simply choose the problem that's causing you the least trouble, and then write some code in to correct for it:

If collisions_with_brick_in_100ms > 3 then ballstuck=1

If ballstuck=1 then DestroyBrick

Good luck to you. Sometimes it's easier to put a quick patch on a problem than rewrite your entire code to fix it.

RaverDave

thank you for replying! at least someone replied!!
Anyhow what i did before posting here was test to see if its stuck on a collision, by making a score conter go up when the brick gets hit, so naturally if its stuck then i would have seen the score go up drastically!! But nope!! So i had no idea why a ball stopped dead!

Tracy

Hmm... upon another quick inspection of your code, I have the following hypothesis:

It looks like you might be moving the ball into the middle of the brick when you set the new X and Y positions. That is, the function currently warps the ball the speed distance every round. (i.e. with a speed of 10: round 0: Ballx=0 1:Ballx=10 2:Ballx=20 3:Ballx=30... and so on.)

The only problem with that is that the ball is never at any of the positions in-between. (say, at ballx=25). Therefore, you could be at position 5 moving towards a brick at position 7, and miss the edge of the brick because you'd next be at position 15- which is inside of the brick.

I'm not quite sure the specifics of the function 'Movesprite,' but you might try 'Movesprite" instead of 'positionsprite.' (I've never messed with it, but I might try soon.)

Again, good luck.

RaverDave

Well,if that was the case, then score counter should go up dramtically right? but it doesnt!

RaverDave

I'm gunna jack this is,had enough of it, if any1 is interested I have a basic editor that can be used for anything single screened, its the one i wrote for this project to do the levels! Maybe its a good learning thing?

kevin

Quotethe rebound code and such hasnt changed atall, so the problem has always been there!
What happens is alot of times (too many to be able to make it pass) the brick doesnt get destroyed yet the ball still rebound, this really should be impossible but maybe there is a logical error I am missing again!!

 Well, if the rebounding works and the block clearing doesn't in some cases.  Then it would seem obvious that the problem has nothing to the do with the rebounding.   It must be a situational issue with the clearing.   Probably rounding from the returned impact cordinates.  Rounding the impact values down might fix (some cases).  But I doubt it.  You'll prolly have to identify the case and react to it..