mirror of
https://github.com/Relintai/pandemonium_demo_projects.git
synced 2024-12-21 13:56:50 +01:00
94 lines
2.9 KiB
GDScript3
94 lines
2.9 KiB
GDScript3
|
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)
|
||
|
# Don't make bullets check collision with other bullets to improve performance.
|
||
|
# Their collision mask is still configured to the default value, which allows
|
||
|
# bullets to detect collisions with the player.
|
||
|
Physics2DServer.body_set_collision_layer(bullet.body, 0)
|
||
|
|
||
|
# 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):
|
||
|
# Order the CanvasItem to update every frame.
|
||
|
update()
|
||
|
|
||
|
|
||
|
func _physics_process(delta):
|
||
|
var transform2d = Transform2D()
|
||
|
var offset = get_viewport_rect().size.x + 16
|
||
|
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 = offset
|
||
|
|
||
|
transform2d.origin = bullet.position
|
||
|
|
||
|
Physics2DServer.body_set_state(bullet.body, Physics2DServer.BODY_STATE_TRANSFORM, transform2d)
|
||
|
|
||
|
|
||
|
# 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()
|