Inertia based movement(broken jumps)
This commit is contained in:
parent
edc8a4d16f
commit
742b79db52
@ -4,6 +4,10 @@ class_name Actor
|
|||||||
const FLOOR_NORMAL := Vector2.UP
|
const FLOOR_NORMAL := Vector2.UP
|
||||||
|
|
||||||
export var speed := Vector2(300, 1000)
|
export var speed := Vector2(300, 1000)
|
||||||
export var gravity := 9800.0
|
# newtonmeters is the unit
|
||||||
|
export var acceleration_force := Vector2(5000, -2000)
|
||||||
|
export var gravity := 9810.0
|
||||||
|
# Kilograms
|
||||||
|
export var mass := 5
|
||||||
|
|
||||||
var _velocity := Vector2.ZERO
|
var _velocity := Vector2.ZERO
|
||||||
|
|||||||
@ -12,22 +12,16 @@ func _on_EnemyDetector_body_entered(body: Node) -> void:
|
|||||||
die()
|
die()
|
||||||
|
|
||||||
|
|
||||||
func apply_movement(delta: float) -> void:
|
func handle_grounded_movement(delta: float, direction: Vector2) -> Vector2:
|
||||||
var is_jump_interrupted := Input.is_action_just_released("jump") and _velocity.y < 0.0
|
return calculate_grounded_velocity(_velocity, delta, speed, direction)
|
||||||
var direction := get_direction()
|
|
||||||
_velocity = calculate_move_velocity(_velocity, speed, direction, is_jump_interrupted)
|
|
||||||
_velocity = move_and_slide(_velocity, FLOOR_NORMAL)
|
|
||||||
|
|
||||||
|
|
||||||
func get_direction() -> Vector2:
|
func handle_jump_movement(delta: float, direction: Vector2) -> Vector2:
|
||||||
return Vector2(
|
return calculate_jump_velocity(_velocity, delta, speed, direction)
|
||||||
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
|
|
||||||
-1.0 if Input.is_action_just_pressed("jump") and is_on_floor() else 1.0
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func handle_move_input():
|
func handle_fall_movement(delta: float, direction: Vector2) -> Vector2:
|
||||||
return null
|
return calculate_fall_velocity(_velocity, delta, speed, direction)
|
||||||
|
|
||||||
|
|
||||||
func apply_gravity(delta, velocity: Vector2):
|
func apply_gravity(delta, velocity: Vector2):
|
||||||
@ -35,17 +29,51 @@ func apply_gravity(delta, velocity: Vector2):
|
|||||||
return velocity
|
return velocity
|
||||||
|
|
||||||
|
|
||||||
func calculate_move_velocity(
|
func calculate_grounded_velocity(
|
||||||
linear_velocity: Vector2, speed: Vector2, direction: Vector2, is_jump_interrupted: bool
|
linear_velocity: Vector2, delta: float, speed: Vector2, direction: Vector2
|
||||||
) -> Vector2:
|
) -> Vector2:
|
||||||
var out := linear_velocity
|
var out_vel := linear_velocity
|
||||||
out.x = speed.x * direction.x
|
# TODO Comments
|
||||||
out = apply_gravity(get_physics_process_delta_time(), out)
|
if direction.x == 0.0:
|
||||||
if direction.y == -1:
|
var deceleration_force = get_ground_friction() * gravity * mass * delta
|
||||||
out.y = speed.y * direction.y
|
var velocity_direction = 1.0
|
||||||
if is_jump_interrupted:
|
if _velocity.x < 0:
|
||||||
out.y = 0
|
velocity_direction = -1.0
|
||||||
return out
|
# Translates velocity back to force and subtracts deceleration force
|
||||||
|
var result_force = (
|
||||||
|
(abs(_velocity.x) * mass) / delta
|
||||||
|
- deceleration_force
|
||||||
|
)
|
||||||
|
if result_force <= 0:
|
||||||
|
out_vel.x = 0
|
||||||
|
else:
|
||||||
|
out_vel.x = result_force / mass * delta * velocity_direction
|
||||||
|
else:
|
||||||
|
out_vel.x += (delta * ((acceleration_force.x / mass) * direction.x))
|
||||||
|
# TODO Is this the right place to determine this?
|
||||||
|
if is_on_floor():
|
||||||
|
var additive_jump_force = -0.1 * abs(_velocity.x) * mass
|
||||||
|
# The one signals, that I calculated the velocity resulting from 1 second of force applied
|
||||||
|
out_vel.y = 1 * ((acceleration_force.y + additive_jump_force) / mass)
|
||||||
|
return out_vel
|
||||||
|
|
||||||
|
|
||||||
|
func get_ground_friction() -> float:
|
||||||
|
return 10.0
|
||||||
|
|
||||||
|
|
||||||
|
func calculate_jump_velocity(
|
||||||
|
linear_velocity: Vector2, delta: float, speed: Vector2, direction: Vector2
|
||||||
|
) -> Vector2:
|
||||||
|
linear_velocity.y = gravity * delta
|
||||||
|
return linear_velocity
|
||||||
|
|
||||||
|
|
||||||
|
func calculate_fall_velocity(
|
||||||
|
linear_velocity: Vector2, delta: float, speed: Vector2, direction: Vector2
|
||||||
|
) -> Vector2:
|
||||||
|
linear_velocity.y = gravity * delta
|
||||||
|
return linear_velocity
|
||||||
|
|
||||||
|
|
||||||
func calculate_stomp_velocity(linear_velocity: Vector2, impulse: float) -> Vector2:
|
func calculate_stomp_velocity(linear_velocity: Vector2, impulse: float) -> Vector2:
|
||||||
@ -54,6 +82,10 @@ func calculate_stomp_velocity(linear_velocity: Vector2, impulse: float) -> Vecto
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
func execute_movement() -> void:
|
||||||
|
_velocity = move_and_slide(_velocity, FLOOR_NORMAL)
|
||||||
|
|
||||||
|
|
||||||
func die() -> void:
|
func die() -> void:
|
||||||
queue_free()
|
queue_free()
|
||||||
PlayerData.deaths += 1
|
PlayerData.deaths += 1
|
||||||
|
|||||||
74
src/Actor/Blobby.tscn.tmp
Normal file
74
src/Actor/Blobby.tscn.tmp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
[gd_scene load_steps=8 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://start-assets/player.png" type="Texture" id=1]
|
||||||
|
[ext_resource path="res://src/Actor/PlayerStateMachine.gd" type="Script" id=2]
|
||||||
|
[ext_resource path="res://src/RayCasters/RayCaster.gd" type="Script" id=3]
|
||||||
|
[ext_resource path="res://src/RayCasters/RayCastDebugLines.gd" type="Script" id=4]
|
||||||
|
[ext_resource path="res://src/Actor/Blobby.gd" type="Script" id=5]
|
||||||
|
|
||||||
|
[sub_resource type="RectangleShape2D" id=1]
|
||||||
|
extents = Vector2( 30.8418, 32 )
|
||||||
|
|
||||||
|
[sub_resource type="RectangleShape2D" id=2]
|
||||||
|
extents = Vector2( 30.9321, 24.5597 )
|
||||||
|
|
||||||
|
[node name="Blobby" type="KinematicBody2D"]
|
||||||
|
collision_mask = 8
|
||||||
|
script = ExtResource( 5 )
|
||||||
|
speed = null
|
||||||
|
gravity = null
|
||||||
|
stomp_impulse = null
|
||||||
|
|
||||||
|
[node name="Player" type="Sprite" parent="."]
|
||||||
|
position = Vector2( 0, -32 )
|
||||||
|
scale = Vector2( 0.64, 0.64 )
|
||||||
|
texture = ExtResource( 1 )
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||||
|
position = Vector2( 0, -32.2102 )
|
||||||
|
shape = SubResource( 1 )
|
||||||
|
|
||||||
|
[node name="RayCaster" type="Node2D" parent="CollisionShape2D"]
|
||||||
|
script = ExtResource( 3 )
|
||||||
|
|
||||||
|
[node name="RayCastDebugLines" type="Line2D" parent="CollisionShape2D/RayCaster"]
|
||||||
|
script = ExtResource( 4 )
|
||||||
|
|
||||||
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
|
visible = false
|
||||||
|
position = Vector2( 0, -181 )
|
||||||
|
current = true
|
||||||
|
limit_left = 0
|
||||||
|
limit_top = 0
|
||||||
|
limit_smoothed = true
|
||||||
|
drag_margin_h_enabled = true
|
||||||
|
drag_margin_v_enabled = true
|
||||||
|
smoothing_enabled = true
|
||||||
|
drag_margin_left = 0.0
|
||||||
|
drag_margin_right = 0.0
|
||||||
|
|
||||||
|
[node name="EnemyDetector" type="Area2D" parent="."]
|
||||||
|
monitorable = false
|
||||||
|
collision_mask = 2
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="EnemyDetector"]
|
||||||
|
modulate = Color( 0.2, 0, 0.494118, 1 )
|
||||||
|
position = Vector2( 0, -32.2102 )
|
||||||
|
shape = SubResource( 2 )
|
||||||
|
|
||||||
|
[node name="StateMachine" type="Node" parent="."]
|
||||||
|
script = ExtResource( 2 )
|
||||||
|
|
||||||
|
[node name="StateLable" type="Label" parent="."]
|
||||||
|
margin_left = -31.0
|
||||||
|
margin_top = -80.0
|
||||||
|
margin_right = 31.0
|
||||||
|
margin_bottom = -64.0
|
||||||
|
text = "Coochie"
|
||||||
|
align = 1
|
||||||
|
valign = 1
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
[connection signal="area_entered" from="EnemyDetector" to="." method="_on_EnemyDetector_area_entered"]
|
||||||
|
[connection signal="body_entered" from="EnemyDetector" to="." method="_on_EnemyDetector_body_entered"]
|
||||||
@ -22,20 +22,66 @@ func _state_logic(delta):
|
|||||||
parent.collision_mask
|
parent.collision_mask
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var handle_input_ref
|
||||||
|
|
||||||
match self.state:
|
match self.state:
|
||||||
"idle":
|
"idle":
|
||||||
parent.apply_movement(delta)
|
handle_input_ref = funcref(self, 'handle_idle_input')
|
||||||
"run":
|
"run":
|
||||||
parent.apply_movement(delta)
|
handle_input_ref = funcref(self, 'handle_run_input')
|
||||||
"jump":
|
"jump":
|
||||||
parent.apply_movement(delta)
|
handle_input_ref = funcref(self, 'handle_jump_input')
|
||||||
"fall":
|
"fall":
|
||||||
parent.apply_movement(delta)
|
handle_input_ref = funcref(self, 'handle_fall_input')
|
||||||
|
_:
|
||||||
|
print("don't panik")
|
||||||
|
|
||||||
|
parent._velocity = handle_input_ref.call_func(delta)
|
||||||
|
parent.execute_movement()
|
||||||
|
|
||||||
|
|
||||||
|
func handle_idle_input(delta, direction := get_direction()) -> Vector2:
|
||||||
|
return parent.handle_grounded_movement(delta, direction)
|
||||||
|
|
||||||
|
|
||||||
|
func handle_run_input(delta, direction := get_direction()) -> Vector2:
|
||||||
|
return parent.handle_grounded_movement(delta, direction)
|
||||||
|
|
||||||
|
|
||||||
|
func handle_jump_input(delta, direction := get_direction()) -> Vector2:
|
||||||
|
return parent.handle_jump_movement(delta, direction)
|
||||||
|
|
||||||
|
|
||||||
|
func handle_fall_input(delta, direction := get_direction()) -> Vector2:
|
||||||
|
return parent.handle_fall_movement(delta, direction)
|
||||||
|
|
||||||
|
|
||||||
|
func get_direction() -> Vector2:
|
||||||
|
return Vector2(
|
||||||
|
(
|
||||||
|
Input.get_action_strength("move_right")
|
||||||
|
- Input.get_action_strength("move_left")
|
||||||
|
),
|
||||||
|
-1.0 if Input.is_action_pressed("jump") else 1.0
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Determines which state should be active at the moment
|
# Determines which state should be active at the moment
|
||||||
func _get_transition(delta):
|
func _get_transition(delta):
|
||||||
parent.get_node("StateLable").text = self.state
|
parent.get_node("StateLable").text = self.state
|
||||||
|
var new_state
|
||||||
|
if ! parent.is_on_floor():
|
||||||
|
if parent._velocity.y < 0:
|
||||||
|
new_state = states.jump
|
||||||
|
if parent._velocity.y > 0:
|
||||||
|
new_state = states.fall
|
||||||
|
elif parent._velocity.x != 0:
|
||||||
|
new_state = states.run
|
||||||
|
else:
|
||||||
|
# TODO How does this apply to enviornment induced movement?
|
||||||
|
new_state = states.idle
|
||||||
|
if new_state != self.state:
|
||||||
|
return new_state
|
||||||
return null
|
return null
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
82
src/Levels/Level03.tscn.tmp
Normal file
82
src/Levels/Level03.tscn.tmp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
[gd_scene load_steps=9 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://src/Actor/Blobby.tscn" type="PackedScene" id=1]
|
||||||
|
[ext_resource path="res://start-assets/tileset.tres" type="TileSet" id=2]
|
||||||
|
[ext_resource path="res://src/Actor/Enemy.tscn" type="PackedScene" id=3]
|
||||||
|
[ext_resource path="res://start-assets/background.png" type="Texture" id=4]
|
||||||
|
[ext_resource path="res://src/Objects/Coin.tscn" type="PackedScene" id=5]
|
||||||
|
[ext_resource path="res://src/UserInterface/UserInterface.tscn" type="PackedScene" id=6]
|
||||||
|
[ext_resource path="res://src/UserInterface/EndsScreen.tscn" type="PackedScene" id=7]
|
||||||
|
[ext_resource path="res://src/Objects/Portal.tscn" type="PackedScene" id=8]
|
||||||
|
|
||||||
|
[node name="Level03" type="Node2D"]
|
||||||
|
|
||||||
|
[node name="UserInterface" type="CanvasLayer" parent="."]
|
||||||
|
|
||||||
|
[node name="UserInterface" parent="UserInterface" instance=ExtResource( 6 )]
|
||||||
|
|
||||||
|
[node name="BackgroundLayer" type="CanvasLayer" parent="."]
|
||||||
|
layer = -1
|
||||||
|
|
||||||
|
[node name="background" type="TextureRect" parent="BackgroundLayer"]
|
||||||
|
anchor_right = 1.016
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
margin_right = -0.384033
|
||||||
|
texture = ExtResource( 4 )
|
||||||
|
expand = true
|
||||||
|
stretch_mode = 1
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="TileMap" type="TileMap" parent="."]
|
||||||
|
tile_set = ExtResource( 2 )
|
||||||
|
cell_size = Vector2( 80, 80 )
|
||||||
|
collision_layer = 8
|
||||||
|
collision_mask = 0
|
||||||
|
format = 1
|
||||||
|
tile_data = PoolIntArray( -1048576, 0, 0, -1048564, 0, 0, -983040, 0, 0, -983028, 0, 0, -917504, 0, 0, -917492, 0, 0, -851968, 0, 0, -851956, 0, 0, -786432, 0, 0, -786420, 0, 0, -720896, 0, 0, -720884, 0, 0, -655360, 0, 0, -655348, 0, 0, -589824, 0, 0, -589812, 0, 0, -524288, 0, 0, -524276, 0, 0, -458752, 0, 0, -458740, 0, 0, -393216, 0, 0, -393215, 0, 0, -393214, 0, 0, -393213, 0, 0, -393204, 0, 0, -327680, 0, 0, -327668, 0, 0, -262144, 0, 0, -262132, 0, 0, -196608, 0, 0, -196607, 0, 0, -196606, 0, 0, -196605, 0, 0, -196596, 0, 0, -131072, 0, 0, -131060, 0, 0, -65536, 0, 0, -65524, 0, 0, 0, 0, 0, 3, 0, 0, 4, 0, 0, 5, 0, 0, 12, 0, 0, 65536, 0, 0, 65544, 0, 0, 65548, 0, 0, 131072, 0, 0, 131084, 0, 0, 196608, 0, 0, 196620, 0, 0, 262144, 0, 0, 262149, 0, 0, 262154, 0, 0, 262155, 0, 0, 262156, 0, 0, 327680, 0, 0, 327681, 0, 0, 327692, 0, 0, 393216, 0, 0, 393228, 0, 0, 458752, 0, 0, 458753, 0, 0, 458754, 0, 0, 458755, 0, 0, 458756, 0, 0, 458757, 0, 0, 458758, 0, 0, 458759, 0, 0, 458760, 0, 0, 458761, 0, 0, 458762, 0, 0, 458763, 0, 0, 458764, 0, 0, 524288, 0, 0, 524289, 0, 0, 524290, 0, 0, 524291, 0, 0, 524292, 0, 0, 524293, 0, 0, 524294, 0, 0, 524295, 0, 0, 524296, 0, 0, 524297, 0, 0, 524298, 0, 0, 524299, 0, 0, 524300, 0, 0, 589824, 0, 0, 589825, 0, 0, 589826, 0, 0, 589827, 0, 0, 589828, 0, 0, 589829, 0, 0, 589830, 0, 0, 589831, 0, 0, 589832, 0, 0, 589833, 0, 0, 589834, 0, 0, 589835, 0, 0, 589836, 0, 0 )
|
||||||
|
|
||||||
|
[node name="Blobby" parent="." instance=ExtResource( 1 )]
|
||||||
|
position = Vector2( 300, 560 )
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" parent="Blobby" index="1"]
|
||||||
|
position = Vector2( 0.224487, -32.0436 )
|
||||||
|
|
||||||
|
[node name="Camera2D" parent="Blobby" index="2"]
|
||||||
|
position = Vector2( 390.714, -75 )
|
||||||
|
limit_top = -10000
|
||||||
|
limit_right = 1040
|
||||||
|
limit_bottom = 700
|
||||||
|
drag_margin_h_enabled = false
|
||||||
|
smoothing_enabled = false
|
||||||
|
editor_draw_limits = true
|
||||||
|
|
||||||
|
[node name="EnemyDetector" parent="Blobby" index="3"]
|
||||||
|
position = Vector2( 14.6832, -44.0497 )
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" parent="Blobby/EnemyDetector" index="0"]
|
||||||
|
position = Vector2( -14.4587, 12.8269 )
|
||||||
|
|
||||||
|
[node name="Enemy" parent="." instance=ExtResource( 3 )]
|
||||||
|
position = Vector2( 715.5, 560 )
|
||||||
|
|
||||||
|
[node name="Coin" parent="." instance=ExtResource( 5 )]
|
||||||
|
position = Vector2( 592, 352 )
|
||||||
|
|
||||||
|
[node name="coin" parent="Coin" index="0"]
|
||||||
|
position = Vector2( 0, 3 )
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" parent="Coin" index="1"]
|
||||||
|
position = Vector2( 0, 3 )
|
||||||
|
|
||||||
|
[node name="Coin2" parent="." instance=ExtResource( 5 )]
|
||||||
|
position = Vector2( 749, 274 )
|
||||||
|
|
||||||
|
[node name="Portal" parent="." instance=ExtResource( 8 )]
|
||||||
|
position = Vector2( 130.332, -461.479 )
|
||||||
|
next_scene = ExtResource( 7 )
|
||||||
|
|
||||||
|
[editable path="Blobby"]
|
||||||
|
|
||||||
|
[editable path="Coin"]
|
||||||
@ -7,10 +7,8 @@
|
|||||||
[ext_resource path="res://start-assets/ui_theme.tres" type="Theme" id=5]
|
[ext_resource path="res://start-assets/ui_theme.tres" type="Theme" id=5]
|
||||||
|
|
||||||
[node name="MainScreen" type="Control"]
|
[node name="MainScreen" type="Control"]
|
||||||
anchor_right = 1.25
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.2
|
anchor_bottom = 1.0
|
||||||
margin_right = -256.0
|
|
||||||
margin_bottom = -120.0
|
|
||||||
theme = ExtResource( 5 )
|
theme = ExtResource( 5 )
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user