刮刮乐:物品互动

This commit is contained in:
cakipaul 2025-02-07 20:52:15 +08:00
parent df4be58868
commit f1c40bb47e
12 changed files with 201 additions and 13 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://djvwe8dh4fmn"
path="res://.godot/imported/刮刮乐.png-2c82b14d7d14852fdee98f2c14a98643.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://asset/art/临时草稿/c02_第一章/刮刮乐.png"
dest_files=["res://.godot/imported/刮刮乐.png-2c82b14d7d14852fdee98f2c14a98643.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

Before

Width:  |  Height:  |  Size: 853 B

After

Width:  |  Height:  |  Size: 853 B

View File

@ -3,15 +3,15 @@
importer="texture" importer="texture"
type="CompressedTexture2D" type="CompressedTexture2D"
uid="uid://c4c7t2lttcf0a" uid="uid://c4c7t2lttcf0a"
path="res://.godot/imported/煤油灯.png-4b4e3a68e5a7458aa1134ee578e8c883.ctex" path="res://.godot/imported/煤油灯.png-9603866113eb55ff801241201ee8d7aa.ctex"
metadata={ metadata={
"vram_texture": false "vram_texture": false
} }
[deps] [deps]
source_file="res://asset/art/临时草稿/煤油灯.png" source_file="res://asset/art/临时草稿/c02_第一章/煤油灯.png"
dest_files=["res://.godot/imported/煤油灯.png-4b4e3a68e5a7458aa1134ee578e8c883.ctex"] dest_files=["res://.godot/imported/煤油灯.png-9603866113eb55ff801241201ee8d7aa.ctex"]
[params] [params]

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -3,15 +3,15 @@
importer="texture" importer="texture"
type="CompressedTexture2D" type="CompressedTexture2D"
uid="uid://doqtpiaf1weqc" uid="uid://doqtpiaf1weqc"
path="res://.godot/imported/煤油灯_点燃.png-aace2ea6aeaad791da0fdcb57c8433a0.ctex" path="res://.godot/imported/煤油灯_点燃.png-0a2f32ef537f73f027921117053029ee.ctex"
metadata={ metadata={
"vram_texture": false "vram_texture": false
} }
[deps] [deps]
source_file="res://asset/art/临时草稿/煤油灯_点燃.png" source_file="res://asset/art/临时草稿/c02_第一章/煤油灯_点燃.png"
dest_files=["res://.godot/imported/煤油灯_点燃.png-aace2ea6aeaad791da0fdcb57c8433a0.ctex"] dest_files=["res://.godot/imported/煤油灯_点燃.png-0a2f32ef537f73f027921117053029ee.ctex"]
[params] [params]

View File

@ -0,0 +1,9 @@
# @tool
extends Sprite2D
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.

View File

@ -0,0 +1,8 @@
shader_type canvas_item;
uniform float grey_scale = .33;
void fragment() {
COLOR.a = step(COLOR.r, .0);
COLOR.rgb = vec3(grey_scale - COLOR.r);
}

View File

@ -0,0 +1,39 @@
[gd_scene load_steps=8 format=3 uid="uid://bvnclp341hxoh"]
[ext_resource type="Script" path="res://scene/entity/ux/刮刮乐.gd" id="1_dja3c"]
[ext_resource type="Texture2D" uid="uid://djvwe8dh4fmn" path="res://asset/art/临时草稿/c02_第一章/刮刮乐.png" id="1_ffdds"]
[ext_resource type="Shader" path="res://scene/entity/ux/刮刮乐.gdshader" id="3_er5jo"]
[ext_resource type="Script" path="res://scene/entity/ux/刮刮乐mask.gd" id="4_wp0ek"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_rw7b6"]
shader = ExtResource("3_er5jo")
shader_parameter/grey_scale = 0.33
[sub_resource type="Image" id="Image_ra1lb"]
data = {
"data": PackedByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
"format": "Lum8",
"height": 18,
"mipmaps": false,
"width": 49
}
[sub_resource type="ImageTexture" id="ImageTexture_o178p"]
image = SubResource("Image_ra1lb")
[node name="刮刮乐" type="Sprite2D"]
position = Vector2(127, 138)
texture = ExtResource("1_ffdds")
script = ExtResource("1_dja3c")
[node name="mask" type="TextureRect" parent="."]
modulate = Color(0.475927, 0.475927, 0.475927, 1)
material = SubResource("ShaderMaterial_rw7b6")
custom_minimum_size = Vector2(49, 18)
offset_left = -24.0
offset_top = 6.0
offset_right = 25.0
offset_bottom = 24.0
texture = SubResource("ImageTexture_o178p")
script = ExtResource("4_wp0ek")
area_size = Vector2(49, 18)

View File

@ -0,0 +1,96 @@
@tool
extends TextureRect
signal shaven(progress: float)
@export var area_size := Vector2(40, 20):
set(val):
area_size = val
custom_minimum_size = val
if is_node_ready():
_init_bit_mask()
@export var debug_reload := false:
set(val):
debug_reload = false
if is_node_ready():
_init_bit_mask()
# points inside radius 5 circle
var brush_points := generate_brush_points(5)
var bit_mask: BitMap
func _ready() -> void:
# init bit mask
_init_bit_mask()
# a solid circle brush, center = (0, 0)
func generate_brush_points(radius: int) -> PackedVector2Array:
var points := PackedVector2Array()
# Check each pixel in square area
for x in range(-radius, radius + 1):
for y in range(-radius, radius + 1):
# If point is within circle radius
if x * x + y * y <= radius * radius:
points.append(Vector2(x, y))
return points
func _init_bit_mask() -> void:
if not bit_mask:
bit_mask = BitMap.new()
bit_mask.create(area_size)
texture = ImageTexture.create_from_image(bit_mask.convert_to_image())
func _shave(mouse_pos: Vector2) -> void:
if not mouse_pressing:
return
var updated = false
for point in brush_points:
var pos = mouse_pos + point
if pos.x < 0 or pos.x >= area_size.x or pos.y < 0 or pos.y >= area_size.y:
continue
bit_mask.set_bitv(pos, true)
updated = true
texture.update(bit_mask.convert_to_image())
if updated:
_send_signal()
func _send_signal() -> void:
var total = area_size.x * area_size.y
var true_bit_count = bit_mask.get_true_bit_count()
var progress = float(true_bit_count) / float(total)
shaven.emit(progress)
var mouse_pressing = false
# 可以刮出区域
func _gui_input(event: InputEvent) -> void:
# 通过鼠标点击拖动刮开区域set_bit 一个 brush_size 的圆形区域为 true
# 每次更新后bit_mask 会更新到 texture 上
# 通过 shaven 信号,通知外部,刮开了多少区域
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
# 先设置 mouse_pressing 为 true
mouse_pressing = true
# 刮开区域
_shave(event.position)
accept_event()
elif event.button_index == MOUSE_BUTTON_LEFT and not event.pressed:
mouse_pressing = false
accept_event()
elif event is InputEventMouseMotion and mouse_pressing:
_shave(event.position)
accept_event()
# elif event is InputEventScreenTouch:
# if event.pressed:
# mouse_pressing = true
# _shave(event.position)
# accept_event()
# elif not event.pressed:
# mouse_pressing = false
# accept_event()

View File

@ -13,8 +13,8 @@
[ext_resource type="AudioStream" uid="uid://dq2ndg5yd3rps" path="res://asset/audio/sfx/c02/出现.mp3" id="11_u68d7"] [ext_resource type="AudioStream" uid="uid://dq2ndg5yd3rps" path="res://asset/audio/sfx/c02/出现.mp3" id="11_u68d7"]
[ext_resource type="PackedScene" uid="uid://ci5anaxsa1apl" path="res://scene/entity/local_inspectable.tscn" id="12_0fckv"] [ext_resource type="PackedScene" uid="uid://ci5anaxsa1apl" path="res://scene/entity/local_inspectable.tscn" id="12_0fckv"]
[ext_resource type="PackedScene" uid="uid://cw3q5pvciumil" path="res://scene/entity/interactable.tscn" id="13_ck13g"] [ext_resource type="PackedScene" uid="uid://cw3q5pvciumil" path="res://scene/entity/interactable.tscn" id="13_ck13g"]
[ext_resource type="Texture2D" uid="uid://c4c7t2lttcf0a" path="res://asset/art/临时草稿/煤油灯.png" id="14_db4pu"] [ext_resource type="Texture2D" uid="uid://c4c7t2lttcf0a" path="res://asset/art/临时草稿/c02_第一章/煤油灯.png" id="14_db4pu"]
[ext_resource type="Texture2D" uid="uid://doqtpiaf1weqc" path="res://asset/art/临时草稿/煤油灯_点燃.png" id="15_5rpxj"] [ext_resource type="Texture2D" uid="uid://doqtpiaf1weqc" path="res://asset/art/临时草稿/c02_第一章/煤油灯_点燃.png" id="15_5rpxj"]
[ext_resource type="Texture2D" uid="uid://b7gyapghy3tsy" path="res://asset/art/neutral_point_light.png" id="16_asses"] [ext_resource type="Texture2D" uid="uid://b7gyapghy3tsy" path="res://asset/art/neutral_point_light.png" id="16_asses"]
[ext_resource type="AudioStream" uid="uid://dvwiuesd0qi1l" path="res://asset/audio/sfx/ui/门牌互动音.wav" id="16_d08tt"] [ext_resource type="AudioStream" uid="uid://dvwiuesd0qi1l" path="res://asset/audio/sfx/ui/门牌互动音.wav" id="16_d08tt"]
[ext_resource type="AudioStream" uid="uid://dky3j8lwcy5sk" path="res://asset/audio/sfx/ui/物品查看.mp3" id="17_lqks2"] [ext_resource type="AudioStream" uid="uid://dky3j8lwcy5sk" path="res://asset/audio/sfx/ui/物品查看.mp3" id="17_lqks2"]

View File

@ -15,15 +15,17 @@ func play() -> void:
visible = true visible = true
var tween = create_tween() var tween = create_tween()
tween.tween_interval(3.0) tween.tween_interval(3.0)
tween.tween_property(self, "self_modulate:a", 0.0, 15.0)
var final_modulate = Color.PALE_VIOLET_RED var final_modulate = Color.PALE_VIOLET_RED
tween.parallel().tween_property(get_parent(), "modulate", final_modulate, 15.0) tween.tween_property(self, "self_modulate:a", 0.0, 4.0)
tween.parallel().tween_property(get_parent(), "modulate", final_modulate, 12.0)
tween = create_tween() tween = create_tween()
var interval = 3. tween.tween_interval(7.0)
# 小蝶名字消失后再显示其他名字
var interval = 2.4
for c in self.get_children(): for c in self.get_children():
c.visible = false c.visible = false
tween.tween_interval(interval)
tween.tween_callback(_stamp_seal.bind(c)) tween.tween_callback(_stamp_seal.bind(c))
tween.tween_interval(interval)
interval = max(interval - 0.3, 0.4) interval = max(interval - 0.3, 0.4)
@ -43,7 +45,7 @@ func _stamp_seal(seal: Sprite2D) -> void:
seal.visible = true seal.visible = true
var origin_scale = seal.scale var origin_scale = seal.scale
create_tween().tween_property(seal, "scale", origin_scale * Vector2(1.05, 1.05), .1) create_tween().tween_property(seal, "scale", origin_scale * Vector2(1.05, 1.05), .1)
create_tween().tween_property(seal, "scale", origin_scale * Vector2(1.0, 1.), .1) create_tween().tween_property(seal, "scale", origin_scale * Vector2(1.0, 1.), .1)
func _draw() -> void: func _draw() -> void: