Tremblement d'écran
Un trauma qui décroît avec le temps, échantillonné depuis FastNoiseLite vers l'offset et la rotation de la caméra. Une explosion part toutes les 1,2 seconde et le curseur la dose.
L'éditeur ci-dessus fait tourner ce projet. Changez une ligne et il se recharge.
Classes Godot utilisées
Camera2DFastNoiseLiteHSlider
Le code
scripts/main.gd
extends Node
const MAX_OFFSET: float = 44.0
const MAX_ROLL: float = 0.07
const DECAY: float = 0.6
var camera: Camera2D
var noise: FastNoiseLite
var flash: Polygon2D
var bar: ColorRect
var readout: Label
var trauma: float = 0.0
var intensity: float = 1.0
var elapsed: float = 0.0
func _ready() -> void:
_add_background()
var view: Vector2 = get_viewport().get_visible_rect().size
noise = FastNoiseLite.new()
noise.noise_type = FastNoiseLite.TYPE_SIMPLEX
noise.frequency = 0.5
_add_city(view)
flash = _make_disc(78.0, Color('#fc7f7f'))
flash.position = Vector2(view.x * 0.5, view.y * 0.62)
add_child(flash)
camera = Camera2D.new()
camera.position = view * 0.5
# ignore_rotation defaults to true and would drop the roll
camera.ignore_rotation = false
add_child(camera)
camera.make_current()
_add_hud(view)
var timer: Timer = Timer.new()
timer.wait_time = 1.2
timer.timeout.connect(_burst)
add_child(timer)
timer.start()
_burst()
print('a blast fires every 1.2s, click or press space for one now, the slider scales it')
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseButton and event.pressed:
_burst()
elif event is InputEventKey and event.pressed and (event as InputEventKey).keycode == KEY_SPACE:
_burst()
func _process(delta: float) -> void:
elapsed += delta
trauma = maxf(trauma - DECAY * delta, 0.0)
var shake: float = trauma * trauma * intensity
camera.offset = Vector2(noise.get_noise_2d(0.0, elapsed * 30.0), noise.get_noise_2d(500.0, elapsed * 30.0)) * MAX_OFFSET * shake
camera.rotation = noise.get_noise_2d(1000.0, elapsed * 30.0) * MAX_ROLL * shake
flash.scale = Vector2.ONE * (0.2 + trauma * 0.9)
flash.modulate.a = trauma * 0.75
bar.size.x = 260.0 * minf(trauma, 1.0)
readout.text = 'trauma %.2f intensity %.2f' % [trauma, intensity]
func _burst() -> void:
trauma = 1.0
func _on_intensity(value: float) -> void:
intensity = value
func _add_city(view: Vector2) -> void:
var ground: Polygon2D = Polygon2D.new()
ground.polygon = PackedVector2Array([Vector2(-600, view.y * 0.62), Vector2(view.x + 600, view.y * 0.62), Vector2(view.x + 600, view.y + 600), Vector2(-600, view.y + 600)])
ground.color = Color('#2a2f3d')
add_child(ground)
var rng: RandomNumberGenerator = RandomNumberGenerator.new()
rng.seed = 3
for i in 11:
var width: float = rng.randf_range(60, 110)
var height: float = rng.randf_range(120, 300)
var tower: Polygon2D = Polygon2D.new()
tower.polygon = PackedVector2Array([Vector2(0, -height), Vector2(width, -height), Vector2(width, 0), Vector2(0, 0)])
tower.color = Color('#8da5f3').lerp(Color('#12141a'), rng.randf_range(0.3, 0.65))
tower.position = Vector2(60 + i * 110, view.y * 0.62)
add_child(tower)
func _make_disc(radius: float, color: Color) -> Polygon2D:
var points: PackedVector2Array = PackedVector2Array()
for i in 32:
points.append(Vector2(cos(TAU * i / 32.0), sin(TAU * i / 32.0)) * radius)
var disc: Polygon2D = Polygon2D.new()
disc.polygon = points
disc.color = color
return disc
func _add_hud(view: Vector2) -> void:
var hud: CanvasLayer = CanvasLayer.new()
add_child(hud)
var frame: Panel = Panel.new()
var style: StyleBoxFlat = StyleBoxFlat.new()
style.bg_color = Color(0, 0, 0, 0)
style.border_color = Color('#8eef97')
style.set_border_width_all(3)
frame.add_theme_stylebox_override('panel', style)
frame.position = Vector2(20, 20)
frame.size = view - Vector2(40, 40)
hud.add_child(frame)
var slider: HSlider = HSlider.new()
slider.min_value = 0.0
slider.max_value = 2.0
slider.step = 0.05
slider.value = intensity
slider.position = Vector2(48, view.y - 90)
slider.size = Vector2(260, 24)
slider.value_changed.connect(_on_intensity)
hud.add_child(slider)
var track: ColorRect = ColorRect.new()
track.color = Color('#2a2f3d')
track.position = Vector2(48, view.y - 140)
track.size = Vector2(260, 14)
hud.add_child(track)
bar = ColorRect.new()
bar.color = Color('#fc7f7f')
bar.position = track.position
bar.size = Vector2(0, 14)
hud.add_child(bar)
readout = Label.new()
readout.add_theme_font_size_override('font_size', 20)
readout.add_theme_color_override('font_color', Color('#f3d48d'))
readout.position = Vector2(48, view.y - 180)
hud.add_child(readout)
var note: Label = Label.new()
note.text = 'the green frame is a CanvasLayer, it never shakes'
note.add_theme_font_size_override('font_size', 20)
note.add_theme_color_override('font_color', Color('#8eef97'))
note.position = Vector2(48, 44)
hud.add_child(note)
func _add_background() -> void:
var layer: CanvasLayer = CanvasLayer.new()
layer.layer = -1
add_child(layer)
var background: ColorRect = ColorRect.new()
background.color = Color('#12141a')
layer.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)