Split project, turn framework into submodule

Fixes #38
This commit is contained in:
Francois Belair 2020-05-14 13:37:50 -04:00
parent 38baf344a8
commit ca1a7088c5
116 changed files with 49 additions and 3213 deletions

View File

@ -1,29 +1,32 @@
# Changelog #
# Changelog
This document lists new features, improvements, changes, and bug fixes in every release of the add-on.
## Master ##
## Master
### Changes ###
## Godot Steering AI Framework 3.0.0
### Changes
- The structure of the project has been overhauled in order to make it possible to import as an add-on in Godot directly.
- Acceleration for agents are now multiplied by delta in order to make acceleration be per second instead of instant. The demos' values have been increased significantly to better fit with reality.
### Fixes
- KinematicBody2DAgents and KinematicBody3DAgents that moved fast enough no longer reverse velocity suddenly during a frame where no acceleration is applied.
- RigidBody2DAgent should no longer crash due to a missing reference.
- Specialized Agents like RigidBody2DAgent should no longer crash due to a missing reference.
## Godot Steering AI Framework 2.1.0 ##
## Godot Steering AI Framework 2.1.0
### Features ###
### Features
- There is now an `Arrive3d` demo to showcase 3D movement.
### Improvements ###
### Improvements
- All the demos got a bit of attention to improve their feel.
### Changes ###
### Changes
- `GSAIUtils.vector3_to_angle` now uses the vector's X and Z components to determine angle. Use `GSAIUtils.vector2_to_angle` for 2D use cases.
- `GSAIMatchOrientation` and its subclasses like `GSAIFace` and `GSAILookWhereYouGo` now include a `use_z` property. It should be `true` when using 3D so that facing will be done with the X and Z components.
@ -31,7 +34,7 @@ This document lists new features, improvements, changes, and bug fixes in every
- Exposed `agent_count` inside the `AvoidCollisionsDemo`.
- Unused and undocumented variable `_body_type` has been removed from `SpecializedAgent`
### Bug fixes ###
### Bug fixes
- Fixed `GSAIKinematicBody3DAgent` and `GSAIRigidBody3DAgent` trying to use `global_position` instead of `transform.origin`.
- The `SeekFleeDemo`'s boundaries will now match the size of the screen.
@ -40,7 +43,7 @@ This document lists new features, improvements, changes, and bug fixes in every
- The specialized agents now use WeakRef internally to prevent crashes when their `body` is freed.
- `RigidBody2DAgent` now properly connects to physics updates.
## Godot Steering AI Framework 2.0.0 ##
## Godot Steering AI Framework 2.0.0
This release brings one new feature and bug fix, and breaking changes to the framework as we renamed all the classes.
@ -50,16 +53,16 @@ If you were using `GSTKinematicBodyAgent` or `GSTRigidBodyAgent`, search and rep
We decided to make this change as soon as possible, as the framework was released a few days ago.
### Features ###
### Features
- There is now a main scene with a demo picker, so you can select and play any demo on the fly.
- The demo projects now support resizing and toggling fullscreen with <kbd>F11</kbd>.
### Improvements ###
### Improvements
- We handled all warnings in the framework, so using it won't add warnings to your projects.
### Changes ###
### Changes
- Renamed all classes from `GST*` (Godot Steering Toolkit) to `GSAI*` (Godot Steering AI).
- Removed `GSTNode2DAgent`, `GSTNodeAgent`, and `GSTSpatialAgent` classes.
@ -68,11 +71,11 @@ We decided to make this change as soon as possible, as the framework was release
- Renamed `GSAIRigidBodyAgent` and `GSAIRigidBodyAgent` to `GSAIRigidBody3DAgent` and `GSAIRigidBody3DAgent` respectively.
- 3D nodes like `Sprite`, `KinematicBody`, etc. are being renamed to `Sprite3D`, `KinematicBody3D`, etc. in the upcoming Godot 4.0 release, to be consistent with 2D nodes. We decided to rename them now instead of breaking compatibility in a future release.
### Bug fixes ###
### Bug fixes
- GSTFollowPath no longer loops back around itself on open paths when `predict_time` is non-zero.
## Godot Steering AI Framework 1.0.0 ##
## Godot Steering AI Framework 1.0.0
This is the first major release of the framework. It comes with:
@ -84,7 +87,7 @@ This is the first major release of the framework. It comes with:
- For 3D games, `KinematicBody3DAgent` and `RigidBody3DAgent`.
- 9 Godot demos to learn straight from the code.
### Manual ###
### Manual
To get started, check out the framework's [manual](https://www.gdquest.com/docs/godot-steering-toolkit/).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-b6a7fb2db36edd3d95dc42f1dc8c1c5d.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icon.png"
dest_files=[ "res://.import/icon.png-b6a7fb2db36edd3d95dc42f1dc8c1c5d.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@ -1,151 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="icon.svg"
inkscape:version="1.1-dev (83f2ee46ff, 2020-02-13)"
id="svg1340"
version="1.1"
viewBox="0 0 16.933333 16.933334"
height="64"
width="64">
<defs
id="defs1334">
<clipPath
id="clipPath1560"
clipPathUnits="userSpaceOnUse">
<rect
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:#293252;fill-opacity:1;stroke:none;stroke-width:1.40425;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;stop-color:#000000;stop-opacity:1"
id="rect1562"
width="16.933332"
height="16.933332"
x="0"
y="9.6346028e-08" />
</clipPath>
</defs>
<sodipodi:namedview
inkscape:snap-global="true"
inkscape:snap-others="false"
inkscape:object-nodes="false"
inkscape:snap-page="true"
inkscape:snap-bbox="true"
inkscape:window-maximized="1"
inkscape:window-y="0"
inkscape:window-x="0"
inkscape:window-height="1043"
inkscape:window-width="1920"
units="px"
showgrid="false"
inkscape:current-layer="layer1"
inkscape:document-units="mm"
inkscape:cy="31.438019"
inkscape:cx="15.072392"
inkscape:zoom="8"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base" />
<metadata
id="metadata1337">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Layer 1">
<rect
y="0"
x="0"
height="16.933332"
width="16.933332"
id="rect1504"
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:#293252;fill-opacity:1;stroke:none;stroke-width:1.40425;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;stop-color:#000000;stop-opacity:1" />
<path
clip-path="url(#clipPath1560)"
id="path2490"
d="M 2.8526138,-0.0226856 2.9507848,1.274306 C 2.5771927,1.4791664 2.2289224,1.7185349 1.9075218,1.988743 L 0.29690799,1.3221671 -0.40866643,2.1624613 0.56110833,3.5585158 C 0.33791661,3.9257554 0.15316113,4.3166174 0.00975169,4.7250204 l -0.7432386,0.090259 -0.009472,1.7228785 0.40521717,0.191826 c 0,0.2151562 0.0190602,0.4320655 0.0310875,0.6505844 0.0205584,0.2185642 0.0528327,0.4331209 0.0974454,0.6435666 l -0.54416748,0.401985 -0.008756,1.5907221 1.2930922,-0.090536 C 0.75306491,10.299542 1.0115466,10.64731 1.3029499,10.96517 l -0.672761,1.553839 0.858959,0.689584 1.4456413,-0.959917 c 0.3687832,0.203771 0.7600417,0.372343 1.1673979,0.502553 l 0.2153945,1.714295 1.0964166,0.176342 0.7818497,-1.5822 c 0.2037711,0 0.4094501,-0.01685 0.6159876,-0.03895 H 6.812698 L 9.8042599,12.732617 9.3779282,8.4823903 6.3854715,8.7696026 6.5157868,10.092058 C 4.6330774,10.272636 2.9585336,8.9258916 2.7734622,7.0836627 2.5888891,5.2418454 3.9644158,3.6030022 5.8465387,3.4220125 L 8.8381053,3.1348571 8.5438181,0.20619376 5.5531989,0.49334922 C 5.3459823,0.51050176 5.1420605,0.5378074 4.9415586,0.57229759 L 4.4901554,-0.01349219 Z M 10.360111,2.7244603 9.577372,4.3066562 c -0.2035882,0 -0.4084223,0.016659 -0.6150947,0.038946 L 5.969764,4.633705 6.2641051,7.5605285 9.2556723,7.273373 a 3.4244787,3.3513826 0 0 1 3.7431617,3.007448 3.4244787,3.3513826 0 0 1 -3.0739683,3.662595 l -2.9915662,0.28894 0.2652052,2.646411 2.7965066,0.01566 0.2241417,-0.0215 c 0.206675,-0.01714 0.41087,-0.0444 0.610692,-0.07889 l 0.0814,0.105523 1.973596,0.01109 -0.06151,-0.818622 c 0.373232,-0.204827 0.723028,-0.444409 1.044158,-0.714444 l 1.609666,0.667466 0.705575,-0.840294 -0.968773,-1.396053 c 0.222649,-0.367242 0.407573,-0.758822 0.551301,-1.167399 l 1.699205,-0.205645 0.181684,-1.073405 -1.533445,-0.725078 c 0.01889,-0.214756 -0.01899,-0.432247 -0.03098,-0.6505829 -0.02061,-0.2185654 -0.05301,-0.4339146 -0.09935,-0.6444001 L 17.342103,8.3379231 16.950314,7.3203422 15.242313,7.4418002 C 15.020345,7.0685674 14.760954,6.7200461 14.469323,6.4020456 L 15.142137,4.8490976 14.284072,4.1595128 12.836646,5.1194284 C 12.467685,4.9156577 12.078251,4.7477386 11.671033,4.6177136 L 11.454747,2.9034731 Z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#2f395f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.17682;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
inkscape:connector-curvature="0" />
<g
style="stroke-width:1.24672"
transform="matrix(0.18285727,0,0,0.14154908,150.31973,-187.36868)"
id="g2450">
<path
inkscape:connector-curvature="0"
style="opacity:1;vector-effect:none;fill:#5e315b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
d="m -822.06042,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
id="path2430" />
<path
id="path2432"
d="m -812.80001,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
style="opacity:1;vector-effect:none;fill:#8c3f5d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="opacity:1;vector-effect:none;fill:#ba6156;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
d="m -803.5396,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
id="path2434" />
<path
id="path2436"
d="m -794.27919,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
style="opacity:1;vector-effect:none;fill:#f2a65e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="opacity:1;vector-effect:none;fill:#ffe478;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
d="m -785.01878,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
id="path2438" />
<path
id="path2440"
d="m -775.75837,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
style="opacity:1;vector-effect:none;fill:#cfff70;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="opacity:1;vector-effect:none;fill:#8fde5d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
d="m -766.49796,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
id="path2442" />
<path
id="path2444"
d="m -757.23755,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
style="opacity:1;vector-effect:none;fill:#3ca370;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="opacity:1;vector-effect:none;fill:#3d6e70;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
d="m -747.97714,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
id="path2446" />
<path
id="path2448"
d="m -738.71673,1434.5708 h 9.26041 v 9.2604 h -9.26041 z"
style="opacity:1;vector-effect:none;fill:#323e4f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.989584;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.97917, 1.97917;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal"
inkscape:connector-curvature="0" />
</g>
<path
sodipodi:nodetypes="cccc"
d="M 1.7415414,13.864431 C 2.8091455,12.301646 3.8954985,10.918152 4.8840406,10.004274 M 12.44693,3.6341761 c 0,0 1.658558,-1.2568206 2.909891,-2.065662"
style="fill:none;stroke:#a0a9ce;stroke-width:1.087;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:1.6;stroke-dasharray:2.174, 2.174;stroke-dashoffset:1.087;stroke-opacity:1"
id="path2283"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path2351"
d="M 4.6789148,3.8638581 6.5936823,6.200326 4.9999674,7.512026 7.0448877,10.007103 8.6388709,8.6952013 10.553866,11.032019 11.16251,4.529541 Z"
style="vector-effect:none;fill:#293252;fill-opacity:1;fill-rule:nonzero;stroke:#7786bb;stroke-width:0.827338;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;paint-order:normal" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.svg-56083ea2a1f1a4f1e49773bdc6d7826c.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/icon.svg"
dest_files=[ "res://.import/icon.svg-56083ea2a1f1a4f1e49773bdc6d7826c.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/background.png-dde469fb1f19281f3784b52d4bea96cd.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/sprites/background.png"
dest_files=[ "res://.import/background.png-dde469fb1f19281f3784b52d4bea96cd.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

View File

@ -1,8 +0,0 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://assets/theme/fonts/montserrat/Montserrat-Medium.ttf" type="DynamicFontData" id=1]
[resource]
size = 26
use_filter = true
font_data = ExtResource( 1 )

View File

@ -1,8 +0,0 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://assets/theme/fonts/montserrat/Montserrat-Bold.ttf" type="DynamicFontData" id=1]
[resource]
size = 26
use_filter = true
font_data = ExtResource( 1 )

View File

@ -1,8 +0,0 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://assets/theme/fonts/source_code_pro/SourceCodePro-Medium.otf" type="DynamicFontData" id=1]
[resource]
size = 26
use_filter = true
font_data = ExtResource( 1 )

View File

@ -1,8 +0,0 @@
[gd_resource type="DynamicFont" load_steps=2 format=2]
[ext_resource path="res://assets/theme/fonts/montserrat/Montserrat-Black.ttf" type="DynamicFontData" id=1]
[resource]
size = 34
use_filter = true
font_data = ExtResource( 1 )

Binary file not shown.

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right"><polyline points="9 18 15 12 9 6"></polyline></svg>

Before

Width:  |  Height:  |  Size: 270 B

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/chevron-right.svg-f77dee7a088177a2ac1d467f4c7cd3e1.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/theme/icons/chevron-right.svg"
dest_files=[ "res://.import/chevron-right.svg-f77dee7a088177a2ac1d467f4c7cd3e1.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-up"><polyline points="18 15 12 9 6 15"></polyline></svg>

Before

Width:  |  Height:  |  Size: 268 B

View File

@ -1,34 +0,0 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/chevron-up.svg-48b5b69265734774d0a7516dcc6f0863.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/theme/icons/chevron-up.svg"
dest_files=[ "res://.import/chevron-up.svg-48b5b69265734774d0a7516dcc6f0863.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@ -1,5 +0,0 @@
[gd_resource type="StyleBoxLine" format=2]
[resource]
color = Color( 1, 1, 1, 0.196078 )
thickness = 2

View File

@ -1,7 +0,0 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
[resource]
background_mode = 2
background_sky = SubResource( 1 )

View File

@ -1,51 +0,0 @@
extends Node
export (float, 0, 3200, 100) var linear_speed_max := 800.0 setget set_linear_speed_max
export (float, 0, 10000, 100) var linear_acceleration_max := 80.0 setget set_linear_acceleration_max
export (float, 0, 100, 0.1) var arrival_tolerance := 25.0 setget set_arrival_tolerance
export (float, 0, 500, 10) var deceleration_radius := 125.0 setget set_deceleration_radius
onready var arriver := $Arriver
onready var target_drawer := $TargetDrawer
func _ready() -> void:
arriver.setup(linear_speed_max, linear_acceleration_max, arrival_tolerance, deceleration_radius)
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.is_pressed():
arriver.target.position = Vector3(event.position.x, event.position.y, 0)
target_drawer.update()
func set_arrival_tolerance(value: float) -> void:
arrival_tolerance = value
if not is_inside_tree():
return
arriver.arrive.arrival_tolerance = value
func set_deceleration_radius(value: float) -> void:
deceleration_radius = value
if not is_inside_tree():
return
arriver.arrive.deceleration_radius = value
func set_linear_speed_max(value: float) -> void:
linear_speed_max = value
if not is_inside_tree():
return
arriver.agent.linear_speed_max = value
func set_linear_acceleration_max(value: float) -> void:
linear_acceleration_max = value
if not is_inside_tree():
return
arriver.agent.linear_acceleration_max = value

View File

@ -1,39 +0,0 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://demos/Arrive/Arriver.gd" type="Script" id=1]
[ext_resource path="res://demos/Utils/DemoInterface.tscn" type="PackedScene" id=2]
[ext_resource path="res://demos/Arrive/ArriveDemo.gd" type="Script" id=3]
[ext_resource path="res://demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=4]
[ext_resource path="res://demos/Arrive/TargetDrawer.gd" type="Script" id=5]
[ext_resource path="res://demos/Utils/CircleDraw.gd" type="Script" id=6]
[sub_resource type="CircleShape2D" id=1]
radius = 23.2163
[node name="ArriveDemo" type="Node"]
script = ExtResource( 3 )
linear_speed_max = 1600.0
linear_acceleration_max = 5000.0
arrival_tolerance = 35.0
deceleration_radius = 180.0
[node name="BackgroudLayer" parent="." instance=ExtResource( 4 )]
[node name="TargetDrawer" type="Node2D" parent="."]
script = ExtResource( 5 )
[node name="Arriver" type="KinematicBody2D" parent="."]
show_behind_parent = true
position = Vector2( 960, 540 )
script = ExtResource( 1 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="Arriver"]
shape = SubResource( 1 )
script = ExtResource( 6 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
outer_color = Color( 0.560784, 0.870588, 0.364706, 1 )
stroke = 6.0
[node name="DemoInterface" parent="." instance=ExtResource( 2 )]
text_bbcode = "Arrive Demo
Mouse click to make the [color=lime]green \"Player\"[/color] move to the [color=fuchsia]purple target[/color]"

View File

@ -1,28 +0,0 @@
extends KinematicBody2D
var agent := GSAIKinematicBody2DAgent.new(self)
var target := GSAIAgentLocation.new()
var arrive := GSAIArrive.new(agent, target)
var _accel := GSAITargetAcceleration.new()
var _velocity := Vector2()
var _drag := 0.1
func _physics_process(delta: float) -> void:
arrive.calculate_steering(_accel)
agent._apply_steering(_accel, delta)
func setup(
linear_speed_max: float,
linear_acceleration_max: float,
arrival_tolerance: float,
deceleration_radius: float
) -> void:
agent.linear_speed_max = linear_speed_max
agent.linear_acceleration_max = linear_acceleration_max
agent.linear_drag_percentage = _drag
arrive.deceleration_radius = deceleration_radius
arrive.arrival_tolerance = arrival_tolerance
target.position = agent.position

View File

@ -1,19 +0,0 @@
extends Node2D
const COLORS := {
deceleration_radius = Color(1.0, 0.419, 0.592, 0.5),
arrival_tolerance = Color(0.278, 0.231, 0.47, 0.3)
}
var arriver: Node2D
func _ready() -> void:
yield(owner, "ready")
arriver = owner.arriver
func _draw():
var target_position := GSAIUtils.to_vector2(arriver.target.position)
draw_circle(target_position, owner.deceleration_radius, COLORS.deceleration_radius)
draw_circle(target_position, owner.arrival_tolerance, COLORS.arrival_tolerance)

View File

@ -1,96 +0,0 @@
[gd_scene load_steps=14 format=2]
[ext_resource path="res://demos/Utils/DemoInterface.tscn" type="PackedScene" id=1]
[ext_resource path="res://demos/Arrive3d/Camera.gd" type="Script" id=2]
[ext_resource path="res://demos/Arrive3d/Seek3dDemo.gd" type="Script" id=3]
[ext_resource path="res://demos/Arrive3d/Seeker.gd" type="Script" id=4]
[ext_resource path="res://demos/Arrive3d/SeekerMat.tres" type="Material" id=5]
[sub_resource type="CapsuleShape" id=1]
[sub_resource type="CapsuleMesh" id=2]
[sub_resource type="CubeMesh" id=3]
material = ExtResource( 5 )
size = Vector3( 0.5, 0.5, 1 )
[sub_resource type="CylinderMesh" id=4]
top_radius = 2.0
bottom_radius = 2.0
height = 0.1
[sub_resource type="SpatialMaterial" id=5]
albedo_color = Color( 0.945098, 0.85098, 0.0745098, 1 )
[sub_resource type="BoxShape" id=6]
extents = Vector3( 1000, 0.1, 1000 )
[sub_resource type="PlaneMesh" id=7]
size = Vector2( 250, 250 )
[sub_resource type="SpatialMaterial" id=8]
albedo_color = Color( 0.0941176, 0.235294, 0.486275, 1 )
[node name="Arrive3dDemo" type="Node"]
script = ExtResource( 3 )
linear_speed_max = 50.0
linear_acceleration_max = 53.2
deceleration_radius = 10.8
angular_speed_max = 550
angular_accel_max = 910
[node name="Arriver" type="KinematicBody" parent="."]
script = ExtResource( 4 )
[node name="CollisionShape" type="CollisionShape" parent="Arriver"]
transform = Transform( 1, 0, 0, 0, -1.62921e-07, 1, 0, -1, -1.62921e-07, 0, 1.5, 0 )
shape = SubResource( 1 )
[node name="Capsule" type="MeshInstance" parent="Arriver"]
transform = Transform( 1, 0, 0, 0, -1.62921e-07, 1, 0, -1, -1.62921e-07, 0, 1.5, 0 )
mesh = SubResource( 2 )
material/0 = ExtResource( 5 )
[node name="Nose" type="MeshInstance" parent="Arriver"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 1.25 )
mesh = SubResource( 3 )
material/0 = null
[node name="Camera" type="Camera" parent="."]
transform = Transform( 0.989952, 0.0720094, -0.121693, 0.0339305, 0.714503, 0.69881, 0.137271, -0.695917, 0.70488, -7.68317, 14.1265, 25.616 )
current = true
script = ExtResource( 2 )
[node name="RayCast" type="RayCast" parent="Camera"]
enabled = true
cast_to = Vector3( -627, 200, -777 )
collision_mask = 2
[node name="MouseTarget" type="Spatial" parent="."]
transform = Transform( 1, 0, 7.45058e-09, 0, 1, 0, 7.45058e-09, 0, 1, -4.76837e-07, 9.53674e-07, 1.90735e-06 )
[node name="MeshInstance" type="MeshInstance" parent="MouseTarget"]
mesh = SubResource( 4 )
material/0 = SubResource( 5 )
[node name="StaticBody" type="StaticBody" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.1, 0 )
collision_layer = 2
collision_mask = 2
[node name="CollisionShape" type="CollisionShape" parent="StaticBody"]
shape = SubResource( 6 )
[node name="Ground" type="MeshInstance" parent="."]
mesh = SubResource( 7 )
material/0 = SubResource( 8 )
[node name="DirectionalLight" type="DirectionalLight" parent="."]
transform = Transform( -0.588165, 0.462179, -0.663666, -0.804031, -0.245728, 0.541436, 0.087159, 0.852061, 0.516134, -17.6076, 12.1748, 0 )
light_energy = 0.5
shadow_enabled = true
[node name="DemoInterface" parent="." instance=ExtResource( 1 )]
mouse_filter = 2
text_bbcode = "3D Arrive Demo
Move the mouse about the field to have the agent turn towards and smoothly arrive at the target marker."

View File

@ -1,24 +0,0 @@
extends Camera
var target: Spatial
onready var ray := $RayCast
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
_set_target_position(event.position)
func setup(_target: Spatial) -> void:
self.target = _target
_set_target_position(get_viewport().get_mouse_position())
func _set_target_position(position: Vector2) -> void:
var to = project_local_ray_normal(position) * 10000
ray.cast_to = to
ray.force_raycast_update()
if ray.is_colliding():
var point = ray.get_collision_point()
target.transform.origin = point

View File

@ -1,92 +0,0 @@
extends Node
export (float, 0, 100, 5) var linear_speed_max := 10.0 setget set_linear_speed_max
export (float, 0, 100, 0.1) var linear_acceleration_max := 1.0 setget set_linear_acceleration_max
export (float, 0, 50, 0.1) var arrival_tolerance := 0.5 setget set_arrival_tolerance
export (float, 0, 50, 0.1) var deceleration_radius := 5.0 setget set_deceleration_radius
export (int, 0, 1080, 10) var angular_speed_max := 270 setget set_angular_speed_max
export (int, 0, 2048, 10) var angular_accel_max := 45 setget set_angular_accel_max
export (int, 0, 178, 2) var align_tolerance := 5 setget set_align_tolerance
export (int, 0, 180, 2) var angular_deceleration_radius := 45 setget set_angular_deceleration_radius
onready var target := $MouseTarget
onready var arriver := $Arriver
func _ready() -> void:
arriver.setup(
deg2rad(align_tolerance),
deg2rad(angular_deceleration_radius),
deg2rad(angular_accel_max),
deg2rad(angular_speed_max),
deceleration_radius,
arrival_tolerance,
linear_acceleration_max,
linear_speed_max,
target
)
$Camera.setup(target)
func set_align_tolerance(value: int) -> void:
align_tolerance = value
if not is_inside_tree():
return
arriver.face.alignment_tolerance = deg2rad(value)
func set_angular_deceleration_radius(value: int) -> void:
deceleration_radius = value
if not is_inside_tree():
return
arriver.face.deceleration_radius = deg2rad(value)
func set_angular_accel_max(value: int) -> void:
angular_accel_max = value
if not is_inside_tree():
return
arriver.agent.angular_acceleration_max = deg2rad(value)
func set_angular_speed_max(value: int) -> void:
angular_speed_max = value
if not is_inside_tree():
return
arriver.agent.angular_speed_max = deg2rad(value)
func set_arrival_tolerance(value: float) -> void:
arrival_tolerance = value
if not is_inside_tree():
return
arriver.arrive.arrival_tolerance = value
func set_deceleration_radius(value: float) -> void:
deceleration_radius = value
if not is_inside_tree():
return
arriver.arrive.deceleration_radius = value
func set_linear_speed_max(value: float) -> void:
linear_speed_max = value
if not is_inside_tree():
return
arriver.agent.linear_speed_max = value
func set_linear_acceleration_max(value: float) -> void:
linear_acceleration_max = value
if not is_inside_tree():
return
arriver.agent.linear_acceleration_max = value

View File

@ -1,47 +0,0 @@
extends KinematicBody
var target_node: Spatial
onready var agent := GSAIKinematicBody3DAgent.new(self)
onready var target := GSAIAgentLocation.new()
onready var accel := GSAITargetAcceleration.new()
onready var blend := GSAIBlend.new(agent)
onready var face := GSAIFace.new(agent, target, true)
onready var arrive := GSAIArrive.new(agent, target)
func _physics_process(delta: float) -> void:
target.position = target_node.transform.origin
target.position.y = transform.origin.y
blend.calculate_steering(accel)
agent._apply_steering(accel, delta)
func setup(
align_tolerance: float,
angular_deceleration_radius: float,
angular_accel_max: float,
angular_speed_max: float,
deceleration_radius: float,
arrival_tolerance: float,
linear_acceleration_max: float,
linear_speed_max: float,
_target: Spatial
) -> void:
agent.linear_speed_max = linear_speed_max
agent.linear_acceleration_max = linear_acceleration_max
agent.linear_drag_percentage = 0.05
agent.angular_acceleration_max = angular_accel_max
agent.angular_speed_max = angular_speed_max
agent.angular_drag_percentage = 0.1
arrive.arrival_tolerance = arrival_tolerance
arrive.deceleration_radius = deceleration_radius
face.alignment_tolerance = align_tolerance
face.deceleration_radius = angular_deceleration_radius
target_node = _target
self.target.position = target_node.transform.origin
blend.add(arrive, 1)
blend.add(face, 1)

View File

@ -1,4 +0,0 @@
[gd_resource type="SpatialMaterial" format=2]
[resource]
albedo_color = Color( 0.152941, 0.764706, 0.247059, 1 )

View File

@ -1,40 +0,0 @@
extends Node
export (float, 0, 1000, 40) var linear_speed_max := 350.0 setget set_linear_speed_max
export (float, 0, 4000, 2) var linear_acceleration_max := 40.0 setget set_linear_accel_max
export (float, 0, 500, 10) var proximity_radius := 140.0 setget set_proximity_radius
export var draw_proximity := true setget set_draw_proximity
onready var spawner := $Spawner
func set_linear_speed_max(value: float) -> void:
linear_speed_max = value
if not is_inside_tree():
return
spawner.set_linear_speed_max(value)
func set_linear_accel_max(value: float) -> void:
linear_acceleration_max = value
if not is_inside_tree():
return
spawner.set_linear_accel_max(value)
func set_proximity_radius(value: float) -> void:
proximity_radius = value
if not is_inside_tree():
return
spawner.set_proximity_radius(value)
func set_draw_proximity(value: bool) -> void:
draw_proximity = value
if not is_inside_tree():
return
spawner.set_draw_proximity(value)

View File

@ -1,26 +0,0 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://demos/AvoidCollisions/Spawner.gd" type="Script" id=1]
[ext_resource path="res://demos/AvoidCollisions/AvoidCollisionsDemo.gd" type="Script" id=2]
[ext_resource path="res://demos/AvoidCollisions/Avoider.tscn" type="PackedScene" id=3]
[ext_resource path="res://demos/Utils/DemoInterface.tscn" type="PackedScene" id=4]
[ext_resource path="res://demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=5]
[node name="AvoidCollisionsDemo" type="Node"]
script = ExtResource( 2 )
linear_speed_max = 520.0
linear_acceleration_max = 2250.0
proximity_radius = 100.0
[node name="BackgroudLayer" parent="." instance=ExtResource( 5 )]
[node name="Spawner" type="Node2D" parent="."]
script = ExtResource( 1 )
avoider_template = ExtResource( 3 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
outer_color = Color( 0.560784, 0.870588, 0.364706, 1 )
agent_count = 80
[node name="DemoInterface" parent="." instance=ExtResource( 4 )]
text_bbcode = "Avoid Collisions Demo
Watch each agent try to keep traveling in a particular direction, but prioritize avoiding collisions with other agents."

View File

@ -1,91 +0,0 @@
extends KinematicBody2D
var draw_proximity: bool
var _boundary_right: float
var _boundary_bottom: float
var _radius: float
var _accel := GSAITargetAcceleration.new()
var _velocity := Vector2.ZERO
var _direction := Vector2()
var _drag := 0.1
var _color := Color(0.4, 1.0, 0.89, 0.3)
onready var collision := $CollisionShape2D
onready var agent := GSAIKinematicBody2DAgent.new(self)
onready var proximity := GSAIRadiusProximity.new(agent, [], 140)
onready var avoid := GSAIAvoidCollisions.new(agent, proximity)
onready var target := GSAIAgentLocation.new()
onready var seek := GSAISeek.new(agent, target)
onready var priority := GSAIPriority.new(agent, 0.0001)
func _draw() -> void:
if draw_proximity:
draw_circle(Vector2.ZERO, proximity.radius, _color)
func _physics_process(delta: float) -> void:
target.position.x = agent.position.x + _direction.x * _radius
target.position.y = agent.position.y + _direction.y * _radius
priority.calculate_steering(_accel)
agent._apply_steering(_accel, delta)
func setup(
linear_speed_max: float,
linear_accel_max: float,
proximity_radius: float,
boundary_right: float,
boundary_bottom: float,
_draw_proximity: bool,
rng: RandomNumberGenerator
) -> void:
rng.randomize()
_direction = Vector2(rng.randf_range(-1, 1), rng.randf_range(-1, 1)).normalized()
agent.linear_speed_max = linear_speed_max
agent.linear_acceleration_max = linear_accel_max
proximity.radius = proximity_radius
_boundary_bottom = boundary_bottom
_boundary_right = boundary_right
_radius = collision.shape.radius
agent.bounding_radius = _radius
agent.linear_drag_percentage = _drag
self.draw_proximity = _draw_proximity
priority.add(avoid)
priority.add(seek)
func set_proximity_agents(agents: Array) -> void:
proximity.agents = agents
func set_random_nonoverlapping_position(others: Array, distance_from_boundary_min: float) -> void:
var rng := RandomNumberGenerator.new()
rng.randomize()
var tries_max := max(100, others.size() * others.size())
while tries_max > 0:
tries_max -= 1
global_position.x = rng.randf_range(
distance_from_boundary_min, _boundary_right - distance_from_boundary_min
)
global_position.y = rng.randf_range(
distance_from_boundary_min, _boundary_bottom - distance_from_boundary_min
)
var done := true
for i in range(others.size()):
var other: Node2D = others[i]
if (
other.global_position.distance_to(position)
<= _radius * 2 + distance_from_boundary_min
):
done = false
if done:
break

View File

@ -1,17 +0,0 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://demos/Utils/CircleDraw.gd" type="Script" id=1]
[ext_resource path="res://demos/AvoidCollisions/Avoider.gd" type="Script" id=2]
[sub_resource type="CircleShape2D" id=1]
radius = 21.3503
[node name="Avoider" type="KinematicBody2D"]
script = ExtResource( 2 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource( 1 )
script = ExtResource( 1 )
inner_color = Color( 0.890196, 0.411765, 0.337255, 1 )
outer_color = Color( 1, 0.709804, 0.439216, 1 )
stroke = 5.0

View File

@ -1,66 +0,0 @@
extends Node2D
export var avoider_template: PackedScene
export var inner_color := Color()
export var outer_color := Color()
export var agent_count := 60
var boundaries: Vector2
func _ready() -> void:
boundaries = Vector2(
ProjectSettings["display/window/size/width"], ProjectSettings["display/window/size/height"]
)
var rng := RandomNumberGenerator.new()
var avoiders := []
var avoider_agents := []
for i in range(agent_count):
var avoider := avoider_template.instance()
add_child(avoider)
avoider.setup(
owner.linear_speed_max,
owner.linear_acceleration_max,
owner.proximity_radius,
boundaries.x,
boundaries.y,
true if i == 0 and owner.draw_proximity else false,
rng
)
avoider_agents.append(avoider.agent)
avoider.set_random_nonoverlapping_position(avoiders, 16)
if i == 0:
avoider.collision.inner_color = inner_color
avoider.collision.outer_color = outer_color
avoiders.append(avoider)
if i % 10 == 0:
yield(get_tree(), "idle_frame")
for child in get_children():
child.set_proximity_agents(avoider_agents)
func _physics_process(_delta: float) -> void:
for child in get_children():
child.global_position = child.global_position.posmodv(boundaries)
func set_linear_speed_max(value: float) -> void:
for child in get_children():
child.agent.linear_speed_max = value
func set_linear_accel_max(value: float) -> void:
for child in get_children():
child.agent.linear_acceleration_max = value
func set_proximity_radius(value: float) -> void:
for child in get_children():
child.proximity.radius = value
get_child(0).update()
func set_draw_proximity(value: bool) -> void:
var child := get_child(0)
child.draw_proximity = value
child.update()

View File

@ -1,28 +0,0 @@
class_name DemoPickerUI
extends Control
# warning-ignore:unused_signal
signal demo_requested
var demo_path := "" setget set_demo_path
onready var list: ItemList = $VBoxContainer/ItemList
onready var button: Button = $VBoxContainer/Button
func _ready() -> void:
# warning-ignore:return_value_discarded
list.connect("demo_selected", self, "set_demo_path")
# warning-ignore:return_value_discarded
list.connect("item_activated", self, "_on_ItemList_item_activated")
# warning-ignore:return_value_discarded
button.connect("pressed", self, "emit_signal", ["demo_requested"])
demo_path = list.file_paths[0]
func set_demo_path(value: String) -> void:
demo_path = value
func _on_ItemList_item_activated(_index: int) -> void:
emit_signal("demo_requested")

View File

@ -1,16 +0,0 @@
extends Node2D
func load_demo(scene_path: String) -> void:
if not scene_path:
return
var demo = load(scene_path)
if demo:
add_child(demo.instance())
func unload() -> void:
for node in get_children():
call_deferred("remove_child", node)
node.queue_free()

View File

@ -1,84 +0,0 @@
[gd_scene load_steps=7 format=2]
[ext_resource path="res://demos/PopulateItemList.gd" type="Script" id=1]
[ext_resource path="res://assets/theme/gdquest.theme" type="Theme" id=2]
[ext_resource path="res://assets/sprites/background.png" type="Texture" id=3]
[ext_resource path="res://demos/DemoPickerUI.gd" type="Script" id=4]
[ext_resource path="res://demos/DemoPlayer.gd" type="Script" id=5]
[ext_resource path="res://demos/Demos.gd" type="Script" id=6]
[node name="Demos" type="Node"]
script = ExtResource( 6 )
[node name="DemoPlayer" type="Node2D" parent="."]
script = ExtResource( 5 )
[node name="DemoPickerUI" type="Control" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
theme = ExtResource( 2 )
script = ExtResource( 4 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="TextureRect" type="TextureRect" parent="DemoPickerUI"]
anchor_right = 1.0
anchor_bottom = 1.0
rect_min_size = Vector2( 1024, 600 )
size_flags_horizontal = 3
size_flags_vertical = 3
texture = ExtResource( 3 )
expand = true
stretch_mode = 2
[node name="VBoxContainer" type="VBoxContainer" parent="DemoPickerUI"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -341.0
margin_top = -290.0
margin_right = 341.0
margin_bottom = 290.0
rect_min_size = Vector2( 682, 0 )
size_flags_horizontal = 3
size_flags_vertical = 3
alignment = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ItemList" type="ItemList" parent="DemoPickerUI/VBoxContainer"]
margin_top = 231.0
margin_right = 682.0
margin_bottom = 240.0
auto_height = true
script = ExtResource( 1 )
[node name="Button" type="Button" parent="DemoPickerUI/VBoxContainer"]
margin_left = 201.0
margin_top = 248.0
margin_right = 481.0
margin_bottom = 348.0
rect_min_size = Vector2( 280, 100 )
size_flags_horizontal = 4
size_flags_vertical = 13
text = "Load scene"
[node name="ButtonGoBack" type="Button" parent="."]
visible = false
anchor_top = 1.0
anchor_bottom = 1.0
margin_left = 48.0
margin_top = -156.0
margin_right = 328.0
margin_bottom = -56.0
rect_min_size = Vector2( 280, 100 )
size_flags_horizontal = 4
size_flags_vertical = 13
theme = ExtResource( 2 )
text = "Go back"
__meta__ = {
"_edit_use_anchors_": false
}

View File

@ -1,30 +0,0 @@
extends Node
onready var demo_picker: DemoPickerUI = $DemoPickerUI
onready var demo_player := $DemoPlayer
onready var button_go_back: Button = $ButtonGoBack
func _ready() -> void:
# warning-ignore:return_value_discarded
demo_picker.connect("demo_requested", self, "_on_DemoPickerUI_demo_requested")
# warning-ignore:return_value_discarded
button_go_back.connect("pressed", self, "_on_ButtonGoBack_pressed")
func _input(event: InputEvent) -> void:
if event.is_action_pressed("toggle_fullscreen"):
OS.window_fullscreen = not OS.window_fullscreen
get_tree().set_input_as_handled()
func _on_DemoPickerUI_demo_requested() -> void:
demo_player.load_demo(demo_picker.demo_path)
demo_picker.hide()
button_go_back.show()
func _on_ButtonGoBack_pressed() -> void:
demo_player.unload()
button_go_back.hide()
demo_picker.show()

View File

@ -1,61 +0,0 @@
extends Node
export (int, 0, 1080, 2) var angular_speed_max := 120 setget set_angular_speed_max
export (int, 0, 2048, 2) var angular_accel_max := 10 setget set_angular_accel_max
export (int, 0, 180, 2) var align_tolerance := 5 setget set_align_tolerance
export (int, 0, 359, 2) var deceleration_radius := 45 setget set_deceleration_radius
export (float, 0, 1000, 40) var player_speed := 600.0 setget set_player_speed
onready var player := $Player
onready var turret := $Turret
func _ready() -> void:
player.speed = player_speed
turret.setup(
player.agent,
deg2rad(align_tolerance),
deg2rad(deceleration_radius),
deg2rad(angular_accel_max),
deg2rad(angular_speed_max)
)
func set_align_tolerance(value: int) -> void:
align_tolerance = value
if not is_inside_tree():
return
turret.face.alignment_tolerance = deg2rad(value)
func set_deceleration_radius(value: int) -> void:
deceleration_radius = value
if not is_inside_tree():
return
turret.face.deceleration_radius = deg2rad(value)
func set_angular_accel_max(value: int) -> void:
angular_accel_max = value
if not is_inside_tree():
return
turret.agent.angular_acceleration_max = deg2rad(value)
func set_angular_speed_max(value: int) -> void:
angular_speed_max = value
if not is_inside_tree():
return
turret.agent.angular_speed_max = deg2rad(value)
func set_player_speed(value: float) -> void:
player_speed = value
if not is_inside_tree():
return
player.speed = player_speed

View File

@ -1,48 +0,0 @@
[gd_scene load_steps=9 format=2]
[ext_resource path="res://demos/Face/Turret.gd" type="Script" id=1]
[ext_resource path="res://demos/Face/FaceDemo.gd" type="Script" id=2]
[ext_resource path="res://demos/Face/Player.gd" type="Script" id=3]
[ext_resource path="res://demos/Utils/DemoInterface.tscn" type="PackedScene" id=4]
[ext_resource path="res://demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=5]
[ext_resource path="res://demos/Utils/CircleDraw.gd" type="Script" id=8]
[sub_resource type="CircleShape2D" id=1]
radius = 20.2633
[sub_resource type="CircleShape2D" id=2]
radius = 37.1052
[node name="FaceDemo" type="Node"]
script = ExtResource( 2 )
angular_speed_max = 662
angular_accel_max = 924
deceleration_radius = 136
[node name="BackgroudLayer" parent="." instance=ExtResource( 5 )]
[node name="Player" type="KinematicBody2D" parent="."]
position = Vector2( 687.363, 351.005 )
script = ExtResource( 3 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="Player"]
shape = SubResource( 1 )
script = ExtResource( 8 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
outer_color = Color( 0.560784, 0.870588, 0.364706, 1 )
stroke = 6.0
[node name="Turret" type="KinematicBody2D" parent="."]
position = Vector2( 984.348, 571.959 )
script = ExtResource( 1 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="Turret"]
shape = SubResource( 2 )
script = ExtResource( 8 )
inner_color = Color( 0.890196, 0.411765, 0.337255, 1 )
outer_color = Color( 1, 0.709804, 0.439216, 1 )
stroke = 8.0
[node name="DemoInterface" parent="." instance=ExtResource( 4 )]
text_bbcode = "Face Demo
Move the [color=lime]green player[/color] around with WASD and notice the [color=#ffb570]orange turret[/color] orient itself"

View File

@ -1,18 +0,0 @@
extends KinematicBody2D
var speed: float
onready var agent := GSAIAgentLocation.new()
func _physics_process(_delta: float) -> void:
var movement := _get_movement()
move_and_slide(movement * speed)
agent.position = Vector3(global_position.x, global_position.y, 0)
func _get_movement() -> Vector2:
return Vector2(
Input.get_action_strength("sf_right") - Input.get_action_strength("sf_left"),
Input.get_action_strength("sf_down") - Input.get_action_strength("sf_up")
)

View File

@ -1,43 +0,0 @@
extends KinematicBody2D
var face: GSAIFace
var agent := GSAIKinematicBody2DAgent.new(self)
var _accel := GSAITargetAcceleration.new()
var _angular_drag := 0.1
var _cannon: Rect2
var _color: Color
onready var collision_shape := $CollisionShape2D
func _ready() -> void:
var radius = collision_shape.shape.radius
_cannon = Rect2(Vector2(-5, 0), Vector2(10, -radius * 2))
_color = collision_shape.outer_color
func _physics_process(delta: float) -> void:
face.calculate_steering(_accel)
agent._apply_steering(_accel, delta)
func _draw() -> void:
draw_rect(_cannon, _color)
func setup(
player_agent: GSAIAgentLocation,
align_tolerance: float,
deceleration_radius: float,
angular_accel_max: float,
angular_speed_max: float
) -> void:
face = GSAIFace.new(agent, player_agent)
face.alignment_tolerance = align_tolerance
face.deceleration_radius = deceleration_radius
agent.angular_acceleration_max = angular_accel_max
agent.angular_speed_max = angular_speed_max
agent.angular_drag_percentage = _angular_drag

View File

@ -1,53 +0,0 @@
extends Node2D
signal path_established(points)
var active_points := []
var is_drawing := false
var distance_threshold := 100.0
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
if is_drawing:
active_points.append(event.position)
update()
elif event is InputEventMouseButton:
if event.pressed and event.button_index == BUTTON_LEFT:
active_points.clear()
active_points.append(event.position)
is_drawing = true
update()
elif not event.pressed:
is_drawing = false
if active_points.size() >= 2:
_simplify()
func _draw() -> void:
if is_drawing:
for point in active_points:
draw_circle(point, 2, Color.red)
else:
if active_points.size() > 0:
draw_circle(active_points.front(), 2, Color.red)
draw_circle(active_points.back(), 2, Color.yellow)
draw_polyline(active_points, Color.skyblue, 1.0)
func _simplify() -> void:
var first: Vector2 = active_points.front()
var last: Vector2 = active_points.back()
var key := first
var simplified_path := [first]
for i in range(1, active_points.size()):
var point: Vector2 = active_points[i]
var distance := point.distance_to(key)
if distance > distance_threshold:
key = point
simplified_path.append(key)
active_points = simplified_path
if active_points.back() != last:
active_points.append(last)
update()
emit_signal("path_established", active_points)

View File

@ -1,70 +0,0 @@
extends Node
export (float, 0, 2000, 40) var linear_speed_max := 600.0 setget set_linear_speed_max
export (float, 0, 9000, 10.0) var linear_acceleration_max := 40.0 setget set_linear_acceleration_max
export (float, 0, 100, 0.1) var arrival_tolerance := 10.0 setget set_arrival_tolerance
export (float, 0, 500, 10) var deceleration_radius := 100.0 setget set_deceleration_radius
export (float, 0, 5, 0.1) var predict_time := 0.3 setget set_predict_time
export (float, 0, 200, 10.0) var path_offset := 20.0 setget set_path_offset
onready var drawer := $Drawer
onready var follower := $PathFollower
func _ready() -> void:
follower.setup(
path_offset,
predict_time,
linear_acceleration_max,
linear_speed_max,
deceleration_radius,
arrival_tolerance
)
func set_linear_speed_max(value: float) -> void:
linear_speed_max = value
if not is_inside_tree():
return
follower.agent.linear_speed_max = value
func set_linear_acceleration_max(value: float) -> void:
linear_acceleration_max = value
if not is_inside_tree():
return
follower.agent.linear_acceleration_max = value
func set_arrival_tolerance(value: float) -> void:
arrival_tolerance = value
if not is_inside_tree():
return
follower.follow.arrival_tolerance = value
func set_deceleration_radius(value: float) -> void:
deceleration_radius = value
if not is_inside_tree():
return
follower.follow.deceleration_radius = value
func set_predict_time(value: float) -> void:
predict_time = value
if not is_inside_tree():
return
follower.follow.prediction_time = value
func set_path_offset(value: float) -> void:
path_offset = value
if not is_inside_tree():
return
follower.follow.path_offset = value

View File

@ -1,37 +0,0 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://demos/FollowPath/Drawer.gd" type="Script" id=1]
[ext_resource path="res://demos/Utils/DemoInterface.tscn" type="PackedScene" id=2]
[ext_resource path="res://demos/FollowPath/PathFollower.gd" type="Script" id=3]
[ext_resource path="res://demos/FollowPath/FollowPathDemo.gd" type="Script" id=4]
[ext_resource path="res://demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=5]
[ext_resource path="res://demos/Utils/CircleDraw.gd" type="Script" id=6]
[sub_resource type="CircleShape2D" id=1]
radius = 24.1954
[node name="FollowPathDemo" type="Node"]
script = ExtResource( 4 )
linear_speed_max = 920.0
linear_acceleration_max = 3740.0
deceleration_radius = 200.0
[node name="BackgroudLayer" parent="." instance=ExtResource( 5 )]
[node name="Drawer" type="Node2D" parent="."]
script = ExtResource( 1 )
[node name="PathFollower" type="KinematicBody2D" parent="."]
position = Vector2( 960, 540 )
script = ExtResource( 3 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="PathFollower"]
shape = SubResource( 1 )
script = ExtResource( 6 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
outer_color = Color( 0.560784, 0.870588, 0.364706, 1 )
stroke = 6.0
[node name="DemoInterface" parent="." instance=ExtResource( 2 )]
text_bbcode = "Follow Path Demo
Use the mouse to draw a path on screen and watch the [color=lime]green \"Agent\"[/color] follow it to the end."

View File

@ -1,49 +0,0 @@
extends KinematicBody2D
var _velocity := Vector2.ZERO
var _accel := GSAITargetAcceleration.new()
var _valid := false
var _drag := 0.1
onready var agent := GSAIKinematicBody2DAgent.new(self)
onready var path := GSAIPath.new(
[
Vector3(global_position.x, global_position.y, 0),
Vector3(global_position.x, global_position.y, 0)
],
true
)
onready var follow := GSAIFollowPath.new(agent, path, 0, 0)
func setup(
path_offset: float,
predict_time: float,
accel_max: float,
speed_max: float,
decel_radius: float,
arrival_tolerance: float
) -> void:
owner.drawer.connect("path_established", self, "_on_Drawer_path_established")
follow.path_offset = path_offset
follow.prediction_time = predict_time
follow.deceleration_radius = decel_radius
follow.arrival_tolerance = arrival_tolerance
agent.linear_acceleration_max = accel_max
agent.linear_speed_max = speed_max
agent.linear_drag_percentage = _drag
func _physics_process(delta: float) -> void:
if _valid:
follow.calculate_steering(_accel)
agent._apply_steering(_accel, delta)
func _on_Drawer_path_established(points: Array) -> void:
var positions := PoolVector3Array()
for p in points:
positions.append(Vector3(p.x, p.y, 0))
path.create_path(positions)
_valid = true

View File

@ -1,79 +0,0 @@
extends Node
onready var spawner := $Spawner
export (float, 0, 2000, 40.0) var linear_speed_max := 600.0 setget set_linear_speed_max
export (float, 0, 9000, 2.0) var linear_accel_max := 40.0 setget set_linear_accel_max
export (float, 0, 300, 2.0) var proximity_radius := 140.0 setget set_proximity_radius
export (float, 0, 200000, 250) var separation_decay_coefficient := 2000.0 setget set_separation_decay_coef
export (float, 0, 2, 0.1) var cohesion_strength := 0.1 setget set_cohesion_strength
export (float, 0, 10, 0.2) var separation_strength := 1.5 setget set_separation_strength
export var show_proximity_radius := true setget set_show_proximity_radius
func _ready() -> void:
spawner.setup(
linear_speed_max,
linear_accel_max,
proximity_radius,
separation_decay_coefficient,
cohesion_strength,
separation_strength,
show_proximity_radius
)
func set_linear_speed_max(value: float) -> void:
linear_speed_max = value
if not is_inside_tree():
return
spawner.set_linear_speed_max(value)
func set_linear_accel_max(value: float) -> void:
linear_accel_max = value
if not is_inside_tree():
return
spawner.set_linear_accel_max(value)
func set_proximity_radius(value: float) -> void:
proximity_radius = value
if not is_inside_tree():
return
spawner.set_proximity_radius(value)
func set_show_proximity_radius(value: bool) -> void:
show_proximity_radius = value
if not is_inside_tree():
return
spawner.set_show_proximity_radius(value)
func set_separation_decay_coef(value: float) -> void:
separation_decay_coefficient = value
if not is_inside_tree():
return
spawner.set_separation_decay_coef(value)
func set_cohesion_strength(value: float) -> void:
cohesion_strength = value
if not is_inside_tree():
return
spawner.set_cohesion_strength(value)
func set_separation_strength(value: float) -> void:
separation_strength = value
if not is_inside_tree():
return
spawner.set_separation_strength(value)

View File

@ -1,26 +0,0 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://demos/GroupBehaviors/Member.tscn" type="PackedScene" id=1]
[ext_resource path="res://demos/GroupBehaviors/Spawner.gd" type="Script" id=2]
[ext_resource path="res://demos/GroupBehaviors/GroupBehaviorsDemo.gd" type="Script" id=3]
[ext_resource path="res://demos/Utils/DemoInterface.tscn" type="PackedScene" id=4]
[ext_resource path="res://demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=5]
[node name="GroupBehaviorsDemo" type="Node"]
script = ExtResource( 3 )
linear_accel_max = 4234.0
proximity_radius = 158.0
separation_decay_coefficient = 121500.0
cohesion_strength = 0.2
separation_strength = 8.8
[node name="BackgroudLayer" parent="." instance=ExtResource( 5 )]
[node name="Spawner" type="Node2D" parent="."]
position = Vector2( 512, 300 )
script = ExtResource( 2 )
member = ExtResource( 1 )
[node name="DemoInterface" parent="." instance=ExtResource( 4 )]
text_bbcode = "Group Behavior Demo
Each of the \"Agents\" are both attempting to stay separated from each other but within reach of their nearest group's center of mass."

View File

@ -1,52 +0,0 @@
extends KinematicBody2D
var separation: GSAISeparation
var cohesion: GSAICohesion
var proximity: GSAIRadiusProximity
var agent := GSAIKinematicBody2DAgent.new(self)
var blend := GSAIBlend.new(agent)
var acceleration := GSAITargetAcceleration.new()
var draw_proximity := false
var _color := Color.red
var _velocity := Vector2()
onready var collision_shape := $CollisionShape2D
func setup(
linear_speed_max: float,
linear_accel_max: float,
proximity_radius: float,
separation_decay_coefficient: float,
cohesion_strength: float,
separation_strength: float
) -> void:
_color = Color(rand_range(0.5, 1), rand_range(0.25, 1), rand_range(0, 1))
collision_shape.inner_color = _color
agent.linear_acceleration_max = linear_accel_max
agent.linear_speed_max = linear_speed_max
agent.linear_drag_percentage = 0.1
proximity = GSAIRadiusProximity.new(agent, [], proximity_radius)
separation = GSAISeparation.new(agent, proximity)
separation.decay_coefficient = separation_decay_coefficient
cohesion = GSAICohesion.new(agent, proximity)
blend.add(separation, separation_strength)
blend.add(cohesion, cohesion_strength)
func _draw() -> void:
if draw_proximity:
draw_circle(Vector2.ZERO, proximity.radius, Color(0.4, 1.0, 0.89, 0.3))
func _physics_process(delta: float) -> void:
if blend:
blend.calculate_steering(acceleration)
agent._apply_steering(acceleration, delta)
func set_neighbors(neighbor: Array) -> void:
proximity.agents = neighbor

View File

@ -1,16 +0,0 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://demos/GroupBehaviors/Member.gd" type="Script" id=1]
[ext_resource path="res://demos/Utils/CircleDraw.gd" type="Script" id=3]
[sub_resource type="CircleShape2D" id=1]
radius = 16.0
[node name="Member" type="KinematicBody2D"]
script = ExtResource( 1 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource( 1 )
script = ExtResource( 3 )
outer_color = Color( 0.301961, 0.65098, 1, 1 )
stroke = 4.0

View File

@ -1,73 +0,0 @@
extends Node2D
export var member: PackedScene
func setup(
linear_speed_max: float,
linear_accel_max: float,
proximity_radius: float,
separation_decay_coefficient: float,
cohesion_strength: float,
separation_strength: float,
show_proximity_radius: bool
) -> void:
var followers := []
for i in range(19):
var follower := member.instance()
add_child(follower)
follower.position += Vector2(rand_range(-60, 60), rand_range(-60, 60))
followers.append(follower)
follower.setup(
linear_speed_max,
linear_accel_max,
proximity_radius,
separation_decay_coefficient,
cohesion_strength,
separation_strength
)
if i == 0 and show_proximity_radius:
follower.draw_proximity = true
follower.update()
var agents := []
for i in followers:
agents.append(i.agent)
for i in followers:
i.proximity.agents = agents
func set_linear_speed_max(value: float) -> void:
for child in get_children():
child.agent.linear_speed_max = value
func set_linear_accel_max(value: float) -> void:
for child in get_children():
child.agent.linear_acceleration_max = value
func set_proximity_radius(value: float) -> void:
for child in get_children():
child.proximity.radius = value
if child == get_child(0):
child.update()
func set_show_proximity_radius(value: bool) -> void:
get_child(0).draw_proximity = value
get_child(0).update()
func set_separation_decay_coef(value: float) -> void:
for child in get_children():
child.separation.decay_coefficient = value
func set_cohesion_strength(value: float) -> void:
for child in get_children():
child.blend.get_behavior_at(1).weight = value
func set_separation_strength(value: float) -> void:
for child in get_children():
child.blend.get_behavior_at(0).weight = value

View File

@ -1,68 +0,0 @@
extends ItemList
signal demo_selected(scene_path)
var file_paths := PoolStringArray()
func _ready() -> void:
# warning-ignore:return_value_discarded
self.connect("item_selected", self, "_on_item_selected")
var this_directory: String = get_tree().current_scene.filename.rsplit("/", false, 1)[0]
file_paths = _find_files(this_directory, ["*Demo.tscn"], true)
populate(file_paths)
select(0)
func populate(demos: PoolStringArray) -> void:
for path in demos:
var demo_name: String = path.rsplit("/", true, 1)[-1]
demo_name = demo_name.rsplit("Demo", true, 1)[0]
demo_name = sentencify(demo_name)
add_item(demo_name)
func sentencify(line: String) -> String:
var regex := RegEx.new()
# warning-ignore:return_value_discarded
regex.compile("[A-Z]")
line = line.split(".", true, 1)[0]
line = regex.sub(line, " $0", true)
return line
func _find_files(
dirpath := "", patterns := PoolStringArray(), is_recursive := false, do_skip_hidden := true
) -> PoolStringArray:
var paths := PoolStringArray()
var directory := Directory.new()
if not directory.dir_exists(dirpath):
printerr("The directory does not exist: %s" % dirpath)
return paths
if not directory.open(dirpath) == OK:
printerr("Could not open the following dirpath: %s" % dirpath)
return paths
# warning-ignore:return_value_discarded
directory.list_dir_begin(true, do_skip_hidden)
var file_name := directory.get_next()
while file_name != "":
if directory.current_is_dir() and is_recursive:
var subdirectory := dirpath.plus_file(file_name)
paths.append_array(_find_files(subdirectory, patterns, is_recursive))
else:
for pattern in patterns:
if file_name.match(pattern):
paths.append(dirpath.plus_file(file_name))
file_name = directory.get_next()
directory.list_dir_end()
return paths
func _on_item_selected(index: int) -> void:
var demo_path := file_paths[index]
emit_signal("demo_selected", demo_path)

View File

@ -1,15 +0,0 @@
extends Node2D
# Wraps the ships' positions around the world border.
var _world_bounds: Vector2
func _ready() -> void:
_world_bounds = Vector2(
ProjectSettings["display/window/size/width"], ProjectSettings["display/window/size/height"]
)
func _physics_process(_delta: float) -> void:
for ship in get_children():
ship.position = ship.position.posmodv(_world_bounds)

View File

@ -1,96 +0,0 @@
extends KinematicBody2D
# Controls the player ship's movements based on player input.
export var thruster_strength := 175.0
export var side_thruster_strength := 10.0
export var velocity_max := 300.0
export var angular_velocity_max := 2.0
export var angular_drag := 0.025
export var linear_drag := 0.025
var _linear_velocity := Vector2()
var _angular_velocity := 0.0
onready var agent := GSAISteeringAgent.new()
func _physics_process(delta: float) -> void:
var movement := _get_movement()
_angular_velocity = _calculate_angular_velocity(
movement.x,
_angular_velocity,
side_thruster_strength,
angular_velocity_max,
angular_drag,
delta
)
rotation += _angular_velocity * delta
_linear_velocity = _calculate_linear_velocity(
movement.y,
_linear_velocity,
Vector2.UP.rotated(rotation),
linear_drag,
thruster_strength,
velocity_max,
delta
)
_linear_velocity = move_and_slide(_linear_velocity)
_update_agent()
func _calculate_angular_velocity(
horizontal_movement: float,
current_velocity: float,
_thruster_strength: float,
_velocity_max: float,
ship_drag: float,
delta: float
) -> float:
var velocity := clamp(
current_velocity + _thruster_strength * horizontal_movement * delta,
-_velocity_max,
_velocity_max
)
velocity = lerp(velocity, 0, ship_drag)
return velocity
func _calculate_linear_velocity(
vertical_movement: float,
current_velocity: Vector2,
facing_direction: Vector2,
ship_drag_coefficient: float,
strength: float,
speed_max: float,
delta: float
) -> Vector2:
var actual_strength := 0.0
if vertical_movement > 0:
actual_strength = strength
elif vertical_movement < 0:
actual_strength = -strength / 1.5
var velocity := current_velocity + facing_direction * actual_strength * delta
velocity = velocity.linear_interpolate(Vector2.ZERO, ship_drag_coefficient)
return velocity.clamped(speed_max)
func _get_movement() -> Vector2:
return Vector2(
Input.get_action_strength("sf_right") - Input.get_action_strength("sf_left"),
Input.get_action_strength("sf_up") - Input.get_action_strength("sf_down")
)
func _update_agent() -> void:
agent.position.x = global_position.x
agent.position.y = global_position.y
agent.linear_velocity.x = _linear_velocity.x
agent.linear_velocity.y = _linear_velocity.y
agent.angular_velocity = _angular_velocity
agent.orientation = rotation

View File

@ -1,39 +0,0 @@
extends Node
export (float, 0, 2000, 40) var linear_speed_max := 120.0 setget set_linear_speed_max
export (float, 0, 2000, 20) var linear_accel_max := 10.0 setget set_linear_accel_max
export (float, 0, 5, 0.1) var predict_time := 1.0 setget set_predict_time
onready var pursuer := $BoundaryManager/Pursuer
onready var seeker := $BoundaryManager/Seeker
func _ready() -> void:
pursuer.setup(predict_time, linear_speed_max, linear_accel_max)
seeker.setup(predict_time, linear_speed_max, linear_accel_max)
func set_linear_speed_max(value: float) -> void:
linear_speed_max = value
if not is_inside_tree():
return
pursuer.agent.linear_speed_max = value
seeker.agent.linear_speed_max = value
func set_linear_accel_max(value: float) -> void:
linear_accel_max = value
if not is_inside_tree():
return
pursuer.agent.linear_acceleration_max = value
seeker.agent.linear_acceleration_max = value
func set_predict_time(value: float) -> void:
predict_time = value
if not is_inside_tree():
return
pursuer._behavior.predict_time_max = value

View File

@ -1,92 +0,0 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://demos/PursueSeek/Pursuer.gd" type="Script" id=1]
[ext_resource path="res://demos/PursueSeek/Player.gd" type="Script" id=2]
[ext_resource path="res://demos/PursueSeek/BoundaryManager.gd" type="Script" id=3]
[ext_resource path="res://demos/PursueSeek/PursueAndSeekDemo.gd" type="Script" id=4]
[ext_resource path="res://demos/Utils/DemoInterface.tscn" type="PackedScene" id=5]
[ext_resource path="res://demos/Utils/Line2DDraw.gd" type="Script" id=6]
[ext_resource path="res://demos/Utils/BackgroudLayer.tscn" type="PackedScene" id=7]
[node name="PursueVSSeekDemo" type="Node"]
script = ExtResource( 4 )
linear_speed_max = 1280.0
linear_accel_max = 1040.0
predict_time = 1.1
[node name="BackgroudLayer" parent="." instance=ExtResource( 7 )]
[node name="BoundaryManager" type="Node2D" parent="."]
script = ExtResource( 3 )
[node name="Player" type="KinematicBody2D" parent="BoundaryManager"]
position = Vector2( 307.552, 555.999 )
rotation = 1.5708
collision_mask = 2
script = ExtResource( 2 )
__meta__ = {
"_edit_group_": true
}
thruster_strength = 1000.0
side_thruster_strength = 40.0
velocity_max = 450.0
angular_velocity_max = 3.0
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Player"]
polygon = PoolVector2Array( 0, -32, -24, 32, 24, 32 )
[node name="Line2D" type="Line2D" parent="BoundaryManager/Player"]
points = PoolVector2Array( 0, 32, 24, 32, 0, -32, -24, 32, 0, 32 )
width = 8.0
default_color = Color( 0.560784, 0.870588, 0.364706, 1 )
joint_mode = 2
antialiased = true
script = ExtResource( 6 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
[node name="Pursuer" type="KinematicBody2D" parent="BoundaryManager"]
position = Vector2( 1240.22, 866.784 )
collision_layer = 2
script = ExtResource( 1 )
__meta__ = {
"_edit_group_": true
}
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Pursuer"]
polygon = PoolVector2Array( 0, -32, -24, 32, 24, 32 )
[node name="Line2D" type="Line2D" parent="BoundaryManager/Pursuer"]
points = PoolVector2Array( 0, 32, 24, 32, 0, -32, -24, 32, 0, 32 )
width = 8.0
default_color = Color( 1, 0.709804, 0.439216, 1 )
joint_mode = 2
antialiased = true
script = ExtResource( 6 )
inner_color = Color( 0.890196, 0.411765, 0.337255, 1 )
[node name="Seeker" type="KinematicBody2D" parent="BoundaryManager"]
position = Vector2( 1240.22, 280.108 )
rotation = 3.14159
collision_layer = 2
script = ExtResource( 1 )
__meta__ = {
"_edit_group_": true
}
use_seek = true
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="BoundaryManager/Seeker"]
polygon = PoolVector2Array( 0, -32, -24, 32, 24, 32 )
[node name="Line2D" type="Line2D" parent="BoundaryManager/Seeker"]
points = PoolVector2Array( 0, 32, 24, 32, 0, -32, -24, 32, 0, 32 )
width = 8.0
default_color = Color( 0.301961, 0.65098, 1, 1 )
joint_mode = 2
antialiased = true
script = ExtResource( 6 )
inner_color = Color( 0.294118, 0.356863, 0.670588, 1 )
[node name="DemoInterface" parent="." instance=ExtResource( 5 )]
text_bbcode = "Pursue vs. Seek Demo
Move the player around with WASD and notice the [color=#ffb570]orange Pursuer[/color] and the [color=aqua]blue Seeker[/color] follow
the [color=lime]green \"Ship\"[/color] around"

View File

@ -1,65 +0,0 @@
extends KinematicBody2D
# Represents a ship that chases after the player.
export var use_seek: bool = false
var _blend: GSAIBlend
var _linear_drag_coefficient := 0.025
var _angular_drag := 0.1
var _direction_face := GSAIAgentLocation.new()
onready var agent := GSAIKinematicBody2DAgent.new(self)
onready var accel := GSAITargetAcceleration.new()
onready var player_agent: GSAISteeringAgent = owner.find_node("Player", true, false).agent
func _ready() -> void:
agent.calculate_velocities = false
set_physics_process(false)
func _physics_process(delta: float) -> void:
_direction_face.position = agent.position + accel.linear.normalized()
_blend.calculate_steering(accel)
agent.angular_velocity = clamp(
agent.angular_velocity + accel.angular * delta, -agent.angular_speed_max, agent.angular_speed_max
)
agent.angular_velocity = lerp(agent.angular_velocity, 0, _angular_drag)
rotation += agent.angular_velocity * delta
var linear_velocity := (
GSAIUtils.to_vector2(agent.linear_velocity)
+ (GSAIUtils.angle_to_vector2(rotation) * -agent.linear_acceleration_max * delta)
)
linear_velocity = linear_velocity.clamped(agent.linear_speed_max)
linear_velocity = linear_velocity.linear_interpolate(Vector2.ZERO, _linear_drag_coefficient)
linear_velocity = move_and_slide(linear_velocity)
agent.linear_velocity = GSAIUtils.to_vector3(linear_velocity)
func setup(predict_time: float, linear_speed_max: float, linear_accel_max: float) -> void:
var behavior: GSAISteeringBehavior
if use_seek:
behavior = GSAISeek.new(agent, player_agent)
else:
behavior = GSAIPursue.new(agent, player_agent, predict_time)
var orient_behavior := GSAIFace.new(agent, _direction_face)
orient_behavior.alignment_tolerance = deg2rad(5)
orient_behavior.deceleration_radius = deg2rad(30)
_blend = GSAIBlend.new(agent)
_blend.add(behavior, 1)
_blend.add(orient_behavior, 1)
agent.angular_acceleration_max = deg2rad(1080)
agent.angular_speed_max = deg2rad(360)
agent.linear_acceleration_max = linear_accel_max
agent.linear_speed_max = linear_speed_max
set_physics_process(true)

View File

@ -1,167 +0,0 @@
extends KinematicBody2D
# Maximum possible linear velocity
export var speed_max := 450.0
# Maximum change in linear velocity
export var acceleration_max := 50.0
# Maximum rotation velocity represented in degrees
export var angular_speed_max := 240
# Maximum change in rotation velocity represented in degrees
export var angular_acceleration_max := 40
export var health_max := 100
export var flee_health_threshold := 20
var velocity := Vector2.ZERO
var angular_velocity := 0.0
var linear_drag := 0.1
var angular_drag := 0.1
# Holds the linear and angular components calculated by our steering behaviors.
var acceleration := GSAITargetAcceleration.new()
onready var current_health := health_max
# GSAISteeringAgent holds our agent's position, orientation, maximum speed and acceleration.
onready var agent := GSAISteeringAgent.new()
onready var player: Node = get_tree().get_nodes_in_group("Player")[0]
# This assumes that our player class will keep its own agent updated.
onready var player_agent: GSAISteeringAgent = player.agent
# Proximities represent an area with which an agent can identify where neighbors in its relevant
# group are. In our case, the group will feature the player, which will be used to avoid a
# collision with them. We use a radius proximity so the player is only relevant inside 100 pixels.
onready var proximity := GSAIRadiusProximity.new(agent, [player_agent], 100)
# GSAIBlend combines behaviors together, calculating all of their acceleration together and adding
# them together, multiplied by a strength. We will have one for fleeing, and one for pursuing,
# toggling them depending on the agent's health. Since we want the agent to rotate AND move, then
# we aim to blend them together.
onready var flee_blend := GSAIBlend.new(agent)
onready var pursue_blend := GSAIBlend.new(agent)
# GSAIPriority will be the main steering behavior we use. It holds sub-behaviors and will pick the
# first one that returns non-zero acceleration, ignoring any afterwards.
onready var priority := GSAIPriority.new(agent)
func _ready() -> void:
# ---------- Configuration for our agent ----------
agent.linear_speed_max = speed_max
agent.linear_acceleration_max = acceleration_max
agent.angular_speed_max = deg2rad(angular_speed_max)
agent.angular_acceleration_max = deg2rad(angular_acceleration_max)
agent.bounding_radius = calculate_radius($CollisionPolygon2D.polygon)
update_agent()
# ---------- Configuration for our behaviors ----------
# Pursue will happen while the agent is in good health. It produces acceleration that takes
# the agent on an intercept course with the target, predicting its position in the future.
var pursue := GSAIPursue.new(agent, player_agent)
pursue.predict_time_max = 1.5
# Flee will happen while the agent is in bad health, so will start disabled. It produces
# acceleration that takes the agent directly away from the target with no prediction.
var flee := GSAIFlee.new(agent, player_agent)
# AvoidCollision tries to keep the agent from running into any of the neighbors found in its
# proximity group. In our case, this will be the player, if they are close enough.
var avoid := GSAIAvoidCollisions.new(agent, proximity)
# Face turns the agent to keep looking towards its target. It will be enabled while the agent
# is not fleeing due to low health. It tries to arrive 'on alignment' with 0 remaining velocity.
var face := GSAIFace.new(agent, player_agent)
# We use deg2rad because the math in the toolkit assumes radians.
# How close for the agent to be 'aligned', if not exact.
face.alignment_tolerance = deg2rad(5)
# When to start slowing down
face.deceleration_radius = deg2rad(60)
# LookWhereYouGo turns the agent to keep looking towards its direction of travel. It will only
# be enabled while the agent is at low health.
var look := GSAILookWhereYouGo.new(agent)
# How close for the agent to be 'aligned', if not exact
look.alignment_tolerance = deg2rad(5)
# When to start slowing down.
look.deceleration_radius = deg2rad(60)
# Behaviors that are not enabled produce 0 acceleration.
# Adding our fleeing behaviors to a blend. The order does not matter.
flee_blend.is_enabled = false
flee_blend.add(look, 1)
flee_blend.add(flee, 1)
# Adding our pursuit behaviors to a blend. The order does not matter.
pursue_blend.add(face, 1)
pursue_blend.add(pursue, 1)
# Adding our final behaviors to the main priority behavior. The order does matter here.
# We want to avoid collision with the player first, flee from the player second when enabled,
# and pursue the player last when enabled.
priority.add(avoid)
priority.add(flee_blend)
priority.add(pursue_blend)
func _physics_process(delta: float) -> void:
# Make sure any change in position and speed has been recorded.
update_agent()
if current_health <= flee_health_threshold:
pursue_blend.is_enabled = false
flee_blend.is_enabled = true
# Calculate the desired acceleration.
priority.calculate_steering(acceleration)
# We add the discovered acceleration to our linear velocity. The toolkit does not limit
# velocity, just acceleration, so we clamp the result ourselves here.
velocity = (velocity + Vector2(acceleration.linear.x, acceleration.linear.y) * delta).clamped(
agent.linear_speed_max
)
# This applies drag on the agent's motion, helping it to slow down naturally.
velocity = velocity.linear_interpolate(Vector2.ZERO, linear_drag)
# And since we're using a KinematicBody2D, we use Godot's excellent move_and_slide to actually
# apply the final movement, and record any change in velocity the physics engine discovered.
velocity = move_and_slide(velocity)
# We then do something similar to apply our agent's rotational speed.
angular_velocity = clamp(
angular_velocity + acceleration.angular * delta, -agent.angular_speed_max, agent.angular_speed_max
)
# This applies drag on the agent's rotation, helping it slow down naturally.
angular_velocity = lerp(angular_velocity, 0, angular_drag)
rotation += angular_velocity * delta
# In order to support both 2D and 3D, the toolkit uses Vector3, so the conversion is required
# when using 2D nodes. The Z component can be left to 0 safely.
func update_agent() -> void:
agent.position.x = global_position.x
agent.position.y = global_position.y
agent.orientation = rotation
agent.linear_velocity.x = velocity.x
agent.linear_velocity.y = velocity.y
agent.angular_velocity = angular_velocity
# We calculate the radius from the collision shape - this will approximate the agent's size in the
# game world, to avoid collisions with the player.
func calculate_radius(polygon: PoolVector2Array) -> float:
var furthest_point := Vector2(-INF, -INF)
for p in polygon:
if abs(p.x) > furthest_point.x:
furthest_point.x = p.x
if abs(p.y) > furthest_point.y:
furthest_point.y = p.y
return furthest_point.length()
func damage(amount: int) -> void:
current_health -= amount
if current_health <= 0:
queue_free()

View File

@ -1,33 +0,0 @@
extends KinematicBody2D
export var speed := 1500.0
var velocity := Vector2.ZERO
var player: Node
onready var timer := $Lifetime
func _ready() -> void:
timer.connect("timeout", self, "_on_Lifetime_timeout")
timer.start()
func _physics_process(delta: float) -> void:
var collision := move_and_collide(velocity * delta)
if collision:
timer.stop()
clear()
collision.collider.damage(10)
func start(direction: Vector2) -> void:
velocity = direction * speed
func clear() -> void:
queue_free()
func _on_Lifetime_timeout() -> void:
clear()

View File

@ -1,23 +0,0 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://demos/Utils/CircleDraw.gd" type="Script" id=1]
[ext_resource path="res://demos/Quickstart/Bullet.gd" type="Script" id=2]
[sub_resource type="CircleShape2D" id=1]
radius = 4.0
[node name="Bullet" type="KinematicBody2D"]
collision_layer = 4
collision_mask = 2
script = ExtResource( 2 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource( 1 )
script = ExtResource( 1 )
inner_color = Color( 0.235294, 0.639216, 0.439216, 1 )
outer_color = Color( 0.560784, 0.870588, 0.364706, 1 )
stroke = 2.0
[node name="Lifetime" type="Timer" parent="."]
process_mode = 0
wait_time = 3.0

Some files were not shown because too many files have changed in this diff Show More