2D multiplayer platformer using Godot Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

102 lines
3.3 KiB

class_name Bullet
extends Node2D
const LIFE_TIME := 0.6
const FADE_TIME := 0.6
var direction : Vector2
var effective_range : float
var maximum_range : float
var velocity : float
var damage : float
var color : Color
var _start_position : Vector2
var _age := 0.0
var _distance := 0.0
func _init(
position : Vector2,
direction : Vector2,
effective_range : float,
maximum_range : float,
velocity : float,
damage : float,
color : Color,
) -> void:
_start_position = position
self.position = position
self.direction = direction
self.effective_range = effective_range
self.maximum_range = maximum_range
self.velocity = velocity
self.damage = damage
self.color = color
func _on_collide(obj: CollisionObject2D, hit_position: Vector2) -> void:
# TODO: Add a global game setting to specify whether shooter or server announces successful hit.
# For now, server is the most straight-forward. Eventually, support client predictive movement?
pass
# protected virtual void OnCollide(CollisionObject2D obj, Vector2 hitPosition)
# {
# // TODO: Add a global game setting to specify whether shooter or server announces successful hit.
# // For now, server is the most straight-forward. Eventually, support client predictive movement?
# if (!(this.GetGame() is Server) || !(obj.GetNodeOrNull("Sprite2D") is Sprite2D sprite)) return;
# var world = this.GetWorld3d();
# var path = world.GetPathTo(sprite);
# var color = new Color(Color, (1 + Color.a) / 2);
# RPC.Reliable(world.GetPlayersTracking(BlockPos.FromVector(obj.GlobalPosition).ToChunkPos()),
# world.SpawnHit, path, hitPosition, color);
# if (obj is Player player) {
# var rangeFactor = Math.Min(1.0F, (MaximumRange - _distance) / (MaximumRange - EffectiveRange));
# player.Health -= Damage * rangeFactor;
# }
# // TODO: Also spawn a ghost of the player who was hit so they can see where they got shot?
# }
func _process(delta: float) -> void:
if _age > LIFE_TIME:
modulate = Color(modulate, modulate.a - delta / FADE_TIME)
if modulate.a <= 0: queue_free()
_age += delta
func _physics_process(delta: float) -> void:
var previous_position := position
_distance = min(maximum_range, velocity * _age)
position = _start_position + direction * _distance
var mask := PhysicsLayer.WORLD | PhysicsLayer.PLAYERS
var ray := PhysicsRayQueryParameters2D.create(previous_position, position, mask)
var result := get_world_2d().direct_space_state.intersect_ray(ray)
if !result.is_empty():
position = result.position as Vector2
_distance = _start_position.distance_to(position)
var obj := result.collider as CollisionObject2D
if obj: _on_collide(obj, position - obj.global_position)
set_physics_process(false)
if _distance > maximum_range:
set_physics_process(false)
queue_redraw()
func _draw() -> void:
var points: Array[Vector2]
var colors: Array[Color]
if _distance > 16:
points.append(Vector2.ZERO)
colors.append(Color(color, color.a * minf(1, 1 - (_distance - effective_range) / (maximum_range - effective_range))))
if _distance > effective_range:
points.append(direction * -(_distance - effective_range))
colors.append(color)
points.append(direction * -maxf(0.0, _distance - 16))
colors.append(color)
points.append(direction * -_distance)
colors.append(Color(color, 0.0))
draw_polyline_colors(points, colors, 1.5, true)