UnderwareDESIGN

PlayBASIC => Beginners => Topic started by: RaverDave on January 11, 2006, 10:33:33 PM

Title: Help with Pong / Arkanoid the source code
Post by: RaverDave on January 11, 2006, 10:33:33 PM
[pbcode]
; PROJECT : Project1
; AUTHOR  : raverdave
; CREATED : 02/01/2006
; EDITED  : 11/01/2006

OpenScreen 640,480,32,2

SetFPS 60
ScreenVsync On
Mouse Off
Type TPaddles
   X#,Y#,SizeX#,SizeY#
EndType
Dim Paddles(2) As Tpaddles

Paddles(1).SizeX#=64: Paddles(1).SizeY#=10
paddles(1).y#=400
Dim map(64,64)
Dim powerdat(64,64)
Dim hitdat(64,64)
Global checked=0
Global currvel=-4
Global PlayerX=50
Global PlayerY=430
Global PlayerWidth =10
Global PlayerHeight =10
Global s$
Global Speed=4
Global currlev=1
Global maxlev=99
Global tilenum=0
Global MyMap = GetFreeMap()
Global bottplay=400
CreateMap MyMap,99
Global currvel=-4
Global mapx=0
Global mapy=0
Global TileWidth=32
Global TileHeight=16
Global Number_of_tiles = 9
Global schange=0
Global thislevel
Global b
Global numofballs=0
Global maxballs=25
Global gamemode=1
Type tBall
     Status
     Xpos#,Ypos#
   Width,Height
     SpeedX#,SpeedY#
     newx#
     newy#
     ballspeed#
     ballangle#
 Image
 LifeTimer
 FlashToggle
EndType

; create an array to house our list of balls
Dim Balls(maxballs) As tBall



maketiles()

; CReate the test Balls
testpos()
createfx1()
Global width=GetImageWidth(40)
Repeat
   loadlev()
   gamemode=1
   Repeat
 LockBuffer
 Cls 0
 SetCursor 0,0
 DrawMap MyMap,currlev,mapx,mapy
 Text 300,450,FPS()
 showdecors()
 If gamemode=1
    balls(0).speedy=0
    balls(0).xpos=paddles(1).x#+paddles(1).sizex#/2
    balls(0).ypos=paddles(1).y#-10
 EndIf
; loop through our list of balls
 For b=0 To numofballs
    If gamemode=0
   Move_Ball(b,MyMap,currlev)
    EndIf
;drawball
    DrawImage 40,balls(b).xpos,balls(b).ypos,1
