# Simplest clamping method posible

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

Yup, this works too =)

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

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)

func damage(amount = 1):
life -= amount
took_damage.emit(life)

if life <= 0:
die()

func die():
died.emit()
queue_free()