v.0 TicTacToe vorlage

main
Daniel Lehmann 2024-03-27 18:02:45 +01:00
commit 51fb7f81d3
14 changed files with 955 additions and 0 deletions

2
.gitattributes vendored 100644
View File

@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

2
.gitignore vendored 100644
View File

@ -0,0 +1,2 @@
# Godot 4+ specific ignores
.godot/

BIN
assets/sprites.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://do2vfb2cj7fk"
path="res://.godot/imported/sprites.png-bb36f92a96c2b9ad48a8528dbf01963e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/sprites.png"
dest_files=["res://.godot/imported/sprites.png-bb36f92a96c2b9ad48a8528dbf01963e.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

451
assets/sprites.svg 100644
View File

@ -0,0 +1,451 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1080"
height="1920"
viewBox="0 0 285.74999 508"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="sprites.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="false"
inkscape:deskcolor="#ffffff"
inkscape:document-units="px"
showborder="false"
inkscape:zoom="1.0333895"
inkscape:cx="162.57182"
inkscape:cy="780.92533"
inkscape:window-width="2560"
inkscape:window-height="1364"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g13"
showgrid="true">
<inkscape:grid
id="grid2"
units="px"
originx="0"
originy="0"
spacingx="31.749999"
spacingy="31.749999"
empcolor="#0099e5"
empopacity="0.30196078"
color="#0099e5"
opacity="0.14901961"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="rect1"
style="fill:#cfe1f5;fill-opacity:1;stroke:#747474;stroke-width:0.758714;stroke-opacity:1"
d="M 2.0803813,95.629348 H 29.794762 c 0.907704,0 1.638454,1.126404 1.638454,2.525566 v 25.940146 c 0,1.39917 -0.73075,2.52557 -1.638454,2.52557 H 2.0803813 c -0.9077019,0 -1.6384515,-1.1264 -1.6384515,-2.52557 V 98.154914 c 0,-1.399162 0.7307496,-2.525566 1.6384515,-2.525566 z"
inkscape:export-filename="sprites.png"
inkscape:export-xdpi="80.039444"
inkscape:export-ydpi="80.039444" />
<path
id="rect1-7"
style="fill:#fefefe;fill-opacity:1;stroke:#747474;stroke-width:0.758714;stroke-opacity:1"
d="M 2.0178085,222.62934 H 29.732189 c 0.907704,0 1.638454,1.12641 1.638454,2.52557 v 25.94014 c 0,1.39917 -0.73075,2.52557 -1.638454,2.52557 H 2.0178085 c -0.9077019,0 -1.63845149,-1.1264 -1.63845149,-2.52557 v -25.94014 c 0,-1.39916 0.73074959,-2.52557 1.63845149,-2.52557 z"
inkscape:export-filename="sprites.png"
inkscape:export-xdpi="80.039444"
inkscape:export-ydpi="80.039444" />
<path
id="rect1-7-4"
style="fill:#d6d6d6;fill-opacity:1;stroke:#747474;stroke-width:0.758714;stroke-opacity:1"
d="m 97.267805,222.62933 h 27.714375 c 0.9077,0 1.63845,1.12641 1.63845,2.52557 v 25.94014 c 0,1.39917 -0.73075,2.52557 -1.63845,2.52557 H 97.267805 c -0.907701,0 -1.638451,-1.1264 -1.638451,-2.52557 V 225.1549 c 0,-1.39916 0.73075,-2.52557 1.638451,-2.52557 z"
inkscape:export-filename="sprites.png"
inkscape:export-xdpi="80.039444"
inkscape:export-ydpi="80.039444" />
<path
id="rect1-3"
style="fill:#81b8f5;fill-opacity:1;stroke:#747474;stroke-width:0.758714;stroke-opacity:1"
d="m 33.767808,95.629358 h 27.714381 c 0.907704,0 1.638454,1.126404 1.638454,2.525566 v 25.940136 c 0,1.39917 -0.73075,2.52557 -1.638454,2.52557 H 33.767808 c -0.907702,0 -1.638452,-1.1264 -1.638452,-2.52557 V 98.154924 c 0,-1.399162 0.73075,-2.525566 1.638452,-2.525566 z"
inkscape:export-filename="sprites.png"
inkscape:export-xdpi="80.039444"
inkscape:export-ydpi="80.039444" />
<path
id="rect1-2"
style="fill:#ff9393;fill-opacity:1;stroke:#747474;stroke-width:0.758714;stroke-opacity:1"
d="m 97.267799,95.629349 h 27.714391 c 0.9077,0 1.63845,1.126404 1.63845,2.52557 v 25.940141 c 0,1.39917 -0.73075,2.52557 -1.63845,2.52557 H 97.267799 c -0.907699,0 -1.638449,-1.1264 -1.638449,-2.52557 V 98.154919 c 0,-1.399166 0.73075,-2.52557 1.638449,-2.52557 z" />
<path
id="rect1-2-9"
style="fill:#ffd5d5;fill-opacity:1;stroke:#747474;stroke-width:0.758714;stroke-opacity:1"
d="m 65.517802,95.629357 h 27.714396 c 0.9077,0 1.63845,1.126406 1.63845,2.525566 v 25.940137 c 0,1.39917 -0.73075,2.52557 -1.63845,2.52557 H 65.517802 c -0.907698,0 -1.638448,-1.1264 -1.638448,-2.52557 V 98.154923 c 0,-1.39916 0.73075,-2.525566 1.638448,-2.525566 z" />
<g
id="g14"
transform="translate(0.136241)">
<circle
style="fill:none;fill-opacity:1;stroke:#4fb130;stroke-width:3.83993;stroke-dasharray:none;stroke-opacity:1"
id="path1"
cx="15.937572"
cy="143.27879"
r="11.309203" />
<g
id="g2"
transform="matrix(1.4099907,0,0,1.4099907,19.237586,-10.028506)"
style="stroke-width:2.81473483;stroke-dasharray:none">
<rect
style="fill:#4fb130;fill-opacity:1;stroke-width:2.81473483;stroke-opacity:0.399065;stroke-dasharray:none"
id="rect2"
width="25.091379"
height="3.5844827"
x="110.41884"
y="29.009678"
rx="1.8679774"
ry="2.8793721"
transform="rotate(45)" />
<rect
style="fill:#4fb130;fill-opacity:1;stroke-width:2.81473483;stroke-opacity:0.399065;stroke-dasharray:none"
id="rect2-7"
width="25.091379"
height="3.5844827"
x="18.256229"
y="-124.75677"
rx="1.8679774"
ry="2.8793721"
transform="rotate(135)" />
</g>
<rect
style="fill:none;fill-opacity:1;stroke:#4fb130;stroke-width:4.00137;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
id="rect3"
width="22.456959"
height="22.456959"
x="36.169022"
y="132.05031"
rx="0"
ry="4.1368074" />
<path
sodipodi:type="star"
style="fill:none;fill-opacity:1;stroke:#4fb130;stroke-width:7.71424;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path4"
inkscape:flatsided="true"
sodipodi:sides="3"
sodipodi:cx="-70.409485"
sodipodi:cy="133.13792"
sodipodi:r1="27.718025"
sodipodi:r2="13.859012"
sodipodi:arg1="0.52359878"
sodipodi:arg2="1.5707963"
inkscape:rounded="0"
inkscape:randomized="0"
d="m -46.404971,146.99694 -48.009028,0 24.004514,-41.57704 z"
inkscape:transform-center-y="-3.7197857"
transform="matrix(0.47480216,0,0,0.5368039,112.82057,75.529531)"
inkscape:transform-center-x="1.3949348e-06" />
</g>
<g
id="g13"
transform="translate(-0.13623953)">
<circle
style="fill:none;fill-opacity:1;stroke:#d9da3b;stroke-width:3.89259;stroke-dasharray:none;stroke-opacity:1"
id="path1-7"
cx="16.210051"
cy="174.39807"
r="11.282871" />
<g
id="g2-5"
transform="matrix(1.4099907,0,0,1.4099907,19.510068,21.09076)"
style="stroke:none;stroke-opacity:1;fill:#d9da3b;fill-opacity:1">
<rect
style="fill:#d9da3b;fill-opacity:1;stroke-width:0.865;stroke-opacity:1;stroke:none"
id="rect2-3"
width="25.091379"
height="3.5844827"
x="110.41884"
y="29.009678"
rx="1.8679774"
ry="2.8793721"
transform="rotate(45)" />
<rect
style="fill:#d9da3b;fill-opacity:1;stroke-width:0.865;stroke-opacity:1;stroke:none"
id="rect2-7-8"
width="25.091379"
height="3.5844827"
x="18.256229"
y="-124.75677"
rx="1.8679774"
ry="2.8793721"
transform="rotate(135)" />
</g>
<rect
style="fill:none;fill-opacity:1;stroke:#d9da3b;stroke-width:4.00137;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
id="rect3-8"
width="22.456959"
height="22.456959"
x="36.441505"
y="163.16957"
rx="0"
ry="4.1368074" />
<path
sodipodi:type="star"
style="fill:none;fill-opacity:1;stroke:#d9da3b;stroke-width:7.71424;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path4-3"
inkscape:flatsided="true"
sodipodi:sides="3"
sodipodi:cx="-70.409485"
sodipodi:cy="133.13792"
sodipodi:r1="27.718025"
sodipodi:r2="13.859012"
sodipodi:arg1="0.52359878"
sodipodi:arg2="1.5707963"
inkscape:rounded="0"
inkscape:randomized="0"
d="m -46.404971,146.99694 -48.009028,0 24.004514,-41.57704 z"
inkscape:transform-center-y="-3.7197817"
transform="matrix(0.47480216,0,0,0.5368039,113.09305,106.6488)"
inkscape:transform-center-x="1.3949348e-06" />
</g>
<g
id="g12"
transform="translate(1.3601261e-6,31.749993)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#5c5c5c;stroke-width:1.6238;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="rect4"
width="24.834532"
height="24.834532"
x="3.5203071"
y="162.36655"
ry="4.4574804" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5"
cx="15.937572"
cy="174.78381"
r="2.6458333" />
</g>
<g
id="g6"
transform="translate(-1.4489925,31.298647)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#5c5c5c;stroke-width:1.6238;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="rect4-1"
width="24.834532"
height="24.834532"
x="100.15672"
y="162.81789"
ry="4.4574804" />
<g
id="g5"
transform="translate(36.527016,-3.0724136)">
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-9-69"
cx="69.219963"
cy="171.85135"
r="2.6458333" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-2"
cx="82.873985"
cy="171.85135"
r="2.6458333" />
</g>
<g
id="g5-1"
transform="translate(36.527016,9.8400234)">
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-9-69-06"
cx="69.219963"
cy="171.85135"
r="2.6458333" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-2-1"
cx="82.873985"
cy="171.85135"
r="2.6458333" />
</g>
</g>
<g
id="g11"
transform="translate(-7.6587743,31.749993)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#5c5c5c;stroke-width:1.6238;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="rect4-1-6"
width="24.834532"
height="24.834532"
x="74.631508"
y="194.92972"
ry="4.4574804" />
<g
id="g5-5"
transform="translate(11.0018,29.039412)">
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-9-69-6"
cx="69.219963"
cy="171.85135"
r="2.6458333" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-2-3"
cx="82.873985"
cy="171.85135"
r="2.6458333" />
</g>
<g
id="g5-5-3"
transform="translate(11.0018,35.495631)">
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-9-69-6-9"
cx="69.219963"
cy="171.85135"
r="2.6458333" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-2-3-0"
cx="82.873985"
cy="171.85135"
r="2.6458333" />
</g>
<g
id="g5-1-9"
transform="translate(11.0018,41.951849)">
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-9-69-06-4"
cx="69.219963"
cy="171.85135"
r="2.6458333" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-2-1-8"
cx="82.873985"
cy="171.85135"
r="2.6458333" />
</g>
</g>
<g
id="g7"
transform="translate(-1.5562582,31.474093)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#5c5c5c;stroke-width:1.6238;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="rect4-1-9"
width="24.834532"
height="24.834532"
x="68.528992"
y="162.64244"
ry="4.4574804" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-7"
cx="80.946259"
cy="175.05971"
r="2.6458333" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-2-17"
cx="87.77327"
cy="168.60349"
r="2.6458333" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-9-69-06-1"
cx="74.119247"
cy="181.51591"
r="2.6458333" />
</g>
<g
id="g10"
transform="translate(0.78421303,31.749993)">
<rect
style="fill:#ffffff;fill-opacity:0.996164;stroke:#5c5c5c;stroke-width:1.6238;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="rect4-1-9-9"
width="24.834532"
height="24.834532"
x="34.196022"
y="194.50227"
ry="4.4574804" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-7-0"
cx="46.613289"
cy="206.91954"
r="2.6458333" />
<g
id="g6-6"
transform="translate(-71.714011,34.420187)">
<g
id="g5-0-3"
transform="translate(42.280323,-5.8082157)">
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-9-69-9-8"
cx="69.219963"
cy="171.85135"
r="2.6458333" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-2-17-5"
cx="82.873985"
cy="171.85135"
r="2.6458333" />
</g>
<g
id="g5-1-7-6"
transform="translate(42.280323,7.1042213)">
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-9-69-06-1-1"
cx="69.219963"
cy="171.85135"
r="2.6458333" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-2-1-1-1"
cx="82.873985"
cy="171.85135"
r="2.6458333" />
</g>
</g>
</g>
<g
id="g8"
transform="translate(-0.10953621,29.909227)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#5c5c5c;stroke-width:1.6238;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="rect4-1-9-8"
width="24.834532"
height="24.834532"
x="35.089771"
y="164.20731"
ry="4.4574804" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-2-17-0"
cx="54.334045"
cy="170.16835"
r="2.6458333" />
<circle
style="fill:#5c5c5c;fill-opacity:1;stroke:none;stroke-width:2.12972;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
id="path5-9-69-06-1-4"
cx="40.680023"
cy="183.08078"
r="2.6458333" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ddkkkb6k0j8pl"
path="res://.godot/imported/sprites.svg-3de0a23bb576a309499d2855bd837d3b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/sprites.svg"
dest_files=["res://.godot/imported/sprites.svg-3de0a23bb576a309499d2855bd837d3b.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
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

65
board/board.gd 100644
View File

@ -0,0 +1,65 @@
extends TileMap
class_name Board
var tile_by_name := {}
var layer_by_name := {}
@export var state_layer: String = "States"
@export var board_layer: String = "Board"
@export var state_name: String = "Name"
@export var empty_state: String = "Empty"
var off_limits: String = ""
@export var active: bool = true
func _ready():
print("Initializing board...")
_index_atlas_coordinates_by_name()
_index_layers_by_name()
$Highlight.size = tile_set.tile_size
print("Tiles: ", ", ".join(tile_by_name.keys()))
func get_state(grid_pos: Vector2) -> String:
var state_tile_data: TileData = self.get_cell_tile_data(layer_by_name[state_layer], grid_pos)
var board_tile_data: TileData = self.get_cell_tile_data(layer_by_name[board_layer], grid_pos)
if not board_tile_data:
return off_limits
if not state_tile_data or not state_tile_data.get_custom_data(state_name):
return empty_state
return state_tile_data.get_custom_data(state_name)
func set_state(grid_pos: Vector2, state: String) -> bool:
if get_state(grid_pos) != empty_state:
return false
self.set_cell(layer_by_name[state_layer], grid_pos, tile_by_name[state]["source_id"], tile_by_name[state]["atlas_coords"])
return true
func global_to_map(global_pos: Vector2) -> Vector2:
return self.local_to_map(self.to_local(global_pos))
func gridpos_at_mouse() -> Vector2:
return global_to_map(get_viewport().get_mouse_position())
func reset() -> void:
for cell in get_used_cells(layer_by_name[state_layer]):
set_cell(layer_by_name[state_layer], cell, -1)
func _index_atlas_coordinates_by_name():
var tileset = self.tile_set
for source_index in range(tileset.get_source_count()):
var source_id = tileset.get_source_id(source_index)
var atlas:TileSetAtlasSource = tileset.get_source(source_id)
for tile_index in range(atlas.get_tiles_count()):
var atlas_coords = atlas.get_tile_id(tile_index)
var tile_data : TileData = atlas.get_tile_data(atlas_coords, 0)
if tile_data and tile_data.get_custom_data(state_name):
tile_by_name[tile_data.get_custom_data(state_name)] = {
"source_id": source_id,
"atlas_coords": atlas_coords
}
func _index_layers_by_name():
for i in range(get_layers_count()):
layer_by_name[get_layer_name(i)] = i

70
board/board.tscn 100644
View File

@ -0,0 +1,70 @@
[gd_scene load_steps=6 format=3 uid="uid://dvlk7imglgpms"]
[ext_resource type="Texture2D" uid="uid://do2vfb2cj7fk" path="res://assets/sprites.png" id="1_lagx3"]
[ext_resource type="Script" path="res://board/board.gd" id="2_vjb6q"]
[ext_resource type="Script" path="res://board/highlight.gd" id="3_m02pi"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_cta1l"]
resource_name = "sprites"
texture = ExtResource("1_lagx3")
texture_region_size = Vector2i(100, 100)
0:0/0 = 0
0:0/0/custom_data_0 = "Blue1"
1:0/0 = 0
1:0/0/custom_data_0 = "Blue2"
2:0/0 = 0
2:0/0/custom_data_0 = "Red1"
3:0/0 = 0
3:0/0/custom_data_0 = "Red2"
0:1/0 = 0
0:1/0/custom_data_0 = "Circle"
1:1/0 = 0
1:1/0/custom_data_0 = "Square"
2:1/0 = 0
2:1/0/custom_data_0 = "Triangle"
3:1/0 = 0
3:1/0/custom_data_0 = "Cross"
0:2/0 = 0
0:2/0/custom_data_0 = "Circle2"
1:2/0 = 0
1:2/0/custom_data_0 = "Square2"
2:2/0 = 0
2:2/0/custom_data_0 = "Triangle2"
3:2/0 = 0
3:2/0/custom_data_0 = "Cross2"
0:3/0 = 0
0:3/0/custom_data_0 = "D1"
1:3/0 = 0
1:3/0/custom_data_0 = "D2"
2:3/0 = 0
2:3/0/custom_data_0 = "D3"
3:3/0 = 0
3:3/0/custom_data_0 = "D4"
0:4/0 = 0
0:4/0/custom_data_0 = "White"
1:4/0 = 0
1:4/0/custom_data_0 = "D5"
2:4/0 = 0
2:4/0/custom_data_0 = "D6"
3:4/0 = 0
3:4/0/custom_data_0 = "Grey"
[sub_resource type="TileSet" id="TileSet_exrha"]
tile_size = Vector2i(100, 100)
custom_data_layer_0/name = "Name"
custom_data_layer_0/type = 4
sources/1 = SubResource("TileSetAtlasSource_cta1l")
[node name="Board" type="TileMap"]
texture_filter = 1
tile_set = SubResource("TileSet_exrha")
rendering_quadrant_size = 100
format = 2
layer_0/name = "Board"
layer_0/tile_data = PackedInt32Array(65537, 1, 0, 131073, 1, 0, 131074, 1, 0, 0, 1, 0, 65536, 1, 0, 131072, 1, 0, 1, 1, 0, 2, 1, 0, 65538, 1, 0)
layer_1/name = "States"
layer_1/tile_data = PackedInt32Array()
script = ExtResource("2_vjb6q")
[node name="Highlight" type="Node2D" parent="."]
script = ExtResource("3_m02pi")

22
board/highlight.gd 100644
View File

@ -0,0 +1,22 @@
extends Node2D
@export var size := Vector2(16,16):
set(value):
size = value
queue_redraw()
@onready var board := get_parent() as Board
func _draw():
draw_rect(Rect2(0,0,size.x,size.y), Color(1,0,0,0.7), false, 2)
func _process(_delta):
var grid_pos = board.global_to_map(get_viewport().get_mouse_position())
var state = board.get_state(grid_pos)
if state == board.empty_state and board.active:
position = board.map_to_local(grid_pos) - size / 2
show()
else:
hide()

65
game.gd 100644
View File

@ -0,0 +1,65 @@
extends Node2D
var current_player: int = 0
var player_states := ["Circle", "Cross"]
var won := ""
@onready var board := $Board as Board
@onready var nextPlayer := $GUI/NextPlayer as Sprite2D
@onready var wonPlayer := $GUI/WonPlayer as Sprite2D
# Called when the node enters the scene tree for the first time.
func _ready():
current_player = 0
board.reset()
won = ""
wonPlayer.hide()
nextPlayer.region_rect.position.x = current_player * 300
nextPlayer.show()
board.active = true
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
if won == "":
if Input.is_action_just_pressed("Click"):
var grid_pos = board.gridpos_at_mouse()
if board.get_state(grid_pos) == board.empty_state:
if board.set_state(grid_pos, player_states[current_player]):
won = _check_win()
if won=="":
current_player = 1 - current_player
nextPlayer.region_rect.position.x = current_player * 300
else:
print("Winner: ", won)
wonPlayer.region_rect.position.x = player_states.find(won) * 300
wonPlayer.show()
nextPlayer.hide()
board.active = false
func _on_restart_button_pressed():
_ready()
var _checks = [
[Vector2i(-1,0), Vector2i(1,0)],
[Vector2i(0,-1), Vector2i(0,1)],
[Vector2i(-1,-1), Vector2i(1,1)],
[Vector2i(-1,1), Vector2i(1,-1)],
]
func _check_win() -> String:
for cell in board.get_used_cells(board.layer_by_name[board.state_layer]):
var state = board.get_state(cell)
for check in _checks:
var same = true
for neighbour in check:
if board.get_state(cell + neighbour) != state:
same = false
continue
if same:
return state
return ""

64
game.tscn 100644
View File

@ -0,0 +1,64 @@
[gd_scene load_steps=4 format=3 uid="uid://dmahmxghpm47w"]
[ext_resource type="Script" path="res://game.gd" id="1_g1ie7"]
[ext_resource type="PackedScene" uid="uid://dvlk7imglgpms" path="res://board/board.tscn" id="1_ym80r"]
[ext_resource type="Texture2D" uid="uid://do2vfb2cj7fk" path="res://assets/sprites.png" id="3_0333r"]
[node name="Game" type="Node2D"]
script = ExtResource("1_g1ie7")
[node name="Board" parent="." instance=ExtResource("1_ym80r")]
position = Vector2(420, 222)
[node name="GUI" type="Node2D" parent="."]
[node name="Title" type="Label" parent="GUI"]
offset_left = 28.0
offset_top = 31.0
offset_right = 718.0
offset_bottom = 103.0
theme_override_font_sizes/font_size = 32
text = "Tic Tac Toe Rapid Prototyper"
[node name="NextPlayer" type="Sprite2D" parent="GUI"]
position = Vector2(690, 59)
scale = Vector2(0.5, 0.5)
texture = ExtResource("3_0333r")
region_enabled = true
region_rect = Rect2(0, 100, 100, 100)
[node name="NextPlayerLabel" type="Label" parent="GUI"]
offset_left = 602.0
offset_top = 47.0
offset_right = 644.0
offset_bottom = 73.0
size_flags_horizontal = 4
text = "Next:"
metadata/_edit_use_anchors_ = true
[node name="WonPlayer" type="Sprite2D" parent="GUI"]
visible = false
position = Vector2(891, 58)
scale = Vector2(0.5, 0.5)
texture = ExtResource("3_0333r")
region_enabled = true
region_rect = Rect2(0, 100, 100, 100)
[node name="WonPlayerLabel" type="Label" parent="GUI"]
offset_left = 807.0
offset_top = 47.0
offset_right = 849.0
offset_bottom = 73.0
size_flags_horizontal = 4
text = "Won:"
metadata/_edit_use_anchors_ = true
[node name="RestartButton" type="Button" parent="GUI"]
offset_left = 983.0
offset_top = 44.0
offset_right = 1086.0
offset_bottom = 75.0
text = "Restart"
metadata/_edit_use_anchors_ = true
[connection signal="pressed" from="GUI/RestartButton" to="." method="_on_restart_button_pressed"]

75
icon.svg 100644
View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="128"
width="128"
version="1.1"
id="svg7"
sodipodi:docname="icon.svg"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs7" />
<sodipodi:namedview
id="namedview7"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="9.0625"
inkscape:cx="63.944828"
inkscape:cy="64"
inkscape:window-width="2560"
inkscape:window-height="1364"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg7" />
<rect
x="2"
y="2"
width="124"
height="124"
rx="14"
fill="#363d52"
stroke="#212532"
stroke-width="4"
id="rect1" />
<path
style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
d="M 39.944828,21.517241 38.841379,112"
id="path7" />
<path
style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
d="M 79.668966,21.075862 77.462069,113.98621"
id="path8" />
<path
style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
d="M 14.565517,52.193103 112.77241,49.765517"
id="path9" />
<path
style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
d="M 17.655172,85.517241 112.33103,83.310345"
id="path10" />
<path
style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
d="M 35.310345,26.593103 16.331034,42.041379"
id="path11" />
<path
style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
d="M 16.110345,24.606897 33.765517,46.234483"
id="path12" />
<ellipse
style="fill:none;stroke:#ffffff;stroke-width:3.00074879;stroke-dasharray:none;stroke-opacity:1"
id="path13"
cx="54.194748"
cy="73.141953"
rx="12.055581"
ry="9.1658545"
transform="matrix(0.99532359,-0.09659684,0.06510887,0.99787817,0,0)" />
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

37
icon.svg.import 100644
View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cqc52ufiirdtv"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.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
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

31
project.godot 100644
View File

@ -0,0 +1,31 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="Tic Tac Toe"
run/main_scene="res://game.tscn"
config/features=PackedStringArray("4.2", "GL Compatibility")
config/icon="res://icon.svg"
[input]
Click={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
[rendering]
textures/canvas_textures/default_texture_filter=0
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"
environment/defaults/default_clear_color=Color(0.203922, 0.203922, 0.203922, 1)