Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Oneirality (PUBLIC DEMO)

A top-down shooter with exploration and resource management taking place in a city underneath. · By Joshulties

"Bouncing Bullet Shells"

A topic by Scel created 96 days ago Views: 59 Replies: 2
Viewing posts 1 to 2
(+1)

Hi  Joshua!

 I really liked the "Bouncing Bullet Shells" system you created. I know you're a Godot 4 developer. Could you please tell me how you implemented it? I'm really interested in learning how to create similar mechanics. Thanks in advance if you could share your knowledge.

Developer

Hello and thank you, Scel! So Oneirality is developed in Godot 3, but the bouncing bullet shells can work in Godot 4. 

Essentially, each bullet casing is a KinematicBody2D (CharacterBody2D for G4) so that it makes use of that node's physics collisions. The casings run a function in the _physics_process that will move the casing downward if its global_position.y value is not less than bound, otherwise it will multiply its velocity by -0.75 so that it bounces up and multiplies velocity.x by 0.5 so it slows down horizontally. It also runs a check to see if its velocity is below a certain threshold to tell it to set_physics_process to false. There are other functions used, but for the main bouncing, this is it. I'll paste some of the code below:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export (float) var bound = 0.0
export (int) var bound_rand = 4
export (int) var motion_rand = 150
export (float) var bound_stop = 0.75

var motion: Vector2 = Vector2(0, -200)  # When instanced, the casing will move upward already. For G4, you can put this in the _ready function.

func _instantiate():
    if not bound_rand == 0:
        bound += (randi() % bound_rand + (bound_rand / 2))
    motion.x += (randi() % motion_rand - (motion_rand / 2))
    motion.y += (randi() % (motion_rand / 2))

func apply_bound(_delta):
    # Should Fall
    if global_position.y < bound:
        motion = motion.move_toward(Vector2(motion.x, motion.y + 10.0), 10.0)
    # Should bounce
    else:
        motion.y = -0.75 * motion.y
        global_position.y -= 0.1
        motion.x = 0.5 * motion.x
        emit_signal("bound_contact")
    
    # Stop physics to prevent performance issues
    if motion.length() < bound_stop:
        set_physics_process(false)
        _bounce_stop()  # This just rounds the casings global_position to be pixel perfect
        emit_signal("bounce_stop")
    
    motion = move_and_slide(motion)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Hope this helps!

Thank you so much for the feedback! I really appreciate you taking the time to explain how your particles work! I saw your message on "X". Now I'm going to use the knowledge I gained in my projects! Thanks again!