From 1a463f8edfaddc8ffe3926edadee321a15477da1 Mon Sep 17 00:00:00 2001 From: orosmatthew Date: Mon, 7 Feb 2022 12:30:45 -0500 Subject: [PATCH] added mouse interaction for #2 --- ParticleSimulation/ParticleNode.tscn | 1 - ParticleSimulation/ParticleSimulationScene.cs | 36 +++++++ .../ParticleSimulationScene.tscn | 8 +- .../Simulation/ParticleSimulation.cs | 89 +++++++++++------- project.godot | 5 + textures/interaction_circle.png | Bin 0 -> 11289 bytes textures/interaction_circle.png.import | 35 +++++++ 7 files changed, 136 insertions(+), 38 deletions(-) create mode 100644 textures/interaction_circle.png create mode 100644 textures/interaction_circle.png.import diff --git a/ParticleSimulation/ParticleNode.tscn b/ParticleSimulation/ParticleNode.tscn index 4f37f7e..450c027 100644 --- a/ParticleSimulation/ParticleNode.tscn +++ b/ParticleSimulation/ParticleNode.tscn @@ -3,7 +3,6 @@ [ext_resource path="res://ParticleSimulation/ParticleNode.cs" type="Script" id=1] [ext_resource path="res://textures/particle_noborder.png" type="Texture" id=2] - [node name="ParticleNode" type="Node2D"] script = ExtResource( 1 ) diff --git a/ParticleSimulation/ParticleSimulationScene.cs b/ParticleSimulation/ParticleSimulationScene.cs index b9a66fa..92b3fa3 100644 --- a/ParticleSimulation/ParticleSimulationScene.cs +++ b/ParticleSimulation/ParticleSimulationScene.cs @@ -21,8 +21,13 @@ public class ParticleSimulationScene : Node2D private ParticleSimulation _particleSimulation; public float PhysicsInterpolationFraction; + private bool _wasInteractPrevEnabled; + private Vector2 _prevMousePos; + public void Initialize(int seed, int nParticles, float zoom) { + _wasInteractPrevEnabled = false; + _prevMousePos = new Vector2(); _maxZoom = zoom; _camera = GetNode("Camera2D"); _cameraTween = GetNode("CameraTween"); @@ -51,6 +56,16 @@ public class ParticleSimulationScene : Node2D if (Input.IsActionJustPressed("reset")) GetParent
().RestartSimulation(); + if (Input.IsActionPressed("enable_interaction")) + { + GetNode("InteractionCircleSprite").Show(); + GetNode("InteractionCircleSprite").Position = GetGlobalMousePosition(); + } + else + { + GetNode("InteractionCircleSprite").Hide(); + } + var shouldTweenStop = false; if (Input.IsActionJustReleased("zoom_in")) @@ -136,6 +151,27 @@ public class ParticleSimulationScene : Node2D public override void _PhysicsProcess(float delta) { + if (Input.IsActionPressed("enable_interaction")) + { + if (_wasInteractPrevEnabled) + { + var mouseVel = GetGlobalMousePosition() - _prevMousePos; + mouseVel /= 5f; + + _prevMousePos = GetGlobalMousePosition(); + _particleSimulation.SetInteractionCircle(GetGlobalMousePosition() + (_spaceSize / 2.0f), 70f, mouseVel); + } + else + { + _wasInteractPrevEnabled = true; + _prevMousePos = GetGlobalMousePosition(); + _particleSimulation.SetInteractionCircle(GetGlobalMousePosition() + (_spaceSize / 2.0f), 70f, Vector2.Zero); + } + } + else + { + _wasInteractPrevEnabled = false; + } _particleSimulation.Update(); foreach (var id in _particleSimulation.LastParticlesRemoved) { diff --git a/ParticleSimulation/ParticleSimulationScene.tscn b/ParticleSimulation/ParticleSimulationScene.tscn index 60c7f12..ca056e4 100644 --- a/ParticleSimulation/ParticleSimulationScene.tscn +++ b/ParticleSimulation/ParticleSimulationScene.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=2 format=2] +[gd_scene load_steps=3 format=2] [ext_resource path="res://ParticleSimulation/ParticleSimulationScene.cs" type="Script" id=1] +[ext_resource path="res://textures/interaction_circle.png" type="Texture" id=2] [node name="ParticleSimulationScene" type="Node2D"] script = ExtResource( 1 ) @@ -13,3 +14,8 @@ zoom = Vector2( 1.35, 1.35 ) smoothing_speed = 100.0 [node name="CameraTween" type="Tween" parent="."] + +[node name="InteractionCircleSprite" type="Sprite" parent="."] +modulate = Color( 1, 1, 1, 0.313726 ) +scale = Vector2( 0.75, 0.75 ) +texture = ExtResource( 2 ) diff --git a/ParticleSimulation/Simulation/ParticleSimulation.cs b/ParticleSimulation/Simulation/ParticleSimulation.cs index 2cb8e22..c59e81c 100644 --- a/ParticleSimulation/Simulation/ParticleSimulation.cs +++ b/ParticleSimulation/Simulation/ParticleSimulation.cs @@ -13,27 +13,27 @@ namespace Particles.ParticleSimulation { // size of simulation space public Vector2 SpaceSize; - + // dictionary of particles with particle Id being the key private readonly Dictionary _particles = new Dictionary(); - + private readonly List _particleTypes = new List(); - + // task list if multi-threaded - #if MULTITHREADED - private readonly List _tasks = new List(); - #endif - +#if MULTITHREADED + private readonly List _tasks = new List(); +#endif + // updated on every simulation update public List LastParticlesAdded { get; private set; } = new List(); public List LastParticlesRemoved { get; private set; } = new List(); // counts up for each particle added private int _idCount; - + private int _maxParticles; private const int MaxParticleTypes = 10; - + private const float HealthDelta = 0.005f; private const float NegativeHealthMultiplier = 2f; private const float PositiveHealthMultiplier = 4f; @@ -51,21 +51,21 @@ namespace Particles.ParticleSimulation { LastParticlesRemoved.Clear(); LastParticlesAdded.Clear(); - + // update all particles - #if MULTITHREADED - _tasks.Clear(); - foreach (var id in _particles.Keys) - _tasks.Add(Task.Factory.StartNew(UpdateParticle, id)); - Task.WaitAll(_tasks.ToArray()); - #else +#if MULTITHREADED + _tasks.Clear(); + foreach (var id in _particles.Keys) + _tasks.Add(Task.Factory.StartNew(UpdateParticle, id)); + Task.WaitAll(_tasks.ToArray()); +#else foreach (var id in _particles.Keys) UpdateParticle(id); - #endif - +#endif + // used to ensure only one particle is moved per update var movedParticle = false; - + foreach (var particle in _particles.Select(p => p.Value)) { particle.WasTeleportedLast = false; @@ -80,10 +80,11 @@ namespace Particles.ParticleSimulation continue; } } + var position = particle.Position; particle.Velocity = particle.Velocity.Clamped(5f); position += particle.Velocity; - particle.Velocity *= 0.855f; // friction + particle.Velocity *= 0.855f; // friction if (position.x > SpaceSize.x) { position.x -= SpaceSize.x; @@ -105,6 +106,7 @@ namespace Particles.ParticleSimulation position.y += SpaceSize.y; particle.WasTeleportedLast = true; } + /* particle.AddAverageSpeedValue(particle.Velocity.Length()); @@ -164,8 +166,8 @@ namespace Particles.ParticleSimulation foreach (var type1 in _particleTypes) foreach (var type2 in _particleTypes) type1.AddRelationship(type2, - new ParticleRelationshipProps(ParticleCollisionRadius, (float) GD.RandRange(25, 55), - (float)GD.RandRange(-0.675, 0.7))); + new ParticleRelationshipProps(ParticleCollisionRadius, (float) GD.RandRange(25, 55), + (float) GD.RandRange(-0.675, 0.7))); } private void CreateRandomParticle() @@ -194,7 +196,7 @@ namespace Particles.ParticleSimulation (float) GD.RandRange(0, SpaceSize.y)); return position; } - + private Vector2 GetScreenWrapPosition(Vector2 p1, Vector2 p2) { var newPosition = p2; @@ -208,15 +210,15 @@ namespace Particles.ParticleSimulation newPosition.y = p2.y + SpaceSize.y; return newPosition; } - + public Particle GetParticle(int id) { return _particles[id]; } - + private void UpdateParticle(object i) { - var id = (int)i; + var id = (int) i; var particle1 = _particles[id]; var closeCount = 0; foreach (var p2 in _particles) @@ -231,11 +233,11 @@ namespace Particles.ParticleSimulation if (distanceSquared < (35f * 35f)) closeCount++; - + // collision force float distance; Vector2 direction; - + if (distanceSquared < (ParticleCollisionRadius * ParticleCollisionRadius)) { direction = particle1.Position.DirectionTo(position); @@ -243,7 +245,7 @@ namespace Particles.ParticleSimulation var collisionForce = 1f / (0.35f + Mathf.Pow(Mathf.E, -1.15f * (distance - 12f))) - 1f / 0.35f; particle1.Velocity += direction * collisionForce; } - + // particle relationship force var props = particle1.Type.GetRelationship(particle2.Type); if (props.Force != 0f && distanceSquared >= props.MinRadius * props.MinRadius && @@ -257,34 +259,49 @@ namespace Particles.ParticleSimulation { if (distance <= mid) { - particleForce = 1f / ((1f / props.Force) + Mathf.Pow(Mathf.E, -4 * (distance - props.MinRadius - 1f))); + particleForce = 1f / ((1f / props.Force) + + Mathf.Pow(Mathf.E, -4 * (distance - props.MinRadius - 1f))); } else { - particleForce = 1f / ((1f / props.Force) + Mathf.Pow(Mathf.E, 4 * (distance - props.MaxRadius + 1f))); + particleForce = 1f / ((1f / props.Force) + + Mathf.Pow(Mathf.E, 4 * (distance - props.MaxRadius + 1f))); } } else { if (distance <= mid) { - particleForce = -1f / ((-1f / props.Force) + Mathf.Pow(Mathf.E, -4 * (distance - props.MinRadius - 1f))); + particleForce = -1f / ((-1f / props.Force) + + Mathf.Pow(Mathf.E, -4 * (distance - props.MinRadius - 1f))); } else { - particleForce = -1f / ((-1f / props.Force) + Mathf.Pow(Mathf.E, 4 * (distance - props.MaxRadius + 1f))); + particleForce = -1f / ((-1f / props.Force) + + Mathf.Pow(Mathf.E, 4 * (distance - props.MaxRadius + 1f))); } } - - + + particle1.Velocity += direction * particleForce; } } - + if (closeCount > 70) particle1.Health -= HealthDelta * NegativeHealthMultiplier; else particle1.Health += HealthDelta * PositiveHealthMultiplier; } + + public void SetInteractionCircle(Vector2 position, float radius, Vector2 velocity) + { + foreach (var p in _particles.Select(i => i.Value)) + { + if (position.DistanceTo(p.Position) <= radius) + { + p.Velocity += velocity; + } + } + } } } diff --git a/project.godot b/project.godot index 1463a46..1d20818 100644 --- a/project.godot +++ b/project.godot @@ -73,6 +73,11 @@ key_zoom_out={ "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":81,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] } +enable_interaction={ +"deadzone": 0.5, +"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null) + ] +} [mono] diff --git a/textures/interaction_circle.png b/textures/interaction_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..90053d493e098448e4659b40e364d156e981a66d GIT binary patch literal 11289 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 literal 0 HcmV?d00001 diff --git a/textures/interaction_circle.png.import b/textures/interaction_circle.png.import new file mode 100644 index 0000000..9d92fcd --- /dev/null +++ b/textures/interaction_circle.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/interaction_circle.png-10aab2660a95f68c88825c76c59d9be8.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://textures/interaction_circle.png" +dest_files=[ "res://.import/interaction_circle.png-10aab2660a95f68c88825c76c59d9be8.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 +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0