;Circle balls(b).xpos,balls(b).ypos,5,1
;draw paddle
    X#=Paddles(1).X#: Y#=Paddles(1).Y#
   Box X#,Y#,X#+Paddles(1).SizeX#,Y#+Paddles(1).SizeY#,1
    If balls(b).ypos<=0
     balls(b).speedy=-balls(b).speedy
     
     checked=0
    EndIf
    If balls(b).ypos>=bottplay+64
   balls(b).speedy=-balls(b).speedy
   checked=0
    EndIf
    If balls(b).xpos<=0+tilewidth
   balls(b).speedx=-balls(b).speedx
   checked=0
    EndIf
    If balls(b).xpos>=tilewidth*14-width
   balls(b).speedx=-balls(b).speedx
   checked=0
    EndIf

    If gamemode=0
   If PointInBox(balls(b).xpos,balls(b).ypos+10,paddles(1).x#,paddles(1).y#,paddles(1).x#+paddles(1).sizex#,paddles(1).y#+paddles(1).sizey#)
      currvel=Rnd(1)+1
      If currvel=0 Then currvel=1
      balls(b).speedy=-Abs(currvel)
      checked=1   
      Inc schange
      SetCursor 350,460
      Print "changed= "+Str$(schange)   
     EndIf
    EndIf  
   
 Next
 control()
 SetCursor 500,400
 Print balls(b).speedy
 SetCursor 450,440
 Print currvel
 
 Text 300,400,s$
 UnLockBuffer
 Sync
   Until quit=1 Or tilenum<=0

Until currlev>maxlev

Function control()
    v=ScanCode()
   If v=30 And numofballs<maxballs
    newball()
   EndIf
   If LeftKey()=1
    Paddles(1).x#=Paddles(1).x#-4
   EndIf
   If RightKey()=1
    Paddles(1).x#=Paddles(1).x#+4
   EndIf
   If v=16
 quit=1
   EndIf
   If v=57 And gamemode=1
 gamemode=0
 currvel=Rnd(5)+1
   s$="Hit bat"
      print"nigga"
      If currvel=0 Then currvel=1
     balls(b).speedy=-Abs(currvel)
        checked=1   
   EndIf
EndFunction



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()

TileWidth=GetMapBlockWidth(ThisMap)
TileHeight=GetMapBlockHeight(ThisMap)

TileX=NewX/TileWidth  
TileY=NewY/Tileheight

If GetMapImpactLeft()
   Print "Impact occured on the LEFT side"  
If (TileX-1)>-1
  For  lp=TileY To (NewY+HEight-1)/TileHeight
   If PeekLevelTile(ThisMap,ThisLevel,TileX-1,lp)<>0
    hitdat(tilex-1,lp)=hitdat(tilex-1,lp)-1
   
      balls(thisball).speedx=4
      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


 
If GetMapImpactRight()
    Print "Impact occured on the RIGHT side"  
; Kill Tile to the left of our position
If (TileX+1)=<GetLevelWidth(ThisMap,ThisLevel)

; Loop down the right edge of the players ball
For  lp=TileY To (NewY+HEight-1)/TileHeight
  If PeekLevelTile(ThisMap,ThisLevel,TileX+1,lp)<>0
   hitdat(tilex+1,lp)=hitdat(tilex+1,lp)-1
 
    balls(thisball).speedx=-4
    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
Next
EndIf

EndIf

If GetMapImpactTop()
 Print "Impact occured on the TOP side"  

; Kill Tile to the left of our position
If (TileY-1)>-1
For  Xlp=TileX To (NewX+Width-1)/TileWidth
If PeekLevelTile(ThisMap,ThisLevel,xlp,TileY-1)<>0
   hitdat(xlp,tiley-1)=hitdat(xlp,tiley-1)-1
  balls(ThisBall).speedy=Abs(balls(thisball).speedy)
 checked=0
    SetCursor 320,10
    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
Next
EndIf

EndIf


If GetMapImpactBot()
  Print "Impact occured on the Bottom side"
If (TileY+1)=<GetLevelHeight(ThisMap,ThisLevel)
  For  Xlp=TileX To (NewX+Width-1)/TileWidth
   If PeekLevelTile(ThisMap,ThisLevel,Xlp,TileY+1)<>0
    hitdat(xlp,tiley+1)=hitdat(xlp,tiley+1)-1
      balls(thisball).speedy=-Abs(balls(thisball).speedy)
    checked=0
  SetCursor 320,10
  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
  Next
EndIf

EndIf
EndIf

;  Set the balls New Position

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


EndFunction

Function maketiles()
; Loop through and draw a series of randomly coloured Boxes to the screen
 Data RGB(255,255,255)     `  White Block
 Data RGB(255,20,25)     `  RED/Block
 Data RGB(255,255,25)    `  Yellow Block
 Data RGB(25,255,25)     `  GREEN
 Data RGB(255,25,255)    `  PURPLE
 Data RGB(55,95,155)    `  PURPLE
 Data -1

For lp=1 To Number_of_tiles
 xpos=lp*tileWidth
 Col=ReadData()
 
 BoxC xpos+0,ypos+0,Xpos+tilewidth,Ypos+tileheight,1,RGBFade(Col,50.0)
 c1=RGBFade(Col,100.0)
;BoxC xpos,ypos,tilewidth,tileheight,RGB(col)
 ShadeBox xpos+1,ypos+1,Xpos+Tilewidth-1,Ypos+Tileheight-2,c1,c1,c2,c2  
Next
; Grab the box graphics that we've just drawn as image.
TempImage=GetFreeImage()
GetImage TempImage,0,0,xpos+TIleWidth,Tileheight
MakeMapGFX MyMAP,TempImage,TileWidth,TileHeight,Number_Of_Tiles,RGB(0,0,0)

EndFunction

Function createnewlev()
   thislevel=currlev
tilenum=0
If currlev>2
reset()
Restore 0
currlev=1
thislevel=currlev
EndIf

CreateLevel MyMap,currlev, 100,100
For Ylp=0 To 14
For Xlp=0 To 12
t=ReadData()
 If t>0
 tilenum=tilenum+1
PokeLevelTile MyMap,currlev,Xlp,ylp,t
EndIf
Next xlp
Next ylp
EndFunction

Function loadlev()
tilenum=0
thislevel=currlev
If currlev>1
reset()
currlev=1
PlayerX=50
PlayerY=430
EndIf
CreateLevel MyMap,currlev, 100,100
File$="arklev"
file$=file$+Str$(CURRLEV)
file$=FILE$+".dat"
ReadFile File$,1
For Ylp=0 To 15
For Xlp=0 To 13
 t=ReadInt(1)
 p=ReadInt(1)
 d=ReadInt(1)
 map(xlp,ylp)=t
 powerdat(xlp,ylp)=p
 hitdat(xlp,ylp)=d
  If t>0
  tilenum=tilenum+1
  PokeLevelTile MyMap,currlev,Xlp,ylp,t
 EndIf
Next xlp
Next ylp
CloseFile 1

EndFunction

Function reset()
XVelo#=-4
Yvelo#=-4
yspeed#=-4
xspeed#=-4
PlayerX=50
PlayerY=430
EndFunction

Function showdecors()
   DrawImage 1,16,0,0
   DrawImage 2,(14*32),0,0
   DrawImage 3,(14*32+16),0,0
EndFunction

Function createfx1()

 CreateImage 1,16,bottplay
 CreateImage 2,16,bottplay
 CreateImage 40,playerwidth,playerheight

 
; Tell PB to erdirect all drawing command to draw  upon this image and now the screen..
 RenderToImage 1
 For lp =0 To bottplay
 
    GouraudStripH 0,RGB(10,10,10),16,RGB(91,90,94),0+lp
 Next
 CopyImage 1,2
 
 CreateImage 3,228,bottplay
 
 RenderToImage 3
 For lp =0 To 228
    GouraudStripV 0,RGB(0,0,200),bottplay,RGB(0,0,10),0+lp
 Next
 
 RenderToImage 40
 CircleC playerwidth/2,playerheight/2,playerwidth/2,1,RGB(255,255,255)

 
RenderToScreen

EndFunction

Function testpos()
   
; Init Ball zero
balls(0).xpos=320
balls(0).ypos=1
balls(0).speedx=-4
balls(0).speedy=-1
balls(0).Width=PlayerWidth
balls(0).Height=PlayerHeight

EndFunction

Function dump()
   

EndFunction

Function newball()
   Inc numofballs
   balls(numofballs).xpos=320
   balls(numofballs).ypos=400
   balls(numofballs).speedx=-4
   balls(numofballs).speedy=-4
   balls(numofballs).Width=PlayerWidth
  balls(numofballs).Height=PlayerHeight   
EndFunction
[/pbcode]

I did get further but a crash with the gui put an end to that
Title: the source kevin
Post by: RaverDave on January 12, 2006, 12:25:06 AM
Just mess around with it when you have some real spare time! There's no rush as I am working hard on the editor, if the editor becomes user friendly enough it might just be intergrated into the game to allow for user created levels!
Title: the source kevin
Post by: stef on January 12, 2006, 12:48:33 PM
Hi!

Great work!

runs with 120

Greetings
stef
Title: the source kevin
Post by: kevin on January 12, 2006, 02:12:16 PM
Dave,

 Just had a quickr glance, and it's looking good...  Keep at it !

 if you want to balls to travel any speed you'll have to modify the collision code a little.    That's about it.   Currently, when an impact occurs. The code inverts the balls speed along either the X or Y axis. depending upon what side the impact occured.    The problem is, it sets the inverted direction using an absolute value.  Which is not what we want. It needs to flip the direction.  

; For example when the ball has a right hand impact, it then set it's new speed on the X axis to -4

i.e

 balls(thisball).speedx=-4  

It also does the same for the Y axis


This is fine if you want the balls to only ever move at either -4 (left) or 4 (right) along either axis..   But what would happen if we set the ball a custom speed of say 1.5 on the X axis and -2 on y (when we launching a ball that is).    

ie.

 balls(thisball).speedx=1.5
 balls(thisball).speedy=-2


So the ball would travel along this path, UNTIL it hits a tile (or the screen edge).  Where our rebound code, changes thhe Speed to either -4 or 4. Depending on what side it hit..

To fix it...  Simple

All we do is reflect the speed when and impact occurs..  like this


 balls(thisball).speedx=balls(thisball).speedx * -1


What this does is takes the current Speed valule and negates it.  Which will will us the rebounded speed.  No matter how fast it's moving.

 Have a play !
Title: the source kevin
Post by: RaverDave on January 12, 2006, 09:29:25 PM
huh?! I havent done much! :D
Well I will mess around anyhow, thanks for your help so far coz I wouldnt have got even this far without it! ;) I sometimes feel like just jacking it in and accepting that I just aint good enough though
Title: the source kevin
Post by: RaverDave on January 12, 2006, 09:42:13 PM
Hmmm, I am having some odd results with that method,sometime it will destroy quite a few before it bothers rebounding from the side of a brick
Title: the source kevin
Post by: RaverDave on January 12, 2006, 09:53:37 PM
[pbcode]
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()

TileWidth=GetMapBlockWidth(ThisMap)
TileHeight=GetMapBlockHeight(ThisMap)

TileX=NewX/TileWidth  
TileY=NewY/Tileheight

If GetMapImpactLeft()
   Print "Impact occured on the LEFT side"  
If (TileX-1)>-1
  For  lp=TileY To (NewY+HEight-1)/TileHeight
   If PeekLevelTile(ThisMap,ThisLevel,TileX-1,lp)<>0
    hitdat(tilex-1,lp)=hitdat(tilex-1,lp)-1
   
      balls(thisball).speedx=balls(thisball).speedx *-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


 
If GetMapImpactRight()
    Print "Impact occured on the RIGHT side"  
; Kill Tile to the left of our position
If (TileX+1)=<GetLevelWidth(ThisMap,ThisLevel)

; Loop down the right edge of the players ball
For  lp=TileY To (NewY+HEight-1)/TileHeight
  If PeekLevelTile(ThisMap,ThisLevel,TileX+1,lp)<>0
   hitdat(tilex+1,lp)=hitdat(tilex+1,lp)-1
 
    balls(thisball).speedx=balls(thisball).speedx *-1
    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
Next
EndIf

EndIf

If GetMapImpactTop()
 Print "Impact occured on the TOP side"  

; Kill Tile to the left of our position
If (TileY-1)>-1
For  Xlp=TileX To (NewX+Width-1)/TileWidth
If PeekLevelTile(ThisMap,ThisLevel,xlp,TileY-1)<>0
   hitdat(xlp,tiley-1)=hitdat(xlp,tiley-1)-1
  balls(thisball).speedy=balls(thisball).speedy * -1
 checked=0
    SetCursor 320,10
    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
Next
EndIf

EndIf


If GetMapImpactBot()
  Print "Impact occured on the Bottom side"
If (TileY+1)=<GetLevelHeight(ThisMap,ThisLevel)
  For  Xlp=TileX To (NewX+Width-1)/TileWidth
   If PeekLevelTile(ThisMap,ThisLevel,Xlp,TileY+1)<>0
    hitdat(xlp,tiley+1)=hitdat(xlp,tiley+1)-1
      balls(thisball).speedy=balls(thisball).speedy * -1
    checked=0
  SetCursor 320,10
  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
  Next
EndIf

EndIf
EndIf

;  Set the balls New Position

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


EndFunction
[/pbcode]



This is what I have in the function, at 1st glance it looks ok, but after abit you realise that its not desirable!
Title: the source kevin
Post by: kevin on January 12, 2006, 10:03:02 PM
Next hint...  

 Why are these "NewX" and "NewY"  still INTEGERS ?   :)


