爆炸

一层 one_shot 火花叠在一层 one_shot 烟雾上,一起重启。点击可以移动爆点,或者等计时器再次触发。

上方的编辑器正在运行这个项目。改一行代码,它就会重新加载。

用到的 Godot 类

CPUParticles2DCanvasItemMaterialTimer

代码

scripts/main.gd
extends Node

const BURST_INTERVAL: float = 1.2
const SPARK_LIFETIME: float = 1.4

var spark: CPUParticles2D
var smoke: CPUParticles2D


func _ready() -> void:
	_add_background()

	var dot: GradientTexture2D = _make_dot()

	smoke = CPUParticles2D.new()
	smoke.texture = dot
	smoke.local_coords = false
	smoke.one_shot = true
	smoke.explosiveness = 1.0
	smoke.amount = 60
	smoke.lifetime = 1.7
	smoke.spread = 180.0
	smoke.initial_velocity_min = 90.0
	smoke.initial_velocity_max = 340.0
	smoke.gravity = Vector2(0, -70)
	smoke.damping_min = 90.0
	smoke.damping_max = 190.0
	smoke.scale_amount_min = 2.0
	smoke.scale_amount_max = 4.2
	smoke.color_ramp = _make_ramp(
		PackedFloat32Array([0.0, 0.25, 1.0]),
		PackedColorArray([Color(0.36, 0.38, 0.46, 0.0), Color(0.36, 0.38, 0.46, 0.22), Color(0.2, 0.21, 0.26, 0.0)])
	)
	add_child(smoke)

	spark = CPUParticles2D.new()
	spark.texture = dot
	spark.local_coords = false
	spark.one_shot = true
	spark.explosiveness = 1.0
	spark.amount = 280
	spark.lifetime = SPARK_LIFETIME
	spark.spread = 180.0
	spark.initial_velocity_min = 260.0
	spark.initial_velocity_max = 820.0
	spark.gravity = Vector2(0, 620)
	spark.damping_min = 90.0
	spark.damping_max = 260.0
	spark.scale_amount_min = 0.4
	spark.scale_amount_max = 1.4
	spark.color_ramp = _make_ramp(
		PackedFloat32Array([0.0, 0.2, 0.6, 1.0]),
		PackedColorArray([Color('#fff6d8'), Color('#f3d48d'), Color('#fc7f7f'), Color(0.7, 0.25, 0.25, 0.0)])
	)
	spark.material = _make_additive()
	add_child(spark)

	var timer: Timer = Timer.new()
	timer.wait_time = BURST_INTERVAL
	timer.timeout.connect(_blast_at_center)
	add_child(timer)
	timer.start()

	_blast_at_center()

	print('click anywhere to blow it up there, one goes off on its own every %.1f s' % BURST_INTERVAL)


func _unhandled_input(event: InputEvent) -> void:
	if event is InputEventMouseButton and event.pressed:
		_blast((event as InputEventMouseButton).position)


func _blast_at_center() -> void:
	_blast(get_viewport().get_visible_rect().size * 0.5)


func _blast(at: Vector2) -> void:
	spark.position = at
	smoke.position = at
	spark.restart()
	smoke.restart()


func _make_additive() -> CanvasItemMaterial:
	var material: CanvasItemMaterial = CanvasItemMaterial.new()
	material.blend_mode = CanvasItemMaterial.BLEND_MODE_ADD

	return material


func _make_ramp(offsets: PackedFloat32Array, colors: PackedColorArray) -> Gradient:
	var ramp: Gradient = Gradient.new()
	ramp.offsets = offsets
	ramp.colors = colors

	return ramp


func _make_dot() -> GradientTexture2D:
	var gradient: Gradient = Gradient.new()
	gradient.set_color(0, Color(1, 1, 1, 1))
	gradient.set_color(1, Color(1, 1, 1, 0))

	var dot: GradientTexture2D = GradientTexture2D.new()
	dot.gradient = gradient
	dot.fill = GradientTexture2D.FILL_RADIAL
	dot.fill_from = Vector2(0.5, 0.5)
	dot.fill_to = Vector2(1.0, 0.5)
	dot.width = 32
	dot.height = 32

	return dot


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)

更多粒子示例