Im trying to make it so that when the paddle in my pong game hits the ball to the same direction it was already moving towards it gets a speed boost and acts like it was impacted instead just being pushed by the paddle like this:
| → O →
I want my game’s physics to be like the game, “paddle force” on itch.io
My paddle code:
extends CharacterBody2D
@onready var charge_time: Timer = $charge_time
@onready var ball
const SPEED = 300.0
@export var rotation_speed = 3 # Speed of rotation
@export var speed = 100.0 # Movement speed
var speed_up: float = 0
var is_moving: bool = false
var rotation_delta: float = 0
var current_rotation: float = 0
@onready var paddle_image: Sprite2D = $Paddle_image
@onready var size: float = 0
func _ready() -> void:
ball = get_parent().get_node("offline_ball")
size = paddle_image.texture.get_size().x
charge_time.timeout.connect(on_charge_timeout)
func _physics_process(delta: float) -> void:
if !is_multiplayer_authority(): return
current_rotation = rotation
var direction := Input.get_axis("Left", "Right")
var direction_hor := Input.get_axis("up", "down")
velocity.x = direction * SPEED if direction else move_toward(velocity.x, 0, SPEED)
velocity.y = direction_hor * SPEED if direction_hor else move_toward(velocity.y, 0, SPEED)
move_and_slide()
if Input.is_action_pressed("Rotate clockwise"):
rotation -= rotation_speed * delta
elif Input.is_action_pressed("Rotate counter clockwise"):
rotation += rotation_speed * delta
is_it_moving()
func is_it_moving() -> void:
rotation_delta = abs(rotation - current_rotation)
is_moving = velocity.length() > 0 or rotation_delta > 0.001
if is_moving and !charge_time.is_stopped():
pass # timer already running
elif is_moving:
charge_time.start(0.2) # start 1-second timer
else:
speed_up = 0
charge_time.stop()
func on_charge_timeout() -> void:
if is_moving:
speed_up = min(speed_up + 10, 300)
print(speed_up)
charge_time.start(0.2) # restart timer for next second
My ball code:
extends StaticBody2D
@onready var speed_timer: Timer = $speed_timer
var screen_size: Vector2
var dir = get_ran_dir()
var speed = 100
var out_bounds: bool = false
var middle = Vector2()
var high: bool
var low: bool
var can_collide := true
@onready var paddle
@onready var physics: Node = $Ball_physics
func _ready() -> void:
paddle = get_parent().get_node("Offlinepaddle")
screen_size = get_viewport_rect().size
position = Vector2(screen_size.x / 2, screen_size.y / 2)
func _physics_process(delta: float) -> void:
var collision = move_and_collide(dir * speed * delta)
if can_collide and collision:
var collider = collision.get_collider()
if collision && collider != paddle:
speed *= 1.2
dir = dir.bounce(collision.get_normal())
temp_pause()
elif collision && collider == paddle:
speed += paddle.speed_up
position += collision.get_normal() * 4
dir = dir.bounce(collision.get_normal())
temp_pause()
position_tracking()
func temp_pause() -> void:
physics.disabled = true
can_collide = false
speed_timer.start()
func _on_speed_timer_timeout() -> void:
physics.disabled = false
can_collide = true
func get_ran_dir() -> Vector2:
var new_dir = Vector2()
new_dir.x = [1,-1].pick_random()
new_dir.y = [1,-1].pick_random()
return new_dir.normalized()
func position_tracking() -> void:
high = position.x >= screen_size.x / 1.01 or position.y >= screen_size.y
low = position.x <= -screen_size.x / 1.01 or position.y <= -screen_size.y
middle = Vector2(screen_size.x / 2, screen_size.y / 2)
screen_size = get_viewport_rect().size
if high or low:
position = middle
speed = 100
print("return")
To be clear the issue seems to be the fact that when the paddle moves to the ball on the same trajectory the ball doesn’t seem to recognize the collision.