Main Menu

Explode Shape

Started by kevin, October 30, 2009, 10:01:43 AM

Previous topic - Next topic

kevin

 Explode Shape

  This example explodes a shape from 2D mesh into a bunch debris styled line fragments, a bit like the old asteroids coin op.


PlayBASIC Code: [Select]
; PROJECT : Exploding_Shape
; AUTHOR : Kevin Picone
; CREATED : 10/31/2009
; EDITED : 10/31/2009
; ---------------------------------------------------------------------

setfps 60


Type tEdge
xpos#,ypos# ; position
SpeedX#,Speedy# ; movement speed
Angle#
RotSpeed#
EdgeLength# ; length of fragment
Endtype

Dim Edges(100) as tEdge

Shape =newconvexshape(50,4)
Xpos#=400
Ypos#=300

do
cls 0

; draw shape to represent some game object
rotateshape Shape,Angle#,1
drawshape shape,Xpos#,Ypos#,1

; press space to explode it
if spacekey()

// dump this shape into the edge buffer
ExplodeShape(Shape,Xpos#,Ypos#,Angle#,rndrange#(1,10))

// kill the old shape and rfandomly create a new one
deleteshape Shape
Shape =newconvexshape(rndrange(20,100),rndrange(4,20))
Xpos#=rnd(800)
Ypos#=rnd(600)
flushkeys

endif


ProcessEdges()

Angle#=wrapangle(Angle#,0.25)


Sync
loop



Function ProcessEdges()
Size=30
ClipRegionX1=-Size
ClipRegionY1=-Size
ClipRegionX2=GetScreenWidth()+Size
ClipRegionY2=GetScreenWidth()+Size

lockbuffer
for lp=0 to getarrayelements(edges(),1)
// check if there's anything allocated at position in the array
if Edges(lp)

// move the fragments base point
Xpos#=Edges(lp).Xpos#+Edges(lp).SpeedX#
Ypos#=Edges(lp).Ypos#+Edges(lp).SpeedY#

Edges(lp).Xpos#=Xpos#
Edges(lp).Ypos#=Ypos#

if pointinbox(Xpos#,ypo#,ClipRegionX1,ClipRegionY1,ClipRegionX2,ClipRegionY2)

Angle#=wrapangle(Edges(lp).Angle#,Edges(lp).RotSpeed#)

// get the size of this fragment
l#=Edges(lp).EdgeLength#

fx#=cosradius(angle#,l#)
fy#=sinradius(angle#,l#)

line Xpos#-fx#,Ypos#-fy#,Xpos#+fx#,Ypos#+fy#

Edges(lp).Angle#=angle#
else
Edges(lp)= Null
endif

endif
next
unlockbuffer

EndFunction



Function ExplodeShape(Thisshape,Xpos#,Ypos#,Angle#,Speed#)

for edge=0 to getshapeedges(ThisShape,1)

if Getshapeedgestatus(ThisShape,edge)
// edge index in the array
Index=GetFreecell(Edges())

Edges(Index).Xpos#=Xpos#
Edges(Index).Ypos#=Ypos#


Edges(Index).RotSpeed#=rndrange#(-10,10)


// get the
Vert1=GetShapeEdge(ThisShape,Edge,0)
Vert2=GetShapeEdge(ThisShape,Edge,1)

// Get the vert and rotate it to the current angle of the shape
x1#,y1#=Rotate2DVertex(ThisShape,Vert1,Angle#)
x2#,y2#=Rotate2DVertex(ThisShape,Vert2,Angle#)


// midr point between
mx#=(x1#+x2#)/2
my#=(y1#+y2#)/2

dist#=getdistance2d(0,0,mx#,my#)
if Dist#>0
nx#=mx#/dist#
ny#=my#/dist#
else
nx#=0
ny#=0
endif

// dist from mid point to one edge of fragment..
Edges(Index).EdgeLength#=getdistance2d(mx#,my#,x2#,y2#)

// Speed fragment is moving
Edges(Index).speedX#=nx#*Speed#
Edges(Index).speedY#=ny#*Speed#

// mid point of line fragment
Edges(Index).Xpos#=Xpos#+mx#
Edges(Index).Ypos#=Ypos#+my#

Edges(Index).Angle#=getangle2d(mx#,my#,x2#,y2#)
Login required to view complete source code






Related Examples

    * 8Way Layered Star Field / Asteroids Style






kevin

#1
    This is just a little update, the only difference really is this that version supports shape scaling as well as rotation and few a few extra comments.   I've left the original just in case you don't need scaling.
 

PlayBASIC Code: [Select]
   setfps 60

Type tEdge
xpos#,ypos# ; position
SpeedX#,Speedy# ; movement speed
Angle# ; current angle
RotSpeed# ; speed this fragment is rotating
EdgeLength# ; length of fragment
Endtype

Dim Edges(100) as tEdge


// Create a start shape to explode
Shape =newconvexshape(50,4)
Xpos#=400
Ypos#=300
Scale#=1

do
cls 0

scale#=2+Sin(Angle#*4)

; draw shape to represent some game object
rotateshape Shape,Angle#,Scale#
drawshape shape,Xpos#,Ypos#,1

; press space to explode it
if spacekey()

// dump this shape into the edge buffer
ExplodeShape(Shape,Xpos#,Ypos#,Angle#,Scale#,rndrange#(1,10))

// kill the old shape and rfandomly create a new one
deleteshape Shape
Shape =newconvexshape(rndrange(20,100),rndrange(4,20))
Xpos#=rnd(800)
Ypos#=rnd(600)
flushkeys

endif

// run through and process any edge frages that may exist
ProcessEdges()

// bump the rotation angle of the current shape
Angle#=wrapangle(Angle#,0.25)

// display instructions
print "Press Space To Explode Current Shape"

Sync
loop



Function ProcessEdges()
Size=30
ClipRegionX1=-Size
ClipRegionY1=-Size
ClipRegionX2=GetScreenWidth()+Size
ClipRegionY2=GetScreenWidth()+Size

lockbuffer
for lp=0 to getarrayelements(edges(),1)
// check if there's anything allocated at position in the array
if Edges(lp)

// move the fragments base point
Xpos#=Edges(lp).Xpos#+Edges(lp).SpeedX#
Ypos#=Edges(lp).Ypos#+Edges(lp).SpeedY#

Edges(lp).Xpos#=Xpos#
Edges(lp).Ypos#=Ypos#

if pointinbox(Xpos#,ypo#,ClipRegionX1,ClipRegionY1,ClipRegionX2,ClipRegionY2)

Angle#=wrapangle(Edges(lp).Angle#,Edges(lp).RotSpeed#)

// get the size of this fragment
l#=Edges(lp).EdgeLength#

fx#=cosradius(angle#,l#)
fy#=sinradius(angle#,l#)

line Xpos#-fx#,Ypos#-fy#,Xpos#+fx#,Ypos#+fy#

Edges(lp).Angle#=angle#
else
Edges(lp)= Null
endif

endif
next
unlockbuffer

EndFunction



Function ExplodeShape(Thisshape,Xpos#,Ypos#,Angle#,Scale#,Speed#)

for edge=0 to getshapeedges(ThisShape,1)

if Getshapeedgestatus(ThisShape,edge)
// edge index in the array
Index=GetFreecell(Edges())

Edges(Index).Xpos#=Xpos#
Edges(Index).Ypos#=Ypos#


Edges(Index).RotSpeed#=rndrange#(-10,10)


// get this edges vertex pair that's using
Vert1=GetShapeEdge(ThisShape,Edge,0)
Vert2=GetShapeEdge(ThisShape,Edge,1)

// Get the verts and rotate them to the current angle of the shape
x1#,y1#=Rotate2DVertex(ThisShape,Vert1,Angle#,Scale#)
x2#,y2#=Rotate2DVertex(ThisShape,Vert2,Angle#,Scale#)


// mid point (middle of edge)
mx#=(x1#+x2#)/2
my#=(y1#+y2#)/2

// Calc normal from shape center
dist#=getdistance2d(0,0,mx#,my#)
if Dist#>0
nx#=mx#/dist#
ny#=my#/dist#
else
nx#=0
ny#=0
endif

// dist from mid point to one edge of fragment..
Edges(Index).EdgeLength#=getdistance2d(mx#,my#,x2#,y2#)

// Speed fragment is moving (speed by the normal (direction) shape is facing)
Edges(Index).speedX#=nx#*Speed#
Edges(Index).speedY#=ny#*Speed#

// mid point of line fragment
Edges(Index).Xpos#=Xpos#+mx#
Edges(Index).Ypos#=Ypos#+my#
Login required to view complete source code