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! |