Hi,
I’m new to Godot and have tried a simple project which has gone well up to this point, I have a simple breakout clone (Arkanoid), I have managed to get a sound effect playing when the ball hits the paddle and when the ball hits a brick, I would like a sound effect to play when the ball hits a wall.
When i use print(collider)
I can see the names of the walls the ball is hitting (UpperWall, RightWall and LeftWall) unfortunately these walls do not exist in the current scope, how can I reference these walls in my ball script?
detecting a wall should be pretty easy, something like this will do:
for i in get_slide_collision_count():
var collision = get_slide_collision(i)
if collision.get_collider() is RigidBody2D:
if collision.get_collider().is_in_group("wall"):
$Brick_Hit.play()
remember to assign the Left, Right, Upper Walls in wall group
put above code in _physics_process(delta): of Ball
My ball.tscn has 3 audio stream player nodes (one for each sound effect)
My ball script has the following code to ascertain what the ball has collided with and play the relevant sound effect.
func _physics_process(delta):
var collision = move_and_collide(velocity * ball_speed * delta)
if (!collision):
return
var collider = collision.get_collider()
print(collider) #debug only prints the object it had collided with
if collider is Brick:
collider.decrease_level()
if (collider is Brick or collider is Paddle):
ball_collision(collider)
if (collider is Paddle):
$Paddle_Bounce.play()
if (collider is Brick):
$Brick_Hit.play()
else:
velocity = velocity.bounce(collision.get_normal())
I can detect the wall with print(collider) and the console shows the UpperWall, LeftWall and Rightwall strings when the ball collides with them.
I tried your method of creating a group called “walls” from my main.tscn my _physics_process(delta) of ball.gd now looks like this
func _physics_process(delta):
var collision = move_and_collide(velocity * ball_speed * delta)
if (!collision):
return
for i in get_slide_collision_count():
var collision2 = get_slide_collision(i)
if collision2.get_collider() is RigidBody2D:
if collision2.get_collider().is_in_group("walls"):
print("Wall Hit")
$Brick_Hit.play()
var collider = collision.get_collider()
print(collider) #debug only prints the object it had collided with
if collider is Brick:
collider.decrease_level()
if (collider is Brick or collider is Paddle):
ball_collision(collider)
if (collider is Paddle):
$Paddle_Bounce.play()
if (collider is Brick):
$Brick_Hit.play()
else:
velocity = velocity.bounce(collision.get_normal())
I had to rename the variable “collision” to “collision2” due to the variable collision being in use already
I stuck a breakpoint at for i in get_slide_collision_count():
once it stops here after stepping through it skips over
this whole section
for i in get_slide_collision_count():
var collision2 = get_slide_collision(i)
if collision2.get_collider() is RigidBody2D:
if collision2.get_collider().is_in_group("walls"):
print("Wall Hit")
$Brick_Hit.play()
Hi zdrmlpzdrmlp,
Paddle is the class name for my ball paddle and Brick is the class name for an individual brick (which lives in brick.gd and brick.tscn)
I have a wall.tscn which contains a rigidbody2d , collisionshape2d and a texturerect node, in my main.tscn i have imported the wall.tscn 3 times and renamed each wall instance the following UpperWall, RightWall and LeftWall, in my ball script printing the collider shows the ball collision names of each wall.
When the ball hits a brick a different sound effect does indeed play (on every collider.decrease_level() )
extends Node
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass
extends CharacterBody2D
class_name Ball
signal life_lost
const VELOCITY_LIMIT = 40
@export var ball_speed = 15
@export var lifes = 3
@export var death_zone: DeathZone
@export var ui: UI
var speed_up_factor = 1.05
var start_position: Vector2
var last_collider_id
# Define the sound effect
var hitSound = load("res://Assets/sound/ball_bounce.wav")
@onready var collision_shape_2d = $CollisionShape2D
func _ready():
ui.set_lifes(lifes)
start_position = position
death_zone.life_lost.connect(on_life_lost)
func _physics_process(delta):
var collision = move_and_collide(velocity * ball_speed * delta)
if (!collision):
return
var collider = collision.get_collider()
print(collider) #debug only prints the object it had collided with
if collider is Brick:
collider.decrease_level()
if (collider is Brick or collider is Paddle):
ball_collision(collider)
if (collider is Paddle):
$Paddle_Bounce.play()
if (collider is Brick):
$Brick_Hit.play()
else:
velocity = velocity.bounce(collision.get_normal())
if collider is Wall:
$Wall_Hit.play()
func start_ball():
position = start_position
randomize()
velocity = Vector2(randf_range(-1, 1), randf_range(-.1, -1)).normalized() * ball_speed
func on_life_lost():
lifes -= 1
if lifes == 0:
ui.game_over()
else:
life_lost.emit()
reset_ball()
ui.set_lifes(lifes)
func reset_ball():
position = start_position
velocity = Vector2.ZERO
func ball_collision(collider):
var ball_width = collision_shape_2d.shape.get_rect().size.x
var ball_center_x = position.x
print(collider.get_width())
var collider_width = collider.get_width()
var collider_center_x = collider.position.x
var velocity_xy = velocity.length()
var collision_x = (ball_center_x - collider_center_x) / (collider_width / 2)
var new_velocity = Vector2.ZERO
new_velocity.x = velocity_xy * collision_x
if collider.get_rid() == last_collider_id && collider is Brick:
new_velocity.x = new_velocity.rotated(deg_to_rad(randf_range(-45, 45))).x * 10
else:
last_collider_id == collider.get_rid()
new_velocity.y = sqrt(absf(velocity_xy* velocity_xy - new_velocity.x * new_velocity.x)) * (-1 if velocity.y > 0 else 1)
var speed_multiplier = speed_up_factor if collider is Paddle else 1
velocity = (new_velocity * speed_multiplier).limit_length(VELOCITY_LIMIT)
zdrmlpzdrmlp,
Thankyou!
That worked perfectly, thankyou for taking the time to help me as well, after rereading the above solution it now makes sense logically.
The issue I had was a simple one… I had forgot to attach the script to the wall scene , I became too focused on the fact the wall script existed that I just forgot to check it was actually attached.