examples: add fireworks example (#8358)
							parent
							
								
									90ecbde712
								
							
						
					
					
						commit
						ba3342a034
					
				|  | @ -0,0 +1,70 @@ | |||
| import objects | ||||
| import gg | ||||
| import gx | ||||
| import rand | ||||
| 
 | ||||
| struct App { | ||||
| mut: | ||||
| 	gg      &gg.Context = 0 | ||||
| 	rockets []objects.Rocket | ||||
| 	frames  [][]objects.Rocket | ||||
| 	// i thought about using a fixed fifo queue for the frames but the array 
 | ||||
| 	// seemed to work fine, if you'd like a challenge try implementing it with the queue :)
 | ||||
| } | ||||
| 
 | ||||
| fn on_frame(mut app App) { | ||||
| 	app.gg.begin() | ||||
| 
 | ||||
| 	// drawing previous frames
 | ||||
| 	for mut frame in app.frames { | ||||
| 		for mut rocket in frame { | ||||
| 			if !rocket.exploded { | ||||
| 				rocket.color.a = byte(f32_max(rocket.color.a - 8, 0)) | ||||
| 				rocket.draw(mut app.gg) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// chance of firing new rocket
 | ||||
| 	if rand.intn(30) == 0 { | ||||
| 		app.rockets << objects.new_rocket() | ||||
| 	} | ||||
| 	// simulating rockets
 | ||||
| 	app.rockets = app.rockets.filter(!it.dead) | ||||
| 
 | ||||
| 	for mut rocket in app.rockets { | ||||
| 		rocket.tick(mut app.gg) | ||||
| 	} | ||||
| 
 | ||||
| 	// adding frame
 | ||||
| 	mut frame := app.rockets.clone() | ||||
| 
 | ||||
| 	for mut rocket in frame { | ||||
| 		rocket.particles = [] | ||||
| 	} | ||||
| 
 | ||||
| 	app.frames << frame | ||||
| 
 | ||||
| 	// trimming out frames
 | ||||
| 	if app.frames.len > 30 { | ||||
| 		app.frames.delete(0) | ||||
| 	} | ||||
| 
 | ||||
| 	app.gg.end() | ||||
| } | ||||
| 
 | ||||
| fn main() { | ||||
| 	mut app := &App{} | ||||
| 
 | ||||
| 	app.gg = gg.new_context( | ||||
| 		width: objects.width | ||||
| 		height: objects.height | ||||
| 		window_title: 'Fireworks!' | ||||
| 		bg_color: gx.black | ||||
| 		use_ortho: true | ||||
| 		user_data: app | ||||
| 		frame_fn: on_frame | ||||
| 	) | ||||
| 
 | ||||
| 	app.gg.run() | ||||
| } | ||||
|  | @ -0,0 +1,12 @@ | |||
| module objects | ||||
| 
 | ||||
| import gx | ||||
| import rand | ||||
| 
 | ||||
| pub fn random_color() gx.Color { | ||||
| 	return gx.Color{ | ||||
| 		r: byte(rand.int_in_range(0, 256)) | ||||
| 		g: byte(rand.int_in_range(0, 256)) | ||||
| 		b: byte(rand.int_in_range(0, 256)) | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,12 @@ | |||
| module objects | ||||
| 
 | ||||
| const ( | ||||
| 	width           = 800 | ||||
| 	height          = 800 | ||||
| 	gravity         = Vector{0, -0.03} | ||||
| 	age_rate        = 1 | ||||
| 	offspring_count = 100 | ||||
| 	rocket_radius   = 5 | ||||
| 	particle_radius = 2.5 | ||||
| 	drag            = 0.98 | ||||
| ) | ||||
|  | @ -0,0 +1,35 @@ | |||
| module objects | ||||
| 
 | ||||
| import gg | ||||
| import gx | ||||
| 
 | ||||
| pub struct Particle { | ||||
| pub mut: | ||||
| 	color    gx.Color | ||||
| 	pos      Vector | ||||
| 	vel      Vector | ||||
| 	accel    Vector | ||||
| 	lifespan f32 = 255 | ||||
| } | ||||
| 
 | ||||
| pub fn (particle Particle) draw(mut ctx gg.Context) { | ||||
| 	ctx.draw_circle(particle.pos.x, height - particle.pos.y, particle_radius, particle.color) | ||||
| } | ||||
| 
 | ||||
| pub fn (mut particle Particle) tick(mut rocket Rocket, mut ctx gg.Context) { | ||||
| 	particle.lifespan -= age_rate | ||||
| 	particle.color.a = byte(particle.lifespan) | ||||
| 
 | ||||
| 	if particle.lifespan <= 0 { | ||||
| 		rocket.dead = true | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	particle.accel += gravity | ||||
| 	particle.vel += particle.accel | ||||
| 	particle.vel = particle.vel.mult(drag) | ||||
| 	particle.pos += particle.vel | ||||
| 	particle.draw(mut ctx) | ||||
| 
 | ||||
| 	particle.accel = {} | ||||
| } | ||||
|  | @ -0,0 +1,68 @@ | |||
| module objects | ||||
| 
 | ||||
| import gg | ||||
| import gx | ||||
| import rand | ||||
| 
 | ||||
| pub struct Rocket { | ||||
| pub mut: | ||||
| 	color     gx.Color | ||||
| 	pos       Vector | ||||
| 	vel       Vector | ||||
| 	accel     Vector | ||||
| 	exploded  bool | ||||
| 	particles []Particle | ||||
| 	dead      bool | ||||
| } | ||||
| 
 | ||||
| pub fn (rocket Rocket) draw(mut ctx gg.Context) { | ||||
| 	ctx.draw_circle(rocket.pos.x, height - rocket.pos.y, rocket_radius, rocket.color) | ||||
| } | ||||
| 
 | ||||
| pub fn (mut rocket Rocket) explode() { | ||||
| 	rocket.exploded = true | ||||
| 
 | ||||
| 	for _ in 0 .. offspring_count { | ||||
| 		rocket.spawn_particle() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn (mut rocket Rocket) tick(mut ctx gg.Context) { | ||||
| 	if !rocket.exploded { | ||||
| 		if rocket.vel.y <= 1 { | ||||
| 			rocket.explode() | ||||
| 		} | ||||
| 
 | ||||
| 		rocket.accel += gravity | ||||
| 		rocket.vel += rocket.accel | ||||
| 		rocket.pos += rocket.vel | ||||
| 		rocket.draw(mut ctx) | ||||
| 
 | ||||
| 		rocket.accel = {} | ||||
| 	} | ||||
| 
 | ||||
| 	for mut particle in rocket.particles { | ||||
| 		particle.tick(mut rocket, mut ctx) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn new_rocket() Rocket { | ||||
| 	return Rocket{ | ||||
| 		color: random_color() | ||||
| 		pos: { | ||||
| 			x: rand.f32_in_range(50, width - 50) | ||||
| 		} | ||||
| 		vel: { | ||||
| 			x: rand.f32_in_range(-1.5, 1.5) | ||||
| 			y: rand.f32_in_range(5, 7) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn (mut rocket Rocket) spawn_particle() { | ||||
| 	rocket.particles << Particle{ | ||||
| 		color: rocket.color | ||||
| 		pos: rocket.pos | ||||
| 		accel: random_vector_in_circle().mult(2) | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,28 @@ | |||
| module objects | ||||
| 
 | ||||
| import math | ||||
| import rand | ||||
| 
 | ||||
| pub struct Vector { | ||||
| pub mut: | ||||
| 	x f32 | ||||
| 	y f32 | ||||
| } | ||||
| 
 | ||||
| pub fn (a Vector) + (b Vector) Vector { | ||||
| 	return Vector{a.x + b.x, a.y + b.y} | ||||
| } | ||||
| 
 | ||||
| pub fn (vector Vector) mult(scalar f32) Vector { | ||||
| 	return Vector{vector.x * scalar, vector.y * scalar} | ||||
| } | ||||
| 
 | ||||
| pub fn random_vector_in_circle() Vector { | ||||
| 	theta := rand.f32n(2 * math.pi) | ||||
| 	y := rand.f32() | ||||
| 
 | ||||
| 	return { | ||||
| 		x: f32(y * math.sin(theta)) | ||||
| 		y: f32(y * math.cos(theta)) | ||||
| 	} | ||||
| } | ||||
		Loading…
	
		Reference in New Issue