Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port the Bullet Shower demo from Godot 2.1 #588

Merged
merged 1 commit into from
Mar 2, 2021

Conversation

Calinou
Copy link
Member

@Calinou Calinou commented Feb 28, 2021

This demo showcases how to use low-level Servers to achieve better CPU performance when drawing large amounts of objects.

The code has been updated for Godot 3.2, cleaned up and has received additional comments.

Preview

No collision

Collision

Copy link
Member

@aaronfranke aaronfranke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall the code looks good. I noticed that @reduz said here that this is "very far from being the most optimized form", so I wonder if there are ways to optimize this further without engine changes (if so, that should be done in this demo).

The images can be compressed with oxipng for slightly less file size: bullet-shower-images.zip

2d/bullet_shower/shower.gd Outdated Show resolved Hide resolved
2d/bullet_shower/shower.gd Outdated Show resolved Hide resolved
2d/bullet_shower/bullets.gd Outdated Show resolved Hide resolved
@Calinou Calinou force-pushed the readd-bullet-shower-demo branch 2 times, most recently from 616ee1b to e38e001 Compare March 1, 2021 15:13
@aaronfranke
Copy link
Member

The code in shower.gd is for the player, so I think it would make more sense to have a player.gd like this:

extends Node2D
# This demo is an example of controling a high number of 2D objects with logic
# and collision without using nodes in the scene. This technique is a lot more
# efficient than using instancing and nodes, but requires more programming and
# is less visual. Bullets are managed together in the `bullets.gd` script.

# The number of bullets currently touched by the player.
var touching = 0

onready var sprite = $AnimatedSprite


func _ready():
	# The player follows the mouse cursor automatically, so there's no point
	# in displaying the mouse cursor.
	Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)


func _input(event):
	if event is InputEventMouseMotion:
		position = event.position - Vector2(0, 16)


func _on_player_body_shape_entered(_body_id, _body, _body_shape, _local_shape):
	touching += 1
	if touching >= 1:
		sprite.frame = 1


func _on_player_body_shape_exited(_body_id, _body, _body_shape, _local_shape):
	touching -= 1
	if touching == 0:
		sprite.frame = 0

+ delete shower.gd + the signals need to be updated + maybe the comment at the top should be moved/copied to bullets.gd.

This demo showcases how to use low-level Servers to achieve better
CPU performance when drawing large amounts of objects.

The code has been updated for Godot 3.2, cleaned up and has received
additional comments.
@aaronfranke aaronfranke merged commit bbf4cff into godotengine:master Mar 2, 2021
@TackerTacker
Copy link

The bullets in this example are all set to the default collision layer so I think they are checking collisions with each other.

Adding Physics2DServer.body_set_collision_layer(bullet.body, 0) at line 41 in bullets.gd makes the example a little bit more perfomant. After this change it can handle 1600 bullets instead of 1300 without frame drops on my machine.
Though I have to say, this is still pretty low IMO, especially for an example that's suppose to be about the most efficient way of doing this.

My hardware isn't great, but I can build the same example with 7 lines of code in Construct 3 and can have 15000 bullets without dropping frames.
Is this as good as it gets, or is there something wrong with the example? I don't think this is a great look for Godot since it is specifically made as an example about performance.

@Calinou
Copy link
Member Author

Calinou commented Mar 20, 2021

After this change it can handle 1600 bullets instead of 1300 without frame drops on my machine.

See https://github.com/cart/godot3-bunnymark.

I would try building this Bullet Shower demo with nodes and see how it performs in comparison to the demo that uses servers. Due to how servers work currently, they don't bring much of a performance advantage since most of the time is still spent in the physics server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants