From cdf0ed3be961eef6845612a9a54e0c567b9c11c6 Mon Sep 17 00:00:00 2001 From: PouleyKetchoupp Date: Fri, 8 Jan 2021 21:29:25 -0700 Subject: [PATCH] Add physics tests for 2D character controller Two tests for character controller, with options to use RigidBody2D, KinematicBody2D or KinematicBody2D with RayShape2D. Tilemap: Tests for moving and jumping within tilemap blocks, with a specific one-way collision test case scenario based on Block Climb Test from https://github.com/madmiraal/godot-gym. Slopes: Tests for moving and jumping in slopes, with different cases based on snap and stop-on-slope parameters for kinematic bodies. --- .../assets/{ => texture}/godot-head.png | Bin .../{ => texture}/godot-head.png.import | 6 +- .../assets/tileset/tiles_demo.png | Bin 0 -> 2583 bytes .../assets/tileset/tiles_demo.png.import | 34 ++ 2d/physics_tests/assets/tileset/tileset.tres | 335 ++++++++++++++++++ 2d/physics_tests/project.godot | 26 +- 2d/physics_tests/tests.gd | 8 + .../tests/functional/test_character.gd | 149 ++++++++ .../functional/test_character_slopes.tscn | 103 ++++++ .../functional/test_character_tilemap.gd | 26 ++ .../functional/test_character_tilemap.tscn | 106 ++++++ .../functional/test_collision_pairs.tscn | 2 +- .../functional/test_one_way_collision.gd | 1 + .../tests/functional/test_raycasting.tscn | 2 +- .../tests/functional/test_shapes.tscn | 2 +- .../tests/performance/test_perf_contacts.tscn | 2 +- 2d/physics_tests/tests/static_scene_flat.tscn | 2 +- .../utils/kinematicbody_controller.gd | 52 +++ .../utils/rigidbody_controller.gd | 62 ++++ 19 files changed, 909 insertions(+), 9 deletions(-) rename 2d/physics_tests/assets/{ => texture}/godot-head.png (100%) rename 2d/physics_tests/assets/{ => texture}/godot-head.png.import (69%) create mode 100644 2d/physics_tests/assets/tileset/tiles_demo.png create mode 100644 2d/physics_tests/assets/tileset/tiles_demo.png.import create mode 100644 2d/physics_tests/assets/tileset/tileset.tres create mode 100644 2d/physics_tests/tests/functional/test_character.gd create mode 100644 2d/physics_tests/tests/functional/test_character_slopes.tscn create mode 100644 2d/physics_tests/tests/functional/test_character_tilemap.gd create mode 100644 2d/physics_tests/tests/functional/test_character_tilemap.tscn create mode 100644 2d/physics_tests/utils/kinematicbody_controller.gd create mode 100644 2d/physics_tests/utils/rigidbody_controller.gd diff --git a/2d/physics_tests/assets/godot-head.png b/2d/physics_tests/assets/texture/godot-head.png similarity index 100% rename from 2d/physics_tests/assets/godot-head.png rename to 2d/physics_tests/assets/texture/godot-head.png diff --git a/2d/physics_tests/assets/godot-head.png.import b/2d/physics_tests/assets/texture/godot-head.png.import similarity index 69% rename from 2d/physics_tests/assets/godot-head.png.import rename to 2d/physics_tests/assets/texture/godot-head.png.import index 7659f2a0..af8b6dd1 100644 --- a/2d/physics_tests/assets/godot-head.png.import +++ b/2d/physics_tests/assets/texture/godot-head.png.import @@ -2,15 +2,15 @@ importer="texture" type="StreamTexture" -path="res://.import/godot-head.png-cc6844293d74c4f45ec6c4ab08de67ee.stex" +path="res://.import/godot-head.png-6a90da7ab6a8c80b4170f240c8e33e70.stex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/godot-head.png" -dest_files=[ "res://.import/godot-head.png-cc6844293d74c4f45ec6c4ab08de67ee.stex" ] +source_file="res://assets/texture/godot-head.png" +dest_files=[ "res://.import/godot-head.png-6a90da7ab6a8c80b4170f240c8e33e70.stex" ] [params] diff --git a/2d/physics_tests/assets/tileset/tiles_demo.png b/2d/physics_tests/assets/tileset/tiles_demo.png new file mode 100644 index 0000000000000000000000000000000000000000..bbb7d44a3ae8879dc76936b7396323ac2afc5d89 GIT binary patch literal 2583 zcmV+y3h4ETP)pJ_>=QzVC4KVV6JfjkpwLMu@}XH7p}R5NE!FJVA7PD(6XMk`f1G(tfk zQ!yi=I_W(R9)pKmyd2UMbzGG8wWvCaa_6{7|X@RvV-F^XR#vO`UkaCtC60nhn* z;r~Iq3OFA|1LFM~qQ4*y7}^K9e0e_S>qT|vO?c(GhaVU)Rhj8OZh$WwHE=fI2?00j zF>&>xyL})X1Kems`~>6+gbc8*1A={?0_N(Am;(y_SOE&@m+Rk8OutWG=ON&By^U56 zs9`5}2dICx|LOPXZ}QJlhWh+{Jt9|6sEUq|2*yAB{`;rjr@zUU^6>RlY6e}@bLq3; zqyP0Ll~d1Ozg6VbW{rs3{k!jy`n&@w*0iaReq_{Qw%kLrvKP4WLS( z=iMgX+3R(lrx~z{!T^b3=nr4l*FpvyH&LrM;NnZD7@*bx<01{v_jM?4z|fxQ@0d5> zNjPj}fz5!Q9KIb9t4VVXSLuUg|fZj6T(;yF{7x1UNE6`FK zhk>TqEDC+qyAt-;>;He~Au||OfOvX}z-{MPyvdl0GW9y~Si!OJG{Coc8O|<-T`9*t zU@BAV7yW*~Rj&{pPaFKtMFkMlPVjRpa0+nQ<$sAkJf1dq3}=@EE`u&euY~CIrLiJB zo;LWO-#ZYXU1+~{y$OE6HUGT}0dOCpak>u)kEad34*?Fax!`!(;5!f?dLI(^0}=%A z#}|k{?g!)xV8<7ZKja5w3*e8>AHUBJXn-M-EPyvYfBX(VKm&%zQg|=#mH>8qk@)TT z^@o1ILckcX2_OT4Hz}^-yS6_3@$+T;8!r+Bz~oR9;5buKi((AN{g_d9CqSv5c!2=Z zd8+KaSm)0ia5Izut|qm-07VSp)(6z~fLT)G_{@wl5`UmmS+AEJ4!0ICy|>8`XMFzn zBYuE3M8b}U2=MWFIad^l?-tLj;HT|W@ptA2v=(rH!>Dz4_4yTn_&fCjwtu@Hu>C#!fOV<> z`F_AU=m)G97hu~aMsE56%)F!@unzhG>*WQo{Qwp`h>zJ3f1)1{XaV=<|5*_C19}?{ z8!bS`hw~3$o);A$*AxxpFIW@&D*lik@H_#G_?R8>GpqPRen7e{?vIaco|!M>?1 zXwW|X^8~malg+c7{{dylYypY+3I2S1H7H%F_#r1mPCo@B`A|pPnXBAmWhNen8g(02mxA34$#kEk7ad z2Wa5C^w1Ng=Lh5q;GdtTIoK2a*t-0HbX(k?KQQW^Ff2eIKOqi({s1vXM(79Pe*%&3 zFNnjRKR`S}f|UG#IsW|x9{BSIh`2c{9;Vfgb0h}+dLIX@s>0Dt~Kb4bt; zj_H2D>!G8=$VhjDmn#j79sw>fp87?0N&5o7pv{;J1?vn*y+iq}tuyeg606F}9(nC{ z+ug@MpOptOlodX-l6U#N9!@q^fqB{7`~f=M5nU&C;{UcqUx0_ctZPso8u%^yG;5HNm0fpUdE5)_)pFDsPwTkObl z=ye8aiT|W>lD*+_?1!x0U zXFv+Nz0SZ!ies%AyV{R%Qe(jOsOyyg^8ErDH&|z&tv+yGXW--4vl>jpQf^!Lw z*H19{2AY9lqA$N-#?Niumgu~b0eq^w7Rx{1k1frE!UoVq3rKms-+>ZFe*QozU*gEm zAIRjp^aFHanZXM}e6N1M+>p$dSHr(P0rPzxRSdqNBLN)G?=$nghn=z8`!IKx!(ju= zCgVr{0_33S)tw*U{gbeHR5JKp{QyU&Xz{3I@O}FMKqg;o^p-ym=jFZeJqYmRTi;gx tHh#du{H*vt&ktyv!T)`JfWem_{s%biLV134zkmP$002ovPDHLkV1lju#;5=Q literal 0 HcmV?d00001 diff --git a/2d/physics_tests/assets/tileset/tiles_demo.png.import b/2d/physics_tests/assets/tileset/tiles_demo.png.import new file mode 100644 index 00000000..9ed1bbf5 --- /dev/null +++ b/2d/physics_tests/assets/tileset/tiles_demo.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/tiles_demo.png-4d398d5cc02bc85a2809dc13fbc9a3c2.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/tileset/tiles_demo.png" +dest_files=[ "res://.import/tiles_demo.png-4d398d5cc02bc85a2809dc13fbc9a3c2.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 diff --git a/2d/physics_tests/assets/tileset/tileset.tres b/2d/physics_tests/assets/tileset/tileset.tres new file mode 100644 index 00000000..ccf9907e --- /dev/null +++ b/2d/physics_tests/assets/tileset/tileset.tres @@ -0,0 +1,335 @@ +[gd_resource type="TileSet" load_steps=14 format=2] + +[ext_resource path="res://assets/tileset/tiles_demo.png" type="Texture" id=1] + +[sub_resource type="ConvexPolygonShape2D" id=1] +points = PoolVector2Array( 0, 6, 32, 6, 32, 32, 0, 32 ) + +[sub_resource type="ConvexPolygonShape2D" id=2] +points = PoolVector2Array( 0, 6, 28, 6, 28, 32, 0, 32 ) + +[sub_resource type="ConvexPolygonShape2D" id=3] +points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) + +[sub_resource type="ConvexPolygonShape2D" id=4] +points = PoolVector2Array( 0, 6, 32, 6, 32, 32, 0, 32 ) + +[sub_resource type="ConvexPolygonShape2D" id=5] +points = PoolVector2Array( 32, 38, 32, 64, 0, 64, 0, 6 ) + +[sub_resource type="ConvexPolygonShape2D" id=6] +points = PoolVector2Array( 0, 0, 28, 0, 28, 32, 0, 32 ) + +[sub_resource type="ConvexPolygonShape2D" id=7] +points = PoolVector2Array( 28, 6, 32, 6, 32, 32, 0, 32, 0, 0, 28, 0 ) + +[sub_resource type="ConvexPolygonShape2D" id=8] +points = PoolVector2Array( 0, 6, 32, 6, 32, 32, 0, 32 ) + +[sub_resource type="ConvexPolygonShape2D" id=9] +points = PoolVector2Array( 0, 6, 28, 6, 28, 32, 0, 32 ) + +[sub_resource type="ConvexPolygonShape2D" id=10] +points = PoolVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) + +[sub_resource type="ConvexPolygonShape2D" id=11] +points = PoolVector2Array( 0, 0, 32, 0, 32, 24, 0, 24 ) + +[sub_resource type="ConvexPolygonShape2D" id=12] +points = PoolVector2Array( 0, 0, 28, 0, 28, 24, 0, 24 ) + +[resource] +0/name = "ground" +0/texture = ExtResource( 1 ) +0/tex_offset = Vector2( 0, 0 ) +0/modulate = Color( 0, 0, 1, 1 ) +0/region = Rect2( 0, 0, 32, 32 ) +0/tile_mode = 0 +0/occluder_offset = Vector2( 0, 0 ) +0/navigation_offset = Vector2( 0, 0 ) +0/shape_offset = Vector2( 0, 0 ) +0/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +0/shape = SubResource( 1 ) +0/shape_one_way = false +0/shape_one_way_margin = 1.0 +0/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 1 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +0/z_index = 0 +1/name = "ground_end" +1/texture = ExtResource( 1 ) +1/tex_offset = Vector2( 0, 0 ) +1/modulate = Color( 1, 1, 1, 1 ) +1/region = Rect2( 32, 0, 32, 32 ) +1/tile_mode = 0 +1/occluder_offset = Vector2( 0, 0 ) +1/navigation_offset = Vector2( 0, 0 ) +1/shape_offset = Vector2( 0, 0 ) +1/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +1/shape = SubResource( 2 ) +1/shape_one_way = false +1/shape_one_way_margin = 1.0 +1/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 2 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +1/z_index = 0 +2/name = "slope" +2/texture = ExtResource( 1 ) +2/tex_offset = Vector2( 0, 0 ) +2/modulate = Color( 1, 1, 1, 1 ) +2/region = Rect2( 64, 64, 32, 64 ) +2/tile_mode = 0 +2/occluder_offset = Vector2( 0, 0 ) +2/navigation_offset = Vector2( 0, 0 ) +2/shape_offset = Vector2( 0, 0 ) +2/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +2/shape = SubResource( 5 ) +2/shape_one_way = false +2/shape_one_way_margin = 1.0 +2/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 5 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +2/z_index = 0 +3/name = "wall" +3/texture = ExtResource( 1 ) +3/tex_offset = Vector2( 0, 0 ) +3/modulate = Color( 1, 1, 1, 1 ) +3/region = Rect2( 32, 32, 32, 32 ) +3/tile_mode = 0 +3/occluder_offset = Vector2( 0, 0 ) +3/navigation_offset = Vector2( 0, 0 ) +3/shape_offset = Vector2( 0, 0 ) +3/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +3/shape = SubResource( 6 ) +3/shape_one_way = false +3/shape_one_way_margin = 1.0 +3/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 6 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +3/z_index = 0 +4/name = "slope_top" +4/texture = ExtResource( 1 ) +4/tex_offset = Vector2( 0, 0 ) +4/modulate = Color( 1, 1, 1, 1 ) +4/region = Rect2( 32, 64, 32, 32 ) +4/tile_mode = 0 +4/occluder_offset = Vector2( 0, 0 ) +4/navigation_offset = Vector2( 0, 0 ) +4/shape_offset = Vector2( 0, 0 ) +4/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +4/shape = SubResource( 7 ) +4/shape_one_way = false +4/shape_one_way_margin = 1.0 +4/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 7 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +4/z_index = 0 +5/name = "one_way" +5/texture = ExtResource( 1 ) +5/tex_offset = Vector2( 0, 0 ) +5/modulate = Color( 1, 1, 1, 1 ) +5/region = Rect2( 64, 0, 32, 32 ) +5/tile_mode = 0 +5/occluder_offset = Vector2( 0, 0 ) +5/navigation_offset = Vector2( 0, 0 ) +5/shape_offset = Vector2( 0, 0 ) +5/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +5/shape = SubResource( 8 ) +5/shape_one_way = true +5/shape_one_way_margin = 1.0 +5/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": true, +"one_way_margin": 1.0, +"shape": SubResource( 8 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +5/z_index = 0 +6/name = "one_way_end" +6/texture = ExtResource( 1 ) +6/tex_offset = Vector2( 0, 0 ) +6/modulate = Color( 1, 1, 1, 1 ) +6/region = Rect2( 96, 0, 32, 32 ) +6/tile_mode = 0 +6/occluder_offset = Vector2( 0, 0 ) +6/navigation_offset = Vector2( 0, 0 ) +6/shape_offset = Vector2( 0, 0 ) +6/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +6/shape = SubResource( 9 ) +6/shape_one_way = true +6/shape_one_way_margin = 1.0 +6/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": true, +"one_way_margin": 1.0, +"shape": SubResource( 9 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +6/z_index = 0 +7/name = "rock" +7/texture = ExtResource( 1 ) +7/tex_offset = Vector2( 0, 0 ) +7/modulate = Color( 1, 1, 1, 1 ) +7/region = Rect2( 0, 32, 32, 32 ) +7/tile_mode = 0 +7/occluder_offset = Vector2( 0, 0 ) +7/navigation_offset = Vector2( 0, 0 ) +7/shape_offset = Vector2( 0, 0 ) +7/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +7/shape = SubResource( 10 ) +7/shape_one_way = false +7/shape_one_way_margin = 1.0 +7/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 10 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +7/z_index = 0 +8/name = "bottom" +8/texture = ExtResource( 1 ) +8/tex_offset = Vector2( 0, 0 ) +8/modulate = Color( 1, 1, 1, 1 ) +8/region = Rect2( 192, 32, 32, 32 ) +8/tile_mode = 0 +8/occluder_offset = Vector2( 0, 0 ) +8/navigation_offset = Vector2( 0, 0 ) +8/shape_offset = Vector2( 0, 0 ) +8/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +8/shape = SubResource( 11 ) +8/shape_one_way = false +8/shape_one_way_margin = 1.0 +8/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 11 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +8/z_index = 0 +9/name = "bottom_end" +9/texture = ExtResource( 1 ) +9/tex_offset = Vector2( 0, 0 ) +9/modulate = Color( 1, 1, 1, 1 ) +9/region = Rect2( 224, 32, 32, 32 ) +9/tile_mode = 0 +9/occluder_offset = Vector2( 0, 0 ) +9/navigation_offset = Vector2( 0, 0 ) +9/shape_offset = Vector2( 0, 0 ) +9/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +9/shape = SubResource( 12 ) +9/shape_one_way = false +9/shape_one_way_margin = 1.0 +9/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 12 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +9/z_index = 0 +10/name = "bottom_corner" +10/texture = ExtResource( 1 ) +10/tex_offset = Vector2( 0, 0 ) +10/modulate = Color( 1, 1, 1, 1 ) +10/region = Rect2( 160, 32, 32, 32 ) +10/tile_mode = 0 +10/occluder_offset = Vector2( 0, 0 ) +10/navigation_offset = Vector2( 0, 0 ) +10/shape_offset = Vector2( 0, 0 ) +10/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +10/shape = SubResource( 3 ) +10/shape_one_way = false +10/shape_one_way_margin = 1.0 +10/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 3 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +10/z_index = 0 +11/name = "tree_trunk_0" +11/texture = ExtResource( 1 ) +11/tex_offset = Vector2( 0, 0 ) +11/modulate = Color( 1, 1, 1, 1 ) +11/region = Rect2( 128, 64, 32, 32 ) +11/tile_mode = 0 +11/occluder_offset = Vector2( 0, 0 ) +11/navigation_offset = Vector2( 0, 0 ) +11/shape_offset = Vector2( 0, 0 ) +11/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +11/shape_one_way = false +11/shape_one_way_margin = 0.0 +11/shapes = [ ] +11/z_index = 0 +12/name = "tree_trunk_1" +12/texture = ExtResource( 1 ) +12/tex_offset = Vector2( 0, 0 ) +12/modulate = Color( 1, 1, 1, 1 ) +12/region = Rect2( 128, 32, 32, 32 ) +12/tile_mode = 0 +12/occluder_offset = Vector2( 0, 0 ) +12/navigation_offset = Vector2( 0, 0 ) +12/shape_offset = Vector2( 0, 0 ) +12/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +12/shape_one_way = false +12/shape_one_way_margin = 0.0 +12/shapes = [ ] +12/z_index = 0 +13/name = "tree_base" +13/texture = ExtResource( 1 ) +13/tex_offset = Vector2( 0, 0 ) +13/modulate = Color( 1, 1, 1, 1 ) +13/region = Rect2( 128, 96, 32, 32 ) +13/tile_mode = 0 +13/occluder_offset = Vector2( 0, 0 ) +13/navigation_offset = Vector2( 0, 0 ) +13/shape_offset = Vector2( 0, 0 ) +13/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +13/shape = SubResource( 4 ) +13/shape_one_way = false +13/shape_one_way_margin = 1.0 +13/shapes = [ { +"autotile_coord": Vector2( 0, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 4 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +13/z_index = 0 +14/name = "tree_top" +14/texture = ExtResource( 1 ) +14/tex_offset = Vector2( 0, 0 ) +14/modulate = Color( 1, 1, 1, 1 ) +14/region = Rect2( 128, 0, 32, 32 ) +14/tile_mode = 0 +14/occluder_offset = Vector2( 0, 0 ) +14/navigation_offset = Vector2( 0, 0 ) +14/shape_offset = Vector2( 0, 0 ) +14/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +14/shape_one_way = false +14/shape_one_way_margin = 0.0 +14/shapes = [ ] +14/z_index = 0 diff --git a/2d/physics_tests/project.godot b/2d/physics_tests/project.godot index 2e09f2e3..7bb73adf 100644 --- a/2d/physics_tests/project.godot +++ b/2d/physics_tests/project.godot @@ -18,10 +18,16 @@ _global_script_classes=[ { "class": "Test", "language": "GDScript", "path": "res://test.gd" +}, { +"base": "Test", +"class": "TestCharacter", +"language": "GDScript", +"path": "res://tests/functional/test_character.gd" } ] _global_script_class_icons={ "OptionMenu": "", -"Test": "" +"Test": "", +"TestCharacter": "" } [application] @@ -72,6 +78,24 @@ toggle_pause={ "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":80,"unicode":0,"echo":false,"script":null) ] } +character_left={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null) + ] +} +character_right={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null) + ] +} +character_jump={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null) + ] +} [memory] diff --git a/2d/physics_tests/tests.gd b/2d/physics_tests/tests.gd index 9bb68c51..d289433b 100644 --- a/2d/physics_tests/tests.gd +++ b/2d/physics_tests/tests.gd @@ -18,6 +18,14 @@ var _tests = [ "id": "Functional Tests/Collision Pairs", "path": "res://tests/functional/test_collision_pairs.tscn", }, + { + "id": "Functional Tests/Character - Slopes", + "path": "res://tests/functional/test_character_slopes.tscn", + }, + { + "id": "Functional Tests/Character - Tilemap", + "path": "res://tests/functional/test_character_tilemap.tscn", + }, { "id": "Functional Tests/One Way Collision", "path": "res://tests/functional/test_one_way_collision.tscn", diff --git a/2d/physics_tests/tests/functional/test_character.gd b/2d/physics_tests/tests/functional/test_character.gd new file mode 100644 index 00000000..95b3f18f --- /dev/null +++ b/2d/physics_tests/tests/functional/test_character.gd @@ -0,0 +1,149 @@ +extends Test +class_name TestCharacter + + +enum E_BodyType { + RIGID_BODY, + KINEMATIC_BODY, + KINEMATIC_BODY_RAY_SHAPE, +} + +const OPTION_OBJECT_TYPE_RIGIDBODY = "Object type/Rigid body (1)" +const OPTION_OBJECT_TYPE_KINEMATIC = "Object type/Kinematic body (2)" +const OPTION_OBJECT_TYPE_KINEMATIC_RAYSHAPE = "Object type/Kinematic body with ray shape (3)" + +const OPTION_MOVE_KINEMATIC_SNAP = "Move Options/Use snap (Kinematic only)" +const OPTION_MOVE_KINEMATIC_STOP_ON_SLOPE = "Move Options/Use stop on slope (Kinematic only)" + +export(Vector2) var _initial_velocity = Vector2.ZERO +export(Vector2) var _constant_velocity = Vector2.ZERO +export(float) var _snap_distance = 0.0 +export(float) var _floor_max_angle = 45.0 +export(E_BodyType) var _body_type = 0 + +var _use_snap = true +var _use_stop_on_slope = true + +var _rigid_body_template = null +var _kinematic_body_template = null +var _kinematic_body_ray_template = null +var _moving_body = null + + +func _ready(): + $Options.connect("option_selected", self, "_on_option_selected") + $Options.connect("option_changed", self, "_on_option_changed") + + _rigid_body_template = find_node("RigidBody2D") + if _rigid_body_template: + remove_child(_rigid_body_template) + var enabled = _body_type == E_BodyType.RIGID_BODY + $Options.add_menu_item(OPTION_OBJECT_TYPE_RIGIDBODY, true, enabled, true) + + _kinematic_body_template = find_node("KinematicBody2D") + if _kinematic_body_template: + remove_child(_kinematic_body_template) + var enabled = _body_type == E_BodyType.KINEMATIC_BODY + $Options.add_menu_item(OPTION_OBJECT_TYPE_KINEMATIC, true, enabled, true) + + _kinematic_body_ray_template = find_node("KinematicBodyRay2D") + if _kinematic_body_ray_template: + remove_child(_kinematic_body_ray_template) + var enabled = _body_type == E_BodyType.KINEMATIC_BODY_RAY_SHAPE + $Options.add_menu_item(OPTION_OBJECT_TYPE_KINEMATIC_RAYSHAPE, true, enabled, true) + + $Options.add_menu_item(OPTION_MOVE_KINEMATIC_SNAP, true, _use_snap) + $Options.add_menu_item(OPTION_MOVE_KINEMATIC_STOP_ON_SLOPE, true, _use_stop_on_slope) + + _start_test() + + +func _process(_delta): + if _moving_body: + if _moving_body.is_on_floor(): + $LabelFloor.text = "ON FLOOR" + $LabelFloor.self_modulate = Color.green + else: + $LabelFloor.text = "OFF FLOOR" + $LabelFloor.self_modulate = Color.red + else: + $LabelFloor.visible = false + + +func _input(event): + var key_event = event as InputEventKey + if key_event and not key_event.pressed: + if key_event.scancode == KEY_1: + if _rigid_body_template: + _on_option_selected(OPTION_OBJECT_TYPE_RIGIDBODY) + elif key_event.scancode == KEY_2: + if _kinematic_body_template: + _on_option_selected(OPTION_OBJECT_TYPE_KINEMATIC) + elif key_event.scancode == KEY_3: + if _kinematic_body_ray_template: + _on_option_selected(OPTION_OBJECT_TYPE_KINEMATIC_RAYSHAPE) + + +func _exit_tree(): + if _rigid_body_template: + _rigid_body_template.free() + if _kinematic_body_template: + _kinematic_body_template.free() + if _kinematic_body_ray_template: + _kinematic_body_ray_template.free() + + +func _on_option_selected(option): + match option: + OPTION_OBJECT_TYPE_RIGIDBODY: + _body_type = E_BodyType.RIGID_BODY + _start_test() + OPTION_OBJECT_TYPE_KINEMATIC: + _body_type = E_BodyType.KINEMATIC_BODY + _start_test() + OPTION_OBJECT_TYPE_KINEMATIC_RAYSHAPE: + _body_type = E_BodyType.KINEMATIC_BODY_RAY_SHAPE + _start_test() + + +func _on_option_changed(option, checked): + match option: + OPTION_MOVE_KINEMATIC_SNAP: + _use_snap = checked + _start_test() + OPTION_MOVE_KINEMATIC_STOP_ON_SLOPE: + _use_stop_on_slope = checked + _start_test() + + +func _start_test(): + if _moving_body: + remove_child(_moving_body) + _moving_body.queue_free() + _moving_body = null + + var test_label = "Testing: " + + var template = null + match _body_type: + E_BodyType.RIGID_BODY: + template = _rigid_body_template + E_BodyType.KINEMATIC_BODY: + template = _kinematic_body_template + E_BodyType.KINEMATIC_BODY_RAY_SHAPE: + template = _kinematic_body_ray_template + + test_label += template.name + _moving_body = template.duplicate() + add_child(_moving_body) + + _moving_body._initial_velocity = _initial_velocity + _moving_body._constant_velocity = _constant_velocity + + if _moving_body is KinematicBody2D: + if _use_snap: + _moving_body._snap = Vector2(0, _snap_distance) + _moving_body._stop_on_slope = _use_stop_on_slope + _moving_body._floor_max_angle = _floor_max_angle + + $LabelTestType.text = test_label diff --git a/2d/physics_tests/tests/functional/test_character_slopes.tscn b/2d/physics_tests/tests/functional/test_character_slopes.tscn new file mode 100644 index 00000000..630d7ef8 --- /dev/null +++ b/2d/physics_tests/tests/functional/test_character_slopes.tscn @@ -0,0 +1,103 @@ +[gd_scene load_steps=11 format=2] + +[ext_resource path="res://tests/functional/test_character.gd" type="Script" id=1] +[ext_resource path="res://tests/test_options.tscn" type="PackedScene" id=3] +[ext_resource path="res://tests/static_scene_flat.tscn" type="PackedScene" id=4] +[ext_resource path="res://utils/rigidbody_controller.gd" type="Script" id=6] +[ext_resource path="res://utils/kinematicbody_controller.gd" type="Script" id=7] + +[sub_resource type="PhysicsMaterial" id=1] +friction = 0.0 + +[sub_resource type="CapsuleShape2D" id=2] +radius = 32.0 +height = 32.0 + +[sub_resource type="CapsuleShape2D" id=3] +radius = 32.0 +height = 32.0 + +[sub_resource type="CircleShape2D" id=4] +radius = 32.0 + +[sub_resource type="RayShape2D" id=5] +length = 64.0 + +[node name="Test" type="Node2D"] +script = ExtResource( 1 ) +_snap_distance = 32.0 +_floor_max_angle = 60.0 + +[node name="LabelTestType" type="Label" parent="."] +margin_left = 14.0 +margin_top = 79.0 +margin_right = 145.0 +margin_bottom = 93.0 +text = "Testing: " +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Options" parent="." instance=ExtResource( 3 )] + +[node name="LabelFloor" type="Label" parent="."] +margin_left = 14.0 +margin_top = 237.929 +margin_right = 145.0 +margin_bottom = 251.929 +text = "ON FLOOR" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="LabelControls" type="Label" parent="."] +margin_left = 14.0 +margin_top = 263.291 +margin_right = 145.0 +margin_bottom = 294.291 +text = "LEFT/RIGHT - MOVE +UP - JUMP" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="RigidBody2D" type="RigidBody2D" parent="."] +position = Vector2( 100, 450 ) +collision_mask = 2147483649 +mode = 2 +physics_material_override = SubResource( 1 ) +contacts_reported = 4 +contact_monitor = true +script = ExtResource( 6 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="RigidBody2D"] +shape = SubResource( 2 ) + +[node name="KinematicBody2D" type="KinematicBody2D" parent="."] +position = Vector2( 100, 450 ) +collision_mask = 2147483649 +script = ExtResource( 7 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="KinematicBody2D"] +shape = SubResource( 3 ) + +[node name="KinematicBodyRay2D" type="KinematicBody2D" parent="."] +position = Vector2( 100, 450 ) +collision_mask = 2147483649 +script = ExtResource( 7 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="KinematicBodyRay2D"] +position = Vector2( 0, -16 ) +shape = SubResource( 4 ) + +[node name="CollisionShapeRay2D" type="CollisionShape2D" parent="KinematicBodyRay2D"] +position = Vector2( 0, -16 ) +shape = SubResource( 5 ) + +[node name="StaticSceneFlat" parent="." instance=ExtResource( 4 )] +position = Vector2( 0, 12 ) + +[node name="StaticBody2D" type="StaticBody2D" parent="."] + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="StaticBody2D"] +polygon = PoolVector2Array( 171.04, 529.248, 379.275, 294.316, 506.084, 429.135, 648.26, 322.058, 868.746, 322.058, 985.282, 36.6919, 1242.91, 531.917 ) diff --git a/2d/physics_tests/tests/functional/test_character_tilemap.gd b/2d/physics_tests/tests/functional/test_character_tilemap.gd new file mode 100644 index 00000000..86fc85e6 --- /dev/null +++ b/2d/physics_tests/tests/functional/test_character_tilemap.gd @@ -0,0 +1,26 @@ +extends TestCharacter + + +const OPTION_TEST_CASE_JUMP_ONE_WAY = "Test Cases/Jump through one-way tiles" + +var _test_jump_one_way = false + + +func _ready(): + $Options.add_menu_item(OPTION_TEST_CASE_JUMP_ONE_WAY, true, false) + + +func _on_option_changed(option, checked): + match option: + OPTION_TEST_CASE_JUMP_ONE_WAY: + _test_jump_one_way = checked + _start_test() + + ._on_option_changed(option, checked) + + +func _start_test(): + ._start_test() + + if _test_jump_one_way: + _moving_body._initial_velocity = Vector2(600, -1000) diff --git a/2d/physics_tests/tests/functional/test_character_tilemap.tscn b/2d/physics_tests/tests/functional/test_character_tilemap.tscn new file mode 100644 index 00000000..1caadf41 --- /dev/null +++ b/2d/physics_tests/tests/functional/test_character_tilemap.tscn @@ -0,0 +1,106 @@ +[gd_scene load_steps=11 format=2] + +[ext_resource path="res://tests/functional/test_character_tilemap.gd" type="Script" id=1] +[ext_resource path="res://tests/test_options.tscn" type="PackedScene" id=3] +[ext_resource path="res://tests/static_scene_flat.tscn" type="PackedScene" id=4] +[ext_resource path="res://assets/tileset/tileset.tres" type="TileSet" id=5] +[ext_resource path="res://utils/rigidbody_controller.gd" type="Script" id=6] +[ext_resource path="res://utils/kinematicbody_controller.gd" type="Script" id=7] + +[sub_resource type="PhysicsMaterial" id=1] +friction = 0.0 + +[sub_resource type="RectangleShape2D" id=2] +extents = Vector2( 16, 32 ) + +[sub_resource type="RectangleShape2D" id=3] +extents = Vector2( 16, 24 ) + +[sub_resource type="RayShape2D" id=4] +length = 24.0 + +[node name="Test" type="Node2D"] +script = ExtResource( 1 ) + +[node name="LabelTestType" type="Label" parent="."] +margin_left = 14.0 +margin_top = 79.0 +margin_right = 145.0 +margin_bottom = 93.0 +text = "Testing: " +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Options" parent="." instance=ExtResource( 3 )] + +[node name="LabelFloor" type="Label" parent="."] +margin_left = 14.0 +margin_top = 237.929 +margin_right = 145.0 +margin_bottom = 251.929 +text = "ON FLOOR" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="LabelControls" type="Label" parent="."] +margin_left = 14.0 +margin_top = 263.291 +margin_right = 145.0 +margin_bottom = 277.291 +text = "LEFT/RIGHT - MOVE +UP - JUMP" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="RigidBody2D" type="RigidBody2D" parent="."] +position = Vector2( 250, 460 ) +collision_mask = 2147483649 +mode = 2 +physics_material_override = SubResource( 1 ) +contacts_reported = 4 +contact_monitor = true +script = ExtResource( 6 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="RigidBody2D"] +shape = SubResource( 2 ) + +[node name="KinematicBody2D" type="KinematicBody2D" parent="."] +position = Vector2( 250, 460 ) +collision_mask = 2147483649 +script = ExtResource( 7 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="KinematicBody2D"] +shape = SubResource( 2 ) + +[node name="KinematicBodyRay2D" type="KinematicBody2D" parent="."] +position = Vector2( 250, 460 ) +collision_mask = 2147483649 +script = ExtResource( 7 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="KinematicBodyRay2D"] +position = Vector2( 0, -8 ) +shape = SubResource( 3 ) + +[node name="CollisionShapeRay2D" type="CollisionShape2D" parent="KinematicBodyRay2D"] +position = Vector2( 0, 8 ) +shape = SubResource( 4 ) + +[node name="CollisionShapeRay2DLeft" type="CollisionShape2D" parent="KinematicBodyRay2D"] +position = Vector2( -16, 8 ) +shape = SubResource( 4 ) + +[node name="CollisionShapeRay2DRight" type="CollisionShape2D" parent="KinematicBodyRay2D"] +position = Vector2( 16, 8 ) +shape = SubResource( 4 ) + +[node name="StaticSceneFlat" parent="." instance=ExtResource( 4 )] +position = Vector2( 0, 12 ) + +[node name="TileMap" type="TileMap" parent="."] +tile_set = ExtResource( 5 ) +cell_size = Vector2( 32, 32 ) +format = 1 +tile_data = PoolIntArray( 458764, 5, 0, 458765, 5, 0, 458766, 5, 0, 458767, 5, 0, 458768, 5, 0, 458769, 5, 0, 458770, 5, 0, 458771, 5, 0, 524300, 5, 0, 524301, 5, 0, 524302, 5, 0, 524303, 5, 0, 524304, 5, 0, 524305, 5, 0, 524306, 5, 0, 524307, 5, 0, 589836, 5, 0, 589837, 5, 0, 589838, 5, 0, 589839, 5, 0, 589840, 5, 0, 589841, 5, 0, 589842, 5, 0, 589843, 5, 0, 655372, 5, 0, 655373, 5, 0, 655374, 5, 0, 655375, 5, 0, 655376, 5, 0, 655377, 5, 0, 655378, 5, 0, 655379, 5, 0, 720908, 5, 0, 720909, 5, 0, 720910, 5, 0, 720911, 5, 0, 720912, 5, 0, 720913, 5, 0, 720914, 5, 0, 720915, 5, 0, 720922, 0, 0, 720923, 0, 0, 720924, 0, 0, 720925, 0, 0, 786438, 5, 0, 786439, 5, 0, 786440, 5, 0, 786441, 5, 0, 786444, 5, 0, 786445, 5, 0, 786446, 5, 0, 786447, 5, 0, 786448, 5, 0, 786449, 5, 0, 786450, 5, 0, 786451, 5, 0, 851980, 5, 0, 851981, 5, 0, 851982, 5, 0, 851983, 5, 0, 851984, 5, 0, 851985, 5, 0, 851986, 5, 0, 851987, 5, 0, 851992, 0, 0, 851993, 0, 0, 851994, 0, 0, 851995, 0, 0, 917516, 5, 0, 917517, 5, 0, 917518, 5, 0, 917519, 5, 0, 917520, 5, 0, 917521, 5, 0, 917522, 5, 0, 917523, 5, 0, 983052, 5, 0, 983053, 5, 0, 983054, 5, 0, 983055, 5, 0, 983056, 5, 0, 983057, 5, 0, 983058, 5, 0, 983059, 5, 0 ) diff --git a/2d/physics_tests/tests/functional/test_collision_pairs.tscn b/2d/physics_tests/tests/functional/test_collision_pairs.tscn index ebcc05d2..d4227acc 100644 --- a/2d/physics_tests/tests/functional/test_collision_pairs.tscn +++ b/2d/physics_tests/tests/functional/test_collision_pairs.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=8 format=2] [ext_resource path="res://tests/functional/test_collision_pairs.gd" type="Script" id=1] -[ext_resource path="res://assets/godot-head.png" type="Texture" id=2] +[ext_resource path="res://assets/texture/godot-head.png" type="Texture" id=2] [ext_resource path="res://tests/test_options.tscn" type="PackedScene" id=3] [sub_resource type="RectangleShape2D" id=1] diff --git a/2d/physics_tests/tests/functional/test_one_way_collision.gd b/2d/physics_tests/tests/functional/test_one_way_collision.gd index fcbc9611..6f84dda2 100644 --- a/2d/physics_tests/tests/functional/test_one_way_collision.gd +++ b/2d/physics_tests/tests/functional/test_one_way_collision.gd @@ -1,6 +1,7 @@ extends Test tool + const OPTION_OBJECT_TYPE_RIGIDBODY = "Object type/Rigid body (1)" const OPTION_OBJECT_TYPE_KINEMATIC = "Object type/Kinematic body (2)" diff --git a/2d/physics_tests/tests/functional/test_raycasting.tscn b/2d/physics_tests/tests/functional/test_raycasting.tscn index c336fa03..32db5b7d 100644 --- a/2d/physics_tests/tests/functional/test_raycasting.tscn +++ b/2d/physics_tests/tests/functional/test_raycasting.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=7 format=2] -[ext_resource path="res://assets/godot-head.png" type="Texture" id=1] +[ext_resource path="res://assets/texture/godot-head.png" type="Texture" id=1] [ext_resource path="res://tests/functional/test_raycasting.gd" type="Script" id=2] [sub_resource type="RectangleShape2D" id=1] diff --git a/2d/physics_tests/tests/functional/test_shapes.tscn b/2d/physics_tests/tests/functional/test_shapes.tscn index 6f4ec6ac..08d38b8c 100644 --- a/2d/physics_tests/tests/functional/test_shapes.tscn +++ b/2d/physics_tests/tests/functional/test_shapes.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=7 format=2] -[ext_resource path="res://assets/godot-head.png" type="Texture" id=1] +[ext_resource path="res://assets/texture/godot-head.png" type="Texture" id=1] [ext_resource path="res://test.gd" type="Script" id=2] [ext_resource path="res://tests/static_scene.tscn" type="PackedScene" id=6] diff --git a/2d/physics_tests/tests/performance/test_perf_contacts.tscn b/2d/physics_tests/tests/performance/test_perf_contacts.tscn index f61e42a3..ab60c944 100644 --- a/2d/physics_tests/tests/performance/test_perf_contacts.tscn +++ b/2d/physics_tests/tests/performance/test_perf_contacts.tscn @@ -2,7 +2,7 @@ [ext_resource path="res://tests/static_scene.tscn" type="PackedScene" id=1] [ext_resource path="res://tests/performance/test_perf_contacts.gd" type="Script" id=2] -[ext_resource path="res://assets/godot-head.png" type="Texture" id=3] +[ext_resource path="res://assets/texture/godot-head.png" type="Texture" id=3] [ext_resource path="res://tests/test_options.tscn" type="PackedScene" id=4] [sub_resource type="RectangleShape2D" id=1] diff --git a/2d/physics_tests/tests/static_scene_flat.tscn b/2d/physics_tests/tests/static_scene_flat.tscn index f07a3f8c..368ac2b3 100644 --- a/2d/physics_tests/tests/static_scene_flat.tscn +++ b/2d/physics_tests/tests/static_scene_flat.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=2 format=2] [sub_resource type="RectangleShape2D" id=1] -extents = Vector2( 512, 50 ) +extents = Vector2( 800, 50 ) [node name="StaticSceneFlat" type="Node2D"] diff --git a/2d/physics_tests/utils/kinematicbody_controller.gd b/2d/physics_tests/utils/kinematicbody_controller.gd new file mode 100644 index 00000000..d8812d33 --- /dev/null +++ b/2d/physics_tests/utils/kinematicbody_controller.gd @@ -0,0 +1,52 @@ +extends KinematicBody2D + + +var _initial_velocity = Vector2.ZERO +var _constant_velocity = Vector2.ZERO +var _velocity = Vector2.ZERO +var _snap = Vector2.ZERO +var _floor_max_angle = 45.0 +var _stop_on_slope = false +var _jumping = false +var _keep_velocity = false + + +func _physics_process(_delta): + if _initial_velocity != Vector2.ZERO: + _velocity = _initial_velocity + _initial_velocity = Vector2.ZERO + _keep_velocity = true + elif _constant_velocity != Vector2.ZERO: + _velocity = _constant_velocity + elif not _keep_velocity: + _velocity.x = 0.0 + + # Handle horizontal controls. + if Input.is_action_pressed("character_left"): + if position.x > 0.0: + _velocity.x = -400.0 + _keep_velocity = false + _constant_velocity = Vector2.ZERO + elif Input.is_action_pressed("character_right"): + if position.x < 1024.0: + _velocity.x = 400.0 + _keep_velocity = false + _constant_velocity = Vector2.ZERO + + # Handle jump controls and gravity. + if is_on_floor(): + if not _jumping and Input.is_action_just_pressed("character_jump"): + # Start jumping. + _jumping = true + _velocity.y = -1000.0 + elif not _jumping: + # Apply velocity when standing for floor detection. + _velocity.y = 10.0 + else: + # Apply gravity and get jump ready. + _jumping = false + _velocity.y += 50.0 + + var snap = _snap if not _jumping else Vector2.ZERO + var max_angle = deg2rad(_floor_max_angle) + move_and_slide_with_snap(_velocity, snap, Vector2.UP, _stop_on_slope, 4, max_angle) diff --git a/2d/physics_tests/utils/rigidbody_controller.gd b/2d/physics_tests/utils/rigidbody_controller.gd new file mode 100644 index 00000000..7b234e5a --- /dev/null +++ b/2d/physics_tests/utils/rigidbody_controller.gd @@ -0,0 +1,62 @@ +extends RigidBody2D + + +var _initial_velocity = Vector2.ZERO +var _constant_velocity = Vector2.ZERO +var _velocity = Vector2.ZERO +var _on_floor = false +var _jumping = false +var _keep_velocity = false + + +func _physics_process(_delta): + if _initial_velocity != Vector2.ZERO: + _velocity = _initial_velocity + _initial_velocity = Vector2.ZERO + _keep_velocity = true + elif _constant_velocity != Vector2.ZERO: + _velocity = _constant_velocity + elif not _keep_velocity: + _velocity.x = 0.0 + + # Handle horizontal controls. + if Input.is_action_pressed("character_left"): + if position.x > 0.0: + _velocity.x = -400.0 + _keep_velocity = false + _constant_velocity = Vector2.ZERO + elif Input.is_action_pressed("character_right"): + if position.x < 1024.0: + _velocity.x = 400.0 + _keep_velocity = false + _constant_velocity = Vector2.ZERO + + # Handle jump controls and gravity. + if is_on_floor(): + if not _jumping and Input.is_action_just_pressed("character_jump"): + # Start jumping. + _jumping = true + _velocity.y = -1000.0 + elif not _jumping: + # Apply velocity when standing for floor detection. + _velocity.y = 10.0 + else: + # Apply gravity and get jump ready. + _jumping = false + _velocity.y += 50.0 + + linear_velocity = _velocity + + +func _integrate_forces(state): + _on_floor = false + + var contacts = state.get_contact_count() + for i in contacts: + var pos = state.get_contact_collider_position(i) + if pos.y > position.y: + _on_floor = true + + +func is_on_floor(): + return _on_floor