balls(ThisBall).xpos=NewX
balls(ThisBall).ypos=NewY
Title: the source kevin
Post by: RaverDave on January 12, 2006, 10:23:41 PM
I dunno :D
but adding a # to all of them,like i just did, causes the collisions not to occur atall!!lol
Title: the source kevin
Post by: RaverDave on January 12, 2006, 10:30:58 PM
Hmmmm..actually why not,I mean they aint floats coz I aint using floats yet?right?? So actually they should still be integers..Why would that be the problem??
Title: the source kevin
Post by: kevin on January 12, 2006, 10:43:44 PM
Looking at the declaration of your type.. Yep their FLOATS..

[pbcode]

Type tBall
    Status
    Xpos#,Ypos#
    Width,Height
    SpeedX#,SpeedY#
    newx#
    newy#
    ballspeed#
    ballangle#
Image
LifeTimer
FlashToggle
EndType

[/pbcode]

Title: the source kevin
Post by: RaverDave on January 12, 2006, 11:00:41 PM
damnit!I 4got about that, they were put in just before a crash!Anyhow I took them out now, but still the same problem! hehe
Title: the source kevin
Post by: RaverDave on January 12, 2006, 11:09:48 PM
Just curious,what time is it where you are? Its 5:09AM here,I been awake all night working on the editor mostly! :D:D
Life's too short
Title: the source kevin
Post by: kevin on January 12, 2006, 11:10:26 PM
Just had a look see.  The drama you mention (if you swap them all to floats) is cause due to rounding rounds when dealing with floats.  The solution was to Store the moved balls position in a floats NEWX# & NEwY#, but perform the collision on integer versions of NEWX + NEWY.   This Avoids avoid any possible roungin errors. And basic keep the code much the same


Bellow is a patched/hacked version that alllows balls to move at any angle + speed.  








OpenScreen 640,480,32,2

SetFPS 60
ScreenVsync On
Mouse Off
Type TPaddles
X#,Y#,SizeX#,SizeY#
EndType
Dim Paddles(2) As Tpaddles

Paddles(1).SizeX#=64: Paddles(1).SizeY#=10
paddles(1).y#=400
Dim map(64,64)
Dim powerdat(64,64)
Dim hitdat(64,64)
Global checked=0
Global currvel=-4
Global PlayerX=50
Global PlayerY=430
Global PlayerWidth =10
Global PlayerHeight =10
Global s$
Global Speed=4
Global currlev=1
Global maxlev=99
Global tilenum=0
Global MyMap = GetFreeMap()
Global bottplay=400
CreateMap MyMap,99
Global currvel=-4
Global mapx=0
Global mapy=0
Global TileWidth=32
Global TileHeight=16
Global Number_of_tiles = 9
Global schange=0
Global thislevel
Global b
Global numofballs=0
Global maxballs=25
Global gamemode=1
Type tBall
    Status
    Xpos#,Ypos#
    Width,Height
    SpeedX#,SpeedY#
    newx#
    newy#
    speed#
    angle#
Image
LifeTimer
FlashToggle
EndType

; create an array to house our list of balls
Dim Balls(maxballs) As tBall



maketiles()

; CReate the test Balls
testpos()
createfx1()
Global width=GetImageWidth(40)
Repeat
loadlev()
gamemode=1
Repeat
LockBuffer
Cls 0
SetCursor 0,0
DrawMap MyMap,currlev,mapx,mapy
Text 300,450,FPS()
showdecors()
If gamemode=1
 balls(0).speedy=0
 balls(0).xpos=paddles(1).x#+paddles(1).sizex#/2
 balls(0).ypos=paddles(1).y#-10
EndIf
; loop through our list of balls
For b=0 To numofballs
 If gamemode=0
  Move_Ball(b,MyMap,currlev)
 EndIf
;drawball
 DrawImage 40,balls(b).xpos,balls(b).ypos,1
;Circle balls(b).xpos,balls(b).ypos,5,1
;draw paddle
 X#=Paddles(1).X#: Y#=Paddles(1).Y#
  Box X#,Y#,X#+Paddles(1).SizeX#,Y#+Paddles(1).SizeY#,1
 If balls(b).ypos<=0
    balls(b).speedy=-balls(b).speedy
   
    checked=0
 EndIf
 If balls(b).ypos>=bottplay+64
  balls(b).speedy=-balls(b).speedy
  checked=0
 EndIf
 If balls(b).xpos<=0+tilewidth
  balls(b).speedx=-balls(b).speedx
  checked=0
 EndIf
 If balls(b).xpos>=tilewidth*14-width
  balls(b).speedx=-balls(b).speedx
  checked=0
 EndIf

 If gamemode=0
  If PointInBox(balls(b).xpos,balls(b).ypos+10,paddles(1).x#,paddles(1).y#,paddles(1).x#+paddles(1).sizex#,paddles(1).y#+paddles(1).sizey#)
   currvel=Rnd(1)+1
   If currvel=0 Then currvel=1
   balls(b).speedy=-Abs(currvel)
   checked=1
   Inc schange
   SetCursor 350,460
   Print "changed= "+Str$(schange)
    EndIf
 EndIf  

Next
control()
SetCursor 500,400
Print balls(b).speedy
SetCursor 450,440
Print currvel

Text 300,400,s$
UnLockBuffer
Sync
Until quit=1 Or tilenum<=0

Until currlev>maxlev

Function control()
 v=ScanCode()
If v=30 And numofballs<maxballs
 newball()
EndIf
If LeftKey()=1
 Paddles(1).x#=Paddles(1).x#-4
EndIf
If RightKey()=1
 Paddles(1).x#=Paddles(1).x#+4
EndIf
If v=16
quit=1
EndIf
If v=57 And gamemode=1
gamemode=0
currvel=Rnd(5)+1
  s$="Hit bat"
   print"nigga"
   If currvel=0 Then currvel=1
    balls(b).speedy=-Abs(currvel)
     checked=1
EndIf
EndFunction





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"  
If (TileX-1)>-1
 For  lp=TileY To (NewY+HEight-1)/TileHeight
  If PeekLevelTile(ThisMap,ThisLevel,TileX-1,lp)<>0
  hitdat(tilex-1,lp)=hitdat(tilex-1,lp)-1
 
     balls(thisball).speedx=balls(thisball).speedx *-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



If GetMapImpactRight()
;    Print "Impact occured on the RIGHT side"  
; Kill Tile to the left of our position
If (TileX+1)=<GetLevelWidth(ThisMap,ThisLevel)

; Loop down the right edge of the players ball
For  lp=TileY To (NewY+HEight-1)/TileHeight
 If PeekLevelTile(ThisMap,ThisLevel,TileX+1,lp)<>0
  hitdat(tilex+1,lp)=hitdat(tilex+1,lp)-1

   balls(thisball).speedx=balls(thisball).speedx *-1
   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
Next
EndIf

EndIf

If GetMapImpactTop()
; Print "Impact occured on the TOP side"  

; Kill Tile to the left of our position
If (TileY-1)>-1
For  Xlp=TileX To (NewX+Width-1)/TileWidth
If PeekLevelTile(ThisMap,ThisLevel,xlp,TileY-1)<>0
hitdat(xlp,tiley-1)=hitdat(xlp,tiley-1)-1
 balls(thisball).speedy=balls(thisball).speedy * -1
checked=0
   SetCursor 320,10
   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
Next
EndIf

EndIf


If GetMapImpactBot()
;  Print "Impact occured on the Bottom side"
If (TileY+1)=<GetLevelHeight(ThisMap,ThisLevel)
 For  Xlp=TileX To (NewX+Width-1)/TileWidth
  If PeekLevelTile(ThisMap,ThisLevel,Xlp,TileY+1)<>0
   hitdat(xlp,tiley+1)=hitdat(xlp,tiley+1)-1
     balls(thisball).speedy=balls(thisball).speedy * -1
   checked=0
 SetCursor 320,10
 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
 Next
EndIf

EndIf
EndIf

;  Set the balls New Position

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


EndFunction






Function maketiles()
; Loop through and draw a series of randomly coloured Boxes to the screen
Data RGB(255,255,255)     `  White Block
Data RGB(255,20,25)     `  RED/Block
Data RGB(255,255,25)    `  Yellow Block
Data RGB(25,255,25)     `  GREEN
Data RGB(255,25,255)    `  PURPLE
Data RGB(55,95,155)    `  PURPLE
Data -1

For lp=1 To Number_of_tiles
xpos=lp*tileWidth
Col=ReadData()

BoxC xpos+0,ypos+0,Xpos+tilewidth,Ypos+tileheight,1,RGBFade(Col,50.0)
c1=RGBFade(Col,100.0)
;BoxC xpos,ypos,tilewidth,tileheight,RGB(col)
ShadeBox xpos+1,ypos+1,Xpos+Tilewidth-1,Ypos+Tileheight-2,c1,c1,c2,c2  
Next
; Grab the box graphics that we've just drawn as image.
TempImage=GetFreeImage()
GetImage TempImage,0,0,xpos+TIleWidth,Tileheight
MakeMapGFX MyMAP,TempImage,TileWidth,TileHeight,Number_Of_Tiles,RGB(0,0,0)

EndFunction

Function createnewlev()
thislevel=currlev
tilenum=0
If currlev>2
reset()
Restore 0
currlev=1
thislevel=currlev
EndIf

CreateLevel MyMap,currlev, 100,100
For Ylp=0 To 14
For Xlp=0 To 12
t=ReadData()
If t>0
tilenum=tilenum+1
PokeLevelTile MyMap,currlev,Xlp,ylp,t
EndIf
Next xlp
Next ylp
EndFunction

Function loadlev()
tilenum=0
thislevel=currlev
If currlev>1
reset()
currlev=1
PlayerX=50
PlayerY=430
EndIf
CreateLevel MyMap,currlev, 100,100
File$="arklev"
file$=file$+Str$(CURRLEV)
file$=FILE$+".dat"
ReadFile File$,1
For Ylp=0 To 15
For Xlp=0 To 13
t=ReadInt(1)
p=ReadInt(1)
d=ReadInt(1)
map(xlp,ylp)=t
powerdat(xlp,ylp)=p
hitdat(xlp,ylp)=d
 If t>0
 tilenum=tilenum+1
 PokeLevelTile MyMap,currlev,Xlp,ylp,t
EndIf
Next xlp
Next ylp
CloseFile 1

EndFunction

Function reset()
XVelo#=-4
Yvelo#=-4
yspeed#=-4
xspeed#=-4
PlayerX=50
PlayerY=430
EndFunction

Function showdecors()
DrawImage 1,16,0,0
DrawImage 2,(14*32),0,0
DrawImage 3,(14*32+16),0,0
EndFunction

Function createfx1()

CreateImage 1,16,bottplay
CreateImage 2,16,bottplay
CreateImage 40,playerwidth,playerheight


; Tell PB to erdirect all drawing command to draw  upon this image and now the screen..
RenderToImage 1
For lp =0 To bottplay

   GouraudStripH 0,RGB(10,10,10),16,RGB(91,90,94),0+lp
Next
CopyImage 1,2

CreateImage 3,228,bottplay

RenderToImage 3
For lp =0 To 228
   GouraudStripV 0,RGB(0,0,200),bottplay,RGB(0,0,10),0+lp
Next

RenderToImage 40
CircleC playerwidth/2,playerheight/2,playerwidth/2,1,RGB(255,255,255)


RenderToScreen

EndFunction

Function testpos()

; Init Ball zero
balls(0).xpos=320
balls(0).ypos=1
balls(0).speedx=-4
balls(0).speedy=-1
balls(0).Width=PlayerWidth
balls(0).Height=PlayerHeight

EndFunction

Function dump()

  If (balls(b).ypos+balls(b).height)>Paddles(1).Y#
  If (balls(b).ypos-balls(b).height)<Paddles(1).Y#+Paddles(1).SizeY#
   If balls(b).xpos-balls(b).width<Paddles(1).X#+paddles(1).sizex#
      If balls(b).xpos>Paddles(1).X#
        currvel=Rnd(5)+1
        s$="Hit bat"
        print"nigga"
        If currvel=0 Then currvel=1
         balls(b).speedy=-Abs(currvel)
          checked=1
          Inc schange
          SetCursor 350,460
          Print "changed= "+Str$(schange)
       EndIf
      EndIf
     EndIf
    EndIf

EndFunction

Function newball()
Inc numofballs
balls(numofballs).xpos=320
balls(numofballs).ypos=400

; Calc a rondom angle facing upwards

Balls(numOfBalls).Angle#=rndrange(180+45,360-45)

Speed#=rndrange(2,5)
balls(numofballs).speed  =Speed#
balls(numofballs).speedx =Cos(Balls(numOfBalls).Angle#)*Speed#
balls(numofballs).speedY =Sin(Balls(numOfBalls).Angle#)*Speed#

;balls(numofballs).speedx=
;balls(numofballs).speedy=-4

balls(numofballs).Width=PlayerWidth
 balls(numofballs).Height=PlayerHeight
EndFunction

Title: the source kevin
Post by: RaverDave on January 12, 2006, 11:15:20 PM
well,this still has the same problem,sometimes a few are destroyed before it bothers to rebound, I saw this problem without floats also! The "a" key still works,best to have to or 3 onscreen so your not waiting about to realise this! But eventually you would see the problem with just 1 ball!

Also I can tell you its only occured since using the:

balls(thisball).speedx=balls(thisball).speedx *-1

methods
Title: the source kevin
Post by: RaverDave on January 13, 2006, 07:34:04 PM
AAaaarrgghhh,I am so stuck! your code doesnt react all the time,it sometimes doesnt respond untill its wiped out a few without rebounding, so what i did was change back to the abs method,so for example:

If GetMapImpactLeft()
;   Print "Impact occured on the LEFT side"  
If (TileX-1)>-1
For  lp=TileY To (NewY+HEight-1)/TileHeight
 If PeekLevelTile(ThisMap,ThisLevel,TileX-1,lp)<>0
 hitdat(tilex-1,lp)=hitdat(tilex-1,lp)-1

    balls(thisball).speedx#=Abs(balls(thisball).speedx#)
    Inc score
    s$="hit brick"
    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




Now this works 99.9% of the time, the 0.1% of the time, the ball stops dead on contact with a brick! I have the values of this impact,these are:


speedx#=0.487478
speedy#=3.97018
speed#=4.0
angle#=263.0

So I have no idea why the ball stops dead rarely!
Title: the source kevin
Post by: RaverDave on January 15, 2006, 08:02:33 PM
Oh my! I am getting sick of this code,been at it days,trying different ways, all I know is since using floats I have problems! The last 'hacked' code you sent kevin just doesnt work right,if you leave it running long enough,perhaps also press 'a' to add more balls,just so your not waiting too long! then you will see that for some odd reason they dont bounce off the bricks sometimes, yet the bricks get destroyed!
***edit**
I even went back to the Abs() way, and though they bounce ok this way, they just stop dead after apparently hitting a brick sometimes.
Title: the source kevin
Post by: kevin on January 15, 2006, 09:18:53 PM
This is logic problem.  I can give you the answer, but it's right there in front you.  I want you to understand why it occurs and how not to make it hapen in the future :)



GetMapImpactLeft()
;   Print "Impact occured on the LEFT side"  

If (TileX-1)>-1

For  lp=TileY To (NewY+HEight-1)/TileHeight
If PeekLevelTile(ThisMap,ThisLevel,TileX-1,lp)<>0

    hitdat(tilex-1,lp)=hitdat(tilex-1,lp)-1

   balls(thisball).speedx#=balls(thisball).speedx#*-1      

   Inc score
   s$="hit brick"
   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







Hint,

 1) Is it possible for the ball ot Hit more than 1 block

 2) What happens to a number when it's multed by -1 MORE than ONCE ?

 a=10
 a=a*-1
 print a
 a=a*-1
 print a
sync
waitkey

 That is your problem !   Look through the logic of the rebound code (in each direction) and you'll hopefully see it.  




NOTE:  If you ABS() the sign of the speed on either axis, your rounding the balls path, which is not what you want.  And not the problem
Title: the source kevin
Post by: RaverDave on January 15, 2006, 09:32:24 PM
Nope,lol..I cant see it :(
looks fine to me..
You do know that hitdat() has only a value of 1 in at the start right(in this level anyhow)?so on the 1st hit it will be 0
Title: the source kevin
Post by: kevin on January 15, 2006, 09:36:51 PM
Questions,

1) Is it possible for the ball to Hit more than 1 block    ????

2) What happens to a number when it's multed by -1 MORE than ONCE ???
Title: the source kevin
Post by: RaverDave on January 15, 2006, 09:39:12 PM
Ah,i see now,yes, it can hit  2 bricks at once!, but how is this avoided?
Title: the source kevin
Post by: RaverDave on January 15, 2006, 09:45:13 PM
Let me say that I never did like the fact that you can destroy 2 at once!
I have had this problem with blitz basic,dark basic..you name it,but never found a way to avoid this
Title: the source kevin
Post by: kevin on January 15, 2006, 09:45:25 PM
Almost there, it's all about where the Balls speed is being flipped..

 Does the balls direction need to be changed for each block it hits, or just change when a collision occurs of a side ?
Title: the source kevin
Post by: RaverDave on January 15, 2006, 09:46:48 PM
/me Scratches head and acts dumb (or am I acting!!) :D
Title: the source kevin
Post by: RaverDave on January 15, 2006, 09:50:09 PM
All I know is that this destroying 2 occurs for example as illustrated
I am not sure how to avoid this, afterall in reality it has the right quite frankly to do so!






|__|__|

   o
   ^

Title: the source kevin
Post by: kevin on January 15, 2006, 10:00:35 PM
QuoteLet me say that I never did like the fact that you can destroy 2 at once!
I have had this problem with blitz basic,dark basic..you name it,but never found a way to avoid this

  The language is totally irrelevant, programming is always a question of  logic.

  If you want the ball to only clear one block, you'll have to work out what block on a side the of the ball,  that has been mainly impacted by it.    Once derived, clear that block.      

  One way of doing that is deciphering this is via counting the number of pixels along the balls collided position that it shares against it's blocks (down whatever edge)  The highest one, gets ripped.  If there's a draw, the both get ripped.  In tha case the ball has hit perfectly spread across the joining of two blocks.

  Anyway, The logic above is simply clearing any tiles on whatever side of the ball comes in contact with.
Title: the source kevin
Post by: RaverDave on January 15, 2006, 10:04:46 PM
Well,as it stands they do both get ripped,thats the problem!
Title: the source kevin
Post by: RaverDave on January 15, 2006, 10:24:41 PM
Right,taking into account the points, the function has now been modified!!

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"  
If (TileX-1)>-1
For  lp=TileY To (NewY+HEight-1)/TileHeight
 If PeekLevelTile(ThisMap,ThisLevel,TileX-1,lp)<>0
 hitdat(tilex-1,lp)=hitdat(tilex-1,lp)-1
  Inc score
  ; balls(thisball).speedx=balls(thisball).speedx *-1
    hitside=1
bottom=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



If GetMapImpactRight()
;    Print "Impact occured on the RIGHT side"  
; Kill Tile to the left of our position
If (TileX+1)=<GetLevelWidth(ThisMap,ThisLevel)

; Loop down the right edge of the players ball
For  lp=TileY To (NewY+HEight-1)/TileHeight
If PeekLevelTile(ThisMap,ThisLevel,TileX+1,lp)<>0
 hitdat(tilex+1,lp)=hitdat(tilex+1,lp)-1
  Inc score
;   balls(thisball).speedx=balls(thisball).speedx *-1
  checked=0
  hitside=1
  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
Next
EndIf

EndIf

If GetMapImpactTop()
; Print "Impact occured on the TOP side"  

; Kill Tile to the left of our position
If (TileY-1)>-1
For  Xlp=TileX To (NewX+Width-1)/TileWidth
If PeekLevelTile(ThisMap,ThisLevel,xlp,TileY-1)<>0
hitdat(xlp,tiley-1)=hitdat(xlp,tiley-1)-1
; balls(thisball).speedy=balls(thisball).speedy * -1
checked=0
Inc score
hittop=1
  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
Next
EndIf

EndIf


If GetMapImpactBot()
;  Print "Impact occured on the Bottom side"
If (TileY+1)=<GetLevelHeight(ThisMap,ThisLevel)
For  Xlp=TileX To (NewX+Width-1)/TileWidth
 If PeekLevelTile(ThisMap,ThisLevel,Xlp,TileY+1)<>0
  hitdat(xlp,tiley+1)=hitdat(xlp,tiley+1)-1
;     balls(thisball).speedy=balls(thisball).speedy * -1
  checked=0
   Inc score
hitbottom=1
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
Next
EndIf

EndIf
EndIf

;  Set the balls New Position

balls(ThisBall).xpos=NewX#
balls(ThisBall).ypos=NewY#
If hittop=1
hittop=0
balls(thisball).speedy=balls(thisball).speedy * -1

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

EndIf
If hitside=1
hitside=0
balls(thisball).speedx=balls(thisball).speedx *-1
EndIf
EndFunction



Can you see what i have done?
take note of this bit:

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

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

EndIf
If hitside=1
hitside=0
balls(thisball).speedx=balls(thisball).speedx *-1
EndIf
Title: the source kevin
Post by: RaverDave on January 15, 2006, 10:26:46 PM
This seems to work! but its hardly desirable,thoough it works! I am not sure how the reaction will be with various balls,maybe i should change the global vars to fileds within the ball type! yes this could be better..
Title: the source kevin
Post by: RaverDave on January 15, 2006, 10:29:08 PM
actually scrap that,my balls just started to go sideways only..lol..hmm maybe the vars in the type idea might work?
Title: the source kevin
Post by: kevin on January 15, 2006, 10:29:57 PM
Examine this.  Try playing with the for next loop end counter.. try values from 1 to  3   -  it's set to 2 at the moment


