Created
March 8, 2023 17:51
-
-
Save N-Carter/cd92bf0eb2c6e6dea269d70ef268138a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends Area2D | |
@export var _walk_speed := 50.0 | |
@export var _jump_speed := 300.0 | |
var _gravity : float = ProjectSettings.get_setting("physics/2d/default_gravity") | |
@onready var _tilemap := Global.tilemap | |
var _velocity : Vector2 | |
var _is_solid_left : bool | |
var _is_solid_right : bool | |
var _is_solid_above : bool | |
var _is_solid_below : bool | |
const TILE_SIZE := 16.0 | |
const TILE_HALF_SIZE := TILE_SIZE * 0.5 | |
func _physics_process(delta : float) -> void: | |
if _is_solid_below: | |
if Input.is_action_just_pressed("action"): | |
_velocity.y = -_jump_speed | |
else: | |
_velocity.y = 0.0 | |
else: | |
_velocity.y += _gravity * delta | |
var direction := Input.get_axis("left", "right") | |
if direction: | |
_velocity.x = direction * _walk_speed | |
else: | |
_velocity.x = move_toward(_velocity.x, 0, _walk_speed) | |
var new_position := global_position + _velocity * delta | |
_is_solid_left = _is_tile_solid(new_position + Vector2(-TILE_HALF_SIZE, 0)) | |
_is_solid_right = _is_tile_solid(new_position + Vector2(TILE_HALF_SIZE, 0)) | |
_is_solid_above = _is_tile_solid(new_position + Vector2(0, -TILE_HALF_SIZE)) | |
_is_solid_below = _is_tile_solid(new_position + Vector2(0, TILE_HALF_SIZE)) | |
# var mod_y := fposmod(new_position.y, TILE_SIZE) | |
# if _is_solid_below and mod_y > TILE_HALF_SIZE: | |
# new_position.y = snappedf(new_position.y, TILE_SIZE) - TILE_HALF_SIZE | |
# if _is_solid_above and mod_y < TILE_HALF_SIZE: | |
# new_position.y = snappedf(new_position.y, TILE_SIZE) + TILE_HALF_SIZE | |
# These only consider tiles to the immediate left or right, but it's also important to consider | |
# tiles which are above or below to the left and right. I think it's necessary to test three | |
# tiles relative to the player's position: | |
# | |
# +-------+-------+ | |
# |√ |√ | ∙ : tile centre | |
# | ∙ | ∙ | √ : tiles to check | |
# | | | + : player's centre in the tile is closest to the marked tiles | |
# +-------+-------+ | |
# |√ | + | | |
# | ∙ | ∙ | | |
# | | | | |
# +-------+-------+ | |
# | |
# The other thing is that you need to determine which obstruction you hit first, and that | |
# depends on your direction of travel. | |
# | |
# What about integer coordinates and velocity? | |
if _is_solid_left or _is_solid_right: | |
new_position.x = snappedf_round(new_position.x, TILE_SIZE) - TILE_HALF_SIZE | |
if _is_solid_above or _is_solid_below: | |
new_position.y = snappedf_round(new_position.y, TILE_SIZE) - TILE_HALF_SIZE | |
global_position = new_position | |
func _is_tile_solid(where : Vector2) -> bool: | |
# "where" is in global coordinates. | |
var tile_coordinates := _tilemap.local_to_map(_tilemap.to_local(where)) | |
var source := _tilemap.get_cell_source_id(0, tile_coordinates) | |
# var atlas_coords := _tilemap.get_cell_atlas_coords(0, tile_coordinates) | |
# print("%s, %s, %s" % [tile_coordinates, source, atlas_coords]) | |
return (source >= 0) | |
func snappedf_round(p_value : float, p_step : float) -> float: | |
if p_step != 0.0: | |
p_value = roundf(p_value / p_step + 0.5) * p_step; | |
return p_value |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment