Added minigame

pull/22/head
jonathan 3 months ago
parent fef1bcc3b6
commit 8624e2aea8

@ -0,0 +1,38 @@
[gd_scene load_steps=7 format=3 uid="uid://bydwj3pbvqrhb"]
[ext_resource type="Script" uid="uid://ct7l4er2kljnc" path="res://scripts/CSharp/Common/Minigame/MinigameController.cs" id="1_17v35"]
[ext_resource type="PackedScene" uid="uid://dhfda4o386byp" path="res://prefabs/minigame/region_visual.tscn" id="2_rrvb1"]
[ext_resource type="Script" uid="uid://djkyrp24ljff0" path="res://scripts/CSharp/Common/Minigame/SpinnyArmVisual.cs" id="3_86pvs"]
[ext_resource type="Texture2D" uid="uid://bgn2ci6nu85t5" path="res://addons/dialogic/Example Assets/next-indicator/next-indicator-dialogic-1.png" id="3_pe4tw"]
[ext_resource type="Script" uid="uid://dq7gahfp0lk7v" path="res://scripts/CSharp/Common/Util/ClickDetect.cs" id="5_86pvs"]
[sub_resource type="CircleShape2D" id="CircleShape2D_pe4tw"]
radius = 554.923
[node name="Minigame" type="Node2D" node_paths=PackedStringArray("_regionsParent")]
script = ExtResource("1_17v35")
_regionVisualPrefab = ExtResource("2_rrvb1")
_regionsParent = NodePath("RegionsParent")
_baseRegionColor = Color(0.176888, 0.482224, 0.338857, 1)
[node name="RegionsParent" type="Node2D" parent="."]
[node name="SpinnyArm" type="Node2D" parent="."]
script = ExtResource("3_86pvs")
[node name="ArmVisual" type="Node2D" parent="SpinnyArm"]
[node name="Sprite" type="Sprite2D" parent="SpinnyArm/ArmVisual"]
position = Vector2(0, -40)
rotation = -3.14159
scale = Vector2(1, 2.08)
texture = ExtResource("3_pe4tw")
[node name="Area2D" type="Area2D" parent="."]
script = ExtResource("5_86pvs")
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
shape = SubResource("CircleShape2D_pe4tw")
[connection signal="ArmMoved" from="." to="SpinnyArm" method="SetAngle"]
[connection signal="Click" from="Area2D" to="." method="Hit"]

