2021-11-14 20:04:32 +00:00
|
|
|
extends Node2D
|
2021-11-08 13:40:11 +00:00
|
|
|
|
2021-11-11 20:38:10 +00:00
|
|
|
# This is the rendered element of a "ship", generated when the game transitions from the placing state to the gameplay state
|
|
|
|
|
2021-11-14 07:21:40 +00:00
|
|
|
# Enum denoting the orientation (X is 0, Y is 1)
|
|
|
|
enum Orientation {X = 0, Y = 1}
|
2021-11-14 20:04:32 +00:00
|
|
|
enum {MISS = -1, READY = 0, HIT = 1, SUNK = 2}
|
2021-11-08 13:40:11 +00:00
|
|
|
|
2021-11-11 21:38:50 +00:00
|
|
|
# Size of ship in board units
|
2021-11-14 20:04:32 +00:00
|
|
|
var size
|
|
|
|
var health
|
2021-11-11 21:38:50 +00:00
|
|
|
# Coordinates of ship's center. Ship extends [-(size-1 >> 1), (size/2 >> 1)]
|
2021-11-14 12:32:46 +00:00
|
|
|
var boardposition = Vector2(-1,-1)
|
2021-11-11 21:38:50 +00:00
|
|
|
# Variable storing whether the ship is sunk, for rendering purposes
|
2021-11-08 13:40:11 +00:00
|
|
|
var sunk = false
|
2021-11-11 21:38:50 +00:00
|
|
|
# Orientation of the ship (see enum Orientation)
|
|
|
|
var orientation = Orientation.Y
|
2021-11-14 09:15:27 +00:00
|
|
|
# array of spots thats been hit
|
2021-11-15 07:17:32 +00:00
|
|
|
var hits = []
|
2021-11-14 20:04:32 +00:00
|
|
|
# Variable storing the positions of each piece of the ship
|
|
|
|
var extents = []
|
2021-11-08 13:40:11 +00:00
|
|
|
|
2021-11-11 21:38:50 +00:00
|
|
|
# Ship sprite metadata
|
2021-11-14 20:04:32 +00:00
|
|
|
# atlas: the texture atlas containing all ship parts
|
|
|
|
var atlas = preload("res://assets/game/TextureAtlas.png")
|
|
|
|
# sprites: the individual sprite nodes which make up the ship
|
|
|
|
var sprites = []
|
|
|
|
# variant: Ships of the same length can have different textures
|
|
|
|
# variant A is 0, variant B is 1, ...
|
2021-11-14 09:15:27 +00:00
|
|
|
var variant = 0
|
2021-11-08 13:40:11 +00:00
|
|
|
|
|
|
|
# Called when the node enters the scene tree for the first time.
|
|
|
|
func _ready():
|
|
|
|
pass # Replace with function body.
|
|
|
|
|
2021-11-11 21:38:50 +00:00
|
|
|
# member functions:
|
2021-11-14 20:04:32 +00:00
|
|
|
# getShip():
|
|
|
|
func get_ship():
|
|
|
|
return [boardposition, size, orientation, variant]
|
2021-11-11 21:38:50 +00:00
|
|
|
|
|
|
|
# getSunk: get whether the ship is sunk
|
2021-11-14 20:04:32 +00:00
|
|
|
func get_sunk():
|
2021-11-08 13:40:11 +00:00
|
|
|
return sunk
|
|
|
|
|
2021-11-14 20:04:32 +00:00
|
|
|
func hit(pos):
|
|
|
|
# Assume the opponent missed
|
|
|
|
var res = MISS
|
|
|
|
# Find the position in the extents
|
|
|
|
var index = extents.find(pos)
|
|
|
|
# If that position exists:
|
|
|
|
if (index > -1):
|
|
|
|
# Hit the ship piece at that location
|
2021-11-15 07:17:32 +00:00
|
|
|
hits[index] = true
|
2021-11-14 20:04:32 +00:00
|
|
|
res = HIT
|
|
|
|
# Decrement its health
|
|
|
|
health -= 1
|
|
|
|
# If there's no more health,
|
|
|
|
if health == 0:
|
|
|
|
# Sink the ship.
|
|
|
|
set_sunk()
|
|
|
|
res = SUNK
|
|
|
|
return res
|
|
|
|
|
|
|
|
# update: (re)calculates extents and textures
|
|
|
|
func update():
|
|
|
|
# Calculate the extents (shouldn't change)
|
|
|
|
extents = get_extent()
|
|
|
|
# Update the textures
|
|
|
|
for i in size:
|
|
|
|
texture(i)
|
|
|
|
|
2021-11-14 09:15:27 +00:00
|
|
|
# returns an array of the positions that the ship occupies
|
2021-11-14 20:04:32 +00:00
|
|
|
func get_extent():
|
2021-11-14 07:21:40 +00:00
|
|
|
var extent = []
|
2021-11-14 13:14:35 +00:00
|
|
|
# Find each tile of the ship
|
2021-11-14 12:32:46 +00:00
|
|
|
for i in size:
|
2021-11-14 13:14:35 +00:00
|
|
|
# Calculate the x axis position
|
|
|
|
var x = boardposition.x - (1 - orientation) * ( (size - 1) / 2 - i )
|
|
|
|
# Calculate the y axis position
|
|
|
|
var y = boardposition.y - orientation * ( (size - 1) / 2 - i )
|
|
|
|
# Append the point onto the array
|
|
|
|
extent.push_back(Vector2(x,y))
|
2021-11-14 07:21:40 +00:00
|
|
|
return extent
|
2021-11-14 13:14:35 +00:00
|
|
|
|
2021-11-14 20:04:32 +00:00
|
|
|
# Update textures
|
2021-11-14 09:15:27 +00:00
|
|
|
func texture(index):
|
2021-11-14 20:04:32 +00:00
|
|
|
var state = 0 # ready
|
2021-11-15 07:17:32 +00:00
|
|
|
if(hits[index]):
|
2021-11-14 20:04:32 +00:00
|
|
|
state = 1 # hit
|
2021-11-14 09:15:27 +00:00
|
|
|
var textureSize = 32
|
2021-11-14 20:04:32 +00:00
|
|
|
# It's okay to create a new texture every time, as resources are refcounted
|
2021-11-14 09:15:27 +00:00
|
|
|
var t = AtlasTexture.new()
|
2021-11-14 20:04:32 +00:00
|
|
|
t.set_atlas(atlas)
|
|
|
|
t.margin = Rect2(0, 0, 32, 32)
|
|
|
|
t.region = Rect2(
|
|
|
|
(size * variant + index) * textureSize,
|
|
|
|
#(size * textureSize) * variant + (32 * index),
|
2021-11-14 09:15:27 +00:00
|
|
|
(size - 2) * textureSize * 2 + (32 * state),
|
|
|
|
textureSize,
|
|
|
|
textureSize
|
|
|
|
)
|
2021-11-14 20:04:32 +00:00
|
|
|
# Create a new Sprite to house the texture, or use the existing sprite
|
|
|
|
var sprite = sprites[index]
|
|
|
|
if sprite == null:
|
|
|
|
sprite = Sprite.new()
|
|
|
|
sprite.texture = t
|
|
|
|
# This is relative to the ship
|
|
|
|
# (index + 1) => Index, but 1-based
|
|
|
|
# (floor((size-1)/2) => Offset from edge to 'center' of ship
|
|
|
|
# Vector2(0.5,0.5) => Center the texture on the axis of rotation
|
|
|
|
# 32 => Converts from board-units to pixels
|
|
|
|
sprite.position = Vector2((index + 1) - (floor((size-1)/2) + 0.5), 0.5) * textureSize
|
|
|
|
sprite.rotation = 0
|
|
|
|
# Add the sprite to the "sprites" group, persistently
|
|
|
|
sprite.add_to_group("Ship Sprites", true)
|
|
|
|
# Add the sprite node to an array so it can be modified later, unless it's already there
|
|
|
|
if not sprites[index]:
|
|
|
|
sprites[index] = sprite
|
|
|
|
add_child(sprite)
|
|
|
|
|
2021-11-11 21:38:50 +00:00
|
|
|
# setSunk: sink the ship
|
2021-11-14 20:04:32 +00:00
|
|
|
func set_sunk():
|
2021-11-08 13:40:11 +00:00
|
|
|
sunk = true
|
|
|
|
|
2021-11-11 21:38:50 +00:00
|
|
|
# _init: called on object initialization. Accepts args if called via <Ship>.new(...)
|
|
|
|
# in_position: position of the ship, in board-coordinates; (0,0) by default
|
|
|
|
# in_size: size of the ship, in board-units; 2 by default
|
|
|
|
# in_orientation: orientation of the ship (see enum Orientation); vertical by default
|
2021-11-14 20:04:32 +00:00
|
|
|
# in_variant: Which ship is this?
|
|
|
|
func _init(in_position = Vector2(0,0), in_size = 0, in_orientation = Orientation.Y, in_variant = 0):
|
|
|
|
# Set the ship's positions
|
2021-11-14 09:15:27 +00:00
|
|
|
boardposition = in_position
|
2021-11-14 20:04:32 +00:00
|
|
|
position = boardposition * 32
|
|
|
|
# Set the ship's size and health
|
2021-11-08 13:40:11 +00:00
|
|
|
size = in_size
|
2021-11-14 20:04:32 +00:00
|
|
|
health = size
|
|
|
|
# Set the ship's orientation/rotation
|
2021-11-08 13:40:11 +00:00
|
|
|
orientation = in_orientation
|
2021-11-14 20:04:32 +00:00
|
|
|
rotation = orientation * PI/2
|
|
|
|
# Set the ship's variant(A, B, ... )
|
|
|
|
variant = in_variant
|
|
|
|
# Resize the size-based arrays
|
2021-11-15 07:17:32 +00:00
|
|
|
hits.resize(in_size)
|
2021-11-14 20:04:32 +00:00
|
|
|
sprites.resize(in_size)
|
|
|
|
# Update the extents and draw the textures
|
|
|
|
update()
|