mirror of
https://github.com/JohnBreaux/Boat-Battle.git
synced 2025-02-04 12:28:35 +00:00
Major restructuring to better support object-oriented design of the main game logic and UI. This was necessary, I swear.
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
extends Node
|
||||
|
||||
|
||||
# Ignore "unused signal" warnings in this class
|
||||
# warning-ignore-all:unused_signal
|
||||
|
||||
# Ask for a scene change
|
||||
signal button_clicked
|
||||
@@ -1,18 +0,0 @@
|
||||
extends Area2D
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
|
||||
func _on_Border_body_entered(body):
|
||||
print(body)
|
||||
@@ -1,91 +0,0 @@
|
||||
extends Control
|
||||
|
||||
onready var Ships = ["2Ship", "3ShipA", "3ShipB", "4Ship", "5Ship"]
|
||||
onready var Crosshair
|
||||
|
||||
class Location:
|
||||
var Coor: Vector2
|
||||
var Length: int
|
||||
var Orientation: bool #vertical is true, (Trueship = vertical) (Falseship = horizontal)
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
if find_next_valid_focus(): find_next_valid_focus().grab_focus()
|
||||
|
||||
|
||||
func _on_Forfeit_pressed():
|
||||
AudioBus.emit_signal("button_clicked")
|
||||
queue_free();
|
||||
MessageBus.emit_signal("change_scene", "Title")
|
||||
|
||||
|
||||
|
||||
func _on_Confirm_Placement_pressed():
|
||||
var valid = true
|
||||
for ship in Ships:
|
||||
# validate_placement returns the x-axis distance from the board
|
||||
# if this is more than zero, the ship is invalid
|
||||
if get_node(ship).validate_placement():
|
||||
valid = false
|
||||
print ("Placement: ", valid)
|
||||
if valid == false:
|
||||
get_node("PlaceShipDialog").popup()
|
||||
else:
|
||||
#Saves the location of ships and length of ship into an array
|
||||
var shipLocation = []
|
||||
for ship in Ships:
|
||||
var location = Location.new()
|
||||
location.Coor = get_node(ship).position
|
||||
location.Length = get_node(ship).get("ship_length")
|
||||
location.Orientation = get_node(ship).get("vertical")
|
||||
shipLocation.append(location)
|
||||
|
||||
#print out the array for testing
|
||||
for x in shipLocation:
|
||||
print("Ship Length: ", x.Length, ", Ship Orientation: ", x.Orientation, "Ship Coor: ", x.Coor)
|
||||
|
||||
#Hides the ship placement UI
|
||||
var confirmButton = get_node("Confirm Placement")
|
||||
var clearButton = get_node("Clear")
|
||||
var ship1 = get_node("2Ship")
|
||||
var ship2 = get_node("3ShipA")
|
||||
var ship3 = get_node("3ShipB")
|
||||
var ship4 = get_node("4Ship")
|
||||
var ship5 = get_node("5Ship")
|
||||
confirmButton.visible = false
|
||||
clearButton.visible = false
|
||||
ship1.visible = false
|
||||
ship2.visible = false
|
||||
ship3.visible = false
|
||||
ship4.visible = false
|
||||
ship5.visible = false
|
||||
|
||||
#Changes to firing mode, makes the fireing mode UI visible (The location of this can be changed later. This position is for testing)
|
||||
var crosshair = get_node("Crosshair")
|
||||
var fireButton = get_node("Fire")
|
||||
crosshair.visible = true
|
||||
fireButton.visible = true
|
||||
return valid # Replace with function body.
|
||||
|
||||
func _on_Clear_pressed():
|
||||
for ship in Ships:
|
||||
get_node(ship).clear()
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
func _on_Fire_pressed():
|
||||
var crosshair = get_node("Crosshair")
|
||||
# hides crosshair
|
||||
crosshair.visible = false
|
||||
if crosshair.validate_position(crosshair.position) == true:
|
||||
# fires at position
|
||||
print("Fire at position: ", crosshair.position)
|
||||
else:
|
||||
#if invalid position popup appears
|
||||
var dialog = get_node("FireDialog")
|
||||
dialog.popup_centered()
|
||||
pass # Replace with function body.
|
||||
|
||||
func _on_FireDialog_confirmed():
|
||||
get_node("Crosshair").visible = true
|
||||
pass # Replace with function body.
|
||||
@@ -1,24 +1,28 @@
|
||||
extends Sprite
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
var snapped = false #when snapped if true crosshair stops following mouse
|
||||
const world_offset = Vector2(36,36)
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
# Move the cursor to 0,0
|
||||
position = board_to_world_space(Vector2(-2,-2))
|
||||
pass # Replace with function body.
|
||||
|
||||
func _physics_process(delta):
|
||||
if snapped == false:
|
||||
position += (get_global_mouse_position() - position)/10
|
||||
func _physics_process(_delta):
|
||||
var mousePos = get_global_mouse_position()
|
||||
# If the cursor is not snapped, and the mouse is over the board
|
||||
if snapped == false and validate_position(mousePos):
|
||||
# Snap the crosshair to the grid, but following the mouse
|
||||
position = (mousePos - world_offset).snapped(Vector2(32,32)) + world_offset
|
||||
|
||||
func _input(event):
|
||||
# Check if left click is being clicked and the sprite is visible (i.e only checks for inputs after ship positions are confirmed)
|
||||
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and visible == true:
|
||||
# Locks the position of the crosshair with left click
|
||||
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and visible and not event.is_pressed():
|
||||
# Make a noise
|
||||
AudioBus.emit_signal("button_clicked")
|
||||
# Locks the position of the crosshair with left click release
|
||||
if validate_position(position) == true:
|
||||
# rounds the board position to the nearest integer
|
||||
snapped = true
|
||||
@@ -26,16 +30,15 @@ func _input(event):
|
||||
position.y = int(round(world_to_board_space(position).y))
|
||||
position = board_to_world_space(position)
|
||||
# Check if left click is being clicked and the sprite is visible (i.e only checks for inputs after ship positions are confirmed)
|
||||
if event is InputEventMouseButton and event.button_index == BUTTON_RIGHT and visible == true:
|
||||
# Unlocks the position of the crosshair with right click
|
||||
elif event is InputEventMouseButton and event.button_index == BUTTON_LEFT and visible == true:
|
||||
# Unlocks the position of the crosshair with left click
|
||||
snapped = false
|
||||
|
||||
func validate_position(vector):
|
||||
# rounds the board position to the nearest integer
|
||||
var boardx = int(round(world_to_board_space(vector).x))
|
||||
var boardy = int(round(world_to_board_space(vector).y))
|
||||
var board = world_to_board_space(vector)
|
||||
# Checks if the board position is within bounds of the board
|
||||
if boardx < 11 and boardx > 0 and boardy < 11 and boardy > 0:
|
||||
if board.x < 9.5 and board.x >= -0.5 and board.y < 9.5 and board.y >= -0.5:
|
||||
# changes the position of the crosshair
|
||||
return true
|
||||
else:
|
||||
@@ -45,15 +48,11 @@ func validate_position(vector):
|
||||
# Convert the world-space coordinates to positions on the board
|
||||
func world_to_board_space(vector):
|
||||
# Do math
|
||||
var res = (vector - offset) / 32 # Basically Fahrenheit/Celcius conversion, but in 2D
|
||||
var res = (vector - world_offset) / 32 # Basically Fahrenheit/Celcius conversion, but in 2D
|
||||
return res
|
||||
|
||||
# Inverse of the above function.
|
||||
func board_to_world_space(vector):
|
||||
# Do math
|
||||
var res = (vector * 32) + offset #Invert the above function
|
||||
var res = (vector * 32) + world_offset #Invert the above function
|
||||
return res #Truncate decimals
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
|
||||
30
godot_ship/script/game/Gameplay/Fire.gd
Normal file
30
godot_ship/script/game/Gameplay/Fire.gd
Normal file
@@ -0,0 +1,30 @@
|
||||
extends Control
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
# Signal to pass the fire location back to yet-unknown nodes
|
||||
signal fire_at
|
||||
|
||||
|
||||
func _on_Fire_pressed():
|
||||
var crosshair = get_node("Crosshair")
|
||||
# hides crosshair
|
||||
crosshair.visible = false
|
||||
if crosshair.validate_position(crosshair.position) == true:
|
||||
var crosshair_pos = crosshair.world_to_board_space(crosshair.position)
|
||||
# fires at position
|
||||
print("Fire at position: ", crosshair_pos)
|
||||
emit_signal("fire_at", crosshair_pos)
|
||||
# Close the Firing menu
|
||||
queue_free()
|
||||
else:
|
||||
#if invalid position popup appears
|
||||
var dialog = get_node("FireDialog")
|
||||
dialog.popup_centered()
|
||||
pass # Replace with function body.
|
||||
|
||||
func _on_FireDialog_confirmed():
|
||||
get_node("Crosshair").visible = true
|
||||
pass # Replace with function body.
|
||||
@@ -1,8 +1,18 @@
|
||||
extends Node
|
||||
|
||||
class ShipData:
|
||||
var Coor: Vector2
|
||||
var Length: int
|
||||
var Orientation: bool #vertical is true, (Trueship = vertical) (Falseship = horizontal)
|
||||
|
||||
# Preloaded assets, to be used later
|
||||
onready var Setup = preload("res://scenes/Game/Setup.tscn")
|
||||
onready var Fire = preload("res://scenes/Game/Fire.tscn")
|
||||
|
||||
# Path to Player class, for instantiating new Players in code
|
||||
var Player = "res://script/game/Gameplay/Player.gd"
|
||||
|
||||
|
||||
# Array of instances of the Player class; stores the Players
|
||||
var players # = player1, player2, ...
|
||||
# turn counter
|
||||
@@ -15,7 +25,13 @@ var is_multiplayer = false
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
game_start()
|
||||
var setup = Setup.instance()
|
||||
setup.connect("game_ready", self, "game_setup")
|
||||
add_child(setup)
|
||||
|
||||
func game_setup(_ships):
|
||||
print_debug("Congrats! Setup complete.")
|
||||
add_child(Fire.instance())
|
||||
|
||||
# Member functions:
|
||||
# game_start: starts the game
|
||||
@@ -29,3 +45,10 @@ func victory_screen():
|
||||
# display_turn(): display which turn it is on the screen
|
||||
func display_turn():
|
||||
pass
|
||||
|
||||
func _on_Forfeit_pressed():
|
||||
AudioBus.emit_signal("button_clicked")
|
||||
end()
|
||||
|
||||
func end():
|
||||
queue_free()
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
extends Control
|
||||
|
||||
# Scenes
|
||||
onready var title_screen = preload("res://scenes/Title Screen.tscn")
|
||||
onready var gameplay = preload("res://scenes/Gameplay.tscn" )
|
||||
onready var options = preload("res://scenes/Options.tscn" )
|
||||
onready var debug_menu = preload("res://scenes/Debug Menu.tscn" )
|
||||
|
||||
#flags
|
||||
var power_saving = true
|
||||
var debug_enabled = true
|
||||
var start_fullscreen = false
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
# Connect to signals
|
||||
var _errno = 0;
|
||||
_errno += MessageBus.connect("start_tcsn" , self, "_on_scene_start_by_name")
|
||||
_errno += MessageBus.connect("change_scene" , self, "_on_scene_start" )
|
||||
_errno += MessageBus.connect("kill_scene" , self, "_on_scene_kill" )
|
||||
_errno += MessageBus.connect("list_scenes" , self, "_on_scene_list" )
|
||||
_errno += MessageBus.connect("quit" , self, "_on_quit_request" )
|
||||
_errno += MessageBus.connect("return_to_title", self, "_on_title_request" )
|
||||
# go fullscreen
|
||||
OS.low_processor_usage_mode = power_saving
|
||||
OS.low_processor_usage_mode_sleep_usec = 6800
|
||||
OS.window_fullscreen = start_fullscreen
|
||||
if debug_enabled:
|
||||
add_child(debug_menu.instance())
|
||||
|
||||
# Process global keybinds
|
||||
func _input(event):
|
||||
if event.is_action_pressed("ui_fullscreen"):
|
||||
# toggle_fullscreen
|
||||
OS.window_fullscreen = !OS.window_fullscreen
|
||||
|
||||
|
||||
# Ensure the scene doesn't become empty
|
||||
func _process(_delta):
|
||||
# Make sure there's something running
|
||||
# Debug counts as one child
|
||||
if get_child_count() < 1 + int(debug_enabled):
|
||||
MessageBus.emit_signal("change_scene", "Title")
|
||||
pass
|
||||
|
||||
# Creates a new instance of each menu scene
|
||||
func _on_scene_start(scene):
|
||||
#print ("_on_scene_start(",scene,")")
|
||||
match scene:
|
||||
"Singleplayer":
|
||||
add_child (gameplay.instance())
|
||||
return true
|
||||
"Multiplayer":
|
||||
add_child (gameplay.instance())
|
||||
# add_child (multiplayercontroller.instance())
|
||||
return true
|
||||
"Options":
|
||||
add_child (options.instance())
|
||||
return true
|
||||
"Title":
|
||||
add_child (title_screen.instance())
|
||||
return true
|
||||
|
||||
func _on_scene_start_by_name(scene):
|
||||
var pack = load("res://scenes/" + scene + ".tscn");
|
||||
add_child(pack.instance());
|
||||
|
||||
# Kills all child nodes with name matching `scene`
|
||||
func _on_scene_kill(scene):
|
||||
var node = find_node(scene, false, false)
|
||||
if node :
|
||||
node.queue_free()
|
||||
MessageBus.emit_signal("print_console", String(node.name) + " killed.\n".c_unescape())
|
||||
|
||||
func _on_scene_list():
|
||||
var children = get_children()
|
||||
var names = []
|
||||
for i in range (children.size()):
|
||||
names.append(children[i].name)
|
||||
MessageBus.emit_signal("print_console", String(names) + "\n".c_unescape())
|
||||
|
||||
|
||||
# Quits
|
||||
func _on_quit_request():
|
||||
get_tree().quit()
|
||||
|
||||
# Kills the current tree and replaces it with a new one
|
||||
func _on_title_request():
|
||||
return get_tree().change_scene("res://scenes/Main.tscn")
|
||||
@@ -1,20 +0,0 @@
|
||||
extends Node
|
||||
|
||||
# Ignore "unused signal" warnings in this class
|
||||
# warning-ignore-all:unused_signal
|
||||
|
||||
# Ask for a scene change
|
||||
signal change_scene(scene_name)
|
||||
|
||||
signal start_tcsn(scene_tcsn_name)
|
||||
# Ask to kill scene
|
||||
signal kill_scene(scene_name)
|
||||
# Ask to list active scenes
|
||||
signal list_scenes()
|
||||
# Ask to quit the game
|
||||
signal quit
|
||||
# Ask to return to title screen
|
||||
signal return_to_title
|
||||
|
||||
# Ask to print a string to debug console
|
||||
signal print_console(string)
|
||||
54
godot_ship/script/game/Setup.gd
Normal file
54
godot_ship/script/game/Setup.gd
Normal file
@@ -0,0 +1,54 @@
|
||||
extends Control
|
||||
|
||||
signal forfeit
|
||||
signal game_ready
|
||||
|
||||
onready var Ships = ["2Ship", "3ShipA", "3ShipB", "4Ship", "5Ship"]
|
||||
|
||||
class ShipData:
|
||||
var Position: Vector2
|
||||
var Length: int
|
||||
var Orientation: bool # (True = vertical) (False = horizontal)
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
# Moves the focus to this menu
|
||||
if find_next_valid_focus(): find_next_valid_focus().grab_focus()
|
||||
|
||||
|
||||
func _on_Confirm_Placement_pressed():
|
||||
# Make the button noise
|
||||
AudioBus.emit_signal("button_clicked")
|
||||
var valid = true
|
||||
for ship in Ships:
|
||||
# validate_placement returns the x-axis distance from the board
|
||||
# if this is more than zero, the ship is invalid
|
||||
if get_node(ship).validate_placement():
|
||||
valid = false
|
||||
print ("Placement: ", valid)
|
||||
if valid == false:
|
||||
get_node("PlaceShipDialog").popup()
|
||||
else:
|
||||
#Saves the location of ships and length of ship into an array
|
||||
var shipLocation = []
|
||||
for ship in Ships:
|
||||
var location = ShipData.new()
|
||||
location.Position = get_node(ship).position
|
||||
location.Length = get_node(ship).get("ship_length")
|
||||
location.Orientation = get_node(ship).get("vertical")
|
||||
shipLocation.append(location)
|
||||
|
||||
#print out the array for testing
|
||||
for x in shipLocation:
|
||||
print("Ship Length: ", x.Length, ", Ship Orientation: ", x.Orientation, ", Ship Position: ", x.Position)
|
||||
|
||||
# Return the shipLocation array to those listening on game_ready
|
||||
emit_signal("game_ready", shipLocation)
|
||||
queue_free()
|
||||
return valid # Replace with function body.
|
||||
|
||||
func _on_Clear_pressed():
|
||||
AudioBus.emit_signal("button_clicked")
|
||||
for ship in Ships:
|
||||
get_node(ship).clear()
|
||||
pass # Replace with function body.
|
||||
@@ -141,11 +141,9 @@ func checkOriginalPos():
|
||||
|
||||
# Called when *this* ship collides with another ship
|
||||
func ship_stacked(_body):
|
||||
print("stacked")
|
||||
collision = true
|
||||
# Called when *this* ship stops colliding with another ship
|
||||
func ship_unstacked(_body):
|
||||
print("unstacked")
|
||||
collision = false
|
||||
|
||||
# Calculate the extents (front to back) of the ship and check whether they're on the board
|
||||
@@ -1,16 +0,0 @@
|
||||
extends Node
|
||||
|
||||
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
#func _process(delta):
|
||||
# pass
|
||||
Reference in New Issue
Block a user