刮刮乐:物品互动
This commit is contained in:
parent
df4be58868
commit
f1c40bb47e
BIN
asset/art/临时草稿/c02_第一章/刮刮乐.png
Normal file
BIN
asset/art/临时草稿/c02_第一章/刮刮乐.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
34
asset/art/临时草稿/c02_第一章/刮刮乐.png.import
Normal file
34
asset/art/临时草稿/c02_第一章/刮刮乐.png.import
Normal 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
|
Before Width: | Height: | Size: 853 B After Width: | Height: | Size: 853 B |
@ -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]
|
||||||
|
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
@ -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]
|
||||||
|
|
9
scene/entity/ux/刮刮乐.gd
Normal file
9
scene/entity/ux/刮刮乐.gd
Normal 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.
|
||||||
|
|
8
scene/entity/ux/刮刮乐.gdshader
Normal file
8
scene/entity/ux/刮刮乐.gdshader
Normal 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);
|
||||||
|
}
|
39
scene/entity/ux/刮刮乐.tscn
Normal file
39
scene/entity/ux/刮刮乐.tscn
Normal 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)
|
96
scene/entity/ux/刮刮乐mask.gd
Normal file
96
scene/entity/ux/刮刮乐mask.gd
Normal 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()
|
@ -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"]
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user