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 :smiley: )

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 :slight_smile:

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

Privacy & Terms