mirror of
https://github.com/GDQuest/godot-platformer-2d.git
synced 2026-07-23 19:06:56 +00:00
Merge branch 'master' of https://github.com/GDquest/godot-metroidvania-2d into redesign
This commit is contained in:
commit
bfb6f449fa
11 changed files with 147 additions and 30 deletions
|
|
@ -318,6 +318,19 @@
|
|||
|
||||
Use a new node branch for each chunk, and separate collision bodies so we can save the best ones as reusable scenes.
|
||||
|
||||
** Refining the core movement
|
||||
|
||||
After testing the level design work from Henrique, some problems with the game's controls are clearer:
|
||||
|
||||
- It's hard to catch a hook at times, as the character falls fast. You have to be too reactive with the input.
|
||||
- The camera doesn't help enough in seeing the challenges ahead, especially with vertical level design.
|
||||
|
||||
This prototype is an attempt at solving these issues:
|
||||
|
||||
- Camera design: the lookahead based on the mouse's position makes the camera jiggle too much. We've got to experiment working with the input direction and move direction of the character. Using the velocity alone makes it so the camera lags behind, while updating based on input instantly almost gives motion sickness.
|
||||
- Store input: jump after fall start, or hook
|
||||
- Allow the player to jump right after a fall started, and to hook if the input was right before actually the snap detector detected the hooking point. Maybe only when falling?
|
||||
|
||||
** TODO Predicting player motion
|
||||
:PROPERTIES:
|
||||
:EFFORT: 3:00
|
||||
|
|
|
|||
17
prototypes/1.hook-movement/CameraRig.tscn
Normal file
17
prototypes/1.hook-movement/CameraRig.tscn
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://CameraRig.gd" type="Script" id=1]
|
||||
|
||||
[node name="CameraRig" type="Position2D"]
|
||||
position = Vector2( 0, -30 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
current = true
|
||||
process_mode = 0
|
||||
drag_margin_h_enabled = false
|
||||
drag_margin_v_enabled = false
|
||||
smoothing_enabled = true
|
||||
smoothing_speed = 4.0
|
||||
editor_draw_drag_margin = true
|
||||
|
||||
5
prototypes/1.hook-movement/Game.gd
Normal file
5
prototypes/1.hook-movement/Game.gd
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
extends Node2D
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("restart"):
|
||||
get_tree().reload_current_scene()
|
||||
30
prototypes/1.hook-movement/InputContinuous.gd
Normal file
30
prototypes/1.hook-movement/InputContinuous.gd
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
"""
|
||||
Generates input events continuously based on a timer
|
||||
Allows the player to hook onto a target even if they pressed the hook key before the hook was in range
|
||||
"""
|
||||
extends Node
|
||||
|
||||
export var timer_duration: = 0.05
|
||||
|
||||
const ACTION_HOOK: = 'hook'
|
||||
|
||||
var _action_names: = []
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed(ACTION_HOOK) and not ACTION_HOOK in _action_names:
|
||||
_action_names.append(ACTION_HOOK)
|
||||
_remove_delayed(_action_names.size() - 1, timer_duration)
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
for action_name in _action_names:
|
||||
var event: = InputEventAction.new()
|
||||
event.action = action_name
|
||||
event.pressed = true
|
||||
Input.parse_input_event(event)
|
||||
|
||||
|
||||
# Coroutine
|
||||
func _remove_delayed(action_id:int, delay:float) -> void:
|
||||
yield(get_tree().create_timer(delay), "timeout")
|
||||
_action_names.remove(action_id)
|
||||
|
|
@ -21,4 +21,8 @@ func update_position(velocity:Vector2) -> void:
|
|||
_camera.position = distance_ratio * mouse_position.normalized() * offset
|
||||
|
||||
Settings.GAMEPAD:
|
||||
_camera.position = ControlUtils.get_aim_joystick_direction() * offset
|
||||
var joystick_direction: = get_aim_joystick_direction()
|
||||
if Input.is_action_pressed("move_right") or Input.is_action_pressed("move_left"):
|
||||
_camera.position.x = sign(velocity.x) * offset.x
|
||||
_camera.position.y = joystick_direction.y * offset.y
|
||||
|
||||
|
|
|
|||
|
|
@ -38,16 +38,7 @@ func _physics_process(delta: float) -> void:
|
|||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("hook") and _can_hook():
|
||||
cooldown.start()
|
||||
arrow.hook_position = (
|
||||
snap_detector.target.global_position
|
||||
if snap_detector.target != null
|
||||
else ray.get_collision_point())
|
||||
|
||||
if aim_mode == true:
|
||||
self.aim_mode = false
|
||||
|
||||
emit_signal("hooked_onto_target", _get_hook_position())
|
||||
_hook()
|
||||
get_tree().set_input_as_handled()
|
||||
|
||||
if event.is_action_pressed("aim"):
|
||||
|
|
@ -55,7 +46,15 @@ func _unhandled_input(event: InputEvent) -> void:
|
|||
get_tree().set_input_as_handled()
|
||||
|
||||
|
||||
func set_aim_mode(value: bool) -> void:
|
||||
func _hook() -> void:
|
||||
cooldown.start()
|
||||
arrow.hook_position = snap_detector.target.global_position if snap_detector.target else ray.get_collision_point()
|
||||
if aim_mode:
|
||||
self.aim_mode = false
|
||||
emit_signal("hooked_onto_target", _get_hook_position())
|
||||
|
||||
|
||||
func set_aim_mode(value:bool) -> void:
|
||||
aim_mode = value
|
||||
Engine.time_scale = 0.05 if aim_mode == true else 1.0
|
||||
|
||||
|
|
@ -79,6 +78,21 @@ func _get_hook_position() -> Vector2:
|
|||
func _get_aim_direction() -> Vector2:
|
||||
match Settings.controls:
|
||||
Settings.GAMEPAD:
|
||||
return ControlUtils.get_aim_joystick_direction()
|
||||
return get_aim_joystick_direction()
|
||||
Settings.KBD_MOUSE, _:
|
||||
return (get_global_mouse_position() - global_position).normalized()
|
||||
|
||||
|
||||
# FIXME
|
||||
static func get_aim_joystick_direction() -> Vector2:
|
||||
var use_right_stick: bool = ProjectSettings.get_setting('debug/testing/controls/use_right_stick')
|
||||
|
||||
# FIXME: axes should be 2 and 3, or RX and RY, is there a calibration issue with the gamepad?
|
||||
if use_right_stick:
|
||||
return Vector2(
|
||||
Input.get_joy_axis(0, JOY_AXIS_3),
|
||||
Input.get_joy_axis(0, JOY_AXIS_4)).normalized()
|
||||
else:
|
||||
return Vector2(
|
||||
Input.get_joy_axis(0, JOY_AXIS_0),
|
||||
Input.get_joy_axis(0, JOY_AXIS_1)).normalized()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ onready var ray_top: RayCast2D = $RayTop
|
|||
|
||||
onready var _offset: float = ray_bottom.position.x
|
||||
|
||||
export var active: = true setget set_active
|
||||
|
||||
export var ray_length: = 30.0 setget set_ray_length
|
||||
|
||||
var _ray_cast_to_x: = ray_length setget _set_ray_cast_to_x
|
||||
|
|
@ -17,6 +19,9 @@ func _ready() -> void:
|
|||
|
||||
|
||||
func is_against_ledge(look_direction: int) -> bool:
|
||||
if not active:
|
||||
return false
|
||||
|
||||
self._ray_cast_to_x = ray_length * look_direction
|
||||
ray_bottom.force_raycast_update()
|
||||
ray_top.force_raycast_update()
|
||||
|
|
@ -38,3 +43,7 @@ func _set_ray_cast_to_x(value: float) -> void:
|
|||
ray_top.cast_to = cast_to
|
||||
ray_bottom.position.x = sign(value) * _offset
|
||||
ray_top.position.x = sign(value) * _offset
|
||||
|
||||
|
||||
func set_active(value:bool) -> void:
|
||||
active = value
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
[ext_resource path="res://src/Actors/Player/Body.gd" type="Script" id=6]
|
||||
[ext_resource path="res://src/Actors/Player/CameraRig.gd" type="Script" id=7]
|
||||
|
||||
|
||||
[sub_resource type="RectangleShape2D" id=1]
|
||||
extents = Vector2( 30, 30 )
|
||||
|
||||
|
|
@ -23,6 +22,8 @@ shape = SubResource( 1 )
|
|||
position = Vector2( 0, -30 )
|
||||
|
||||
[node name="LedgeDetector" parent="." instance=ExtResource( 3 )]
|
||||
active = true
|
||||
ray_length = 30.0
|
||||
|
||||
[node name="FloorDetector" type="RayCast2D" parent="."]
|
||||
position = Vector2( 0, -30 )
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=9 format=2]
|
||||
[gd_scene load_steps=10 format=2]
|
||||
|
||||
[ext_resource path="res://assets/theme/gdquest.theme" type="Theme" id=1]
|
||||
[ext_resource path="res://src/UI/Title.tscn" type="PackedScene" id=2]
|
||||
|
|
@ -33,6 +33,7 @@ func _on_Settings_controls_changed(controls:int) -> void:
|
|||
radius = 401.995
|
||||
|
||||
[node name="Game" type="Node2D"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="TopLayer" type="CanvasLayer" parent="."]
|
||||
editor/display_folded = true
|
||||
|
|
@ -42,7 +43,7 @@ editor/display_folded = true
|
|||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
mouse_filter = 2
|
||||
theme = ExtResource( 1 )
|
||||
theme = ExtResource( 2 )
|
||||
__meta__ = {
|
||||
"_edit_group_": true,
|
||||
"_edit_lock_": true
|
||||
|
|
@ -62,7 +63,7 @@ margin_top = 40.0
|
|||
margin_right = -40.0
|
||||
margin_bottom = -40.0
|
||||
|
||||
[node name="Title" parent="TopLayer/UI/Panel/Column" instance=ExtResource( 2 )]
|
||||
[node name="Title" parent="TopLayer/UI/Panel/Column" instance=ExtResource( 3 )]
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
|
|
@ -78,7 +79,7 @@ margin_top = 44.0
|
|||
margin_right = 280.0
|
||||
margin_bottom = 70.0
|
||||
text = "Player info"
|
||||
script = ExtResource( 3 )
|
||||
script = ExtResource( 4 )
|
||||
|
||||
[node name="InfoLabel2" type="Label" parent="TopLayer/UI/Panel/Column"]
|
||||
margin_top = 78.0
|
||||
|
|
@ -190,31 +191,55 @@ collision_mask = 0
|
|||
[node name="1" type="CollisionPolygon2D" parent="HookableWall"]
|
||||
polygon = PoolVector2Array( -40, -160, 0, -160, 0, 120, -40, 120 )
|
||||
|
||||
[node name="HookTarget1" parent="." instance=ExtResource( 5 )]
|
||||
[node name="HookTarget1" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 1680, 480 )
|
||||
|
||||
[node name="HookTarget4" parent="." instance=ExtResource( 5 )]
|
||||
[node name="HookTarget4" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 3360, 720 )
|
||||
|
||||
[node name="HookTarget6" parent="." instance=ExtResource( 5 )]
|
||||
[node name="HookTarget6" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 3880, 440 )
|
||||
|
||||
[node name="HookTarget5" parent="." instance=ExtResource( 5 )]
|
||||
[node name="HookTarget5" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 2964, 440 )
|
||||
|
||||
[node name="HookTarget7" parent="." instance=ExtResource( 5 )]
|
||||
[node name="HookTarget7" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 2560, -212 )
|
||||
|
||||
[node name="HookTarget8" parent="." instance=ExtResource( 5 )]
|
||||
[node name="HookTarget8" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 2960, -360 )
|
||||
|
||||
[node name="HookTarget9" parent="." instance=ExtResource( 5 )]
|
||||
position = Vector2( 3400, -400 )
|
||||
[node name="HookTarget9" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 3360, -400 )
|
||||
|
||||
[node name="HookTarget2" parent="." instance=ExtResource( 5 )]
|
||||
[node name="HookTarget10" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 3240, -720 )
|
||||
|
||||
[node name="HookTarget11" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 2800, -720 )
|
||||
|
||||
[node name="HookTarget12" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 2400, -760 )
|
||||
|
||||
[node name="HookTarget13" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 2680, -1080 )
|
||||
|
||||
[node name="HookTarget14" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 3000, -960 )
|
||||
|
||||
[node name="HookTarget15" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 3440, -1000 )
|
||||
|
||||
[node name="HookTarget16" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 3680, -720 )
|
||||
|
||||
[node name="HookTarget17" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 4000, -960 )
|
||||
|
||||
[node name="HookTarget2" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 1960, 190 )
|
||||
|
||||
[node name="HookTarget3" parent="." instance=ExtResource( 5 )]
|
||||
[node name="HookTarget3" parent="." instance=ExtResource( 6 )]
|
||||
position = Vector2( 1640, -240 )
|
||||
|
||||
[node name="Flag" type="Node2D" parent="."]
|
||||
|
|
@ -239,6 +264,7 @@ end_cap_mode = 2
|
|||
|
||||
[node name="ZeroGravityArea" type="Area2D" parent="."]
|
||||
editor/display_folded = true
|
||||
visible = false
|
||||
position = Vector2( 2720, -280 )
|
||||
__meta__ = {
|
||||
"_edit_group_": true
|
||||
|
|
|
|||
|
|
@ -212,4 +212,3 @@ default_color = Color( 0.815686, 0.709804, 0.435294, 1 )
|
|||
texture_mode = 8
|
||||
begin_cap_mode = 2
|
||||
end_cap_mode = 2
|
||||
|
||||
|
|
|
|||
|
|
@ -5,4 +5,3 @@
|
|||
[resource]
|
||||
background_mode = 2
|
||||
background_sky = SubResource( 1 )
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue