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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions 2d/bullet_shower/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Bullet Shower

This demonstrates how to manage large amounts of objects efficiently using
low-level Servers.

See
[Optimization using Servers](https://docs.godotengine.org/en/latest/tutorials/performance/using_servers.html)
in the documentation for more information.

Language: GDScript

Renderer: GLES 2

## Screenshots

![No collision](screenshots/no_collision.png)

![Collision](screenshots/collision.png)
Binary file added 2d/bullet_shower/bullet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions 2d/bullet_shower/bullet.png.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[remap]

importer="texture"
type="StreamTexture"
path="res://.import/bullet.png-ff1424653e10246c11e3724e402c519e.stex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://bullet.png"
dest_files=[ "res://.import/bullet.png-ff1424653e10246c11e3724e402c519e.stex" ]

[params]

compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
86 changes: 86 additions & 0 deletions 2d/bullet_shower/bullets.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
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.

const BULLET_COUNT = 500
const SPEED_MIN = 20
const SPEED_MAX = 80

const bullet_image = preload("res://bullet.png")

var bullets = []
var shape


class Bullet:
var position = Vector2()
var speed = 1.0
# The body is stored as a RID, which is an "opaque" way to access resources.
# With large amounts of objects (thousands or more), it can be significantly
# faster to use RIDs compared to a high-level approach.
var body = RID()


func _ready():
randomize()

shape = Physics2DServer.circle_shape_create()
# Set the collision shape's radius for each bullet in pixels.
Physics2DServer.shape_set_data(shape, 8)

for _i in BULLET_COUNT:
var bullet = Bullet.new()
# Give each bullet its own speed.
bullet.speed = rand_range(SPEED_MIN, SPEED_MAX)
bullet.body = Physics2DServer.body_create()

Physics2DServer.body_set_space(bullet.body, get_world_2d().get_space())
Physics2DServer.body_add_shape(bullet.body, shape)

# Place bullets randomly on the viewport and move bullets outside the
# play area so that they fade in nicely.
bullet.position = Vector2(
rand_range(0, get_viewport_rect().size.x) + get_viewport_rect().size.x,
rand_range(0, get_viewport_rect().size.y)
)
var transform2d = Transform2D()
transform2d.origin = bullet.position
Physics2DServer.body_set_state(bullet.body, Physics2DServer.BODY_STATE_TRANSFORM, transform2d)

bullets.push_back(bullet)


func _process(delta):
var transform2d = Transform2D()
for bullet in bullets:
bullet.position.x -= bullet.speed * delta

if bullet.position.x < -16:
# The bullet has left the screen; move it back to the right.
bullet.position.x = get_viewport_rect().size.x + 16

transform2d.origin = bullet.position

Physics2DServer.body_set_state(bullet.body, Physics2DServer.BODY_STATE_TRANSFORM, transform2d)

# Order the CanvasItem to update since bullets are moving every frame.
update()


# Instead of drawing each bullet individually in a script attached to each bullet,
# we are drawing *all* the bullets at once here.
func _draw():
var offset = -bullet_image.get_size() * 0.5
for bullet in bullets:
draw_texture(bullet_image, bullet.position + offset)


# Perform cleanup operations (required to exit without error messages in the console).
func _exit_tree():
for bullet in bullets:
Physics2DServer.free_rid(bullet.body)

Physics2DServer.free_rid(shape)
bullets.clear()
Binary file added 2d/bullet_shower/face_happy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions 2d/bullet_shower/face_happy.png.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[remap]

importer="texture"
type="StreamTexture"
path="res://.import/face_happy.png-38d387d31ec13459f749c93ce3d75d80.stex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://face_happy.png"
dest_files=[ "res://.import/face_happy.png-38d387d31ec13459f749c93ce3d75d80.stex" ]

[params]

compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
Binary file added 2d/bullet_shower/face_sad.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions 2d/bullet_shower/face_sad.png.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[remap]

importer="texture"
type="StreamTexture"
path="res://.import/face_sad.png-0ac7165eab24f595aba17a746a66c550.stex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://face_sad.png"
dest_files=[ "res://.import/face_sad.png-0ac7165eab24f595aba17a746a66c550.stex" ]

[params]

compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
Binary file added 2d/bullet_shower/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions 2d/bullet_shower/icon.png.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[remap]

importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]

[params]

compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
33 changes: 33 additions & 0 deletions 2d/bullet_shower/player.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
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_body_shape_entered(_body_id, _body, _body_shape, _local_shape):
touching += 1
if touching >= 1:
sprite.frame = 1


func _on_body_shape_exited(_body_id, _body, _body_shape, _local_shape):
touching -= 1
if touching == 0:
sprite.frame = 0
41 changes: 41 additions & 0 deletions 2d/bullet_shower/project.godot
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters

config_version=4

_global_script_classes=[ ]
_global_script_class_icons={

}

[application]

config/name="Bullet Shower"
config/description="Demonstrates how to manage large amounts of objects efficiently using low-level Servers."
run/main_scene="res://shower.tscn"
config/icon="res://icon.png"

[display]

window/dpi/allow_hidpi=true
window/stretch/mode="2d"
window/stretch/aspect="expand"

[physics]

2d/cell_size=64
common/enable_pause_aware_picking=true

[rendering]

quality/driver/driver_name="GLES2"
quality/intended_usage/framebuffer_allocation=0
quality/intended_usage/framebuffer_allocation.mobile=0
vram_compression/import_etc=true
vram_compression/import_etc2=false
environment/default_clear_color=Color( 0.133333, 0.133333, 0.2, 1 )
Empty file.
Binary file added 2d/bullet_shower/screenshots/collision.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 2d/bullet_shower/screenshots/no_collision.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 33 additions & 0 deletions 2d/bullet_shower/shower.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[gd_scene load_steps=7 format=2]

[ext_resource path="res://bullets.gd" type="Script" id=2]
[ext_resource path="res://face_happy.png" type="Texture" id=3]
[ext_resource path="res://face_sad.png" type="Texture" id=4]
[ext_resource path="res://player.gd" type="Script" id=5]

[sub_resource type="SpriteFrames" id=1]
animations = [ {
"frames": [ ExtResource( 3 ), ExtResource( 4 ) ],
"loop": true,
"name": "default",
"speed": 5.0
} ]

[sub_resource type="CircleShape2D" id=2]
radius = 27.0

[node name="Shower" type="Node2D"]

[node name="Bullets" type="Node2D" parent="."]
script = ExtResource( 2 )

[node name="Player" type="Area2D" parent="."]
script = ExtResource( 5 )

[node name="AnimatedSprite" type="AnimatedSprite" parent="Player"]
frames = SubResource( 1 )

[node name="CollisionShape2D" type="CollisionShape2D" parent="Player"]
shape = SubResource( 2 )
[connection signal="body_shape_entered" from="Player" to="Player" method="_on_body_shape_entered"]
[connection signal="body_shape_exited" from="Player" to="Player" method="_on_body_shape_exited"]