Created
November 14, 2023 12:20
-
-
Save marinho/542b0677ddcb01116fb172a487bd3472 to your computer and use it in GitHub Desktop.
Code to leave an ink print on ground as the player moves
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Godot; | |
using System.Linq; | |
using System.Collections.Generic; | |
using Isometric3DEngine; | |
public partial class InkCanvas : Node3D | |
{ | |
[Export] | |
public int MaximumAmountOfDrops = 100; | |
[Export] | |
public Sprite3D InkDropSprite; | |
[Export] | |
public Sprite3D InkSplashSprite; | |
[Export] | |
public float InkDropDistance = 0.1f; | |
[Export] | |
public float InkDropDistanceWhenEnding = 0.2f; | |
[Export] | |
public Vector3 PositionOffset = Vector3.Zero; | |
[Export] | |
public float InkDropScale = 1.0f; | |
[ExportGroup("Random")] | |
[Export] | |
public Vector3 RandomRotation = Vector3.Zero; | |
[Export] | |
public Vector3 RandomScale = Vector3.Zero; | |
[Export] | |
public Vector3 RandomOffset = Vector3.Zero; | |
[Export] | |
public float RandomAlpha = 0f; | |
List<Sprite3D> InkDrops; | |
ColorPalette _ColorPalette = (ColorPalette) | |
ResourceLoader.Load("res://resources/color_palette.tres"); | |
// method that runs when the node is ready | |
public override void _Ready() | |
{ | |
InkDrops = new List<Sprite3D>(); | |
} | |
public bool InkDrop(Vector3 position, bool isEnding, ColorPaletteChoices inkColorChoice) | |
{ | |
if (HasInkAtPosition(position, isEnding)) | |
return false; | |
var sprite = GetInkSprite(); | |
Color inkColor = _ColorPalette.GetColor(inkColorChoice); | |
ApplyInkSprite(sprite, position, inkColor, InkDropSprite); | |
return true; | |
} | |
public bool InkSplash(Vector3 position, ColorPaletteChoices inkColorChoice) | |
{ | |
var sprite = GetInkSprite(); | |
Color inkColor = _ColorPalette.GetColor(inkColorChoice); | |
ApplyInkSprite(sprite, position, inkColor, InkSplashSprite); | |
return true; | |
} | |
void ApplyInkSprite(Sprite3D sprite, Vector3 position, Color inkColor, Sprite3D spriteToCopy) | |
{ | |
sprite.Texture = spriteToCopy.Texture; | |
sprite.Modulate = new Color( | |
inkColor.R, | |
inkColor.G, | |
inkColor.B, | |
(float)GD.RandRange(inkColor.A - RandomAlpha, inkColor.A) | |
); | |
sprite.Transform = new Transform3D(Basis.Identity, Vector3.Zero); | |
sprite.GlobalPosition = RandomizePosition(position); | |
sprite.Rotation = RandomizeRotation(spriteToCopy.Rotation); | |
sprite.Scale = RandomizeScale(spriteToCopy.Scale * InkDropScale); | |
sprite.Visible = true; | |
} | |
Vector3 RandomizePosition(Vector3 position) | |
{ | |
var randomPosition = new Vector3( | |
position.X + (float)GD.RandRange(-RandomOffset.X, RandomOffset.X), | |
position.Y + (float)GD.RandRange(-RandomOffset.Y, RandomOffset.Y), | |
position.Z + (float)GD.RandRange(-RandomOffset.Z, RandomOffset.Z) | |
); | |
return randomPosition + PositionOffset; | |
} | |
Vector3 RandomizeRotation(Vector3 rotation) | |
{ | |
return new Vector3( | |
rotation.X + (float)GD.RandRange(-RandomRotation.X, RandomRotation.X), | |
rotation.Y + (float)GD.RandRange(-RandomRotation.Y, RandomRotation.Y), | |
rotation.Z + (float)GD.RandRange(-RandomRotation.Z, RandomRotation.Z) | |
); | |
} | |
Vector3 RandomizeScale(Vector3 scale) | |
{ | |
return new Vector3( | |
scale.X + (float)GD.RandRange(-RandomScale.X, RandomScale.X), | |
scale.Y + (float)GD.RandRange(-RandomScale.Y, RandomScale.Y), | |
scale.Z + (float)GD.RandRange(-RandomScale.Z, RandomScale.Z) | |
); | |
} | |
private Sprite3D GetInkSprite() | |
{ | |
Sprite3D result; | |
if (InkDrops.Count >= MaximumAmountOfDrops) | |
{ | |
result = InkDrops[0]; | |
InkDrops.RemoveAt(0); | |
} | |
else | |
{ | |
result = new Sprite3D(); | |
AddChild(result); | |
} | |
InkDrops.Add(result); | |
result.Visible = false; | |
return result; | |
} | |
private bool HasInkAtPosition(Vector3 position, bool inkIsEnding) | |
{ | |
float dropDistance = inkIsEnding ? InkDropDistanceWhenEnding : InkDropDistance; | |
// get the number of children in InkParentPath that are positioned at the same X and Z as the player, with a radius of 0.5 | |
var spritesWithinRadius = InkDrops | |
.Where(child => child is Sprite3D && child.Visible) | |
.Select(child => (Sprite3D)child) | |
.Where( | |
child => | |
child is Sprite3D && child.GlobalPosition.DistanceTo(position) < dropDistance | |
); | |
// if there are more than 0 children, return | |
return spritesWithinRadius.Count() > 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment