bullet texture animations
This commit is contained in:
parent
f44f38b58c
commit
3d2fde3381
11 changed files with 160 additions and 18 deletions
BIN
graphics/bullets/normal_bullet/test_bullet.png
Normal file
BIN
graphics/bullets/normal_bullet/test_bullet.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 226 B |
40
graphics/bullets/normal_bullet/test_bullet.png.import
Normal file
40
graphics/bullets/normal_bullet/test_bullet.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://c21fe72aym3fe"
|
||||||
|
path="res://.godot/imported/test_bullet.png-e27a782e7860ecdf3e348ccb8f02c46f.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://graphics/bullets/normal_bullet/test_bullet.png"
|
||||||
|
dest_files=["res://.godot/imported/test_bullet.png-e27a782e7860ecdf3e348ccb8f02c46f.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
BIN
graphics/bullets/normal_bullet/test_bullet_overlay.png
Normal file
BIN
graphics/bullets/normal_bullet/test_bullet_overlay.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 170 B |
|
|
@ -0,0 +1,40 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cgqgb84k38tbe"
|
||||||
|
path="res://.godot/imported/test_bullet_overlay.png-84014c5d26c5acae5e04b3916f24076c.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://graphics/bullets/normal_bullet/test_bullet_overlay.png"
|
||||||
|
dest_files=["res://.godot/imported/test_bullet_overlay.png-84014c5d26c5acae5e04b3916f24076c.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
|
@ -1,19 +1,35 @@
|
||||||
[gd_scene load_steps=13 format=3 uid="uid://dxsp66qpvm65b"]
|
[gd_scene load_steps=17 format=3 uid="uid://dxsp66qpvm65b"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://q2fys6o0jy6w" path="res://objects/starfield/starfield.tscn" id="1_4oowd"]
|
[ext_resource type="PackedScene" uid="uid://q2fys6o0jy6w" path="res://objects/starfield/starfield.tscn" id="1_4oowd"]
|
||||||
[ext_resource type="PackedScene" uid="uid://c714s5d7d5765" path="res://objects/player/player.tscn" id="2_j8ivh"]
|
[ext_resource type="PackedScene" uid="uid://c714s5d7d5765" path="res://objects/player/player.tscn" id="2_j8ivh"]
|
||||||
[ext_resource type="Script" uid="uid://cj2fj7snls8aa" path="res://systems/bullets/bullet_set.gd" id="3_cf1so"]
|
[ext_resource type="Script" uid="uid://cj2fj7snls8aa" path="res://systems/bullets/bullet_set.gd" id="3_cf1so"]
|
||||||
[ext_resource type="Texture2D" uid="uid://du7gh3nk66mpo" path="res://graphics/bullets/normal_bullet/bullet_1.png" id="4_hlyn7"]
|
[ext_resource type="Script" uid="uid://0ognvvq2ncd7" path="res://systems/visuals/animation_strip.gd" id="4_4oowd"]
|
||||||
[ext_resource type="Script" uid="uid://dntp60my5f65m" path="res://systems/bullets/bullet_behaviors/simple_linear_behavior.gd" id="4_t1bs8"]
|
[ext_resource type="Script" uid="uid://dntp60my5f65m" path="res://systems/bullets/bullet_behaviors/simple_linear_behavior.gd" id="4_t1bs8"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://c21fe72aym3fe" path="res://graphics/bullets/normal_bullet/test_bullet.png" id="5_4oowd"]
|
||||||
[ext_resource type="Script" uid="uid://vus1a0flwtnm" path="res://systems/bullets/bullet_preset.gd" id="6_sle1e"]
|
[ext_resource type="Script" uid="uid://vus1a0flwtnm" path="res://systems/bullets/bullet_preset.gd" id="6_sle1e"]
|
||||||
[ext_resource type="Script" uid="uid://dtuc6qerbfset" path="res://systems/bullets/spawn_patterns/ring_pattern.gd" id="6_uu3sg"]
|
[ext_resource type="Script" uid="uid://dtuc6qerbfset" path="res://systems/bullets/spawn_patterns/ring_pattern.gd" id="6_uu3sg"]
|
||||||
[ext_resource type="Script" uid="uid://ckedfcjjnv7dq" path="res://systems/bullets/spawn_patterns/spawn_pattern_randomizer.gd" id="7_4oowd"]
|
[ext_resource type="Script" uid="uid://ckedfcjjnv7dq" path="res://systems/bullets/spawn_patterns/spawn_pattern_randomizer.gd" id="7_4oowd"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://cgqgb84k38tbe" path="res://graphics/bullets/normal_bullet/test_bullet_overlay.png" id="7_sle1e"]
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_c0i5a"]
|
||||||
|
script = ExtResource("4_4oowd")
|
||||||
|
texture = ExtResource("5_4oowd")
|
||||||
|
frames = 2
|
||||||
|
fps = 10.0
|
||||||
|
metadata/_custom_type_script = "uid://0ognvvq2ncd7"
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_t1bs8"]
|
[sub_resource type="Resource" id="Resource_t1bs8"]
|
||||||
script = ExtResource("4_t1bs8")
|
script = ExtResource("4_t1bs8")
|
||||||
initial_speed = 120.0
|
initial_speed = 120.0
|
||||||
metadata/_custom_type_script = "uid://dntp60my5f65m"
|
metadata/_custom_type_script = "uid://dntp60my5f65m"
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_1xo0o"]
|
||||||
|
script = ExtResource("4_4oowd")
|
||||||
|
texture = ExtResource("7_sle1e")
|
||||||
|
frames = 2
|
||||||
|
fps = 10.0
|
||||||
|
metadata/_custom_type_script = "uid://0ognvvq2ncd7"
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_4oowd"]
|
[sub_resource type="Resource" id="Resource_4oowd"]
|
||||||
script = ExtResource("6_uu3sg")
|
script = ExtResource("6_uu3sg")
|
||||||
bullet_count = 1
|
bullet_count = 1
|
||||||
|
|
@ -34,7 +50,8 @@ metadata/_custom_type_script = "uid://ckedfcjjnv7dq"
|
||||||
[sub_resource type="Resource" id="Resource_hxqcc"]
|
[sub_resource type="Resource" id="Resource_hxqcc"]
|
||||||
script = ExtResource("6_sle1e")
|
script = ExtResource("6_sle1e")
|
||||||
behavior = SubResource("Resource_t1bs8")
|
behavior = SubResource("Resource_t1bs8")
|
||||||
textures = Array[Texture2D]([ExtResource("4_hlyn7")])
|
base_graphics = Array[ExtResource("4_4oowd")]([SubResource("Resource_c0i5a")])
|
||||||
|
overlay_graphics = Array[ExtResource("4_4oowd")]([SubResource("Resource_1xo0o")])
|
||||||
colors = Array[Color]([Color(1, 0, 0, 1), Color(0, 0, 1, 1), Color(0, 1, 0, 1), Color(1, 1, 0, 1)])
|
colors = Array[Color]([Color(1, 0, 0, 1), Color(0, 0, 1, 1), Color(0, 1, 0, 1), Color(1, 1, 0, 1)])
|
||||||
hitbox_size = Vector2i(6, 6)
|
hitbox_size = Vector2i(6, 6)
|
||||||
pattern = SubResource("Resource_sle1e")
|
pattern = SubResource("Resource_sle1e")
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,19 @@ signal recycled()
|
||||||
|
|
||||||
|
|
||||||
## Texture to draw for the bullet.
|
## Texture to draw for the bullet.
|
||||||
@export var texture: Texture2D = null:
|
@export var base_graphic: AnimationStrip = null:
|
||||||
set(value):
|
set(value):
|
||||||
texture = value
|
base_graphic = value
|
||||||
queue_redraw()
|
queue_redraw()
|
||||||
_update_visibility_notifier()
|
_update_visibility_notifier()
|
||||||
|
|
||||||
|
@export var color: Color
|
||||||
|
|
||||||
|
@export var overlay_graphic: AnimationStrip = null:
|
||||||
|
set(value):
|
||||||
|
overlay_graphic = value
|
||||||
|
queue_redraw()
|
||||||
|
|
||||||
## Size of the bullet's collision box.
|
## Size of the bullet's collision box.
|
||||||
@export var hitbox_size: Vector2i = Vector2i.ZERO:
|
@export var hitbox_size: Vector2i = Vector2i.ZERO:
|
||||||
set(value):
|
set(value):
|
||||||
|
|
@ -60,10 +67,12 @@ static func create(
|
||||||
#bullet = Bullet.new()
|
#bullet = Bullet.new()
|
||||||
var bullet := Bullet.new()
|
var bullet := Bullet.new()
|
||||||
|
|
||||||
if not preset.textures.is_empty():
|
if not preset.base_graphics.is_empty():
|
||||||
bullet.texture = preset.textures.pick_random()
|
var index = randi() % preset.base_graphics.size()
|
||||||
|
bullet.base_graphic = preset.base_graphics[index]
|
||||||
|
bullet.overlay_graphic = preset.overlay_graphics[index]
|
||||||
if not preset.colors.is_empty():
|
if not preset.colors.is_empty():
|
||||||
bullet.modulate = preset.colors.pick_random()
|
bullet.color = preset.colors.pick_random()
|
||||||
bullet.hitbox_size = preset.hitbox_size
|
bullet.hitbox_size = preset.hitbox_size
|
||||||
bullet.face_direction = preset.face_direction
|
bullet.face_direction = preset.face_direction
|
||||||
|
|
||||||
|
|
@ -103,15 +112,18 @@ func _enter_tree() -> void:
|
||||||
_update_visibility_notifier()
|
_update_visibility_notifier()
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(_delta: float) -> void:
|
||||||
if not Engine.is_editor_hint():
|
if not Engine.is_editor_hint():
|
||||||
|
queue_redraw()
|
||||||
if face_direction:
|
if face_direction:
|
||||||
rotation = direction.angle()
|
rotation = direction.angle()
|
||||||
|
|
||||||
|
|
||||||
func _draw() -> void:
|
func _draw() -> void:
|
||||||
if texture:
|
if base_graphic:
|
||||||
draw_texture(texture, -texture.get_size() * 0.5)
|
base_graphic.draw(self, time_elapsed, color)
|
||||||
|
if overlay_graphic:
|
||||||
|
overlay_graphic.draw(self, time_elapsed, Color.WHITE)
|
||||||
|
|
||||||
|
|
||||||
func _get_configuration_warnings() -> PackedStringArray:
|
func _get_configuration_warnings() -> PackedStringArray:
|
||||||
|
|
@ -121,14 +133,14 @@ func _get_configuration_warnings() -> PackedStringArray:
|
||||||
# sets the canvas item up to notify when it leaves the screen
|
# sets the canvas item up to notify when it leaves the screen
|
||||||
# this essentially mimics `VisibleOnScreenNotifier` without an additional node
|
# this essentially mimics `VisibleOnScreenNotifier` without an additional node
|
||||||
func _update_visibility_notifier() -> void:
|
func _update_visibility_notifier() -> void:
|
||||||
if not texture or not is_inside_tree() or Engine.is_editor_hint():
|
if not base_graphic or not base_graphic.texture or not is_inside_tree() or Engine.is_editor_hint():
|
||||||
return
|
return
|
||||||
|
|
||||||
# the visibility rect is set to twice the size of the texture to add a little margin
|
# the visibility rect is set to twice the size of the texture to add a little margin
|
||||||
# (func(): pass) is the cleanest way i could think of to have a callback that does nothing
|
# (func(): pass) is the cleanest way i could think of to have a callback that does nothing
|
||||||
RenderingServer.canvas_item_set_visibility_notifier(
|
RenderingServer.canvas_item_set_visibility_notifier(
|
||||||
get_canvas_item(), true,
|
get_canvas_item(), true,
|
||||||
Rect2(-texture.get_size(), texture.get_size() * 2.0),
|
Rect2(-base_graphic.texture.get_size(), base_graphic.texture.get_size() * 2.0),
|
||||||
(func(): pass), _on_screen_exited
|
(func(): pass), _on_screen_exited
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,10 @@ func deinit_bullet(bullet: Bullet) -> void:
|
||||||
|
|
||||||
## Processes one tick of a [Bullet]'s movement.
|
## Processes one tick of a [Bullet]'s movement.
|
||||||
func process_bullet(bullet: Bullet, delta: float) -> void:
|
func process_bullet(bullet: Bullet, delta: float) -> void:
|
||||||
var last_time = bullet.time_elapsed
|
#var last_time = bullet.time_elapsed
|
||||||
bullet.time_elapsed += delta
|
#bullet.time_elapsed += delta
|
||||||
if last_time < action_delay and bullet.time_elapsed >= action_delay and action_on_delay:
|
#if last_time < action_delay and bullet.time_elapsed >= action_delay and action_on_delay:
|
||||||
action_on_delay.perform(bullet)
|
#action_on_delay.perform(bullet)
|
||||||
if action_on_interval:
|
if action_on_interval:
|
||||||
_bullet_interval_cooldowns[bullet] -= delta
|
_bullet_interval_cooldowns[bullet] -= delta
|
||||||
if _bullet_interval_cooldowns[bullet] <= 0.0:
|
if _bullet_interval_cooldowns[bullet] <= 0.0:
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,22 @@
|
||||||
|
@tool
|
||||||
class_name BulletPreset
|
class_name BulletPreset
|
||||||
extends Resource
|
extends Resource
|
||||||
|
|
||||||
|
|
||||||
@export_group("Bullets")
|
@export_group("Bullets")
|
||||||
@export var behavior: BulletBehavior = null
|
@export var behavior: BulletBehavior = null
|
||||||
@export var textures: Array[Texture2D] = []
|
@export var base_graphics: Array[AnimationStrip] = []:
|
||||||
|
set(value):
|
||||||
|
base_graphics = value
|
||||||
|
if base_graphics.size() != overlay_graphics.size():
|
||||||
|
overlay_graphics.resize(base_graphics.size())
|
||||||
|
notify_property_list_changed()
|
||||||
|
@export var overlay_graphics: Array[AnimationStrip] = []:
|
||||||
|
set(value):
|
||||||
|
overlay_graphics = value
|
||||||
|
if base_graphics.size() != overlay_graphics.size():
|
||||||
|
overlay_graphics.resize(base_graphics.size())
|
||||||
|
notify_property_list_changed()
|
||||||
@export var colors: Array[Color] = [Color.WHITE]
|
@export var colors: Array[Color] = [Color.WHITE]
|
||||||
@export var hitbox_size: Vector2i = Vector2i.ZERO
|
@export var hitbox_size: Vector2i = Vector2i.ZERO
|
||||||
@export var face_direction: bool = false
|
@export var face_direction: bool = false
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ func _physics_process(delta: float) -> void:
|
||||||
|
|
||||||
for bullet in get_children():
|
for bullet in get_children():
|
||||||
if bullet is Bullet:
|
if bullet is Bullet:
|
||||||
|
bullet.time_elapsed += delta
|
||||||
preset.behavior.process_bullet(bullet, delta)
|
preset.behavior.process_bullet(bullet, delta)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
19
systems/visuals/animation_strip.gd
Normal file
19
systems/visuals/animation_strip.gd
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
class_name AnimationStrip
|
||||||
|
extends Resource
|
||||||
|
|
||||||
|
|
||||||
|
@export var texture: Texture
|
||||||
|
@export var frames: int = 1
|
||||||
|
@export var fps: float = 1.0
|
||||||
|
|
||||||
|
|
||||||
|
func draw(canvas_item: CanvasItem, time: float, modulate: Color = Color.WHITE) -> void:
|
||||||
|
var frame_size = Vector2((texture.get_width() / frames), float(texture.get_height()))
|
||||||
|
var current_frame = fmod(floorf(time * fps), frames)
|
||||||
|
print(time * fps)
|
||||||
|
canvas_item.draw_texture_rect_region(
|
||||||
|
texture,
|
||||||
|
Rect2(-frame_size * 0.5, frame_size),
|
||||||
|
Rect2(Vector2(current_frame * frame_size.x, 0.0), frame_size),
|
||||||
|
modulate
|
||||||
|
)
|
||||||
1
systems/visuals/animation_strip.gd.uid
Normal file
1
systems/visuals/animation_strip.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://0ognvvq2ncd7
|
||||||
Loading…
Add table
Add a link
Reference in a new issue