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 00000000..bbb7d44a Binary files /dev/null and b/2d/physics_tests/assets/tileset/tiles_demo.png differ 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