@ -0,0 +1,25 @@
[gd_scene load_steps=5 format=3 uid="uid://dhfda4o386byp"]
[ext_resource type="Script" uid="uid://cdpsa4qrlai31" path="res://scripts/CSharp/Common/Minigame/RegionVisual.cs" id="1_4ymj8"]
[ext_resource type="Shader" uid="uid://d0dayn7dc885j" path="res://shader/minigame_pie_section.gdshader" id="1_8p2xn"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_86pvs"]
resource_local_to_scene = true
shader = ExtResource("1_8p2xn")
shader_parameter/textureSize = 400.0
shader_parameter/fillColor = Color(0.285466, 0.685481, 0.880632, 1)
shader_parameter/borderColor = Color(1, 1, 1, 1)
shader_parameter/borderWidth = 0.025
shader_parameter/angles = Vector2(0.01, 0.18)
shader_parameter/smoothWidth = 0.0052
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_0navw"]
size = Vector2(400, 400)
[node name="RegionVisual" type="Node2D" node_paths=PackedStringArray("_sliceSprite")]
script = ExtResource("1_4ymj8")
_sliceSprite = NodePath("Sprite2D")
[node name="Sprite2D" type="Sprite2D" parent="."]
material = SubResource("ShaderMaterial_86pvs")
texture = SubResource("PlaceholderTexture2D_0navw")

@ -11,8 +11,8 @@ config_version=5
[application] [application]
config/name="Babushka" config/name="Babushka"
run/main_scene="uid://bopv10dqm1knc" run/main_scene="uid://c1dsbe7ryaije"
config/features=PackedStringArray("4.5", "C#", "Forward Plus") config/features=PackedStringArray("4.4", "C#", "Forward Plus")
run/max_fps=120 run/max_fps=120
boot_splash/fullsize=false boot_splash/fullsize=false
boot_splash/image="uid://utam4axkvutc" boot_splash/image="uid://utam4axkvutc"

@ -187,10 +187,10 @@ offset_right = 794.0
offset_bottom = -472.0 offset_bottom = -472.0
text = "Hello world" text = "Hello world"
[connection signal="SignalTransitionState" from="FightHappening" to="ActionAnimationController/StateReactionActionAnimation" method="FightHappeningStateTransitioned"]
[connection signal="SignalTransitionState" from="FightHappening" to="FightVisuals" method="FightHappeningStateChange"] [connection signal="SignalTransitionState" from="FightHappening" to="FightVisuals" method="FightHappeningStateChange"]
[connection signal="SignalTransitionState" from="FightHappening" to="ActionSelect/StateReactionInputActionSelect" method="FightHappeningStateTransitioned"] [connection signal="SignalTransitionState" from="FightHappening" to="ActionSelect/StateReactionInputActionSelect" method="FightHappeningStateTransitioned"]
[connection signal="SignalTransitionState" from="FightHappening" to="StateMachineDebugger" method="StateChange"] [connection signal="SignalTransitionState" from="FightHappening" to="StateMachineDebugger" method="StateChange"]
[connection signal="SignalTransitionState" from="FightHappening" to="ActionAnimationController/StateReactionActionAnimation" method="FightHappeningStateTransitioned"]
[connection signal="OnStateEntered" from="ActionAnimationController/StateReactionActionAnimation" to="ActionAnimationController" method="StateEnter"] [connection signal="OnStateEntered" from="ActionAnimationController/StateReactionActionAnimation" to="ActionAnimationController" method="StateEnter"]
[connection signal="OnStateExited" from="ActionAnimationController/StateReactionActionAnimation" to="ActionAnimationController" method="StateExit"] [connection signal="OnStateExited" from="ActionAnimationController/StateReactionActionAnimation" to="ActionAnimationController" method="StateExit"]
[connection signal="pressed" from="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer/AttackButton" to="ActionSelect" method="SelectAction" binds= [1]] [connection signal="pressed" from="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer/AttackButton" to="ActionSelect" method="SelectAction" binds= [1]]

@ -0,0 +1,12 @@
[gd_scene load_steps=3 format=3 uid="uid://c1dsbe7ryaije"]
[ext_resource type="Script" uid="uid://iv0dbf32bfw1" path="res://scripts/CSharp/Common/TestScripts/MinigameTestStarter.cs" id="1_fwf73"]
[ext_resource type="PackedScene" uid="uid://bydwj3pbvqrhb" path="res://prefabs/minigame/minigame.tscn" id="1_wh3re"]
[node name="BabushkaSceneMinigameTest" type="Node2D" node_paths=PackedStringArray("_minigameController")]
script = ExtResource("1_fwf73")
_minigameController = NodePath("Minigame")
[node name="Minigame" parent="." instance=ExtResource("1_wh3re")]
[node name="Camera2D" type="Camera2D" parent="."]

@ -0,0 +1,180 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Babushka.scripts.CSharp.Common.Util;
using Godot;
namespace Babushka.scripts.CSharp.Common.Minigame;
public partial class MinigameController : Node2D
{
public class Builder<T>
{
internal class Region
{
public required T value;
public float proportion = 1f;
}
public enum DoubleHitHandling
{
Allow,
Disallow,
Remove,
}
internal List<Region> regions = new();
internal DoubleHitHandling doubleHitHandling = DoubleHitHandling.Allow;
internal int maxHitCount = 3;
// add region
public Builder<T> AddRegion(T value)
{
regions.Add(new Region { value = value });
return this;
}
// region settings
public Builder<T> RegionWithProportion(float proportion)
{
if (regions.Count == 0)
throw new InvalidOperationException("No region to set proportion for");
regions.Last().proportion = proportion;
return this;
}
// general settings
public Builder<T> WithDoubleHitHandling(DoubleHitHandling handling)
{
if (handling != DoubleHitHandling.Allow)
throw new NotImplementedException();
doubleHitHandling = handling;
return this;
}
public Builder<T> WithHitCount(int hitCount)
{
this.maxHitCount = hitCount;
return this;
}
}
private TaskCompletionSource? _minigameComplete;
private List<int>? _hits;
private float _armPosition = 0f;
private float _armSpeed = 1f;
private List<float>? _regions;
private int _maxHitCount;
[Export] private PackedScene _regionVisualPrefab = null!;
[Export] private Node2D _regionsParent = null!;
[Export] private Color _baseRegionColor = Colors.Red;
[Signal] public delegate void ArmMovedEventHandler(float newPos);
public override void _EnterTree()
{
HideMinigame();
}
public override void _Process(double delta)
{
_armPosition += _armSpeed * (float)delta;
_armPosition = Mathf.PosMod(_armPosition, 1);
EmitSignalArmMoved(_armPosition);
}
public async Task<List<T>> Run<T>(Builder<T> builder)
{
ShowMinigame();
Setup(builder);
await _minigameComplete!.Task;
var returnValue = _hits!.Select(h => builder.regions[h].value).ToList();
Reset();
HideMinigame();
return returnValue;
}
public void Hit()
{
if (_hits == null) return;
int i;
for (i = 0; i < _regions!.Count - 1; i++)
{
if (_armPosition < _regions[i])
{
break;
}
}
_hits.Add(i);
_armSpeed = -_armSpeed;
if (_hits.Count >= _maxHitCount)
{
_minigameComplete!.SetResult();
}
}
private void Setup<T>(Builder<T> builder)
{
_minigameComplete = new();
_hits = [];
_armPosition = 0f;
_armSpeed = 1f;
_regions = [];
SetupRegions(builder);
_maxHitCount = builder.maxHitCount;
}
private void SetupRegions<T>(Builder<T> builder)
{
// common calculations
var totalRegionProportion = builder.regions.Sum(r => r.proportion);
// spawn regions
var regionSum = 0f;
foreach (var region in builder.regions)
{
var regionVisual = _regionVisualPrefab.Instantiate<RegionVisual>();
_regionsParent.AddChild(regionVisual);
var normalisedAngleStart = regionSum / totalRegionProportion;
var normalisedAngleEnd = (regionSum + region.proportion) / totalRegionProportion;
var normalAngles = new Vector2(normalisedAngleStart, normalisedAngleEnd);
regionVisual.Setup(normalAngles, _baseRegionColor.RandomHue());
regionSum += region.proportion;
_regions!.Add(normalisedAngleEnd);
}
}
private void ShowMinigame()
{
Show();
ProcessMode = ProcessModeEnum.Inherit;
}
private void HideMinigame()
{
Hide();
ProcessMode = ProcessModeEnum.Disabled;
}
private void Reset()
{
_minigameComplete = null;
_hits = null;
_regionsParent.GetChildren().ForEach(c => c.QueueFree());
}
}

@ -0,0 +1,19 @@
using Godot;
using System;
public partial class RegionVisual : Node
{
[Export] private Sprite2D _sliceSprite;
public override void _EnterTree()
{
//_sliceSprite.Material = new Material()
}
public void Setup(Vector2 normalAngles, Color color)
{
var mat = (_sliceSprite.Material as ShaderMaterial)!;
mat.SetShaderParameter("angles", normalAngles);
mat.SetShaderParameter("fillColor", color);
}
}

@ -0,0 +1,10 @@
using Godot;
using System;
public partial class SpinnyArmVisual : Node2D
{
public void SetAngle(float normalAngle)
{
Rotation = normalAngle * float.Pi * 2;
}
}

@ -0,0 +1,30 @@
using System.Collections.Generic;
using System.Linq;
using Babushka.scripts.CSharp.Common.Minigame;
using Godot;
namespace Babushka.scripts.CSharp.Common.TestScripts;
public partial class MinigameTestStarter : Node
{
[Export] private MinigameController _minigameController = null!;
public override void _Ready()
{
_minigameController.Run(
new MinigameController.Builder<int>()
.WithHitCount(5)
.AddRegion(1)
.AddRegion(2).RegionWithProportion(2)
.AddRegion(3)
.AddRegion(4).RegionWithProportion(2)
.AddRegion(5)
.AddRegion(6).RegionWithProportion(2)
).ContinueWith(task => OnEnd(task.Result));
}
private void OnEnd(List<int> result)
{
GD.Print(string.Join(" ,", result));
}
}

@ -0,0 +1,16 @@
using Godot;
namespace Babushka.scripts.CSharp.Common.Util;
public partial class ClickDetect : Area2D
{
[Signal] public delegate void ClickEventHandler();
public override void _Input(InputEvent evt)
{
if (evt is InputEventMouseButton { ButtonIndex: MouseButton.Left, Pressed: true })
{
EmitSignalClick();
}
}
}

@ -4,6 +4,8 @@ using System.Collections.Generic;
using System.Data.SqlTypes; using System.Data.SqlTypes;
using System.Linq; using System.Linq;
using System.Xml.Schema; using System.Xml.Schema;
using Godot;
namespace Babushka.scripts.CSharp.Common.Util; namespace Babushka.scripts.CSharp.Common.Util;
public static class LinqExtras public static class LinqExtras
@ -46,4 +48,11 @@ public static class LinqExtras
} }
return selfList; return selfList;
} }
public static Color RandomHue(this Color color)
{
color.ToHsv(out _, out float saturation, out var value );
var rng = new RandomNumberGenerator();
return Color.FromHsv(rng.Randf(), saturation, value);
}
} }

