mlpcardgame/Scenes/Scripts/Board.gd

140 lines
4.5 KiB
GDScript3
Raw Normal View History

2019-05-04 19:33:47 +00:00
extends Spatial
2019-05-05 23:35:58 +00:00
class_name Board
onready var CardTemplate := preload("res://Scenes/Components/Card.tscn")
2019-05-04 19:33:47 +00:00
onready var camera := $Camera
2019-05-05 19:19:39 +00:00
onready var hand := $Camera/Hand
onready var ui := $BoardUI
2019-05-05 19:19:39 +00:00
onready var cards := $Cards
export var mouseHandThreshold = 0.9
2019-05-06 11:12:57 +00:00
var holdingCard: Card = null
var focusedCard: Card = null
2019-05-04 19:33:47 +00:00
var mouseOrigin: Vector2
var lastCameraTransform: Transform
func _ready():
2019-05-06 11:12:57 +00:00
add_card("ff36", 0, true)
add_card("ff36", 0, true)
add_card("ff36", 0, true)
add_card("ff36", 0, true)
add_card("ff36", 0, true)
add_card("ff36", 0, true)
add_card("ff36", 0, true)
add_card("ff36", 0, true)
add_card("ff36", 0, true)
add_card("ff36", 0, true)
add_card("ff36", 0, false)
2019-05-06 11:12:57 +00:00
reorder_hand()
2019-05-04 19:33:47 +00:00
func _input(event: InputEvent):
# Camera zoom
if event.is_action("zoom_in"):
camera.zoom(true)
elif event.is_action("zoom_out"):
camera.zoom(false)
# Save original camera and mouse position before panning
if event.is_action_pressed("pan"):
mouseOrigin = get_viewport().get_mouse_position()
lastCameraTransform = camera.transform
2019-05-04 21:42:07 +00:00
func _process(delta: float):
2019-05-05 19:19:39 +00:00
# If mouse is under a certain area then we're managing our hand
var absMousePos := get_viewport().get_mouse_position()
2019-05-04 19:33:47 +00:00
# If panning, translate mouse delta to camera delta
if Input.is_action_pressed("pan"):
2019-05-05 19:19:39 +00:00
var mouseDelta := absMousePos - mouseOrigin
var mousePos: Vector2 = mouseDelta * 0.0096 * (1-camera.get_zoom()/5) # Magic numbers everywhere
2019-05-05 19:19:39 +00:00
camera.transform.origin = lastCameraTransform.origin - Vector3(mousePos.x, 0, mousePos.y)
# If holding a card, move it between board/hand
if holdingCard != null:
2019-05-05 19:19:39 +00:00
var relPos: float = absMousePos.y / get_viewport().size.y
var selectingHand: bool = relPos > mouseHandThreshold
if selectingHand and not holdingCard.inHand:
holdingCard.inHand = true
call_deferred("reparent", holdingCard, cards, hand)
elif not selectingHand and holdingCard.inHand:
holdingCard.inHand = false
call_deferred("reparent", holdingCard, hand, cards)
2019-05-05 19:19:39 +00:00
func _card_picked(card: Card):
holdingCard = card
2019-05-06 11:12:57 +00:00
# Fix rotation if coming from hand
if holdingCard.inHand:
holdingCard.rotation = Vector3.ZERO
2019-05-05 19:19:39 +00:00
func _card_dropped(card: Card):
holdingCard = null
2019-05-06 11:12:57 +00:00
reorder_hand()
func _card_selected(card: Card):
if card.inHand and focusedCard == null:
focusedCard = card
card.animation.play("focus")
func _card_unselected(card: Card):
if focusedCard == card:
focusedCard = null
card.animation.play("blur")
2019-05-05 19:19:39 +00:00
func reparent(object: Node, from: Node, to: Node):
from.remove_child(object)
to.add_child(object)
object.set_owner(to)
2019-05-06 11:12:57 +00:00
reorder_hand()
func add_card(cardID: String, playerID: int, inHand: bool):
var card := CardTemplate.instance()
card.cardID = cardID
card.playerID = playerID
card.inHand = inHand
card.connect("card_dropped", self, "_card_dropped", [card])
card.connect("card_picked", self, "_card_picked", [card])
card.connect("card_selected", ui, "_card_selected", [card])
card.connect("card_unselected", ui, "_card_unselected", [card])
2019-05-06 11:12:57 +00:00
card.connect("card_selected", self, "_card_selected", [card])
card.connect("card_unselected", self, "_card_unselected", [card])
2019-05-05 23:35:58 +00:00
card.connect("card_menu", ui, "show_card_menu", [card])
if inHand:
# TODO if player != me, put in opponent's hand
hand.add_child(card)
else:
2019-05-06 11:12:57 +00:00
cards.add_child(card)
const MAX_CARD_DISTANCE := 0.5
const HAND_SCREEN_PERC := 0.8
const CARD_ROTATION := 0.03
const UNITSPERPX := 0.003
func reorder_hand():
var cardsInHand: Array = hand.get_children()
cardsInHand.sort_custom(TransformSorter, "sort")
var size := cardsInHand.size()
# Calculate total width of the player's hand and other things
# This is done in two ways, for small hands, MAX_CARD_DISTANCE is usually used
# as constant distance between cards, however, as the hand gets larger we don't
# want them to go offscreen, therefore a "maximum screen %" is used to determine
# how to fit all the cards within a % of the viewport's width
var distancePerc := get_viewport().size.x * HAND_SCREEN_PERC * UNITSPERPX / size
var distance := distancePerc#max(distancePerc, MAX_CARD_DISTANCE)
var totalWidth := distance * (size-1)
var minX := -totalWidth/2
# Iterate over all items, keep track of the index
var i := 0
for child in cardsInHand:
child.transform.origin = Vector3(minX + distance * i, 0.02*i, 0)
child.rotation = Vector3(0, CARD_ROTATION * (size - i - 1), 0)
i += 1
child.reset_transform()
class TransformSorter:
static func sort(a, b):
if a.transform.origin.x < b.transform.origin.x:
return true
return false