organizes card scene, exports tween functionality to its own node and script

This commit is contained in:
2025-04-27 22:49:45 -04:00
parent ce0bc104ff
commit 3c02ae63f9
10 changed files with 45 additions and 66 deletions

144
scenes/card/card.gd Normal file
View File

@ -0,0 +1,144 @@
extends Node2D
## The card class
##
## Represents an instance of a card to be displayed on the tabletop.
## Contains helper text for the text, the cards ID, and the image path.
# Card information.
var card_id: String
var card_name: String
var card_type: String
var oracle_text: String
# Card properties.
var tapped: bool
# Card input state.
var is_focused: bool # Is the card a focus?
var is_dragging: bool # Is the card currently being dragged?
var mouse_offset: Vector2
func _physics_process(delta: float) -> void:
if is_focused:
# TODO: Export handling keypresses to its own area.
if Input.is_action_just_pressed("MAIN"):
tapped = not tapped
$TweenController.tap(tapped, delta)
if is_dragging:
$TweenController.move_to(get_global_mouse_position() - mouse_offset, delta)
func _on_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
if event is not InputEventMouseButton:
return
match event.button_index:
# MOUSE BUTTONS
MOUSE_BUTTON_LEFT:
if event.pressed:
Input.set_default_cursor_shape(Input.CURSOR_DRAG)
mouse_offset = get_global_mouse_position() - global_position
is_dragging = true
else:
Input.set_default_cursor_shape(Input.CURSOR_POINTING_HAND)
is_dragging = false
MOUSE_BUTTON_RIGHT:
# TODO: Tooltip menu for right-button clicking on cards.
pass
func _on_mouse_entered() -> void:
# Do not care about mouse entering if we're dragging the card.
if is_dragging:
return
Input.set_default_cursor_shape(Input.CURSOR_POINTING_HAND)
$TweenController.scale(1.05)
is_focused = true
func _on_mouse_exited() -> void:
# Do not care about mouse exiting if we're dragging the card.
if is_dragging:
return
Input.set_default_cursor_shape(Input.CURSOR_ARROW)
$TweenController.scale(1.0)
is_focused = false
func _card_error(error_type: String) -> String:
return "ERROR::CARD::%s::%s::%s::\n" % [card_id, card_name, error_type]
func init(id: String) -> void:
card_id = id
func _ready() -> void:
var load_status = _load_card()
if load_status != OK:
# TODO: No need to push another error as the failure state of loading does that already,
# if the card is not cached, perhaps a placeholder blank card can be used instead?
# Setting that up can be put here later...
push_error("Failed to load card.")
func _load_card() -> Error:
if _load_data() != OK:
return FAILED
if _load_image() != OK:
return FAILED
return OK
func _load_data() -> Error:
var cached_json = FileAccess.get_file_as_string("user://card_cache/" + card_id + "/card.json")
if cached_json.is_empty():
push_error("%s\nCard json data was not found in cache" % _card_error("CACHE"))
return FAILED
var card_json = JSON.parse_string(cached_json)
if card_json == null:
push_error("%s\nCard json data is could not be parsed as valid json" % _card_error("DATA"))
return FAILED
card_name = card_json["name"]
card_type = card_json["type_line"]
oracle_text = card_json["oracle_text"]
return OK
func _load_image() -> Error:
# NOTE: Assuming we're going with using the .png cards on board.
var cached_img = FileAccess.get_file_as_bytes("user://card_cache/" + card_id + "/card.png")
if cached_img.is_empty():
push_error("%sCard on-board image was not found in cache" % _card_error("CACHE"))
return FAILED
var image = Image.new()
var image_status: Error = image.load_png_from_buffer(cached_img)
if image_status != OK:
push_error("%sCard on-board image failed to load correctly" % _card_error("IMAGE"))
return FAILED
var size = $Area2D/CollisionShape2D.shape.size
image.resize(int(size.x), int(size.y), Image.INTERPOLATE_LANCZOS)
var image_texture = ImageTexture.new()
image_texture.set_image(image)
$Sprite2D.texture = image_texture
return OK

1
scenes/card/card.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://b3yqd1qu7dyq

24
scenes/card/card.tscn Normal file
View File

@ -0,0 +1,24 @@
[gd_scene load_steps=4 format=3 uid="uid://cah3mvdnom1xg"]
[ext_resource type="Script" uid="uid://b3yqd1qu7dyq" path="res://scenes/card/card.gd" id="1_kikvd"]
[ext_resource type="Script" uid="uid://bkk0pyypi1id7" path="res://scenes/card/tween.gd" id="2_imta7"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kikvd"]
size = Vector2(125, 175)
[node name="Card" type="Node2D"]
script = ExtResource("1_kikvd")
[node name="Sprite2D" type="Sprite2D" parent="."]
[node name="Area2D" type="Area2D" parent="."]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
shape = SubResource("RectangleShape2D_kikvd")
[node name="TweenController" type="Node2D" parent="."]
script = ExtResource("2_imta7")
[connection signal="input_event" from="Area2D" to="." method="_on_input_event"]
[connection signal="mouse_entered" from="Area2D" to="." method="_on_mouse_entered"]
[connection signal="mouse_exited" from="Area2D" to="." method="_on_mouse_exited"]

0
scenes/card/input.gd Normal file
View File

1
scenes/card/input.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://dhgk6fhw8oua0

22
scenes/card/tween.gd Normal file
View File

@ -0,0 +1,22 @@
extends Node
@export var move_speed = 1.0
@export var tap_speed = 5.0
@export var scale_speed = 0.1
func move_to(location: Vector2, delta: float) -> void:
var tween = create_tween()
tween.tween_property(get_parent(), "position", location, delta * move_speed)
func tap(tapped: bool, delta: float) -> void:
var tween = create_tween()
var rotation = 90 if tapped else 0
tween.tween_property(get_parent(), "rotation_degrees", rotation, delta * tap_speed)
func scale(scalar: float) -> void:
var tween = create_tween()
var new_scale = Vector2.ONE * scalar
tween.tween_property(get_parent(), "scale", new_scale, scale_speed)

1
scenes/card/tween.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://bkk0pyypi1id7