online multiplayer chess game (note server currently down)
ui + ux
- check if the internet is available before allowing multiplayer access - make the pieces turn as they move - better logging system
bendn 2022-05-22
parent f10a4cb · commit 80849d0
-rw-r--r--Board.tscn4
-rw-r--r--Grid.gd16
-rw-r--r--Piece.tscn40
-rw-r--r--Utils.gd11
-rw-r--r--networking/Network.gd19
-rw-r--r--pieces/Piece.gd17
-rw-r--r--project.godot6
-rw-r--r--ui/Lobby.gd53
-rw-r--r--ui/Log.gd32
9 files changed, 151 insertions, 47 deletions
diff --git a/Board.tscn b/Board.tscn
index 69da5de..32c0223 100644
--- a/Board.tscn
+++ b/Board.tscn
@@ -7,6 +7,10 @@
[node name="Grid" type="Node2D" parent="."]
script = ExtResource( 1 )
+overlay_color = null
+clockrunning_color = null
+clockrunninglow = null
+clocklow = null
[node name="Background" type="Node2D" parent="Grid"]
diff --git a/Grid.gd b/Grid.gd
index 3496e65..8d19b6c 100644
--- a/Grid.gd
+++ b/Grid.gd
@@ -70,9 +70,9 @@ static func print_matrix_pretty(mat) -> void: # print the matrix
for j in range(8): # for each row
var r: Array = mat[j] # get the row
if j == 0:
- print(topper_header) # print the top border
+ Log.info(topper_header) # print the top border
else:
- print(middle_header) # print the middle border
+ Log.info(middle_header) # print the middle border
var row = "┃ %s ┃ " % str(8 - j) # init the string
for i in range(8): # for each column
var c = r[i] # get the column
@@ -80,8 +80,8 @@ static func print_matrix_pretty(mat) -> void: # print the matrix
row += c.mininame + ender # add the shortname
else: # if there is no piece
row += " " + ender
- print(row) # print the string
- print("%s\n%s\n%s" % [middish_heads, letter_header, smaller_heads])
+ Log.info(row) # print the string
+ Log.info("%s\n%s\n%s" % [middish_heads, letter_header, smaller_heads])
func reload_sprites() -> void:
@@ -184,7 +184,7 @@ func drawed() -> void:
func win(winner) -> void:
return # TODO: make gameovers work again
Events.emit_signal("game_over")
- print(winner, " won the game in ", Globals.turns(), " turns!")
+ Log.info([winner, " won the game in ", Globals.turns(), " turns!"])
SoundFx.play("Victory")
yield(get_tree().create_timer(5), "timeout")
Events.emit_signal("go_back")
@@ -202,7 +202,7 @@ func check_in_check(prin = false) -> bool: # check if in_check
Globals.in_check = true # set in_check
Globals.checking_piece = spot # set checking_piece
SoundFx.play("Check")
- print("check")
+ Log.info("check")
return true # stop at the first check found
return false
@@ -309,7 +309,7 @@ func check_for_frame(position: Vector2) -> bool: # check for a frame, validatin
func square_clicked(position: Vector2) -> void: # square clicked
- print(Utils.to_algebraic(position), " clicked")
+ Log.debug(Utils.to_algebraic(position) + " clicked")
if promoting != null:
return
if Globals.turn != Globals.team:
@@ -358,7 +358,7 @@ func handle_move(position) -> void:
)
return
- if last_clicked is Pawn:
+ if Utils.is_pawn(last_clicked):
var pawn = last_clicked
if pawn.enpassant:
for i in range(len(pawn.enpassant)):
diff --git a/Piece.tscn b/Piece.tscn
index 875b2d7..1f64fc9 100644
--- a/Piece.tscn
+++ b/Piece.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=7 format=2]
+[gd_scene load_steps=9 format=2]
[ext_resource path="res://pieces/Piece.gd" type="Script" id=1]
[ext_resource path="res://assets/pieces/california/wP.png" type="Texture" id=2]
@@ -79,6 +79,40 @@ tracks/1/keys = {
} ]
}
+[sub_resource type="Animation" id=6]
+resource_name = "Left"
+length = 0.4
+step = 0.05
+tracks/0/type = "value"
+tracks/0/path = NodePath("Sprite:rotation_degrees")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/keys = {
+"times": PoolRealArray( 0, 0.2, 0.4 ),
+"transitions": PoolRealArray( 2, 1, 0.5 ),
+"update": 0,
+"values": [ 0.0, -20.0, 0.0 ]
+}
+
+[sub_resource type="Animation" id=9]
+resource_name = "Right"
+length = 0.4
+step = 0.05
+tracks/0/type = "value"
+tracks/0/path = NodePath("Sprite:rotation_degrees")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/keys = {
+"times": PoolRealArray( 0, 0.2, 0.4 ),
+"transitions": PoolRealArray( 2, 1, 0.5 ),
+"update": 0,
+"values": [ 0.0, 20.0, 0.0 ]
+}
+
[node name="Piece" type="Node2D"]
script = ExtResource( 1 )
@@ -103,3 +137,7 @@ texture = ExtResource( 3 )
anims/Move = SubResource( 1 )
anims/RESET = SubResource( 3 )
anims/Take = SubResource( 2 )
+
+[node name="RotatePlayer" type="AnimationPlayer" parent="."]
+anims/Left = SubResource( 6 )
+anims/Right = SubResource( 9 )
diff --git a/Utils.gd b/Utils.gd
index 0c6e7a0..cfe5ec1 100644
--- a/Utils.gd
+++ b/Utils.gd
@@ -60,6 +60,15 @@ static func get_node_name(node) -> Array:
return ["", ""]
+func internet_available() -> bool:
+ var http = HTTPRequest.new()
+ add_child(http)
+ var httpurl = "https://1.1.1.1"
+ var returnable = http.request(httpurl) == OK
+ http.queue_free()
+ return returnable
+
+
func walk_dir(path = "res://assets/pieces") -> PoolStringArray: # walk the directory, finding the asset packs
var folders: PoolStringArray = [] # init the folders
var dir := Directory.new() # init the directory
@@ -71,7 +80,7 @@ func walk_dir(path = "res://assets/pieces") -> PoolStringArray: # walk the dire
folders.append(file_name) # add the folder
file_name = dir.get_next() # get the next file
else:
- printerr("An error occurred when trying to access the path " + path) # print the error
+ Log.err("An error occurred when trying to access the path " + path) # print the error
return folders # return the folders
diff --git a/networking/Network.gd b/networking/Network.gd
index a1398c7..2b42f98 100644
--- a/networking/Network.gd
+++ b/networking/Network.gd
@@ -4,6 +4,8 @@ class_name Network
var ws := WebSocketClient.new()
var game_code := ""
+var connected = false
+
const HEADERS := {
"move": "M",
"joinrequest": "J",
@@ -38,7 +40,7 @@ func _ready() -> void:
ws.connect("connection_closed", self, "_connection_closed")
ws.connect("connection_error", self, "_connection_error")
ws.connect("data_received", self, "_data_recieved")
- print("Connecting to server...") # maybe i shouldnt broadcast the server url
+ Log.debug("Connecting to server %s..." % url)
ws.connect_to_url(url)
var t = Timer.new()
add_child(t)
@@ -52,17 +54,20 @@ func ping() -> void:
func _connection_established(_protocol) -> void:
+ connected = true
emit_signal("connection_established")
- print("Connection established")
+ Log.info("Connection established")
func _connection_closed(_was_clean_closed) -> void:
- printerr("Connection closed")
+ connected = false
+ Log.err("Connection closed")
emit_signal("game_over", "Connection closed", false)
func _connection_error() -> void:
- printerr("Connection error")
+ connected = false
+ Log.err("Connection error")
emit_signal("game_over", "Connection error", false)
@@ -95,10 +100,8 @@ func _data_recieved() -> void:
func _process(_delta) -> void:
- if (
- ws.get_connection_status() == ws.CONNECTION_CONNECTING
- or ws.get_connection_status() == ws.CONNECTION_CONNECTED
- ):
+ var wsstatus = ws.get_connection_status()
+ if wsstatus == ws.CONNECTION_CONNECTING or wsstatus == ws.CONNECTION_CONNECTED:
ws.poll()
diff --git a/pieces/Piece.gd b/pieces/Piece.gd
index e62b705..9584883 100644
--- a/pieces/Piece.gd
+++ b/pieces/Piece.gd
@@ -12,6 +12,7 @@ var team := "w"
onready var sprite := $Sprite
onready var tween := $Tween
onready var anim := $AnimationPlayer
+onready var rotate := $RotatePlayer
onready var colorrect := $ColorRect
onready var frame := $Frame
@@ -60,6 +61,11 @@ static func to_algebraic(position) -> String:
func move(newpos: Vector2) -> void: # dont use directly; use moveto
tween.interpolate_property(self, "position", position, newpos * Globals.grid.piece_size, 0.3, Tween.TRANS_BACK)
+ var signresult = sign(newpos.x * Globals.grid.piece_size.x - global_position.x)
+ if signresult == 1:
+ rotate.play("Right")
+ elif signresult == -1:
+ rotate.play("Left")
anim.play("Move")
tween.start()
@@ -75,11 +81,11 @@ func moveto(position, real := true, take := false, override_moveto = false) -> v
Utils.add_move(algebraic_take_notation(position))
real_position = position
move(real_position)
- print(
+ Log.debug(
(
"%s moving from %s to %s"
% [
- mininame + shortname + " white" if white else " black",
+ shortname + " white" if white else " black",
Utils.to_algebraic(global_position / Globals.grid.piece_size),
Utils.to_algebraic(real_position)
]
@@ -114,8 +120,11 @@ func traverse(arr := [], no_enemys = false, check_spots_check = true) -> Array:
pos += i
if !is_on_board(pos):
break
- if at_pos(pos) != null: # only one enemy
- if no_enemys: # or none
+ if at_pos(pos) != null:
+ if at_pos(pos).white == white: # fren
+ break
+ # certaintly a enemy
+ if no_enemys: # do we want enemys?
break
circle_array.append(pos)
break
diff --git a/project.godot b/project.godot
index 4d6d36e..7e12dac 100644
--- a/project.godot
+++ b/project.godot
@@ -60,6 +60,11 @@ _global_script_classes=[ {
"path": "res://pieces/Knight.gd"
}, {
"base": "Node",
+"class": "Log",
+"language": "GDScript",
+"path": "res://ui/Log.gd"
+}, {
+"base": "Node",
"class": "Network",
"language": "GDScript",
"path": "res://networking/Network.gd"
@@ -110,6 +115,7 @@ _global_script_class_icons={
"HueSlider": "",
"King": "res://assets/pieces/california/wK.png",
"Knight": "res://assets/pieces/california/wN.png",
+"Log": "",
"Network": "",
"OldColorView": "",
"Pawn": "res://assets/pieces/california/wP.png",
diff --git a/ui/Lobby.gd b/ui/Lobby.gd
index c9861c8..e4da73d 100644
--- a/ui/Lobby.gd
+++ b/ui/Lobby.gd
@@ -17,7 +17,7 @@ func toggle(onoff) -> void:
func _handle_game_over(error = "game over", isok = true) -> void:
- reset_buttons()
+ set_buttons()
Globals.reset_vars()
end_game()
_set_status(error, isok)
@@ -27,27 +27,23 @@ func _set_status(text, isok) -> void: # Simple way to show status.
if isok:
status_ok.set_text(text)
status_fail.set_text("")
- status_ok.visible = len(status_ok.text) > 0
- status_fail.visible = len(status_fail.text) > 0
else:
status_ok.set_text("")
status_fail.set_text(text)
- status_fail.visible = len(status_fail.text) > 0
- status_ok.visible = len(status_ok.text) > 0
+ status_ok.visible = len(status_ok.text) > 0
+ status_fail.visible = len(status_fail.text) > 0
func _on_join_pressed() -> void:
Globals.network.game_code = validate_text()
Globals.network.send_packet(Globals.network.game_code, Globals.network.HEADERS.joinrequest)
- address.editable = false
- buttons.hide()
+ set_buttons(false)
func _on_HostButton_pressed() -> void:
Globals.network.game_code = validate_text()
Globals.network.send_packet(Globals.network.game_code, Globals.network.HEADERS.hostrequest)
- address.editable = false
- buttons.hide()
+ set_buttons(false)
func validate_text(text = address.get_text()) -> String:
@@ -63,19 +59,25 @@ func _ready() -> void:
get_tree().set_auto_accept_quit(false)
Events.connect("go_back", self, "_handle_game_over")
if !is_instance_valid(Globals.network):
- Globals.network = Network.new()
- Globals.network.connect("move_data", self, "_on_data")
- Globals.network.connect("join_result", self, "_on_join_result")
- Globals.network.connect("host_result", self, "_on_host_result")
- Globals.network.connect("game_over", self, "_handle_game_over")
- Globals.network.connect("start_game", self, "_start_game")
- Globals.network.connect("connection_established", self, "network_ready")
- add_child(Globals.network)
+ if Utils.internet_available():
+ _set_status("Connecting...", true)
+ var net = Network.new()
+ net.connect("move_data", self, "_on_data")
+ net.connect("join_result", self, "_on_join_result")
+ net.connect("host_result", self, "_on_host_result")
+ net.connect("game_over", self, "_handle_game_over")
+ net.connect("start_game", self, "_start_game")
+ net.connect("connection_established", self, "network_ready")
+ add_child(net)
+ Globals.network = net
+ else:
+ set_buttons(false)
+ _set_status("No internet connection", false)
func network_ready():
- for child in buttons.get_children():
- child.disabled = false
+ set_buttons(true)
+ _set_status("", true)
func end_game() -> void:
@@ -101,12 +103,13 @@ func _on_join_result(accepted: String) -> void:
Globals.network.send_packet("", Globals.network.HEADERS.startgame)
else:
_set_status(accepted, false)
- reset_buttons()
+ set_buttons()
-func reset_buttons() -> void:
- buttons.show()
- address.editable = true
+func set_buttons(enabled = true) -> void:
+ for c in buttons.get_children():
+ c.disabled = !enabled
+ address.editable = enabled
func _on_host_result(accepted: String) -> void:
@@ -115,7 +118,7 @@ func _on_host_result(accepted: String) -> void:
_set_status("Hosted!", true)
else:
_set_status(accepted, false)
- reset_buttons()
+ set_buttons()
func add_turn() -> void:
@@ -126,7 +129,7 @@ func add_turn() -> void:
func _on_data(data: Dictionary) -> void:
- print(data, " recieved")
+ Log.debug([data, " recieved"])
Globals.fullmove = data["fullmove"]
Globals.turn = data["turn"]
Globals.halfmove = data["halfmove"]
diff --git a/ui/Log.gd b/ui/Log.gd
new file mode 100644
index 0000000..8f3cd54
--- /dev/null
+++ b/ui/Log.gd
@@ -0,0 +1,32 @@
+extends Node
+class_name Log
+
+
+static func info(information) -> void: # logs the input string
+ print(to_str(information))
+
+
+static func debug(information) -> void: # logs the input string on debug builds
+ if OS.is_debug_build():
+ print(to_str(information))
+
+
+static func err(information) -> void: # logs the input string to stderr
+ printerr(information)
+
+
+static func to_str(arg) -> String:
+ if typeof(arg) == TYPE_ARRAY:
+ return arr2str(arg)
+ elif typeof(arg) == TYPE_STRING:
+ return arg
+ else:
+ err("Called with invalid arguments")
+ return ""
+
+
+static func arr2str(arr: Array) -> String:
+ var string = ""
+ for i in arr:
+ string += str(i) + " "
+ return string