refactor and prep Mono for new game
This commit is contained in:
parent
915dca82e5
commit
3da9aba2d4
6 changed files with 95 additions and 213 deletions
|
@ -77,15 +77,11 @@ static class Arts
|
|||
}
|
||||
|
||||
// menu
|
||||
Matrix m4_menu = Matrix.TRS(
|
||||
Vec3.Zero,
|
||||
Quat.Identity,
|
||||
U.cm
|
||||
);
|
||||
Matrix m4_menu = Mono.menu_pose.ToMatrix(Mono.menu_scale);
|
||||
Hierarchy.Push(m4_menu);
|
||||
|
||||
// score
|
||||
char[] score_txt = Mono.slash_len.ToString("000").ToCharArray();
|
||||
char[] score_txt = Mono.score.ToString("000").ToCharArray();
|
||||
for (int i = 0; i < score_txt.Length; i++)
|
||||
{
|
||||
Text.Add(
|
||||
|
|
49
src/Maths.cs
49
src/Maths.cs
|
@ -45,6 +45,53 @@ public static class Maths
|
|||
}
|
||||
|
||||
public static float lerp(float a, float b, float t) => a + (b - a) * t;
|
||||
|
||||
// directions for moving in the grid
|
||||
public static readonly XYZi[] directions = new XYZi[]
|
||||
{
|
||||
new(-1, 0, 0), // lft
|
||||
new(+1, 0, 0), // rht
|
||||
new(0, -1, 0), // dwn
|
||||
new(0, +1, 0), // up
|
||||
new(0, 0, -1), // fwd
|
||||
new(0, 0, +1), // back
|
||||
};
|
||||
public static readonly XYZi[] corners = new XYZi[]
|
||||
{
|
||||
new(-1, -1, -1),
|
||||
new(-1, -1, +1),
|
||||
new(-1, +1, -1),
|
||||
new(-1, +1, +1),
|
||||
new(+1, -1, -1),
|
||||
new(+1, -1, +1),
|
||||
new(+1, +1, -1),
|
||||
new(+1, +1, +1)
|
||||
};
|
||||
|
||||
public static XYZi InsetCell(XYZi cell)
|
||||
{
|
||||
// [!] don't inset past 0
|
||||
return new(
|
||||
cell.x - Maths.sign(cell.x),
|
||||
cell.y - Maths.sign(cell.y),
|
||||
cell.z - Maths.sign(cell.z)
|
||||
);
|
||||
}
|
||||
|
||||
public static int[] GetShuffledIndices<T>(T[] array)
|
||||
{
|
||||
int[] indices = new int[array.Length];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
indices[i] = i;
|
||||
}
|
||||
for (int i = indices.Length - 1; i > 0; i--)
|
||||
{
|
||||
int j = System.Random.Shared.Next(i + 1);
|
||||
(indices[j], indices[i]) = (indices[i], indices[j]);
|
||||
}
|
||||
return indices;
|
||||
}
|
||||
}
|
||||
|
||||
public class DeltaBool
|
||||
|
@ -101,6 +148,8 @@ public struct XYZi
|
|||
public override int GetHashCode()
|
||||
=> HashCode.Combine(x, y, z);
|
||||
|
||||
public static readonly XYZi Zero = new XYZi(0, 0, 0);
|
||||
|
||||
public StereoKit.Vec3 ToVec3
|
||||
=> StereoKit.V.XYZ(x, y, z);
|
||||
|
||||
|
|
237
src/Mono.cs
237
src/Mono.cs
|
@ -5,79 +5,47 @@ namespace slash;
|
|||
|
||||
static class Mono
|
||||
{
|
||||
public static double game_time = 0.0;
|
||||
public static double game_time;
|
||||
|
||||
public static double intro_skip = 0.0;
|
||||
public static bool intro = true; // press to move until x condition or hold to skip
|
||||
public static bool menu = true;
|
||||
public static int score;
|
||||
|
||||
public static Pose box_pose = new(0, -3 * U.cm, -10 * U.cm);
|
||||
public static float box_dist = 32 * U.cm;
|
||||
public static float box_scale = 1.333f * U.cm;
|
||||
public const int SD_X = 3, SD_Y = 2, SD_Z = 3;
|
||||
public static SpatialArray<int>
|
||||
box_space = new(SD_X - 1, SD_Y - 1, SD_Z - 1, -1),
|
||||
s_array = new(SD_X, SD_Y, SD_Z, -1),
|
||||
tail_fill = new(SD_X, SD_Y, SD_Z, -1);
|
||||
public static DeltaBool menu;
|
||||
public static Pose menu_pose;
|
||||
public static float menu_scale;
|
||||
|
||||
static void update_s_array()
|
||||
{
|
||||
s_array.Clear(-1);
|
||||
for (int i = 0; i < slash_len; i++)
|
||||
{
|
||||
s_array[slash[i]] = i;
|
||||
}
|
||||
}
|
||||
|
||||
public static XYZi[] slash = new XYZi[
|
||||
Maths.u_length(SD_X) * Maths.u_length(SD_Y) * Maths.u_length(SD_Z)
|
||||
];
|
||||
public static int slash_len = 1;
|
||||
public static int grow_buffer = 3;
|
||||
public static XYZi slash_dir = new(0, 0, 1);
|
||||
public static DeltaBool in_box = new(true);
|
||||
public static Dictionary<XYZi, XYZi> holes = new();
|
||||
public static XYZi food = new(0, 0, 0); // [!] start random to keep new game fresh?
|
||||
public static int eaten = 0;
|
||||
public static DeltaBool eaten_latch = new(false);
|
||||
public static DeltaBool food_next = new(false);
|
||||
public static double eat_timestamp = 0.0;
|
||||
|
||||
public enum BoxMode
|
||||
public enum Mode
|
||||
{
|
||||
Float = -1,
|
||||
Hold = 0,
|
||||
Mount = 1,
|
||||
}
|
||||
public static BoxMode box_mode = BoxMode.Mount;
|
||||
public static DeltaBool in_cone = new(true);
|
||||
public static DeltaBool in_dist = new(false);
|
||||
public static Mode mode;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
for (int i = 0; i < slash.Length; i++)
|
||||
{
|
||||
slash[i] = new XYZi(0, 0, 0);
|
||||
}
|
||||
update_s_array();
|
||||
game_time = 0.0;
|
||||
menu = new(true);
|
||||
menu_pose = new(0, 0, 0);
|
||||
menu_scale = 1 * U.cm;
|
||||
mode = Mode.Mount;
|
||||
}
|
||||
|
||||
public static void Frame()
|
||||
{
|
||||
if (Rig.btn_back.delta == +1)
|
||||
{
|
||||
menu = !menu;
|
||||
SFX.click.PlayBox(new XYZi(0, 0, Mono.SD_Z + 1));
|
||||
menu.Step(!menu.state);
|
||||
SFX.click.PlayMenu();
|
||||
}
|
||||
|
||||
if (menu)
|
||||
if (menu.state)
|
||||
{
|
||||
// just one btn(resume) in menu rn
|
||||
if (Rig.btn_select.delta == +1)
|
||||
{
|
||||
Rig.btn_select.delta = 0; // [!] hacky capture
|
||||
menu = false;
|
||||
SFX.click.PlayBox(new XYZi(0, 0, Mono.SD_Z + 1));
|
||||
menu.Step(false);
|
||||
SFX.click.PlayMenu();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,164 +59,33 @@ static class Mono
|
|||
Quat.FromAngles(0, -sx * 180.0f * Time.Stepf, 0)
|
||||
);
|
||||
// orbital_view
|
||||
box_pose.position = Input.Head.position + Input.Head.orientation * V.XYZ(0, -0 * U.cm, -10 * U.cm);
|
||||
// box_pose.position = Input.Head.position + Input.Head.orientation * V.XYZ(0, -0 * U.cm, -10 * U.cm);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
in_dist.Step(Vec3.Distance(Rig.r_con_stick.position, box_pose.position) < 6 * U.cm);
|
||||
bool pickup = in_dist.state && Rig.btn_grip.delta == +1;
|
||||
in_cone.Step(Vec3.AngleBetween(
|
||||
Rig.head.orientation * Vec3.Forward,
|
||||
Vec3.Direction(box_pose.position, Rig.head.position)
|
||||
) < 15.0f);
|
||||
switch (box_mode)
|
||||
{
|
||||
case BoxMode.Float:
|
||||
if (pickup) { box_mode = BoxMode.Hold; }
|
||||
break;
|
||||
case BoxMode.Hold:
|
||||
box_pose.position = Rig.r_con_stick.position;
|
||||
box_dist = Vec3.Distance(box_pose.position, Rig.head.position);
|
||||
if (Rig.btn_grip.delta == -1) { box_mode = in_cone.state ? BoxMode.Mount : BoxMode.Float; }
|
||||
break;
|
||||
case BoxMode.Mount:
|
||||
// orbital_view
|
||||
box_pose.position = Rig.head.position + Rig.head.orientation * V.XYZ(0, -(SD_Y + 0.5f) * box_scale, -box_dist);
|
||||
if (pickup) { box_mode = BoxMode.Hold; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XYZi next_pos = slash[0] + Rig.new_dir;
|
||||
bool neck_break = next_pos == slash[1];
|
||||
if (!neck_break && !food_next.state)
|
||||
{
|
||||
slash_dir = Rig.new_dir;
|
||||
}
|
||||
|
||||
food_next.Step(!Mono.eaten_latch.state && (Mono.slash[0] + Mono.slash_dir) == Mono.food);
|
||||
if (food_next.delta == +1)
|
||||
{
|
||||
SFX.maw.PlayBox(Mono.slash[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static (bool, XYZi) Feed()
|
||||
{
|
||||
// [!] handle out of the box exception on tail
|
||||
// by making the spatial arrays encapsulate the layer outside of the box
|
||||
tail_fill.Clear(-1);
|
||||
Gas(tail_fill, slash[slash_len - 1]);
|
||||
|
||||
// step from head using directions towards the tail
|
||||
// and stop at either 1 cell away from the tail or 5 spaces away from the head
|
||||
bool viable = false;
|
||||
bool viable_step = false;
|
||||
XYZi cell = slash[0];
|
||||
for (int step = 0; step < 5; step++)
|
||||
{
|
||||
viable_step = false;
|
||||
int min_dist = 100;
|
||||
XYZi min_cell = new();
|
||||
int[] dir_indices = GetShuffledIndices(directions);
|
||||
for (int i = 0; i < directions.Length; i++)
|
||||
{
|
||||
XYZi dir = directions[dir_indices[i]];
|
||||
XYZi dir_cell = cell + dir;
|
||||
int tail_dist = tail_fill[dir_cell];
|
||||
if (tail_dist > 1 && tail_dist < min_dist && box_space.InRange(dir_cell))
|
||||
{
|
||||
min_dist = tail_dist;
|
||||
min_cell = dir_cell;
|
||||
viable = true;
|
||||
viable_step = true;
|
||||
}
|
||||
}
|
||||
if (viable_step)
|
||||
{
|
||||
tail_fill[min_cell] = -1; // prevent backtracking
|
||||
cell = min_cell;
|
||||
}
|
||||
// if (min_dist <= 1)
|
||||
// in_dist.Step(Vec3.Distance(Rig.r_con_stick.position, box_pose.position) < 6 * U.cm);
|
||||
// bool pickup = in_dist.state && Rig.btn_grip.delta == +1;
|
||||
// in_cone.Step(Vec3.AngleBetween(
|
||||
// Rig.head.orientation * Vec3.Forward,
|
||||
// Vec3.Direction(box_pose.position, Rig.head.position)
|
||||
// ) < 15.0f);
|
||||
// switch (mode)
|
||||
// {
|
||||
// case Mode.Float:
|
||||
// if (pickup) { mode = Mode.Hold; }
|
||||
// break;
|
||||
// case Mode.Hold:
|
||||
// box_pose.position = Rig.r_con_stick.position;
|
||||
// box_dist = Vec3.Distance(box_pose.position, Rig.head.position);
|
||||
// if (Rig.btn_grip.delta == -1) { mode = in_cone.state ? Mode.Mount : Mode.Float; }
|
||||
// break;
|
||||
// case Mode.Mount:
|
||||
// // orbital_view
|
||||
// box_pose.position = Rig.head.position + Rig.head.orientation * V.XYZ(0, -(SD_Y + 0.5f) * box_scale, -box_dist);
|
||||
// if (pickup) { mode = Mode.Hold; }
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
return (viable, cell);
|
||||
}
|
||||
|
||||
// space fill algorithm
|
||||
static void Gas(SpatialArray<int> fill_array, XYZi sv)
|
||||
{
|
||||
Queue<XYZi> queue = new Queue<XYZi>();
|
||||
queue.Enqueue(sv);
|
||||
fill_array[sv] = 0;
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
XYZi _sv = queue.Dequeue();
|
||||
int currentDistance = fill_array[_sv];
|
||||
|
||||
// check all 6 directions
|
||||
foreach (XYZi dir in directions)
|
||||
{
|
||||
XYZi newV = _sv + dir;
|
||||
|
||||
if (fill_array.InRange(newV) && fill_array[newV] == -1 && s_array[newV] == -1)
|
||||
{
|
||||
fill_array[newV] = currentDistance + 1;
|
||||
queue.Enqueue(newV);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int[] GetShuffledIndices<T>(T[] array)
|
||||
{
|
||||
int[] indices = new int[array.Length];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
indices[i] = i;
|
||||
}
|
||||
for (int i = indices.Length - 1; i > 0; i--)
|
||||
{
|
||||
int j = System.Random.Shared.Next(i + 1);
|
||||
(indices[j], indices[i]) = (indices[i], indices[j]);
|
||||
}
|
||||
return indices;
|
||||
}
|
||||
|
||||
// directions for moving in the grid
|
||||
static readonly XYZi[] directions = new XYZi[]
|
||||
{
|
||||
new(-1, 0, 0), // lft
|
||||
new(+1, 0, 0), // rht
|
||||
new(0, -1, 0), // dwn
|
||||
new(0, +1, 0), // up
|
||||
new(0, 0, -1), // fwd
|
||||
new(0, 0, +1), // back
|
||||
};
|
||||
static readonly XYZi[] corners = new XYZi[]
|
||||
{
|
||||
new(-1, -1, -1),
|
||||
new(-1, -1, +1),
|
||||
new(-1, +1, -1),
|
||||
new(-1, +1, +1),
|
||||
new(+1, -1, -1),
|
||||
new(+1, -1, +1),
|
||||
new(+1, +1, -1),
|
||||
new(+1, +1, +1)
|
||||
};
|
||||
|
||||
static XYZi InsetCell(XYZi cell)
|
||||
{
|
||||
// [!] don't inset past 0
|
||||
return new(
|
||||
cell.x - Maths.sign(cell.x),
|
||||
cell.y - Maths.sign(cell.y),
|
||||
cell.z - Maths.sign(cell.z)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ class Program
|
|||
// stepper
|
||||
// if (Time.Total > 3.0) return; // buffer app loading [!] relace with user prompt to start (spawn box in hand or something)
|
||||
|
||||
if (!Mono.menu)
|
||||
if (!Mono.menu.state)
|
||||
{
|
||||
Mono.game_time += Time.Step;
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ namespace slash;
|
|||
|
||||
static class SFX
|
||||
{
|
||||
public static void PlayBox(this Sound sound, XYZi pos)
|
||||
public static void PlayMenu(this Sound sound)
|
||||
{
|
||||
sound.Play(Mono.box_pose.ToMatrix(Mono.box_scale) * pos.ToVec3);
|
||||
sound.Play(Mono.menu_pose.ToMatrix(Mono.menu_scale) * Vec3.Zero);
|
||||
}
|
||||
|
||||
public static Sound click = Sound.FromFile("sfx/click.mp3");
|
||||
|
|
|
@ -39,9 +39,9 @@ static class VFX
|
|||
particle.pos += particle.vel * Time.Stepf;
|
||||
float scl_rad = particle.scl * 0.5f * 0.333f;
|
||||
Vec3 next_pos = V.XYZ(
|
||||
Maths.s_clamp(particle.pos.x, Mono.SD_X - 0.5f - scl_rad),
|
||||
Maths.s_clamp(particle.pos.y, Mono.SD_Y - 0.5f - scl_rad),
|
||||
Maths.s_clamp(particle.pos.z, Mono.SD_Z - 0.5f - scl_rad)
|
||||
Maths.s_clamp(particle.pos.x, 1 - 0.5f - scl_rad),
|
||||
Maths.s_clamp(particle.pos.y, 1 - 0.5f - scl_rad),
|
||||
Maths.s_clamp(particle.pos.z, 1 - 0.5f - scl_rad)
|
||||
);
|
||||
if (next_pos.x != particle.pos.x || next_pos.y != particle.pos.y || next_pos.z != particle.pos.z)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue