online multiplayer chess game (note server currently down)
| -rw-r--r-- | Game.tscn | 2 | ||||
| -rw-r--r-- | Square.gd | 5 | ||||
| -rw-r--r-- | Square.tscn | 1 | ||||
| -rw-r--r-- | Utils.gd | 2 | ||||
| -rw-r--r-- | board/chess.gd | 2 | ||||
| -rw-r--r-- | project.godot | 7 | ||||
| -rw-r--r-- | ui/board/Arrows.gd | 67 | ||||
| -rw-r--r-- | ui/board/Board.gd (renamed from Board.gd) | 17 | ||||
| -rw-r--r-- | ui/board/Board.tscn (renamed from Board.tscn) | 15 | ||||
| -rw-r--r-- | ui/menus/sidebarright/sandisplay/SanDisplay.gd | 19 |
10 files changed, 112 insertions, 25 deletions
@@ -15,7 +15,7 @@ [ext_resource path="res://assets/ui/checkedbox.png" type="Texture" id=16] [ext_resource path="res://assets/ui/CascadiaCode.ttf" type="DynamicFontData" id=17] [ext_resource path="res://assets/ui/ubuntu/ubuntu-bold-italic.ttf" type="DynamicFontData" id=18] -[ext_resource path="res://Board.tscn" type="PackedScene" id=29] +[ext_resource path="res://ui/board/Board.tscn" type="PackedScene" id=29] [sub_resource type="StyleBoxTexture" id=6] texture = ExtResource( 15 ) @@ -2,6 +2,7 @@ extends ColorRect class_name BackgroundSquare signal clicked +signal right_clicked onready var circle := $CircleHolder/Circle @@ -18,6 +19,6 @@ func _ready() -> void: func _gui_input(event: InputEvent): - if !Globals.spectating and event is InputEventMouseButton and Input.is_action_pressed("click"): - emit_signal("clicked") + if !Globals.spectating and event is InputEventMouseButton and event.pressed: + emit_signal("clicked" if event.button_index == BUTTON_LEFT else "right_clicked") get_tree().set_input_as_handled() diff --git a/Square.tscn b/Square.tscn index cb05f72..de3771e 100644 --- a/Square.tscn +++ b/Square.tscn @@ -31,7 +31,6 @@ anchor_right = 1.0 anchor_bottom = 1.0 margin_right = -1180.0 margin_bottom = -780.0 -mouse_filter = 1 script = ExtResource( 1 ) [node name="CircleHolder" type="CenterContainer" parent="."] @@ -113,7 +113,7 @@ func walk_dir(path := "res://assets/pieces", only_dir := true, exclude := []) -> files.append(split[0]) # add the file file_name = dir.get_next() # get the next file else: - push_error("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 files.sort() # sort the files return PoolStringArray(files) # return the files diff --git a/board/chess.gd b/board/chess.gd index e895a3f..21fc37f 100644 --- a/board/chess.gd +++ b/board/chess.gd @@ -1061,7 +1061,7 @@ func pgn() -> String: return moves.join(" ") -func load_pgn(pgn, options := {}) -> int: # FIXME: mildly broken. move generator for a8 cannot get a4, for some reason. +func load_pgn(pgn: String, options := {}) -> int: # allow the user to specify the sloppy move parser to work around over # disambiguation bugs in Fritz and Chessbase var sloppy: bool = options.sloppy if "sloppy" in options else false diff --git a/project.godot b/project.godot index aa87fa8..3359564 100644 --- a/project.godot +++ b/project.godot @@ -87,7 +87,7 @@ _global_script_classes=[ { "base": "Control", "class": "Grid", "language": "GDScript", -"path": "res://Board.gd" +"path": "res://ui/board/Board.gd" }, { "base": "GridContainer", "class": "GridMenu", @@ -366,6 +366,11 @@ shift={ "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777237,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] } +rclick={ +"deadzone": 0.5, +"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":2,"pressed":false,"doubleclick":false,"script":null) + ] +} [rendering] diff --git a/ui/board/Arrows.gd b/ui/board/Arrows.gd new file mode 100644 index 0000000..2f84bd2 --- /dev/null +++ b/ui/board/Arrows.gd @@ -0,0 +1,67 @@ +extends Control + +var arrows := [] +var first: Vector2 +var ev: Vector2 +var b: Grid + +const w = 20 + + +func _setup(_b: Grid): + b = _b + Events.connect("turn_over", self, "on_turn_over") + for k in Chess.SQUARE_MAP: + b.background_array[Chess.SQUARE_MAP[k]].connect("right_clicked", self, "right_clicked", [k]) + + +func right_clicked(clicked: String) -> void: + first = ((Chess.algebraic2vec(clicked) * b.piece_size) + b.piece_size / 2) + + +func _process(_delta): + update() + + +func _draw(): + if !b: + return + var s = b.piece_size + var c = b.overlay_color + if first: + var loc_m = ((get_local_mouse_position() / s) - Vector2(.5, .5)).round() + loc_m = Vector2(clamp(loc_m.x, 0, 7), clamp(loc_m.y, 0, 7)) + var m_pos = (loc_m * s) + s / 2 + if Input.is_action_pressed("rclick"): # dragging + draw_line(first, m_pos, c, w, true) + draw_triangle(first.angle_to_point(m_pos), m_pos, c) + else: + if first != m_pos: + var arr: PoolVector2Array = [first, m_pos] + if arrows.find(arr) == -1: + arrows.append(arr) + else: + arrows.erase(arr) # redoing == kill + first = Vector2.ZERO + + for arrow in arrows: + draw_line(arrow[0], arrow[1], c, w, true) + draw_triangle(arrow[0].angle_to_point(arrow[1]), arrow[1], c) + + +# r: the radians of rotation. +func draw_triangle(r: float, p: Vector2, c: Color) -> void: + var tri: PoolVector2Array = [Vector2(-24, 0), Vector2(0, -40), Vector2(24, 0)] + for i in range(len(tri)): + tri[i] = tri[i].rotated(r - PI / 2) + p + draw_colored_polygon(tri, c) + + +func clear_arrows(): + arrows.resize(0) + first = Vector2.ZERO + + +func on_turn_over(): + if b.chess.turn != Globals.team: # i just went; arrows can go away now + clear_arrows() diff --git a/Board.gd b/ui/board/Board.gd index a63dd00..eb71113 100644 --- a/Board.gd +++ b/ui/board/Board.gd @@ -76,6 +76,7 @@ func init_board() -> void: # create the board background.add_child(square) # add the square to the background square.connect("clicked", self, "square_clicked", [alg]) # connect the clicked event background_array[i] = square # add the square to the background array + $Arrows._setup(self) # initialize the arrows func init_labels() -> void: @@ -161,7 +162,6 @@ func square_clicked(clicked_square: String) -> void: return for m in last_clicked_moves: if m.to == clicked_square && m.from == last_clicked.position: - print(m) move(m.san, false) break clear_circles() @@ -184,9 +184,7 @@ func square_clicked(clicked_square: String) -> void: func move(san: String, is_recieved_move := true) -> void: if is_valid_move(san): var sound_handled = false - print(san) var move_0x88 = chess.__move_from_san(san, true) - print(chess.__move_to_san(move_0x88)) chess.__make_move(move_0x88) if move_0x88.flags & Chess.BITS.CAPTURE: board[move_0x88.to].took() @@ -210,7 +208,7 @@ func move(san: String, is_recieved_move := true) -> void: p.open_promotion_previews() yield(p, "promotion_decided") move_0x88["promotion"] = p.promote_to - PacketHandler.send_mov(chess.__move_to_san(move_0x88)) # we changed "promotion", so send update the san + san = chess.__move_to_san(move_0x88) # update the san with new promotion data p.queue_free() else: # was opponents turn, this is opponents move: promotion is already chosen p.queue_free() # the q_f above happens after a dozen yields @@ -219,10 +217,10 @@ func move(san: String, is_recieved_move := true) -> void: make_piece(p.position, move_0x88.promotion, p.color) SoundFx.play("Move" if move_0x88.flags & Chess.BITS.NORMAL else "Capture") sound_handled = true - else: + else: # not promotion: from **always** moves to `to` var _p = board[move_0x88.from].move(Chess.algebraic(move_0x88.to)) - if !is_recieved_move: - PacketHandler.send_mov(san) # move may have been modified, so recreat the san + if !is_recieved_move: + PacketHandler.send_mov(san) if !sound_handled: SoundFx.play("Move") emit_signal("add_to_pgn", san) @@ -285,6 +283,7 @@ func load_pgn(pgn: String) -> void: emit_signal("clear_pgn") var movs: PoolStringArray = Pgn.parse(pgn).moves emit_signal("load_pgn", movs) + check_game_over() func undo(two: bool = false) -> void: @@ -299,6 +298,10 @@ func undo(two: bool = false) -> void: func _on_turn_over(): + check_game_over() + + +func check_game_over(): if chess.in_checkmate(): # they won if its my turn, i won if its their turn. win(Globals.team if Globals.team != chess.turn else Chess.__swap_color(Globals.team), "checkmate") diff --git a/Board.tscn b/ui/board/Board.tscn index 8234a93..2451c8c 100644 --- a/Board.tscn +++ b/ui/board/Board.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=2 format=2] +[gd_scene load_steps=3 format=2] -[ext_resource path="res://Board.gd" type="Script" id=1] +[ext_resource path="res://ui/board/Board.gd" type="Script" id=1] +[ext_resource path="res://ui/board/Arrows.gd" type="Script" id=2] [node name="Board" type="Control"] anchor_right = 1.0 @@ -26,6 +27,13 @@ anchor_bottom = 1.0 mouse_filter = 2 [node name="Foreground" type="CanvasLayer" parent="."] +layer = 0 + +[node name="Arrows" type="Control" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 +script = ExtResource( 2 ) [node name="Darken" type="ColorRect" parent="."] visible = false @@ -34,3 +42,6 @@ anchor_bottom = 1.0 mouse_filter = 2 mouse_default_cursor_shape = 7 color = Color( 0, 0, 0, 0.784314 ) + +[node name="Polygon2D" type="Polygon2D" parent="."] +polygon = PoolVector2Array( -500, -500, -475, -540, -523, -540 ) diff --git a/ui/menus/sidebarright/sandisplay/SanDisplay.gd b/ui/menus/sidebarright/sandisplay/SanDisplay.gd index fdb64ef..e45859f 100644 --- a/ui/menus/sidebarright/sandisplay/SanDisplay.gd +++ b/ui/menus/sidebarright/sandisplay/SanDisplay.gd @@ -16,14 +16,10 @@ func _ready() -> void: scroll_bar.hide() scroll_bar.step = .15 #smoth add_child(tween) - if Globals.grid: - Globals.grid.connect("add_to_pgn", self, "add_move") - Globals.grid.connect("load_pgn", self, "add_moves") - Globals.grid.connect("clear_pgn", self, "clear") - Globals.grid.connect("remove_last", self, "pop") - else: - for i in "hello how do you do": - add_move(i) + Globals.grid.connect("add_to_pgn", self, "add_to_pgn") + Globals.grid.connect("load_pgn", self, "add_moves") + Globals.grid.connect("clear_pgn", self, "clear") + Globals.grid.connect("remove_last", self, "pop") func create_number_label(num: int) -> void: @@ -34,18 +30,23 @@ func create_number_label(num: int) -> void: base.name = base.number.text +func add_to_pgn(m: String) -> void: + add_move(m) + scroll_down() + + func add_move(move: String) -> void: if added_sans % 2 == 0: # warning-ignore:integer_division create_number_label((added_sans / 2) + 1) added_sans += 1 sans.get_children()[-1].add_move(move) - scroll_down() func add_moves(moves: PoolStringArray) -> void: for move in moves: add_move(move) + scroll_down() func scroll_down(): |