From fd51682eb062ce52b13c9d13b9955dc83f2daf38 Mon Sep 17 00:00:00 2001 From: John Breaux Date: Sun, 14 Nov 2021 14:04:32 -0600 Subject: [PATCH] Ship: Complete initial implementation. Impl's #16 --- godot_ship/scenes/Game/Ship.tscn | 7 +- godot_ship/script/game/Gameplay/Ship.gd | 117 ++++++++++++++++++------ 2 files changed, 89 insertions(+), 35 deletions(-) diff --git a/godot_ship/scenes/Game/Ship.tscn b/godot_ship/scenes/Game/Ship.tscn index 6b026e1..a41a401 100644 --- a/godot_ship/scenes/Game/Ship.tscn +++ b/godot_ship/scenes/Game/Ship.tscn @@ -2,10 +2,5 @@ [ext_resource path="res://script/game/Gameplay/Ship.gd" type="Script" id=1] -[node name="Ship" type="Control"] -anchor_right = 1.0 -anchor_bottom = 1.0 +[node name="Ship" type="Node2D"] script = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} diff --git a/godot_ship/script/game/Gameplay/Ship.gd b/godot_ship/script/game/Gameplay/Ship.gd index 5952eab..2432fb6 100644 --- a/godot_ship/script/game/Gameplay/Ship.gd +++ b/godot_ship/script/game/Gameplay/Ship.gd @@ -1,12 +1,14 @@ -extends Control +extends Node2D # This is the rendered element of a "ship", generated when the game transitions from the placing state to the gameplay state # Enum denoting the orientation (X is 0, Y is 1) enum Orientation {X = 0, Y = 1} +enum {MISS = -1, READY = 0, HIT = 1, SUNK = 2} # Size of ship in board units -var size = 2 +var size +var health # Coordinates of ship's center. Ship extends [-(size-1 >> 1), (size/2 >> 1)] var boardposition = Vector2(-1,-1) # Variable storing whether the ship is sunk, for rendering purposes @@ -15,11 +17,16 @@ var sunk = false var orientation = Orientation.Y # array of spots thats been hit var hit = [] +# Variable storing the positions of each piece of the ship +var extents = [] # Ship sprite metadata -# sprite: the texture atlas containing all ship parts -var atlas # = TODO: figure out how to use one sprite for multiple textures -# variant: for ship 3. A is 0, B is 1 +# 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, ... var variant = 0 # Called when the node enters the scene tree for the first time. @@ -27,24 +34,43 @@ func _ready(): pass # Replace with function body. # member functions: -# getSize: get the size of the ship, in board-units (2 for 2-ship, 3 for 3-ship, ...) -func getSize(): - return size - -# getPosition: get the position of the ship's center, in board units -func getPosition(): - return boardposition - -# getOrientation: get the orientation of the ship (see enum Orientation) -func getOrientation(): - return orientation +# getShip(): +func get_ship(): + return [boardposition, size, orientation, variant] # getSunk: get whether the ship is sunk -func getSunk(): +func get_sunk(): return sunk +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 + hit[index] = true + 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) + # returns an array of the positions that the ship occupies -func getExtent(): +func get_extent(): var extent = [] # Find each tile of the ship for i in size: @@ -56,32 +82,65 @@ func getExtent(): extent.push_back(Vector2(x,y)) return extent -# generates a texture at the spot (index should start at 0) +# Update textures func texture(index): - var state = 0 # floating + var state = 0 # ready if(hit[index]): - state = 1 # sunk + state = 1 # hit var textureSize = 32 + # It's okay to create a new texture every time, as resources are refcounted var t = AtlasTexture.new() - t.atlas = load("res://assets/game/TextureAtlas.png") - t.region ( - (size * textureSize) * variant + (32 * index), + t.set_atlas(atlas) + t.margin = Rect2(0, 0, 32, 32) + t.region = Rect2( + (size * variant + index) * textureSize, + #(size * textureSize) * variant + (32 * index), (size - 2) * textureSize * 2 + (32 * state), textureSize, textureSize ) - - pass - + # 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) + # setSunk: sink the ship -func setSunk(): +func set_sunk(): sunk = true # _init: called on object initialization. Accepts args if called via .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 -func _init(in_position = Vector2(0,0), in_size = 2, in_orientation = Orientation.Y): +# 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 boardposition = in_position + position = boardposition * 32 + # Set the ship's size and health size = in_size + health = size + # Set the ship's orientation/rotation orientation = in_orientation + rotation = orientation * PI/2 + # Set the ship's variant(A, B, ... ) + variant = in_variant + # Resize the size-based arrays + hit.resize(in_size) + sprites.resize(in_size) + # Update the extents and draw the textures + update()