Hi guys, do you think this method of clamping player pos. has any drawbacks? it works exactly as intended, but sometimes I feel like I’m missing something. (obv, the min and max can be replaced with some func that finds the screen size, but I’m not there yet
)
move_and_slide()
global_position.x = clamp (global_position.x, 0, 1280)
global_position.y = clamp (global_position.y, 0 , 720)
EDIT:
replacing hard values with
get_viewport().size.[x or y]
and leaving minimum at 0 worked great, there we go. Still, question remains: Is there a drawback?
If it works, it works!
The only thing I can think of is to use clampf
instead of clamp
. The f stands for float, assumes float inputs, and gives a float output, so you can be more certain of the math going on under the hood.
In this case I think it makes no difference, but do be wary of mixing ints and floats in general, as that can result in unexpected loss of precision (rounding, but I wrote it this way because there is an engine warning that uses that term, just in case you ever see it).
Hi there!
The cleanest way I found is to directly use the clamp method of the Vector2 class like this :
var rect = get_viewport_rect()
global_position = global_position.clamp(rect.position, rect.size)
EDIT: I didn’t finished the video at the time I wrote this, but the guy ended up by writing almost the same as me ^^
3 Likes
I knew there would be someone who could do it in less if statements. I was so proud to have figured this out, but this solution is so much better than my four if statements.
I would assume we could do something very similar with the player movement? Or are the conditions necessary because it is a movement? (In my head it seems to make sense in an if statement, but so did the clamp method I applied initially).
Hi @spoopy, in fact I made a complete different thing for the player movement inspired by my previous knowledge of game dev. I’m new to Godot, but I’m not new to game dev. Instructors tends to write a much easier to understand code for people that are new to code and that is ok.
I can share with you my Player
class, I added some comments.
Basically, I’m using the _input
callback function to get a Vector2
that gives me the player direction.
Then in the _physics_process
I compute a velocity modifier according to the direction.
If the player have a zero modifier (when you press no direction on your keyboard) I apply a deceleration to give a small sliding effect to the ship so that it not stop abruptly.
I’m also using other thing like the @export
syntax for the rocket_scene
and the rocket_container
references, so you have to drag and drop the references in the Godot interface in the inspector in order to give the right reference.
Also, I certainly changed some naming compared to the original tutorial, for example "move_left"
is just "left"
in my code in the _input
function.
Feel free to ask me question, and if anyone have recommendation on my code, do not hesitate 
Have a great day!
class_name Player
extends CharacterBody2D
# This will be the factor of the direction vector to compute velocity
const ACCELERATION = 30
# This will decelerate 1/DECELERATION of the velocity each frame
const DECELERATION = 20
# These values are used to clamp the velocity
const MAX = 400
const VELOCITY_MIN = Vector2(-MAX, -MAX)
const VELOCITY_MAX = Vector2(MAX, MAX)
var life = 3
var score = 0
var direction = Vector2.ZERO
signal took_damage
signal died
@export var rocket_scene: PackedScene
@export var rocket_container: Node
func _input(event):
direction = Input.get_vector("left", "right", "up", "down")
if (Input.is_action_just_pressed("fire")):
fire()
func _physics_process(_delta):
# The modifier is the direction times the acceleration factor
var modifier = direction * ACCELERATION
# If no modifier due to direction then compute deceleration
if modifier == Vector2.ZERO:
modifier = -velocity / DECELERATION
# Add modifier to velocity
velocity += modifier
# Clamp velocity
velocity = velocity.clamp(VELOCITY_MIN, VELOCITY_MAX)
# Move
move_and_slide()
# Clamp the position to screen space
var rect = get_viewport_rect()
global_position = global_position.clamp(rect.position, rect.size)
func fire():
var r = rocket_scene.instantiate()
r.speed = 2000
r.global_position = global_position + Vector2(60, 0)
rocket_container.add_child(r)
func damage(amount = 1):
life -= amount
took_damage.emit(life)
if life <= 0:
die()
func die():
died.emit()
queue_free()
func add_score(amount):
score += amount
1 Like