While the previous collision demo have shown auto sliding collision, this one preview a new mode called Sticky collision.
What happens is that the sprite is stopped at it's first impact point. This point is returned to the user rather than being slid down the wall face.
This allows you to manually rebound sprites off the world surfaces.. Which is what the code bellow does.
In a nut shell it's rebounding 200 rotated sprites off the angled enivorment. Simple huh :)
While this new mode is only available in PB1.081 (the very latest beta). You could sorta get this working in PB1.08. By changing the SpriteCollisinoMode from 5 (sticky) back to 4 (sliding).. That'd sorta make it work, but not correctly..
LoadIMage "Bubble_64x64.bmp",1
Preparefximage 1
WorldWidth=2000
WorldHeight=1500
; create a Camera
CreateCamera 1
Limitcamera 1,true
LimitCameraBounds 1,0,0,WorldWidth+1,WorldHeight+1
Restart:
if GetWorldStatus(2) then deleteworld 2
; Create world
CreateWorld 2
CaptureToWorld 2
; ==============================================
; draw a series of boarder line for this world
; ==============================================
Dot 0,0
line 0,0,worldwidth,0
line worldwidth,0,worldwidth,worldheight
line worldwidth,worldheight,0,worldheight
line 0,worldheight,0,0
; draw a series of polygon shaped obejct into the world
for lp=1 to rndrange(20,50)
xpos#=50+rnd(worldwidth-100)
zpos#=50+rnd(worldheight-100)
size=rndrange(30,100)
angle=rnd(359)
Make_Convex(rndrange(3,20),xpos#,zpos#,Size,angle)
next lp
; Partition The world up into 32 by 32 cells
PartitionWorld 2,32
; Tell PB to return to Immediate drawing mode
DrawGfxImmediate
; Create A batch of Ball Sprites
MaxBalls=200
Type tBalls
Angle#
Speed#
SpriteINdex
EndType
Dim Balls(MaxBalls) as tBalls
For ThisBall=1 to MaxBalls
Balls(Thisball).speed#=rndrange(1,6)
Balls(ThisBall).Angle#=rnd(359)
; Create the Sprite
CreateSprite ThisBall
; Assign this sprite image #1
SpriteImage ThisBall,1
; Set the Sprites to Rotated Draw mode
SpriteDrawMode ThisBall,2
; Center the Sprites handle for this image
Centerspritehandle ThisBall
; Set up this sprites collision
SpriteCollision Thisball,True
; Set Sprite to have STICKY World Collision
SpriteCollisionMode ThisBall, 5
; Set sprite to collide with world #2
SpriteCollisionWorld ThisBall,2
Scale#=0.5+(rnd(100)/100.0)
; Set the Size of the Collision Radius
SpriteCollisionRadius ThisBall,31*Scale#
ScaleSprite THisBall,Scale#
; Randomly POsition this Sprite within the world
Repeat
X=rnd(Worldwidth)
y=rnd(WorldHeight)
positionSpriteXyz ThisBall,X,y,50
MoveSprite ThisBall,1,1
until GetSpriteWorldIMpact(ThisBall)=False
next
positionSpriteXyz 1,X,y,5
; statrt of DO/Loop
Do
; capture to scene and grab the world info
CaptureToScene
ClsScene
; Move All the sprites
For ThisBall=1 to MaxBalls
Angle#=Balls(ThisBall).Angle#
Speed#=Balls(ThisBall).Speed#
MoveSprite ThisBall,cosradius(angle#,speed#),sinradius(angle#,speed#)
; Set Sprites drw mode to rotated (2)
SpriteDrawMode ThisBall,2
; Check this sprite hit the world during the last move
If GetSpriteWorldIMpact(ThisBall)=True
; Get the Walls Normals
nx#=getnormalx#(0)
ny#=getnormaly#(0)
WallAngle#=AtanFull(ny#,nx#)
Angle#=wrapangle(angle#,180)
Angle#=WrapAngle(WallAngle#,WallAngle#-Angle#)
; Set the balls/sprites new direction
Balls(ThisBall).Angle#=Angle#
; Set sprite to AlphaADD with a random colour so it flashes
SpriteDrawMode ThisBall,2+4096
r=rndrange(100,200)
g=rndrange(100,200)
b=rndrange(100,200)
SpriteAlphaAddColour ThisBall,rgb(r,g,b)
endif
; Turn the sprite
turnsprite ThisBall,1
next
;set camera to follow sprite one
x#=getspritex(1)
y#=getspritey(1)
spritedrawmode 1,2+4096
PositionCamera 1,X#-(getscreenwidth()/2),y#-(getScreenHeight()/2)
drawallsprites
capturedepth 100
CameraGrabWorld 1,2
; draw the camera
DrawCamera 1
; show the fps rate and continue this loop
text 0,0,fps()
if spacekey() then goto restart
sync
loop
; ==============================================================
; This function creates a convex polygon shape
; ==============================================================
Function Make_Convex(edges,xpos#,ypos#,Size,angle)
sa#=360.0/edges
c=rndrgb()
for lp=0 to edges-1
a#=angle+(lp*sa#)
x1#=xpos#+cosRadius(a#,size)
y1#=ypos#+SinRadius(a#,size)
if lp<(edges-1)
a#=angle+((lp+1)*sa#)
else
a#=angle
endif
x2#=xpos#+cosRadius(a#,size)
y2#=ypos#+SinRadius(a#,size)
line x2#,y2#,x1#,y1#
next lp
endfunction i
Hello Kevin,
It works for me, ~ 120 FPS.
Have a nice day,
Tomaz
Rebound Balls Demo
This demo shows Play Basic newest world collision mode "Sticky". Sprites set to sticky mode return the first point of impact between the sprite and the collision surface, rather than sliding down the surface. So the sprite can be rebounded (reflected,killed etc) however the users see fit.
The demo is running 250 rebounding sprites of a world. The camera will auto follows ball #1
Source Included (requires PB1.081 though :) )
Download
[plink] Rebound Balls Demo + Src (757k) (http://www.underwaredesign.com/files/demos/PB_ReboundBalls.zip)[/plink]
Hello,
Nice demo - looks like Pinball. FPS ~ 250. Everytime the ball is nearing the outside wall, it appears a white line. This was meant to be this way, right?
Have a nice day,
Tomaz
erm, what ?
Hello Kevin,
This white line appears when ball is nearing the end of the black space (before the ball touch the end). Hope it make some sense.
Have a nice day,
Tomaz
it's prolly the boarder of the world.
Although, the world space should be full(ish) of wall to rebound off. ?