Bullet Hell engine.
Community Forums/Showcase/Bullet Hell engine.
| ||
| I've been working on a bullet hell engine for my upcoming shmup. If you don't know what "bullet hell" is google please. The code works on some base principals. You would provide an enemy boss or otherwise. This enemy contains a "burst_timeline" object. This timeline holds "shot_burst" objects which define one burst of enemy shots and how long to delay befor activation. The "burst_timeline" counts up and activates "shot_burst" objects in time. These shot bursts define how many shots are created, and at what angles and speeds. I'll provide the source code. I hope sombody can gleam something from it. These games aren't played much in America but they have a very solid funfactor. They are simple and require mastery. ![]() and now the code for your adaptation: You will need the bullet image. Name "image.png" ![]()
Strict
Global enemy_shots:TList= New TList ' list for our enemy shots
Global cell_groups:TList = New TList ' this is for the cell groups
Type enemy_shot
Field x:Float, y:Float, direction:Float, speed:Float, radius:Float
Function Create(x:Float, y:Float, direction:Float, speed:Float, radius:Float)
Local temp:enemy_shot= New enemy_shot
temp.x=x
temp.y=y
temp.speed=speed
temp.direction = direction
temp.radius = radius
ListAddLast(enemy_shots,temp)
EndFunction
Method update()
outside_screen()
move()
draw()
End Method
Method move()
x:+Cos(direction)*speed
y:+Sin(direction)*speed
End Method
Method outside_screen()
If x<0
destroy()
End If
If y<0
destroy()
End If
If x>640
destroy()
End If
If y>480
destroy()
End If
End Method
Method destroy()
ListRemove(enemy_shots,Self)
End Method
Method draw()
DrawImageRect(image, x - radius, y - radius, radius * 2, radius * 2)
End Method
End Type ' basic bullet
Type shot_burst
Field x:Float, y:Float, fill_angle:Float, numshots:Float, direction:Float, step_delay:Int, shot_speed:Float, shot_radius = 16
Method fire()
Local start_angle:Float = direction - (fill_angle / 2.0)
Local sub_angle:Float = fill_angle / numshots
For Local i = 0 To numshots - 1
enemy_shot.Create(x, y, start_angle + (i * sub_angle) + (sub_angle *.5), shot_speed, shot_radius)
Next
End Method
End Type ' resides witin a burst timeline 'describes a pattern
Type burst_timeline
Field num_bursts#=0,bursts:shot_burst[],event_time%,reset_time=0
Method add_burst(burst:shot_burst) ' add a burst and time from last shot to be executed
Local new_length%=bursts.length+1
bursts=bursts[..new_length]' holds bursts
bursts[new_length-1]=burst
num_bursts:+1
If burst.step_delay>reset_time ' if the new burst needs more time add to the reset time
reset_time=burst.step_delay
End If
End Method
Method update()
For Local i:shot_burst=EachIn(bursts)
If i.step_delay=event_time
i.fire()
EndIf
Next
event_time:+1
If event_time>reset_time
event_time=0
End If
End Method
End Type
'test
Local p:burst_timeline = New burst_timeline ' here is a burst timelie-
' that might be stored in an enemy or boss type
' use a series of for loops to add burst patterns to our burst_timeline object
For Local i:Float = 1 To 11
Local d:shot_burst = New shot_burst 'Left side
d.step_delay = i * 10
d.x = 320 - 120
d.y = 128
d.shot_speed = 2
d.direction = 180
d.numshots = 5
d.fill_angle = i * 36
p.add_burst(d)
Local e:shot_burst = New shot_burst
e.step_delay = i * 10 'right side
e.x = 320 + 120
e.y = 128
e.shot_speed = 2
e.direction = 0
e.numshots = 5
e.fill_angle = i * 36
p.add_burst(e)
Next ' add twin burst pattern
Local m = p.reset_time ' this local var will give us
'a continue count from the last for loop
For Local i:Float = 1 To 30
Local e:shot_burst = New shot_burst
Local n = i
If n > 12
n = 12
End If
e.step_delay = m + i * 2
e.x = 320
e.y = 240
e.shot_speed = 2
e.direction = 90
e.numshots = n
e.fill_angle =M+ i * 12
p.add_burst(e)
Next ' add bottom bloom
m = p.reset_time ' update our left off count
For Local i:Float = 1 To 30
Local e:shot_burst = New shot_burst
e.step_delay = m + i * 2
e.x = 320
e.y = 120
e.shot_speed = 2
e.direction = i * 12
e.numshots = 12
e.fill_angle = 360
p.add_burst(e)
Next ' add top radial burst
m = p.reset_time ' update last ticks again
For Local i:Float = 1 To 10
For Local j = 0 To 11
Local e:shot_burst = New shot_burst
e.step_delay = m + i * 10
e.x = 320 + Cos(j * 30) * 32
e.y = 240 + Sin(j * 30) * 32
e.shot_speed = 3
e.direction = i * 15
e.numshots = 6
e.fill_angle = 360
e.shot_radius = 8
p.add_burst(e)
Next
Next ' add ring shots
m = p.reset_time ' update last ticks again
For Local i:Float = 1 To 10
Local e:shot_burst = New shot_burst
e.step_delay = m
e.x = 320
e.y = 240
e.shot_speed = 2 + (I *.05)
e.direction = 0
e.numshots = 36
e.fill_angle = 360
e.shot_radius = 32
p.add_burst(e)
Next ' add exanding line ring
Graphics 640, 480
SetMaskColor(0, 0, 0)
SetBlend(ALPHABLEND)
Global image:TImage = LoadImage("image.png")
While not KeyDown(KEY_ESCAPE)
Cls
p.update()
For Local e:enemy_shot=EachIn(enemy_shots)
e.update()
Next
DrawText("Bullets: :" + CountList(enemy_shots), 12, 12)
Flip
Wend
|
| ||
| Very nice, thanks for letting us have a peek! |