a=10
print "Starting A="+Str$(a)

For lp=1 to 2
   a=a*-1
   print "The state of A Inside the loop ="+Str$(a)    
next

print "Final A="+Str$(a)

sync
waitkey


Notice how the number of loops affects the ultimate sign of the A variable.


Now relate this back the ball collision fragments of code...  

If the ball hits two blocks on the Right hand side say.

Then the loop runs down this right edge clearing each block.

Within the clear loop it flips the SIGN the speedX each loop...

 Obviously, if it clears two blocks, then the Xspeed sign will be flipped
and then flipped back..  Hence the logic error..  

 So, the balls speed only needs to be flipped when a collision registers, not during the block clearing loop itself.
Title: the source kevin
Post by: RaverDave on January 15, 2006, 10:45:42 PM
Finally!! I might have fixed it!!

ok i put for example the type looks like this:

ype tBall
   Status
   Xpos#,Ypos#
   Width,Height
   SpeedX#,SpeedY#
   newx#
   newy#
   speed#
   angle#
   hittop
   hitbottom
   hitside
Image
LifeTimer
FlashToggle
EndType
[QUOTE]



Now then when a impact occurs i set whatever to 1 like so:
[CODE]
If GetMapImpactLeft()
;   Print "Impact occured on the LEFT side"  
If (TileX-1)>-1
For  lp=TileY To (NewY+HEight-1)/TileHeight
 If PeekLevelTile(ThisMap,ThisLevel,TileX-1,lp)<>0
 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


Ok then I check if its equal to 1 outside the for next loop of that functioon,near the bottom, like so:


If balls(thisball).hitside=1
balls(thisball).hitside=0

balls(thisball).speedx=balls(thisball).speedx *-1
EndIf
EndFunction

And then the speed is changed!
I do this for the tophit and bottomhit fileds aswell!

Maybe this works,it seems to work!
Title: the source kevin
Post by: kevin on January 15, 2006, 10:51:37 PM
Bingo... in a round about kind of way..

or you could do this way


if GetMapImpactLeft()
;   Print "Impact occured on the LEFT side"  

; Do the Balls Rebound
 balls(thisball).speedx=balls(thisball).speedx *-1

; Now do the loop to clear the tiles
If (TileX-1)>-1
For  lp=TileY To (NewY+HEight-1)/TileHeight
If PeekLevelTile(ThisMap,ThisLevel,TileX-1,lp)<>0
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
Next
EndIf
EndIf

Title: the source kevin
Post by: RaverDave on January 15, 2006, 10:53:49 PM
Oh my,thats cruelly shorter!
I feel inadequate!
Title: the source kevin
Post by: RaverDave on January 15, 2006, 10:54:36 PM
maybe mine has the advantage of being more modular..lol
Title: the source kevin
Post by: RaverDave on January 15, 2006, 11:05:22 PM
Oh NO!! It worked, then as I was admiring the balls rebounding,one of them stopped dead!lol,on a brick, it only moved again when another ball destroyed that brick..
Title: the source kevin
Post by: RaverDave on January 16, 2006, 10:47:03 AM
I have implemented your way,cleaned the code up,now then very rarely it tends to bounce off a brick but not destroy the brick,I sometimes have to watch it for ages before this happens,to be sure! But yep its definately hapenning! Is this another simple logic over-sight?
Title: the source kevin
Post by: RaverDave on January 16, 2006, 07:05:08 PM
Well, been working away at the code and the editor on and off all day, I implemented non destructable bricks, now this has shown a major snag in all this sytem, the ball on a given angle can get stuck in a rebound! But I think only if there is a 1 brick gap between the columns! So its gunna need careful planning or some hack to stop this
Title: the source kevin
Post by: RaverDave on January 17, 2006, 12:09:41 AM
Nah! It gets stuck in a rebound no matter what! I have presented a snapshot of an example of where it would get cought in a rebound loop! Its the area I have put a dimaond shape in black, not necessarily in this way does it loop but its typical example!
So the aim of the level would be to get to the top and destroy the only destructible bricks on that level (red and yellow) the white ones are not destructable
Title: the source kevin
Post by: kevin on January 17, 2006, 05:53:22 AM
If it gets stuck at the screen edges, that's most probably caused by the edge flip not bothering to reposition the ball inside the egde, instead it just flips the speed.

 When the balls hits the edge (any of them)  it should be re position the bal inside the edge along the axis.  

Ie.

  If BallX >  RightEdge
      ; POsition ball so it can't cause a collision next frame
      BallX = RightEdge-BallWidth

     ; flip the speed
     BallSpeedX=BallSpeedX * -1
  endif
Title: the source kevin
Post by: RaverDave on January 17, 2006, 12:00:55 PM
well i tried it,eventually it got stuck again, after clearing the level 14 times though..  :/
I didnt mean it gets stuck stuck, it goes in a continues rebound loop! if you look at the snapshot closely you will see i have shown this with black lines(sorta middle left hand side) So I am saying the ball hits the side, then the bottom of a brick, rebounds to hit the side of the brick below that, rebounds to hit the top of the brick below that, then back to the side! In a diamond shape