Confettis
Deux canons tirant des bandes de papier avec gravité et rotation. Un color_initial_ramp constant donne à chaque morceau une couleur plate de la palette.
L'éditeur ci-dessus fait tourner ce projet. Changez une ligne et il se recharge.
Classes Godot utilisées
CPUParticles2DGradientImageTexture
Le code
scripts/main.gd
extends Node
const FIRE_INTERVAL: float = 1.1
var cannons: Array[CPUParticles2D] = []
var next_cannon: int = 0
func _ready() -> void:
_add_background()
var view: Vector2 = get_viewport().get_visible_rect().size
cannons.append(_add_cannon(Vector2(130, view.y - 70), Vector2(0.85, -1.0)))
cannons.append(_add_cannon(Vector2(view.x - 130, view.y - 70), Vector2(-0.85, -1.0)))
var timer: Timer = Timer.new()
timer.wait_time = FIRE_INTERVAL
timer.timeout.connect(_fire_next)
add_child(timer)
timer.start()
_fire_next()
print('click to set both cannons off at once, they take turns on their own')
func _unhandled_input(event: InputEvent) -> void:
if not (event is InputEventMouseButton and event.pressed):
return
for cannon in cannons:
cannon.restart()
func _fire_next() -> void:
cannons[next_cannon].restart()
next_cannon = (next_cannon + 1) % cannons.size()
func _add_cannon(at: Vector2, aim: Vector2) -> CPUParticles2D:
_add_nozzle(at, aim)
var cannon: CPUParticles2D = CPUParticles2D.new()
cannon.position = at
cannon.texture = _make_bar(11, 16)
cannon.local_coords = false
cannon.emitting = false
cannon.one_shot = true
cannon.explosiveness = 1.0
cannon.amount = 170
cannon.lifetime = 2.4
cannon.direction = aim
cannon.spread = 24.0
cannon.initial_velocity_min = 620.0
cannon.initial_velocity_max = 1180.0
cannon.gravity = Vector2(0, 760)
cannon.damping_min = 20.0
cannon.damping_max = 80.0
cannon.angle_min = -180.0
cannon.angle_max = 180.0
cannon.angular_velocity_min = -640.0
cannon.angular_velocity_max = 640.0
cannon.scale_amount_min = 0.7
cannon.scale_amount_max = 1.25
cannon.color_initial_ramp = _make_palette()
cannon.color_ramp = _make_fade()
add_child(cannon)
return cannon
func _add_nozzle(at: Vector2, aim: Vector2) -> void:
var size: Vector2 = Vector2(64, 26)
var nozzle: Polygon2D = Polygon2D.new()
nozzle.polygon = PackedVector2Array([Vector2(-size.x, -size.y * 0.35), Vector2(0, -size.y * 0.5), Vector2(0, size.y * 0.5), Vector2(-size.x, size.y * 0.35)])
nozzle.color = Color('#2a2f3d')
nozzle.position = at
nozzle.rotation = aim.angle()
add_child(nozzle)
func _make_palette() -> Gradient:
var palette: Gradient = Gradient.new()
# linear interpolation would blend the picks into mud instead of handing out flat colors
palette.interpolation_mode = Gradient.GRADIENT_INTERPOLATE_CONSTANT
palette.offsets = PackedFloat32Array([0.0, 0.2, 0.4, 0.6, 0.8])
palette.colors = PackedColorArray([Color('#8da5f3'), Color('#8eef97'), Color('#f3d48d'), Color('#fc7f7f'), Color('#e6e9f2')])
return palette
func _make_fade() -> Gradient:
var fade: Gradient = Gradient.new()
fade.offsets = PackedFloat32Array([0.0, 0.75, 1.0])
fade.colors = PackedColorArray([Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 0)])
return fade
func _make_bar(bar_width: int, bar_height: int) -> ImageTexture:
var image: Image = Image.create(bar_width, bar_height, false, Image.FORMAT_RGBA8)
image.fill(Color.WHITE)
return ImageTexture.create_from_image(image)
func _add_background() -> void:
var background: ColorRect = ColorRect.new()
background.color = Color('#12141a')
add_child(background)
# ColorRect defaults to MOUSE_FILTER_STOP and would eat the click before _unhandled_input
background.mouse_filter = Control.MOUSE_FILTER_IGNORE
background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)