1
0
mirror of https://github.com/JohnBreaux/Boat-Battle.git synced 2024-11-15 13:25:58 +00:00
Boat-Battle/godot_ship/script/game/SetupShip.gd
tommy-l-ngo 06b8711a08
Game logic (#14)
* Create game classes

* Pushing what I've done of the game logic.

* Commented my code

Deals with ship placement on board and ship rotation on board

* Comment game logic code, and edit for style.

* Added Clear board button and Confirm Placement button

* Fix up some stuff

* Pass

* I accidentally the buttons + Fix some hitbox mistakes.

* Improve hitbox leniency, and don't allow ships to rotate into each other.

* Fixed Dialog Box that pops up for Confirm Placement

* Update Gameplay.tscn

* Partial fire functionality added.

Currently hides all ship placement UI and makes visible all fire functionality. The crosshair currently does not snap to a grid. The ships are saved in an area of location objects holding the length, orientation, and coordinates of the ship.

* Crosshair now snaps into place

* Created Sprites for 2Ship and 3ShipA

* Created Sprite for Ship3B

* Created Sprite for Ship4

* Created Sprite for Ship5

* Created Sprite for "Hit"

* Created Sprites for Ship2 Destroyed and Ship3A Destroyed

* Created Sprite for Ship3B Destroyed

* Created Sprite for Ship4 Destroyed

* Created Sprite for Ship5 Destroyed

* Created Sprite for "Miss"

* Fixed blurry pixel art

Changed texture rendering

* Added temporary title screen text

* Major restructuring to better support object-oriented design of the main game logic and UI. This was necessary, I swear.

* Accidentally offset the Setup menu by a handful of pixels. Whoops.

* Setup: remove unused signal

* Comment on which parts of Game are only there for testing purposes.

* Fixed up the Title Screen text

imported font

* Fixed Crosshair pixel rendering

* Consolidate backgrounds

* Added more SFX sounds

* Created Sprite for Light Mode

* Fix null deref when entering singleplayer after exiting multiplayer

* Hien's work

* Revert "Hien's work"

This reverts commit f099ed6c80.

* Stuff

* Make git happy by pushing gdengine imports

* Put Background in main

* Removed option background

* Added Confirmation Dialog for Forfeit

* Revert "Merge branch 'game-logic' of https://github.com/StatewideInk/Group12 into game-logic"

This reverts commit 104ffaab0a, reversing
changes made to 63dec75688.

* Fix title screen never going (whoops

* Oops I made the background invisible

* removed option background again

* Added dark/light mode functionality

* Added signal for audio SFX

* Load the theme on startup

* Added Confirmation dialog for Forfeit

* Fixed Texture Rendering for Light Mode Background

* Sounds no longer scale linearly

* Remove unused resourse main.tres

* Added victory screen

Added a victory screen. Since there is no current way to win, there is a 'win' button added to the top left of the game screen. Once clicked, victory text will appear and the player will be given the option to return to the main menu.

* restart button is invisible

Co-authored-by: John Breaux <JohnBreaux@my.unt.edu>
Co-authored-by: JohnBreaux <89870642+JohnBreaux@users.noreply.github.com>
Co-authored-by: hpham474 <HienPham@my.unt.edu>
Co-authored-by: Chance Atkinson <chancewatkinson@gmail.com>
2021-11-14 00:43:05 -06:00

199 lines
6.7 KiB
GDScript

extends RigidBody2D
var held = false
var originalPos # Position before moving the ship
var snapOriginalPos = false # Gets the original position
var mousePos # Stores the last known mouse position so the physics engine can use it
var vertical = true # Gets ship which is either vertical or horizonal
var startingPos # Starting position of ships before being placed
# Ships are all named starting with their length,
# So we cast from string to int, on the ship name, and get the length
onready var ship_length = int(name)
# This is set when we're colliding with something
var collision = false
# Called when the node enters the scene tree for the first time.
func _ready():
mode = MODE_KINEMATIC
contacts_reported = 64
set_use_custom_integrator(true)
# Snap the ships to the grid, so the engine won't get mad when they're moved away from the starting position every frame
position = (position - offset).snapped(Vector2(32, 32)) + offset
startingPos = position
var _trash
# Connect to my own signals, and not the signals of my fellowships
# PLEASE don't parameterize; there's no way to tell these signals apart with the args the engine provides.
_trash = connect("body_entered", self, "ship_stacked")
_trash = connect("body_exited", self, "ship_unstacked")
# Radius of the "knob" on the center of each ship
var click_radius = 16
func _input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
if (event.position - position).length() < click_radius:
if not held and event.pressed:
AudioBus.emit_signal("button_clicked")
pickup()
if held and not event.pressed:
drop()
# Convert the center of this piece to board-space
var bs_position = world_to_board_space(position)
# Check whether the piece is within half a board-space of the grid (-0.5, 9.5)
if not (bs_position.x > -0.5 and bs_position.x < 9.5 and bs_position.y > -0.5 and bs_position.y < 9.5):
if originalPos != null:
collision = true
vertical = true
if event is InputEventMouseMotion and held:
if snapOriginalPos == false:
originalPos = position
snapOriginalPos = true
# Save the moise position, so _physics_process can use it
mousePos = event.position;
if event.is_action_pressed("ui_rotate"):
if not held and not checkOriginalPos():
if(event.position - position).length() < click_radius:
#Play a sound
AudioBus.emit_signal("button_clicked")
# Rotation has been moved to _physics_process,
# as per recommendation of godot_engine.org
vertical = not vertical
# It takes 3 physics ticks for the rotation to update the hitboxes
# Determined imperically through testing, may work differently on different machines(?)
released = 3
# Offset from the corner of the screen to the corner of the board
const offset = Vector2(36, 36)
# The previous verticality of the object
var prev_vertical = true
# The previous position of the object
var prev_position = Vector2(0,0)
# The number of frames after an object is released to check for physics updates
var released = 0
# _physics_process: called in place of the physics processor
# Checks collision and updates the position and rotation of the object
func _physics_process(_delta):
# calculate whether the piece has been rotated or moved
var rotated = prev_vertical != vertical
var moved = prev_position != position
# If the piece is held, move it to the mouse:
if held and mousePos and mousePos != position:
position = mousePos
mousePos = null
# Snap it to the grid if not held (and previously moved)
if not held and moved:
position = (position - offset).snapped(Vector2(32, 32)) + offset
prev_position = position
# If it's been moved or rotated, snap it to the board
if released or rotated:
# check whether the ends of the piece are within the board
var linear_move = check_extents(position, vertical, ship_length)
# if not, move them back inside
if linear_move:
if vertical:
position += 32 * Vector2(0, linear_move)
else:
position += 32 * Vector2(linear_move, 0)
pass
# Check collisions after released, reset if colliding
if collision and released:
position = startingPos
rotation = 0
vertical = true
# Rotate if the piece needs to be rotated
if rotated:
prev_vertical = vertical
rotation = -PI/2 * int(not vertical) # int(true) == 1, int(false) == 0
# Count down the number of physics timesteps left until the piece can stop processing
if released > 0:
released = released - 1
func pickup():
if not held:
raise() # Render this ship on top of other ships
held = true # mark it as held
collision = false # Assume we're not colliding by default
func drop():
if held:
released = 1 # mark the node as released
held = false # mark the node as not held
snapOriginalPos = false
func checkOriginalPos():
return position == startingPos
# Called when *this* ship collides with another ship
func ship_stacked(_body):
collision = true
# Called when *this* ship stops colliding with another ship
func ship_unstacked(_body):
collision = false
# Calculate the extents (front to back) of the ship and check whether they're on the board
# Returns how many squares to move the ship along its orientation axis (positive or negative)
func check_extents(center, orientation, length):
center = world_to_board_space(center) # Convert to board-space (0-10)
# Calculate the position of the front of the ship
# Orientation is true when the ship is vertical
var bow = vectorget(center, orientation) - floor((length - 1) / 2)
# if out of bounds, return how much to move the ship by
if bow < 0:
return -bow
# Calculate the position of the rear of the ship
var stern = vectorget(center, orientation) + floor(length / 2)
# If out of bounds, return how much to move the ship by
if stern >= 10:
return -(stern - 9)
return 0
func validate_placement():
# Checks whether the ship's center is on the board.
# As long as the ship was moved according to the rules defined in the
# _physics_process function, this should be necessary and sufficient
# to say the ship is on the board
return check_extents(position, false, 1)
func clear():
# ships return home on collision
# simulate a collision
collision = true
released = 1
# 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
return res
# Inverse of the above function.
func board_to_world_space(vector):
# Do math
var res = (vector * 32) + offset #Invert the above function
return res #Truncate decimals
# index a Vector2 like an array
# Why is this needed?
# So we can discard the unimportant axis! (a ship is always 1 unit wide!)
func vectorget(vector, axis):
if axis:
return vector.y
else:
return vector.x