Compare commits
10 Commits
17017d631e
...
d8afe20123
Author | SHA1 | Date | |
---|---|---|---|
d8afe20123 | |||
8e6dc46b38 | |||
1a463f8edf | |||
bf7ef8bd76 | |||
ad380ec3fe | |||
a8b07fdbd9 | |||
527b0c64f1 | |||
005e34498e | |||
dda22a8367 | |||
a3019beef1 |
61
.gitignore
vendored
61
.gitignore
vendored
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
# Created by https://www.toptal.com/developers/gitignore/api/godot,jetbrains,csharp,visualstudiocode
|
# Created by https://www.toptal.com/developers/gitignore/api/jetbrains+all,godot,csharp
|
||||||
# Edit at https://www.toptal.com/developers/gitignore?templates=godot,jetbrains,csharp,visualstudiocode
|
# Edit at https://www.toptal.com/developers/gitignore?templates=jetbrains+all,godot,csharp
|
||||||
|
|
||||||
### Csharp ###
|
### Csharp ###
|
||||||
## Ignore Visual Studio temporary files, build results, and
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
@ -413,7 +413,7 @@ export_presets.cfg
|
|||||||
.mono/
|
.mono/
|
||||||
data_*/
|
data_*/
|
||||||
|
|
||||||
### JetBrains ###
|
### JetBrains+all ###
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
@ -492,49 +492,20 @@ fabric.properties
|
|||||||
# Android studio 3.1+ serialized cache file
|
# Android studio 3.1+ serialized cache file
|
||||||
.idea/caches/build_file_checksums.ser
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
### JetBrains Patch ###
|
### JetBrains+all Patch ###
|
||||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
# Ignores the whole .idea folder and all .iml files
|
||||||
|
# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
|
||||||
|
|
||||||
# *.iml
|
.idea/*
|
||||||
# modules.xml
|
|
||||||
# .idea/misc.xml
|
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
|
||||||
# *.ipr
|
|
||||||
|
*.iml
|
||||||
|
modules.xml
|
||||||
|
.idea/misc.xml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
# Sonarlint plugin
|
# Sonarlint plugin
|
||||||
# https://plugins.jetbrains.com/plugin/7973-sonarlint
|
.idea/sonarlint
|
||||||
.idea/**/sonarlint/
|
|
||||||
|
|
||||||
# SonarQube Plugin
|
# End of https://www.toptal.com/developers/gitignore/api/jetbrains+all,godot,csharp
|
||||||
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
|
|
||||||
.idea/**/sonarIssues.xml
|
|
||||||
|
|
||||||
# Markdown Navigator plugin
|
|
||||||
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
|
|
||||||
.idea/**/markdown-navigator.xml
|
|
||||||
.idea/**/markdown-navigator-enh.xml
|
|
||||||
.idea/**/markdown-navigator/
|
|
||||||
|
|
||||||
# Cache file creation bug
|
|
||||||
# See https://youtrack.jetbrains.com/issue/JBR-2257
|
|
||||||
.idea/$CACHE_FILE$
|
|
||||||
|
|
||||||
# CodeStream plugin
|
|
||||||
# https://plugins.jetbrains.com/plugin/12206-codestream
|
|
||||||
.idea/codestream.xml
|
|
||||||
|
|
||||||
### VisualStudioCode ###
|
|
||||||
!.vscode/*.code-snippets
|
|
||||||
|
|
||||||
# Local History for Visual Studio Code
|
|
||||||
|
|
||||||
# Built Visual Studio Code Extensions
|
|
||||||
*.vsix
|
|
||||||
|
|
||||||
### VisualStudioCode Patch ###
|
|
||||||
# Ignore all local history of files
|
|
||||||
.history
|
|
||||||
.ionide
|
|
||||||
|
|
||||||
# Support for Project snippet scope
|
|
||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/godot,jetbrains,csharp,visualstudiocode
|
|
||||||
|
13
.idea/.idea.Particles/.idea/.gitignore
vendored
13
.idea/.idea.Particles/.idea/.gitignore
vendored
@ -1,13 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# Rider ignored files
|
|
||||||
/projectSettingsUpdater.xml
|
|
||||||
/.idea.Particles.iml
|
|
||||||
/contentModel.xml
|
|
||||||
/modules.xml
|
|
||||||
# Editor-based HTTP Client requests
|
|
||||||
/httpRequests/
|
|
||||||
# Datasource local storage ignored files
|
|
||||||
/dataSources/
|
|
||||||
/dataSources.local.xml
|
|
@ -1 +0,0 @@
|
|||||||
Particles
|
|
@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
|
||||||
</project>
|
|
@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="UserContentModel">
|
|
||||||
<attachedFolders />
|
|
||||||
<explicitIncludes />
|
|
||||||
<explicitExcludes />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
30
Main.cs
30
Main.cs
@ -1,24 +1,44 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
using System;
|
using System;
|
||||||
|
using Particles.ParticleSimulation;
|
||||||
|
|
||||||
public class Main : Node
|
public class Main : Node
|
||||||
{
|
{
|
||||||
|
|
||||||
public void StartSimulation(int seed, int nParticles)
|
public int Seed;
|
||||||
|
public float Zoom;
|
||||||
|
|
||||||
|
private int _nParticles;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
|
OS.MinWindowSize = new Vector2(1024, 600);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartSimulation(int nParticles)
|
||||||
|
{
|
||||||
|
_nParticles = nParticles;
|
||||||
var particleSimulationPackedScene = GD.Load<PackedScene>("res://ParticleSimulation/ParticleSimulationScene.tscn");
|
var particleSimulationPackedScene = GD.Load<PackedScene>("res://ParticleSimulation/ParticleSimulationScene.tscn");
|
||||||
var particleSimulationScene = particleSimulationPackedScene.Instance<ParticleSimulationScene>();
|
var particleSimulationScene = particleSimulationPackedScene.Instance<ParticleSimulationScene>();
|
||||||
particleSimulationScene.Name = "Simulation";
|
particleSimulationScene.Name = Seed.ToString();
|
||||||
AddChild(particleSimulationScene);
|
AddChild(particleSimulationScene);
|
||||||
particleSimulationScene.Initialize(seed, nParticles);
|
particleSimulationScene.Initialize(Seed, nParticles, Zoom);
|
||||||
GetNode<Control>("MainMenu").Hide();
|
GetNode<Control>("MainMenu").Hide();
|
||||||
//OS.WindowResizable = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ExitToMenu()
|
public void ExitToMenu()
|
||||||
{
|
{
|
||||||
GetNode("Simulation").QueueFree();
|
GetNode(Seed.ToString()).QueueFree();
|
||||||
GetNode<Control>("MainMenu").Show();
|
GetNode<Control>("MainMenu").Show();
|
||||||
|
GetNode<MainMenu>("MainMenu").RefreshSeedText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RestartSimulation()
|
||||||
|
{
|
||||||
|
GetNode<ParticleSimulationScene>(Seed.ToString()).Hide();
|
||||||
|
GetNode(Seed.ToString()).QueueFree();
|
||||||
|
Seed = Mathf.Abs((int)GD.Randi());
|
||||||
|
StartSimulation(_nParticles);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
using System.Globalization;
|
||||||
using Godot;
|
using Godot;
|
||||||
using System;
|
|
||||||
|
|
||||||
public class MainMenu : Control
|
public class MainMenu : Control
|
||||||
{
|
{
|
||||||
@ -10,6 +10,14 @@ public class MainMenu : Control
|
|||||||
private Button _toggleFullScreenButton;
|
private Button _toggleFullScreenButton;
|
||||||
private TextEdit _seedText;
|
private TextEdit _seedText;
|
||||||
private TextEdit _particleCountText;
|
private TextEdit _particleCountText;
|
||||||
|
private Button _randomizeButton;
|
||||||
|
private Label _zoomValue;
|
||||||
|
private HSlider _zoomSlider;
|
||||||
|
|
||||||
|
private Label _invalidLabel;
|
||||||
|
|
||||||
|
private string _prevSeedText;
|
||||||
|
private string _prevParticleCountText;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
@ -17,25 +25,83 @@ public class MainMenu : Control
|
|||||||
_main = GetTree().Root.GetNode<Main>("Main");
|
_main = GetTree().Root.GetNode<Main>("Main");
|
||||||
_simulateButton = GetNode("MenuButtons").GetNode<Button>("SimulateButton");
|
_simulateButton = GetNode("MenuButtons").GetNode<Button>("SimulateButton");
|
||||||
_toggleFullScreenButton = GetNode("MenuButtons").GetNode<Button>("ToggleFullscreenButton");
|
_toggleFullScreenButton = GetNode("MenuButtons").GetNode<Button>("ToggleFullscreenButton");
|
||||||
_seedText = GetNode("MenuButtons").GetNode<TextEdit>("SeedText");
|
_seedText = GetNode("MenuButtons").GetNode("Inputs").GetNode("Seed").GetNode<TextEdit>("SeedText");
|
||||||
_particleCountText = GetNode("MenuButtons").GetNode<TextEdit>("ParticleCountText");
|
_particleCountText = GetNode("MenuButtons").GetNode("Inputs").GetNode("ParticleCount").GetNode<TextEdit>("ParticleCountText");
|
||||||
|
_randomizeButton = GetNode("MenuButtons").GetNode("Inputs").GetNode("Seed").GetNode<Button>("RandomizeButton");
|
||||||
|
_zoomValue = GetNode("MenuButtons").GetNode("Inputs").GetNode("Zoom").GetNode<Label>("ZoomValue");
|
||||||
|
_zoomSlider = GetNode("MenuButtons").GetNode("Inputs").GetNode("Zoom").GetNode<HSlider>("ZoomSlider");
|
||||||
|
_invalidLabel = GetNode<Label>("InvalidLabel");
|
||||||
|
|
||||||
// Connect signals
|
// Connect signals
|
||||||
_simulateButton.Connect("pressed", this, nameof(_OnSimulatePressed));
|
_simulateButton.Connect("pressed", this, nameof(_OnSimulatePressed));
|
||||||
_toggleFullScreenButton.Connect("pressed", this, nameof(_OnToggleFullscreenPressed));
|
_toggleFullScreenButton.Connect("pressed", this, nameof(_OnToggleFullscreenPressed));
|
||||||
|
_randomizeButton.Connect("pressed", this, nameof(_OnRandomizePressed));
|
||||||
|
_zoomSlider.Connect("value_changed", this, nameof(_OnZoomSliderChange));
|
||||||
|
_seedText.Connect("text_changed", this, nameof(_OnSeedTextChange));
|
||||||
|
_particleCountText.Connect("text_changed", this, nameof(_OnParticleCountTextChange));
|
||||||
|
|
||||||
// Random seed
|
// Random seed
|
||||||
GD.Randomize();
|
GD.Randomize();
|
||||||
var randomSeed = (int)GD.Randi();
|
var randomSeed = Mathf.Abs((int)GD.Randi());
|
||||||
_seedText.Text = randomSeed.ToString();
|
_main.Seed = randomSeed;
|
||||||
|
RefreshSeedText();
|
||||||
|
|
||||||
|
// Set default previous values
|
||||||
|
_prevSeedText = _seedText.Text;
|
||||||
|
_prevParticleCountText = _particleCountText.Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void _OnParticleCountTextChange()
|
||||||
|
{
|
||||||
|
var particleCountCheck = int.TryParse(_particleCountText.Text, out var nParticles);
|
||||||
|
if (!particleCountCheck && !_particleCountText.Text.Empty())
|
||||||
|
{
|
||||||
|
ShowInvalid();
|
||||||
|
_particleCountText.Text = _prevParticleCountText;
|
||||||
|
}
|
||||||
|
else if (!_particleCountText.Text.Empty())
|
||||||
|
{
|
||||||
|
_prevParticleCountText = _particleCountText.Text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void _OnSeedTextChange()
|
||||||
|
{
|
||||||
|
var seedCheck = int.TryParse(_seedText.Text, out var seed);
|
||||||
|
if (!seedCheck && !_seedText.Text.Empty())
|
||||||
|
{
|
||||||
|
ShowInvalid();
|
||||||
|
_seedText.Text = _prevSeedText;
|
||||||
|
}
|
||||||
|
else if (!_seedText.Text.Empty())
|
||||||
|
{
|
||||||
|
_prevSeedText = _seedText.Text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void _OnZoomSliderChange(float value)
|
||||||
|
{
|
||||||
|
_zoomValue.Text = value.ToString(CultureInfo.InvariantCulture);
|
||||||
|
_main.Zoom = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RefreshSeedText()
|
||||||
|
{
|
||||||
|
_seedText.Text = _main.Seed.ToString();
|
||||||
|
_prevSeedText = _seedText.Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void _OnSimulatePressed()
|
public void _OnSimulatePressed()
|
||||||
{
|
{
|
||||||
// Start simulation with seed and number of particles
|
// Start simulation with seed and number of particles
|
||||||
var nParticles = _particleCountText.Text.ToInt();
|
if (_seedText.Text.Empty() || _particleCountText.Text.Empty())
|
||||||
var seed = _seedText.Text.ToInt();
|
{
|
||||||
_main.StartSimulation(seed, nParticles);
|
ShowInvalid();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_main.Zoom = (float)_zoomSlider.Value;
|
||||||
|
_main.Seed = int.Parse(_seedText.Text);
|
||||||
|
_main.StartSimulation(int.Parse(_particleCountText.Text));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void _OnToggleFullscreenPressed()
|
public void _OnToggleFullscreenPressed()
|
||||||
@ -43,6 +109,13 @@ public class MainMenu : Control
|
|||||||
OS.WindowFullscreen = !OS.WindowFullscreen;
|
OS.WindowFullscreen = !OS.WindowFullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void _OnRandomizePressed()
|
||||||
|
{
|
||||||
|
var randomSeed = Mathf.Abs((int)GD.Randi());
|
||||||
|
_main.Seed = randomSeed;
|
||||||
|
RefreshSeedText();
|
||||||
|
}
|
||||||
|
|
||||||
public override void _Input(InputEvent @event)
|
public override void _Input(InputEvent @event)
|
||||||
{
|
{
|
||||||
// Quit only if menu is visible
|
// Quit only if menu is visible
|
||||||
@ -51,4 +124,19 @@ public class MainMenu : Control
|
|||||||
GetTree().Quit();
|
GetTree().Quit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void ShowInvalid()
|
||||||
|
{
|
||||||
|
GetNode<Tween>("InvalidTween").ResetAll();
|
||||||
|
GetNode<Timer>("InvalidTimer").Stop();
|
||||||
|
GetNode<Timer>("InvalidTimer").WaitTime = 3.0f;
|
||||||
|
_invalidLabel.Modulate = new Color(1, 1, 1, 1);
|
||||||
|
var invalidTimer = GetNode<Timer>("InvalidTimer");
|
||||||
|
invalidTimer.Start();
|
||||||
|
await ToSignal(invalidTimer, "timeout");
|
||||||
|
var invalidTween = GetNode<Tween>("InvalidTween");
|
||||||
|
invalidTween.InterpolateProperty(_invalidLabel, "modulate:a", 1, 0, 1);
|
||||||
|
invalidTween.Start();
|
||||||
|
await ToSignal(invalidTween, "tween_all_completed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,85 +14,134 @@ anchor_right = 1.0
|
|||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
theme = ExtResource( 1 )
|
theme = ExtResource( 1 )
|
||||||
script = ExtResource( 3 )
|
script = ExtResource( 3 )
|
||||||
__meta__ = {
|
|
||||||
"_edit_use_anchors_": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[node name="MenuButtons" type="VBoxContainer" parent="."]
|
[node name="MenuButtons" type="VBoxContainer" parent="."]
|
||||||
anchor_left = 0.5
|
anchor_left = 0.5
|
||||||
anchor_top = 0.5
|
anchor_top = 0.582
|
||||||
anchor_right = 0.5
|
anchor_right = 0.5
|
||||||
anchor_bottom = 0.5
|
anchor_bottom = 0.582
|
||||||
margin_left = -150.0
|
margin_left = -304.0
|
||||||
margin_top = -132.0
|
margin_top = -172.5
|
||||||
margin_right = 150.0
|
margin_right = 304.0
|
||||||
margin_bottom = 337.685
|
margin_bottom = 172.5
|
||||||
custom_constants/separation = 12
|
custom_constants/separation = 12
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="ParticleCountLabel" type="Label" parent="MenuButtons"]
|
[node name="Inputs" type="HBoxContainer" parent="MenuButtons"]
|
||||||
margin_right = 300.0
|
margin_right = 608.0
|
||||||
margin_bottom = 27.0
|
margin_bottom = 138.0
|
||||||
text = "Number of Particles"
|
alignment = 1
|
||||||
align = 1
|
|
||||||
|
|
||||||
[node name="ParticleCountText" type="TextEdit" parent="MenuButtons"]
|
[node name="Seed" type="VBoxContainer" parent="MenuButtons/Inputs"]
|
||||||
margin_top = 39.0
|
margin_right = 200.0
|
||||||
margin_right = 300.0
|
margin_bottom = 138.0
|
||||||
margin_bottom = 103.769
|
rect_min_size = Vector2( 200, 0 )
|
||||||
rect_min_size = Vector2( 0, 64.769 )
|
|
||||||
text = "1000"
|
|
||||||
|
|
||||||
[node name="SeedLabel" type="Label" parent="MenuButtons"]
|
[node name="SeedLabel" type="Label" parent="MenuButtons/Inputs/Seed"]
|
||||||
margin_top = 115.0
|
margin_right = 200.0
|
||||||
margin_right = 300.0
|
margin_bottom = 21.0
|
||||||
margin_bottom = 142.0
|
text = "Seed Number"
|
||||||
text = "Optional Seed Number"
|
|
||||||
align = 1
|
align = 1
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="SeedText" type="TextEdit" parent="MenuButtons"]
|
[node name="SeedText" type="TextEdit" parent="MenuButtons/Inputs/Seed"]
|
||||||
margin_top = 154.0
|
margin_top = 25.0
|
||||||
margin_right = 300.0
|
margin_right = 200.0
|
||||||
margin_bottom = 218.769
|
margin_bottom = 89.769
|
||||||
rect_min_size = Vector2( 0, 64.769 )
|
rect_min_size = Vector2( 0, 64.769 )
|
||||||
text = "12345"
|
text = "12345"
|
||||||
|
|
||||||
|
[node name="RandomizeButton" type="Button" parent="MenuButtons/Inputs/Seed"]
|
||||||
|
margin_top = 93.0
|
||||||
|
margin_right = 200.0
|
||||||
|
margin_bottom = 138.251
|
||||||
|
text = "Randomize!"
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="ParticleCount" type="VBoxContainer" parent="MenuButtons/Inputs"]
|
||||||
|
margin_left = 204.0
|
||||||
|
margin_right = 404.0
|
||||||
|
margin_bottom = 138.0
|
||||||
|
rect_min_size = Vector2( 200, 0 )
|
||||||
|
|
||||||
|
[node name="ParticleCountLabel" type="Label" parent="MenuButtons/Inputs/ParticleCount"]
|
||||||
|
margin_right = 200.0
|
||||||
|
margin_bottom = 21.0
|
||||||
|
text = "Particle Count"
|
||||||
|
align = 1
|
||||||
|
|
||||||
|
[node name="ParticleCountText" type="TextEdit" parent="MenuButtons/Inputs/ParticleCount"]
|
||||||
|
margin_top = 25.0
|
||||||
|
margin_right = 200.0
|
||||||
|
margin_bottom = 90.0
|
||||||
|
rect_min_size = Vector2( 0, 65 )
|
||||||
|
text = "1000"
|
||||||
|
|
||||||
|
[node name="Zoom" type="VBoxContainer" parent="MenuButtons/Inputs"]
|
||||||
|
margin_left = 408.0
|
||||||
|
margin_right = 608.0
|
||||||
|
margin_bottom = 138.0
|
||||||
|
rect_min_size = Vector2( 200, 0 )
|
||||||
|
|
||||||
|
[node name="ZoomLabel" type="Label" parent="MenuButtons/Inputs/Zoom"]
|
||||||
|
margin_right = 200.0
|
||||||
|
margin_bottom = 21.0
|
||||||
|
text = "World Size"
|
||||||
|
align = 1
|
||||||
|
|
||||||
|
[node name="ZoomValue" type="Label" parent="MenuButtons/Inputs/Zoom"]
|
||||||
|
margin_top = 25.0
|
||||||
|
margin_right = 200.0
|
||||||
|
margin_bottom = 46.0
|
||||||
|
text = "1.4"
|
||||||
|
align = 1
|
||||||
|
|
||||||
|
[node name="ZoomSlider" type="HSlider" parent="MenuButtons/Inputs/Zoom"]
|
||||||
|
margin_top = 50.0
|
||||||
|
margin_right = 200.0
|
||||||
|
margin_bottom = 92.0
|
||||||
|
min_value = 0.5
|
||||||
|
max_value = 5.0
|
||||||
|
step = 0.1
|
||||||
|
value = 1.4
|
||||||
|
|
||||||
[node name="SimulateButton" type="Button" parent="MenuButtons"]
|
[node name="SimulateButton" type="Button" parent="MenuButtons"]
|
||||||
margin_top = 230.0
|
margin_top = 150.0
|
||||||
margin_right = 300.0
|
margin_right = 608.0
|
||||||
margin_bottom = 281.251
|
margin_bottom = 195.251
|
||||||
text = "Simulate!"
|
text = "Simulate!"
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="Warning" type="Label" parent="MenuButtons"]
|
[node name="Warning" type="Label" parent="MenuButtons"]
|
||||||
margin_top = 293.0
|
margin_top = 207.0
|
||||||
margin_right = 300.0
|
margin_right = 608.0
|
||||||
margin_bottom = 338.0
|
margin_bottom = 252.0
|
||||||
custom_fonts/font = SubResource( 1 )
|
custom_fonts/font = SubResource( 1 )
|
||||||
text = "Simulation cannot be resized
|
text = "Simulation cannot be resized
|
||||||
once simulation starts!"
|
once simulation starts!"
|
||||||
align = 1
|
align = 1
|
||||||
|
|
||||||
[node name="HBoxContainer" type="HBoxContainer" parent="MenuButtons"]
|
[node name="HBoxContainer" type="HBoxContainer" parent="MenuButtons"]
|
||||||
margin_top = 350.0
|
margin_top = 264.0
|
||||||
margin_right = 300.0
|
margin_right = 608.0
|
||||||
margin_bottom = 350.0
|
margin_bottom = 264.0
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="ToggleFullscreenButton" type="Button" parent="MenuButtons"]
|
[node name="ToggleFullscreenButton" type="Button" parent="MenuButtons"]
|
||||||
margin_top = 362.0
|
margin_top = 276.0
|
||||||
margin_right = 300.0
|
margin_right = 608.0
|
||||||
margin_bottom = 413.251
|
margin_bottom = 321.251
|
||||||
text = "Toggle Fullscreen"
|
text = "Toggle Fullscreen!"
|
||||||
|
|
||||||
[node name="Logo" type="TextureRect" parent="."]
|
[node name="Logo" type="TextureRect" parent="."]
|
||||||
show_behind_parent = true
|
show_behind_parent = true
|
||||||
@ -108,7 +157,41 @@ rect_scale = Vector2( 0.35, 0.35 )
|
|||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
texture = ExtResource( 2 )
|
texture = ExtResource( 2 )
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
|
"_edit_lock_": true,
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[connection signal="pressed" from="MenuButtons/ToggleFullscreenButton" to="." method="_on_ToggleFullscreen_pressed"]
|
[node name="Controls" type="Label" parent="."]
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
margin_left = -183.0
|
||||||
|
margin_top = -81.0
|
||||||
|
margin_right = -10.0
|
||||||
|
margin_bottom = -12.0
|
||||||
|
custom_fonts/font = SubResource( 1 )
|
||||||
|
text = "Controls
|
||||||
|
R to Restart
|
||||||
|
Esc to Exit"
|
||||||
|
align = 1
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="InvalidLabel" type="Label" parent="."]
|
||||||
|
modulate = Color( 1, 1, 1, 0 )
|
||||||
|
margin_left = 15.0
|
||||||
|
margin_top = 16.0
|
||||||
|
margin_right = 226.0
|
||||||
|
margin_bottom = 43.0
|
||||||
|
text = "Invalid Inputs!"
|
||||||
|
uppercase = true
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="InvalidTween" type="Tween" parent="."]
|
||||||
|
|
||||||
|
[node name="InvalidTimer" type="Timer" parent="."]
|
||||||
|
one_shot = true
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
[ext_resource path="res://ParticleSimulation/ParticleNode.cs" type="Script" id=1]
|
[ext_resource path="res://ParticleSimulation/ParticleNode.cs" type="Script" id=1]
|
||||||
[ext_resource path="res://textures/particle_noborder.png" type="Texture" id=2]
|
[ext_resource path="res://textures/particle_noborder.png" type="Texture" id=2]
|
||||||
|
|
||||||
|
|
||||||
[node name="ParticleNode" type="Node2D"]
|
[node name="ParticleNode" type="Node2D"]
|
||||||
script = ExtResource( 1 )
|
script = ExtResource( 1 )
|
||||||
|
|
||||||
|
@ -7,17 +7,39 @@ public class ParticleSimulationScene : Node2D
|
|||||||
{
|
{
|
||||||
private Node2D _particleNodes;
|
private Node2D _particleNodes;
|
||||||
|
|
||||||
|
private Camera2D _camera;
|
||||||
|
private Tween _cameraTween;
|
||||||
|
|
||||||
|
private Vector2 _cameraZoomTarget;
|
||||||
|
private Vector2 _cameraPosTarget;
|
||||||
|
|
||||||
|
private float _maxZoom;
|
||||||
|
private Vector2 _spaceSize;
|
||||||
|
|
||||||
|
private const float CameraZoomSpeed = 0.5f;
|
||||||
|
|
||||||
private ParticleSimulation _particleSimulation;
|
private ParticleSimulation _particleSimulation;
|
||||||
public float PhysicsInterpolationFraction;
|
public float PhysicsInterpolationFraction;
|
||||||
|
|
||||||
public void Initialize(int seed, int nParticles)
|
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>("Camera2D");
|
||||||
|
_cameraTween = GetNode<Tween>("CameraTween");
|
||||||
_particleNodes = GetNode<Node2D>("ParticleNodes");
|
_particleNodes = GetNode<Node2D>("ParticleNodes");
|
||||||
|
_cameraZoomTarget = _camera.Zoom;
|
||||||
|
_cameraPosTarget = _camera.Position;
|
||||||
GD.Seed((ulong)seed);
|
GD.Seed((ulong)seed);
|
||||||
GD.Print("Last Seed: " + seed);
|
GD.Print("Last Seed: " + seed);
|
||||||
var viewSize = GetViewportRect().Size;
|
var viewSize = GetViewportRect().Size;
|
||||||
var zoom = GetNode<Camera2D>("Camera2D").Zoom;
|
_camera.Zoom = new Vector2(zoom, zoom);
|
||||||
var spaceSize = new Vector2(viewSize.x * zoom.x, viewSize.y * zoom.y);
|
var spaceSize = viewSize * zoom;
|
||||||
|
_spaceSize = spaceSize;
|
||||||
_particleSimulation = new ParticleSimulation
|
_particleSimulation = new ParticleSimulation
|
||||||
{
|
{
|
||||||
SpaceSize = spaceSize
|
SpaceSize = spaceSize
|
||||||
@ -28,14 +50,128 @@ public class ParticleSimulationScene : Node2D
|
|||||||
|
|
||||||
public override void _Process(float delta)
|
public override void _Process(float delta)
|
||||||
{
|
{
|
||||||
|
// Game state inputs
|
||||||
if (Input.IsActionJustPressed("quit"))
|
if (Input.IsActionJustPressed("quit"))
|
||||||
GetParent<Main>().ExitToMenu();
|
GetParent<Main>().ExitToMenu();
|
||||||
if (Input.IsActionJustPressed("reset")) GetTree().ReloadCurrentScene();
|
if (Input.IsActionJustPressed("reset"))
|
||||||
|
GetParent<Main>().RestartSimulation();
|
||||||
|
|
||||||
|
if (Input.IsActionPressed("enable_interaction"))
|
||||||
|
{
|
||||||
|
GetNode<Sprite>("InteractionCircleSprite").Show();
|
||||||
|
GetNode<Sprite>("InteractionCircleSprite").Position = GetGlobalMousePosition();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GetNode<Sprite>("InteractionCircleSprite").Hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
var shouldTweenStop = false;
|
||||||
|
|
||||||
|
if (Input.IsActionJustReleased("zoom_in"))
|
||||||
|
{
|
||||||
|
shouldTweenStop = true;
|
||||||
|
|
||||||
|
// Zoom
|
||||||
|
_cameraZoomTarget -= new Vector2(0.1f, 0.1f);
|
||||||
|
|
||||||
|
// Movement
|
||||||
|
var mousePos = GetGlobalMousePosition();
|
||||||
|
var posDelta = _cameraPosTarget - mousePos;
|
||||||
|
posDelta = posDelta.Clamped(500f);
|
||||||
|
_cameraPosTarget -= posDelta * 0.2f;
|
||||||
|
}
|
||||||
|
if (Input.IsActionJustReleased("zoom_out"))
|
||||||
|
{
|
||||||
|
shouldTweenStop = true;
|
||||||
|
|
||||||
|
// Zoom
|
||||||
|
_cameraZoomTarget += new Vector2(0.1f, 0.1f);
|
||||||
|
|
||||||
|
// Movement
|
||||||
|
var mousePos = GetGlobalMousePosition();
|
||||||
|
var posDelta = _cameraPosTarget - mousePos;
|
||||||
|
posDelta = posDelta.Clamped(500f);
|
||||||
|
_cameraPosTarget += posDelta * 0.2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cameraDir = new Vector2();
|
||||||
|
|
||||||
|
if (Input.IsActionPressed("up"))
|
||||||
|
cameraDir += new Vector2(0, -1);
|
||||||
|
if (Input.IsActionPressed("down"))
|
||||||
|
cameraDir += new Vector2(0, 1);
|
||||||
|
if (Input.IsActionPressed("left"))
|
||||||
|
cameraDir += new Vector2(-1, 0);
|
||||||
|
if (Input.IsActionPressed("right"))
|
||||||
|
cameraDir += new Vector2(1, 0);
|
||||||
|
|
||||||
|
if (cameraDir.LengthSquared() != 0)
|
||||||
|
{
|
||||||
|
shouldTweenStop = true;
|
||||||
|
cameraDir = cameraDir.Normalized();
|
||||||
|
_cameraPosTarget += cameraDir * 1000f * delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Input.IsActionPressed("key_zoom_in"))
|
||||||
|
{
|
||||||
|
shouldTweenStop = true;
|
||||||
|
_cameraZoomTarget -= new Vector2(0.01f, 0.01f) * (delta * 60f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Input.IsActionPressed("key_zoom_out"))
|
||||||
|
{
|
||||||
|
shouldTweenStop = true;
|
||||||
|
_cameraZoomTarget += new Vector2(0.01f, 0.01f) * (delta * 60f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldTweenStop)
|
||||||
|
{
|
||||||
|
_cameraTween.StopAll();
|
||||||
|
|
||||||
|
_cameraZoomTarget.x = Mathf.Clamp(_cameraZoomTarget.x, 0.01f, _maxZoom);
|
||||||
|
_cameraZoomTarget.y = Mathf.Clamp(_cameraZoomTarget.y, 0.01f, _maxZoom);
|
||||||
|
|
||||||
|
_cameraPosTarget.x = Mathf.Clamp(_cameraPosTarget.x,
|
||||||
|
0f - (_maxZoom - _cameraZoomTarget.x) * (_spaceSize.x / (Mathf.Sqrt2 * 2)),
|
||||||
|
0f + (_maxZoom - _cameraZoomTarget.x) * (_spaceSize.x / (Mathf.Sqrt2 * 2)));
|
||||||
|
_cameraPosTarget.y = Mathf.Clamp(_cameraPosTarget.y,
|
||||||
|
0f - (_maxZoom - _cameraZoomTarget.y) * (_spaceSize.y / (Mathf.Sqrt2 * 2)),
|
||||||
|
0f + (_maxZoom - _cameraZoomTarget.y) * (_spaceSize.y / (Mathf.Sqrt2 * 2)));
|
||||||
|
|
||||||
|
_cameraTween.InterpolateProperty(_camera, "zoom", _camera.Zoom, _cameraZoomTarget, CameraZoomSpeed,
|
||||||
|
Tween.TransitionType.Quint, Tween.EaseType.Out);
|
||||||
|
_cameraTween.InterpolateProperty(_camera, "position", _camera.Position, _cameraPosTarget, CameraZoomSpeed,
|
||||||
|
Tween.TransitionType.Quint, Tween.EaseType.Out);
|
||||||
|
_cameraTween.Start();
|
||||||
|
}
|
||||||
|
|
||||||
PhysicsInterpolationFraction = Engine.GetPhysicsInterpolationFraction();
|
PhysicsInterpolationFraction = Engine.GetPhysicsInterpolationFraction();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _PhysicsProcess(float delta)
|
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();
|
_particleSimulation.Update();
|
||||||
foreach (var id in _particleSimulation.LastParticlesRemoved)
|
foreach (var id in _particleSimulation.LastParticlesRemoved)
|
||||||
{
|
{
|
||||||
@ -50,7 +186,7 @@ public class ParticleSimulationScene : Node2D
|
|||||||
{
|
{
|
||||||
var simulationParticle = _particleSimulation.GetParticle(particleNode.SimulationId);
|
var simulationParticle = _particleSimulation.GetParticle(particleNode.SimulationId);
|
||||||
particleNode.LastSimulationPosition = particleNode.Position;
|
particleNode.LastSimulationPosition = particleNode.Position;
|
||||||
particleNode.CurrentSimulationPosition = simulationParticle.Position;
|
particleNode.CurrentSimulationPosition = simulationParticle.Position - (_spaceSize / 2.0f);
|
||||||
particleNode.SetColor(simulationParticle.Type.Hue, simulationParticle.Health,
|
particleNode.SetColor(simulationParticle.Type.Hue, simulationParticle.Health,
|
||||||
Mathf.Clamp(simulationParticle.AverageSpeed / 1.5f, 1f, 1f));
|
Mathf.Clamp(simulationParticle.AverageSpeed / 1.5f, 1f, 1f));
|
||||||
particleNode.WasTeleportedLast = simulationParticle.WasTeleportedLast;
|
particleNode.WasTeleportedLast = simulationParticle.WasTeleportedLast;
|
||||||
|
@ -1,7 +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://ParticleSimulation/ParticleSimulationScene.cs" type="Script" id=1]
|
||||||
|
[ext_resource path="res://textures/interaction_circle.png" type="Texture" id=2]
|
||||||
|
|
||||||
[node name="ParticleSimulationScene" type="Node2D"]
|
[node name="ParticleSimulationScene" type="Node2D"]
|
||||||
script = ExtResource( 1 )
|
script = ExtResource( 1 )
|
||||||
@ -9,6 +9,13 @@ script = ExtResource( 1 )
|
|||||||
[node name="ParticleNodes" type="Node2D" parent="."]
|
[node name="ParticleNodes" type="Node2D" parent="."]
|
||||||
|
|
||||||
[node name="Camera2D" type="Camera2D" parent="."]
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
anchor_mode = 0
|
|
||||||
current = true
|
current = true
|
||||||
zoom = Vector2( 1.35, 1.35 )
|
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 )
|
||||||
|
@ -20,9 +20,9 @@ namespace Particles.ParticleSimulation
|
|||||||
private readonly List<ParticleType> _particleTypes = new List<ParticleType>();
|
private readonly List<ParticleType> _particleTypes = new List<ParticleType>();
|
||||||
|
|
||||||
// task list if multi-threaded
|
// task list if multi-threaded
|
||||||
#if MULTITHREADED
|
#if MULTITHREADED
|
||||||
private readonly List<Task> _tasks = new List<Task>();
|
private readonly List<Task> _tasks = new List<Task>();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// updated on every simulation update
|
// updated on every simulation update
|
||||||
public List<int> LastParticlesAdded { get; private set; } = new List<int>();
|
public List<int> LastParticlesAdded { get; private set; } = new List<int>();
|
||||||
@ -53,15 +53,15 @@ namespace Particles.ParticleSimulation
|
|||||||
LastParticlesAdded.Clear();
|
LastParticlesAdded.Clear();
|
||||||
|
|
||||||
// update all particles
|
// update all particles
|
||||||
#if MULTITHREADED
|
#if MULTITHREADED
|
||||||
_tasks.Clear();
|
_tasks.Clear();
|
||||||
foreach (var id in _particles.Keys)
|
foreach (var id in _particles.Keys)
|
||||||
_tasks.Add(Task.Factory.StartNew(UpdateParticle, id));
|
_tasks.Add(Task.Factory.StartNew(UpdateParticle, id));
|
||||||
Task.WaitAll(_tasks.ToArray());
|
Task.WaitAll(_tasks.ToArray());
|
||||||
#else
|
#else
|
||||||
foreach (var id in _particles.Keys)
|
foreach (var id in _particles.Keys)
|
||||||
UpdateParticle(id);
|
UpdateParticle(id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// used to ensure only one particle is moved per update
|
// used to ensure only one particle is moved per update
|
||||||
var movedParticle = false;
|
var movedParticle = false;
|
||||||
@ -80,6 +80,7 @@ namespace Particles.ParticleSimulation
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var position = particle.Position;
|
var position = particle.Position;
|
||||||
particle.Velocity = particle.Velocity.Clamped(5f);
|
particle.Velocity = particle.Velocity.Clamped(5f);
|
||||||
position += particle.Velocity;
|
position += particle.Velocity;
|
||||||
@ -105,6 +106,7 @@ namespace Particles.ParticleSimulation
|
|||||||
position.y += SpaceSize.y;
|
position.y += SpaceSize.y;
|
||||||
particle.WasTeleportedLast = true;
|
particle.WasTeleportedLast = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
particle.AddAverageSpeedValue(particle.Velocity.Length());
|
particle.AddAverageSpeedValue(particle.Velocity.Length());
|
||||||
|
|
||||||
@ -165,7 +167,7 @@ namespace Particles.ParticleSimulation
|
|||||||
foreach (var type2 in _particleTypes)
|
foreach (var type2 in _particleTypes)
|
||||||
type1.AddRelationship(type2,
|
type1.AddRelationship(type2,
|
||||||
new ParticleRelationshipProps(ParticleCollisionRadius, (float) GD.RandRange(25, 55),
|
new ParticleRelationshipProps(ParticleCollisionRadius, (float) GD.RandRange(25, 55),
|
||||||
(float)GD.RandRange(-0.675, 0.7)));
|
(float) GD.RandRange(-0.675, 0.7)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateRandomParticle()
|
private void CreateRandomParticle()
|
||||||
@ -216,7 +218,7 @@ namespace Particles.ParticleSimulation
|
|||||||
|
|
||||||
private void UpdateParticle(object i)
|
private void UpdateParticle(object i)
|
||||||
{
|
{
|
||||||
var id = (int)i;
|
var id = (int) i;
|
||||||
var particle1 = _particles[id];
|
var particle1 = _particles[id];
|
||||||
var closeCount = 0;
|
var closeCount = 0;
|
||||||
foreach (var p2 in _particles)
|
foreach (var p2 in _particles)
|
||||||
@ -257,22 +259,26 @@ namespace Particles.ParticleSimulation
|
|||||||
{
|
{
|
||||||
if (distance <= mid)
|
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
|
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
|
else
|
||||||
{
|
{
|
||||||
if (distance <= mid)
|
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
|
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)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,5 +292,16 @@ namespace Particles.ParticleSimulation
|
|||||||
else
|
else
|
||||||
particle1.Health += HealthDelta * PositiveHealthMultiplier;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,59 @@ quit={
|
|||||||
"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":16777217,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
"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":16777217,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
up={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"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":87,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
down={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"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":16777234,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
left={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"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":65,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
right={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"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":16777233,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
zoom_in={
|
||||||
|
"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":4,"pressed":false,"doubleclick":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
zoom_out={
|
||||||
|
"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":5,"pressed":false,"doubleclick":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
key_zoom_in={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"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":69,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
key_zoom_out={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"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]
|
[mono]
|
||||||
|
|
||||||
|
project/assembly_name="Particles"
|
||||||
profiler/enabled=true
|
profiler/enabled=true
|
||||||
|
|
||||||
[physics]
|
[physics]
|
||||||
|
BIN
textures/interaction_circle.png
Normal file
BIN
textures/interaction_circle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
35
textures/interaction_circle.png.import
Normal file
35
textures/interaction_circle.png.import
Normal file
@ -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
|
@ -1,7 +1,11 @@
|
|||||||
[gd_resource type="Theme" load_steps=34 format=2]
|
[gd_resource type="Theme" load_steps=34 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://ui/UIpack_vector.svg" type="Texture" id=1]
|
[ext_resource path="res://ui/UIpack_vector.svg" type="Texture" id=1]
|
||||||
[ext_resource path="res://ui/ColorTube-Regular.ttf" type="DynamicFontData" id=2]
|
[ext_resource path="res://ui/kenvector_future.ttf" type="DynamicFontData" id=2]
|
||||||
|
|
||||||
|
[sub_resource type="DynamicFont" id=33]
|
||||||
|
size = 18
|
||||||
|
font_data = ExtResource( 2 )
|
||||||
|
|
||||||
[sub_resource type="StyleBoxTexture" id=1]
|
[sub_resource type="StyleBoxTexture" id=1]
|
||||||
texture = ExtResource( 1 )
|
texture = ExtResource( 1 )
|
||||||
@ -173,9 +177,6 @@ region = Rect2( 1007, 450, 39, 31 )
|
|||||||
texture = ExtResource( 1 )
|
texture = ExtResource( 1 )
|
||||||
region_rect = Rect2( 1051, 317, 4, 100 )
|
region_rect = Rect2( 1051, 317, 4, 100 )
|
||||||
|
|
||||||
[sub_resource type="DynamicFont" id=33]
|
|
||||||
font_data = ExtResource( 2 )
|
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
default_font = SubResource( 33 )
|
default_font = SubResource( 33 )
|
||||||
Button/colors/font_color = Color( 0, 0, 0, 1 )
|
Button/colors/font_color = Color( 0, 0, 0, 1 )
|
||||||
@ -184,7 +185,7 @@ Button/colors/font_color_focus = Color( 0, 0, 0, 1 )
|
|||||||
Button/colors/font_color_hover = Color( 0.34902, 0.34902, 0.34902, 1 )
|
Button/colors/font_color_hover = Color( 0.34902, 0.34902, 0.34902, 1 )
|
||||||
Button/colors/font_color_pressed = Color( 0.388235, 0.388235, 0.388235, 1 )
|
Button/colors/font_color_pressed = Color( 0.388235, 0.388235, 0.388235, 1 )
|
||||||
Button/constants/hseparation = 2
|
Button/constants/hseparation = 2
|
||||||
Button/fonts/font = null
|
Button/fonts/font = SubResource( 33 )
|
||||||
Button/styles/disabled = SubResource( 1 )
|
Button/styles/disabled = SubResource( 1 )
|
||||||
Button/styles/focus = SubResource( 2 )
|
Button/styles/focus = SubResource( 2 )
|
||||||
Button/styles/hover = SubResource( 3 )
|
Button/styles/hover = SubResource( 3 )
|
||||||
@ -197,7 +198,7 @@ CheckBox/colors/font_color_hover_pressed = Color( 0.34902, 0.34902, 0.34902, 1 )
|
|||||||
CheckBox/colors/font_color_pressed = Color( 0.388235, 0.388235, 0.388235, 1 )
|
CheckBox/colors/font_color_pressed = Color( 0.388235, 0.388235, 0.388235, 1 )
|
||||||
CheckBox/constants/check_vadjust = 0
|
CheckBox/constants/check_vadjust = 0
|
||||||
CheckBox/constants/hseparation = 4
|
CheckBox/constants/hseparation = 4
|
||||||
CheckBox/fonts/font = null
|
CheckBox/fonts/font = SubResource( 33 )
|
||||||
CheckBox/icons/checked = SubResource( 6 )
|
CheckBox/icons/checked = SubResource( 6 )
|
||||||
CheckBox/icons/radio_checked = SubResource( 7 )
|
CheckBox/icons/radio_checked = SubResource( 7 )
|
||||||
CheckBox/icons/radio_unchecked = SubResource( 8 )
|
CheckBox/icons/radio_unchecked = SubResource( 8 )
|
||||||
@ -215,7 +216,7 @@ CheckButton/colors/font_color_hover_pressed = Color( 0.388235, 0.388235, 0.38823
|
|||||||
CheckButton/colors/font_color_pressed = Color( 0.388235, 0.388235, 0.388235, 1 )
|
CheckButton/colors/font_color_pressed = Color( 0.388235, 0.388235, 0.388235, 1 )
|
||||||
CheckButton/constants/check_vadjust = 0
|
CheckButton/constants/check_vadjust = 0
|
||||||
CheckButton/constants/hseparation = 4
|
CheckButton/constants/hseparation = 4
|
||||||
CheckButton/fonts/font = null
|
CheckButton/fonts/font = SubResource( 33 )
|
||||||
CheckButton/icons/off = SubResource( 31 )
|
CheckButton/icons/off = SubResource( 31 )
|
||||||
CheckButton/icons/off_disabled = SubResource( 31 )
|
CheckButton/icons/off_disabled = SubResource( 31 )
|
||||||
CheckButton/icons/on = SubResource( 32 )
|
CheckButton/icons/on = SubResource( 32 )
|
||||||
@ -241,7 +242,7 @@ LineEdit/colors/font_color_selected = Color( 0.894118, 0.894118, 0.894118, 1 )
|
|||||||
LineEdit/colors/font_color_uneditable = Color( 0.88, 0.88, 0.88, 0.5 )
|
LineEdit/colors/font_color_uneditable = Color( 0.88, 0.88, 0.88, 0.5 )
|
||||||
LineEdit/colors/selection_color = Color( 0.34902, 0.34902, 0.34902, 1 )
|
LineEdit/colors/selection_color = Color( 0.34902, 0.34902, 0.34902, 1 )
|
||||||
LineEdit/constants/minimum_spaces = 12
|
LineEdit/constants/minimum_spaces = 12
|
||||||
LineEdit/fonts/font = null
|
LineEdit/fonts/font = SubResource( 33 )
|
||||||
LineEdit/icons/clear = null
|
LineEdit/icons/clear = null
|
||||||
LineEdit/styles/focus = SubResource( 16 )
|
LineEdit/styles/focus = SubResource( 16 )
|
||||||
LineEdit/styles/normal = SubResource( 17 )
|
LineEdit/styles/normal = SubResource( 17 )
|
||||||
@ -252,7 +253,7 @@ OptionButton/colors/font_color_hover = Color( 0.34902, 0.34902, 0.34902, 1 )
|
|||||||
OptionButton/colors/font_color_pressed = Color( 0, 0, 0, 1 )
|
OptionButton/colors/font_color_pressed = Color( 0, 0, 0, 1 )
|
||||||
OptionButton/constants/arrow_margin = 2
|
OptionButton/constants/arrow_margin = 2
|
||||||
OptionButton/constants/hseparation = 2
|
OptionButton/constants/hseparation = 2
|
||||||
OptionButton/fonts/font = null
|
OptionButton/fonts/font = SubResource( 33 )
|
||||||
OptionButton/icons/arrow = SubResource( 18 )
|
OptionButton/icons/arrow = SubResource( 18 )
|
||||||
OptionButton/styles/disabled = null
|
OptionButton/styles/disabled = null
|
||||||
OptionButton/styles/focus = null
|
OptionButton/styles/focus = null
|
||||||
@ -266,7 +267,7 @@ PopupMenu/colors/font_color_disabled = Color( 0.4, 0.4, 0.4, 0.8 )
|
|||||||
PopupMenu/colors/font_color_hover = Color( 0.388235, 0.388235, 0.388235, 1 )
|
PopupMenu/colors/font_color_hover = Color( 0.388235, 0.388235, 0.388235, 1 )
|
||||||
PopupMenu/constants/hseparation = 4
|
PopupMenu/constants/hseparation = 4
|
||||||
PopupMenu/constants/vseparation = 32
|
PopupMenu/constants/vseparation = 32
|
||||||
PopupMenu/fonts/font = null
|
PopupMenu/fonts/font = SubResource( 33 )
|
||||||
PopupMenu/icons/checked = SubResource( 20 )
|
PopupMenu/icons/checked = SubResource( 20 )
|
||||||
PopupMenu/icons/radio_checked = SubResource( 26 )
|
PopupMenu/icons/radio_checked = SubResource( 26 )
|
||||||
PopupMenu/icons/radio_unchecked = SubResource( 27 )
|
PopupMenu/icons/radio_unchecked = SubResource( 27 )
|
||||||
@ -283,7 +284,7 @@ TextEdit/colors/bookmark_color = Color( 0.08, 0.49, 0.98, 1 )
|
|||||||
TextEdit/colors/brace_mismatch_color = Color( 1, 0.2, 0.2, 1 )
|
TextEdit/colors/brace_mismatch_color = Color( 1, 0.2, 0.2, 1 )
|
||||||
TextEdit/colors/breakpoint_color = Color( 0.8, 0.8, 0.4, 0.2 )
|
TextEdit/colors/breakpoint_color = Color( 0.8, 0.8, 0.4, 0.2 )
|
||||||
TextEdit/colors/caret_background_color = Color( 0, 0, 0, 1 )
|
TextEdit/colors/caret_background_color = Color( 0, 0, 0, 1 )
|
||||||
TextEdit/colors/caret_color = Color( 0.88, 0.88, 0.88, 1 )
|
TextEdit/colors/caret_color = Color( 0, 0, 0, 1 )
|
||||||
TextEdit/colors/code_folding_color = Color( 0.8, 0.8, 0.8, 0.8 )
|
TextEdit/colors/code_folding_color = Color( 0.8, 0.8, 0.8, 0.8 )
|
||||||
TextEdit/colors/completion_background_color = Color( 0.17, 0.16, 0.2, 1 )
|
TextEdit/colors/completion_background_color = Color( 0.17, 0.16, 0.2, 1 )
|
||||||
TextEdit/colors/completion_existing_color = Color( 0.87, 0.87, 0.87, 0.13 )
|
TextEdit/colors/completion_existing_color = Color( 0.87, 0.87, 0.87, 0.13 )
|
||||||
@ -308,7 +309,7 @@ TextEdit/constants/completion_lines = 7
|
|||||||
TextEdit/constants/completion_max_width = 50
|
TextEdit/constants/completion_max_width = 50
|
||||||
TextEdit/constants/completion_scroll_width = 3
|
TextEdit/constants/completion_scroll_width = 3
|
||||||
TextEdit/constants/line_spacing = 4
|
TextEdit/constants/line_spacing = 4
|
||||||
TextEdit/fonts/font = null
|
TextEdit/fonts/font = SubResource( 33 )
|
||||||
TextEdit/icons/fold = null
|
TextEdit/icons/fold = null
|
||||||
TextEdit/icons/folded = null
|
TextEdit/icons/folded = null
|
||||||
TextEdit/icons/space = null
|
TextEdit/icons/space = null
|
||||||
|
Loading…
Reference in New Issue
Block a user