Godot Version
4.2.1
Explanation
I’m fairly new to programming and Godot and I’m trying to recreate the shield from SpaceMaster X-7 for the Atari 2600. It’s a diamond shaped line with collision detection.
What I now have in Godot is a Node2D called ShieldControl, which contains the script.
Then I have an Area2D called ShieldCollision with a CollisionPolygon2D as a child for collision detection.
And I have a Line2D called ShieldLine, which just draws the line on the screen.
Here is the code that is in the ShieldControl script.
extends Node2D
@onready var Collision = $ShieldCollision/CollisionPolygon2D;
@onready var ShieldLine = $ShieldLine;
# Movement shield line and collision
const move_speed_x_base = 15;
const move_speed_y_base = 7;
var move_multiplier = 0.9;
var move_speed_x = move_speed_x_base * move_multiplier;
var move_speed_y = move_speed_y_base * move_multiplier;
var direction_collision = 1;
var direction_shieldline = 1;
func _physics_process(delta):
shield_movement();
func shield_movement():
# Shield line
if ShieldLine.points[0].y <= 16:
direction_shieldline = -direction_shieldline;
elif ShieldLine.points[0].y >= 56:
direction_shieldline = -direction_shieldline;
# Collision field
if Collision.polygon[0].y <= -56:
direction_collision = -direction_collision;
elif Collision.polygon[0].y >= -16:
direction_collision = -direction_collision;
# Shield line
ShieldLine.points[0].y += direction_shieldline * move_speed_y * get_process_delta_time();
ShieldLine.points[1].x -= direction_shieldline * move_speed_x * get_process_delta_time();
ShieldLine.points[2].y -= direction_shieldline * move_speed_y * get_process_delta_time();
ShieldLine.points[3].x += direction_shieldline * move_speed_x * get_process_delta_time();
ShieldLine.points[4].y += direction_shieldline * move_speed_y * get_process_delta_time();
# Collision positions
Collision.polygon[0].y += direction_collision * move_speed_y * get_process_delta_time();
Collision.polygon[1].x -= direction_collision * move_speed_x * get_process_delta_time();
Collision.polygon[2].y -= direction_collision * move_speed_y * get_process_delta_time();
Collision.polygon[3].x += direction_collision * move_speed_x * get_process_delta_time();
func _on_area_entered(area):
if area.is_in_group("PlayerBullet"):
area.queue_free();
if area.is_in_group("Player"):
area.death();
In the function shield_movement() I have the code to move the first point of the CollisionPolygon2D up and down.
If the point goes below 16 or above 56 it will flip the direction (basically flipping 1 to -1 and visa versa).
Then I apply the movement to the different points. The y-axis moves at a different speed than the x-axis, so the diamond shape will remain shaped like that. And all the points ‘listen’ to the direction flipping, so when point 0 flips, the others will as well.
The problem
When starting the game, sometimes the shield won’t start. And sometimes when it did start, it will get stuck at one of the outer ends and jitter at the position.
I know why, but I don’t know how to solve it.
When it gets stuck, it’s because it went out of the allowed position, but the move_speed wasn’t quick enough to get back into the allowed position within 1 frame or so, so it will flip the direction again and then will be out of the allowed position for ever.
At the start, it probably moves out of the allowed position immediately, so it can’t get back in and gets stuck.
I think it has something to do with the clamp function, but I can’t figure out how to apply it in my code.
Questions
Does it indeed have to do with the clamp function? And if so, how do I apply that to my code?
And what is a better way to code the constant up and down movement?