--- /dev/null
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://84uig641vqbo"
+path="res://.godot/imported/cell.png-b4fb4fd99ff37b23731fe9581e05cc6c.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://asset/cell.png"
+dest_files=["res://.godot/imported/cell.png-b4fb4fd99ff37b23731fe9581e05cc6c.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
--- /dev/null
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b6om08wjtci31"
+path="res://.godot/imported/grid.png-d8396e465b7b7ae024fe789e791b5ec8.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://asset/grid.png"
+dest_files=["res://.godot/imported/grid.png-d8396e465b7b7ae024fe789e791b5ec8.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
--- /dev/null
+[gd_scene load_steps=3 format=3 uid="uid://cmdvtaiunt32k"]
+
+[ext_resource type="Script" uid="uid://ds1rixr57lt7e" path="res://script/cell.gd" id="1_gxfu7"]
+[ext_resource type="Texture2D" uid="uid://84uig641vqbo" path="res://asset/cell.png" id="2_eibgp"]
+
+[node name="Cell" type="Node2D"]
+script = ExtResource("1_gxfu7")
+block_size = 20
+
+[node name="TextureRect" type="TextureRect" parent="."]
+offset_right = 20.0
+offset_bottom = 20.0
+texture = ExtResource("2_eibgp")
+expand_mode = 1
[application]
config/name="catris"
+config/version="0.1.0"
+run/main_scene="uid://dkgkwg3aoct5i"
config/features=PackedStringArray("4.4", "Forward Plus")
config/icon="res://icon.svg"
+
+[display]
+
+window/stretch/mode="canvas_items"
+
+[input]
+
+player_left={
+"deadzone": 0.2,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
+]
+}
+player_right={
+"deadzone": 0.2,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null)
+]
+}
+player_up={
+"deadzone": 0.2,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
+]
+}
+player_down={
+"deadzone": 0.2,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
+]
+}
--- /dev/null
+[gd_scene load_steps=4 format=3 uid="uid://4saff6435gux"]
+
+[ext_resource type="Script" uid="uid://bex8wrsgbx63r" path="res://script/board.gd" id="1_b3264"]
+[ext_resource type="PackedScene" uid="uid://cmdvtaiunt32k" path="res://piece/cell.tscn" id="2_32fhn"]
+[ext_resource type="Texture2D" uid="uid://b6om08wjtci31" path="res://asset/grid.png" id="3_rl6p6"]
+
+[node name="Board" type="Control"]
+custom_minimum_size = Vector2(200, 300)
+layout_mode = 3
+anchors_preset = 5
+anchor_left = 0.5
+anchor_right = 0.5
+grow_horizontal = 2
+script = ExtResource("1_b3264")
+cell_catalogue = Array[PackedScene]([ExtResource("2_32fhn")])
+
+[node name="grid" type="TextureRect" parent="."]
+unique_name_in_owner = true
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+texture = ExtResource("3_rl6p6")
+stretch_mode = 1
+
+[node name="turnTimer" type="Timer" parent="."]
+unique_name_in_owner = true
+
+[connection signal="timeout" from="turnTimer" to="." method="_on_turn_timer_timeout"]
--- /dev/null
+[gd_scene load_steps=3 format=3 uid="uid://dkgkwg3aoct5i"]
+
+[ext_resource type="Script" uid="uid://8iyak3tfdvkh" path="res://script/main.gd" id="1_itxqv"]
+[ext_resource type="PackedScene" uid="uid://4saff6435gux" path="res://scene/board.tscn" id="2_v0l8b"]
+
+[node name="main" type="Node"]
+script = ExtResource("1_itxqv")
+fullscreen = false
+screen_size_fractional = 0.7
+
+[node name="MarginContainer" type="MarginContainer" parent="."]
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/margin_left = 10
+theme_override_constants/margin_top = 10
+theme_override_constants/margin_right = 10
+theme_override_constants/margin_bottom = 10
+
+[node name="buildVersion" type="Label" parent="MarginContainer"]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_vertical = 8
+text = "0.0.0"
+
+[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"]
+layout_mode = 2
+alignment = 1
+
+[node name="MarginContainer2" type="MarginContainer" parent="MarginContainer/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="MarginContainer3" type="MarginContainer" parent="MarginContainer/HBoxContainer"]
+layout_mode = 2
+size_flags_vertical = 4
+theme_override_constants/margin_left = 0
+theme_override_constants/margin_top = 0
+theme_override_constants/margin_right = 0
+theme_override_constants/margin_bottom = 0
+
+[node name="Board" parent="MarginContainer/HBoxContainer/MarginContainer3" instance=ExtResource("2_v0l8b")]
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
--- /dev/null
+extends Control
+class_name Board
+
+@export var block_size: int = 20
+@export var cell_catalogue: Array[PackedScene]
+
+var _grid_filled: Array[bool] = []
+var _player_position: Vector2i = Vector2i.ZERO
+var _player_cell: Cell = null
+var _grid_final_y_row: int = 0
+var _grid_final_x_row: int = 0
+
+var _num_pieces: int = 0
+
+func _ready() -> void:
+ _grid_final_y_row = size.y / block_size
+ _grid_final_x_row = size.x / block_size
+ print("Grid is " + str(_grid_final_x_row) + " by " + str(_grid_final_y_row))
+
+ for i in range(0, _grid_final_x_row):
+ for j in range(0, _grid_final_y_row):
+ _grid_filled.append(false)
+
+ _on_turn_timer_timeout()
+
+
+func _input(event: InputEvent) -> void:
+ if event.is_action_pressed("player_left"):
+ _move_cell(Vector2i(-1, 0))
+ elif event.is_action_pressed("player_right"):
+ _move_cell(Vector2i(1, 0))
+
+ if event.is_action_pressed("player_up"):
+ # TODO: rotate
+ pass
+
+ if event.is_action("player_down"):
+ _move_cell(Vector2i(0, 1))
+
+
+func _add_player_cell():
+ var scene: PackedScene = cell_catalogue.pick_random()
+ var cell: Cell = scene.instantiate()
+ cell.block_size = block_size
+
+ _player_position = Vector2i(5, 0)
+ cell.position = _player_position * block_size
+ _player_cell = cell
+
+ add_child(cell)
+ _num_pieces += 1
+ print("Added piece: " + str(_num_pieces))
+
+
+func _move_cell(v: Vector2i):
+ var new_player_position: Vector2i = _player_position + v
+
+ if new_player_position.x < 0 or new_player_position.x >= _grid_final_x_row:
+ # ignore input that moves beyond lateral boundaries
+ return
+
+ if _is_grid_position_taken(new_player_position):
+ # if movement is vertical and blocked, then we're done
+ if v.y != 0:
+ _end_round()
+ return
+
+ # update player position
+ _player_position = new_player_position
+ if _player_cell:
+ _player_cell.position = _player_position * block_size
+
+ # if at the bottom of the grid, we're done
+ if (_player_position.y == _grid_final_y_row - 1):
+ _end_round()
+
+func _end_round():
+ print("Time for a new piece!")
+ # disconnect player controls from current piece
+ _player_cell = null
+
+ # fill in collision grid with piece cells
+ _set_grid_position(_player_position, true)
+ #_print_grid()
+
+ # now start a new round
+ _on_turn_timer_timeout()
+
+
+func _on_turn_timer_timeout() -> void:
+ if _player_cell == null:
+ _add_player_cell()
+ else:
+ _move_cell(Vector2i(0, 1))
+ %turnTimer.start()
+
+
+func _set_grid_position(v: Vector2i, b: bool):
+ _grid_filled[v.x + v.y * _grid_final_x_row] = b
+
+
+func _is_grid_position_taken(v: Vector2i) -> bool:
+ return _grid_filled[v.x + v.y * _grid_final_x_row]
+
+
+func _print_grid():
+ for i in range(0, _grid_final_y_row):
+ var row = []
+ for j in range(0, _grid_final_x_row):
+ row.append(_grid_filled[j + i * _grid_final_x_row])
+ print(str(row))
--- /dev/null
+uid://bex8wrsgbx63r
--- /dev/null
+@tool
+extends Node2D
+class_name Cell
+
+
+@export var block_size: int = 10:
+ set(s):
+ block_size = s
+ _set_size_to_block_size()
+
+
+func _ready() -> void:
+ _set_size_to_block_size()
+
+
+func _set_size_to_block_size():
+ if get_node_or_null("TextureRect"):
+ $TextureRect.size = Vector2(block_size, block_size)
--- /dev/null
+uid://ds1rixr57lt7e
--- /dev/null
+extends Node
+
+
+@export var fullscreen: bool = true
+@export var screen_size_fractional: float = 0.5
+
+
+func _ready() -> void:
+ _set_project_version()
+ _set_screen_size()
+
+
+func _set_project_version() -> void:
+ var version = ProjectSettings.get_setting("application/config/version")
+ %buildVersion.text = "v" + str(version)
+
+
+func _set_screen_size() -> void:
+ var _screen_size: Vector2i = DisplayServer.screen_get_size()
+ if fullscreen:
+ DisplayServer.window_set_position(Vector2i.ZERO)
+ DisplayServer.window_set_size(_screen_size)
+ else:
+ var _win_pos = _screen_size * (1.0 - screen_size_fractional) * 0.5
+ var _win_size = _screen_size * screen_size_fractional
+ DisplayServer.window_set_position(_win_pos)
+ DisplayServer.window_set_size(_win_size)
+
+
+func _input(event: InputEvent) -> void:
+ if event.is_action_pressed("ui_cancel"):
+ get_tree().quit()
--- /dev/null
+uid://8iyak3tfdvkh