@ -0,0 +1,72 @@
shader_type canvas_item;
uniform float textureSize = 400.0;
uniform vec3 fillColor:source_color = vec3(1.0,0.0,0.0);
uniform vec3 borderColor:source_color = vec3(1.0,1.0,1.0);
uniform float borderWidth = 0.1;
uniform vec2 angles = vec2(0.2,0.4);
uniform float smoothWidth:hint_range(0.0001, 0.1, 0.0001) = 0.01;
void vertex() {
}
//vec2 polar_coordinates(vec2 uv, vec2 center, vec2 tps) {
// vec2 dir = uv - center*textureSize*tps.x;
// dir = vec2(dir.y,-dir.x);
// float radius = length(dir) * 2.0;
// float angle = atan(dir.y, dir.x) * 1.0/(3.1416 * 2.0);
// return vec2(radius/(textureSize*tps.x), angle + 0.5);
//}
float sd_circle(vec2 norm_uv,float radius){
float d = distance(norm_uv,vec2(0.0));
return d - radius;
}
float sd_line(vec2 norm_uv){
return norm_uv.x;
}
vec2 rotate_uv(vec2 norm_uv, float angle_normal){
float angle_rad = angle_normal * 2.0 * PI;
mat2 rotation = mat2(vec2( cos(angle_rad), sin(angle_rad)),
vec2(-sin(angle_rad), cos(angle_rad)));
return norm_uv * rotation;
}
vec2 normalize_uv(vec2 uv,vec2 tps){
vec2 zeroToOne = uv / (textureSize*tps);
return zeroToOne*2.0-1.0;
}
void fragment() {
//vec2 pc = polar_coordinates(UV,vec2(0.5,0.5),TEXTURE_PIXEL_SIZE);
//bool isIn = pc.x<1.0 && pc.y > 0.2 && pc.y < 0.9;
////bool isIn = TEXTURE_PIXEL_SIZE.x < 1.0/3.99;
////COLOR = vec4(pc.x,pc.y,0,1);
//COLOR.a = isIn?1.0f:0.0f;
//COLOR.rgb = (pc.x > 1.0-borderWidth)?borderColor:fillColor;
vec2 normal_uv = normalize_uv(UV,TEXTURE_PIXEL_SIZE);
//vec2 normal_uv = VERTEX;
bool isBigAngle = angles.y - angles.x >0.5;
float line1 = sd_line(rotate_uv(normal_uv,angles.x));
float line2 = sd_line(rotate_uv(normal_uv,angles.y));
float linesCombined = isBigAngle ? min(-line1,line2):max(-line1,line2);
float circle = sd_circle(normal_uv,0.95);
float final_distance = max(linesCombined,circle);
//float final_distance = sd_line(normal_uv);
COLOR.a = 1.0-smoothstep(0.0,1.0, final_distance/smoothWidth);
//COLOR.r = 0.0;
//COLOR.g = 0.0;
//COLOR.b = 0.0;
//COLOR.rg = VERTEX*SCREEN_PIXEL_SIZE;
//COLOR.rg = UV*TEXTURE_PIXEL_SIZE;
//COLOR.rg = center;
COLOR.rgb = fillColor;
}
//void light() {
// // Called for every pixel for every light affecting the CanvasItem.
// // Uncomment to replace the default light processing function with this one.
//}
Loading…
Cancel
Save