Compare commits

..

10 commits

7 changed files with 261 additions and 20 deletions

BIN
Assets/meshes/assets.glb (Stored with Git LFS)

Binary file not shown.

View file

@ -41,6 +41,29 @@ sdkmanager "platforms;android-33" "build-tools;33.0.0"
```
todo
spawn enemies in line to player
slash with 4 sheathed swords
give the player a reason to slash in the different directions
swoop in from the different directions in an x
lft hand -> rht hip
rht hand -> lft hip
shoulders either
setup environment
mesh slopes as a base ground layer?
and groundwork for player movement/interactions
troubleshoot linux pc/vr stereokit
embedded blades
this helps with the gap in hit detection
as the slash part works great, but once the blade is deep within the enemy without the velocity to carry through
it could break off/get embedded in the enemy
stretch cursor is the gun?
stretch is the trigger
cursor is the bullet
strength/sensitivity calculated on bullet hit
with force based movement relative cursor rather than rope swing (*temporary effect)
pitch
anime slasher with juicy dofs
@ -52,10 +75,15 @@ todo
stylized visuals
fun to play daily for a couple weeks or so
design principles
defying gravity(dante style) > zero gravity || gravity
core mechanics
stretch slash
revolver
flick reload
joystick dash
grind on surfaces
toylike level editor
(no details to get bogged down with)
shape environment

View file

@ -86,14 +86,63 @@ static class Arts
);
// bamboo
Mesh.Cube.Draw(
mat_unlit,
Matrix.TS(
V.XYZ(0, 1, -5),
V.XYZ(0.1f, 2, 0.1f)
),
Color.Hex(0xB9E7AFFF)
);
for (int i = -12; i <= 12; i++)
{
float z_offset = Noise.s_scalar_x(i) * 2.0f;
float x_offset = Noise.s_scalar_x(i + 32) * 0.2f;
float x_wind = Maths.smooth_stop(Maths.u_scalar(SKMath.Sin((i * 0.16f) - Time.Totalf)));
Vec3[] p = new Vec3[] {
V.XYZ(i * 0.3f, 0, -10 + z_offset),
V.XYZ(i * 0.3f, 1, -10 + z_offset),
V.XYZ(i * 0.3f, 4, -10 + z_offset),
V.XYZ(i * 0.3f + x_offset + x_wind, 5, -10 + z_offset),
};
// debug bezier points
// for (int i = 0; i < p.Length; i++)
// {
// Mesh.Sphere.Draw(
// mat_justcolor,
// Matrix.TS(
// p[i],
// 2 * U.mm
// ),
// Color.White
// );
// }
// ground bump
// Mesh.Sphere.Draw(
// mat_justcolor,
// Matrix.TS(
// box_mount,
// 3 * U.mm
// ),
// Color.Hex(0x959493FF).ToLinear()
// );
int steps = 92;
Vec3 pastPos = p[0];
float pastThc = 0.0f;
for (int j = 0; j < steps; j++)
{
float t = (float)j / (steps - 1);
Vec3 a = Vec3.Lerp(p[0], p[1], t);
Vec3 b = Vec3.Lerp(p[1], p[2], t);
Vec3 c = Vec3.Lerp(p[2], p[3], t);
Vec3 pos = Vec3.Lerp(Vec3.Lerp(a, b, t), Vec3.Lerp(b, c, t), t);
float thc = (1.0f + Maths.precision((1.0f - t), Maths.lerp(0.1f, 0.2f, Noise.u_scalar_x(i))) * 2.0f) * U.cm * 6.0f;
Lines.Add(
pastPos,
pos,
thc != pastThc ? Color.Hex(0x959493FF).ToLinear() : Color.Hex(0xB9E7AFFF).ToLinear(),
thc
);
pastPos = pos;
pastThc = thc;
}
}
// unit cube
// Mesh.Cube.Draw(
@ -104,8 +153,9 @@ static class Arts
// enemy
Enemy enemy_test = Mono.enemy_types[(int)(Time.Totalf % Mono.enemy_types.Length)];
enemy_test.pose.position = V.XYZ(SKMath.Sin(Time.Totalf * 1f) * 1.0f, 0.666f, -3.0f);
enemy_test.pose.orientation = Quat.FromAngles(0, Time.Totalf * 30, 0);
Quat enemy_orbit = Quat.FromAngles(0, 0, 45) * Quat.FromAngles(0, (Time.Totalf * 30) % 360, 0);
enemy_test.pose.position = V.XYZ(0, 0, -3.0f) + enemy_orbit * V.XYZ(0, 0, -3);
// V.XYZ(SKMath.Sin(Time.Totalf * 1f) * 1.0f, 0.666f, -3.0f);
for (int i = 0; i < enemy_test.cols.Count; i++)
{
Sphere col = enemy_test.cols[i];
@ -130,7 +180,7 @@ static class Arts
Mesh mesh = new();
Quat blade_ori = Rig.r_hld.orientation;
Vec3 blade_pos = Rig.r_hld.position;
Vec3 tip_pos = blade_pos + blade_ori * V.XYZ(0, 0, 1);
Vec3 tip_pos = blade_pos + blade_ori * V.XYZ(0, 0, -1);
mesh.SetData(
new Vertex[] {
new( blade_pos, V.XYZ(0,0,1)),
@ -146,8 +196,51 @@ static class Arts
Matrix.Identity,
Color.Hex(0xF9BF05FF).ToLinear()
);
Ray slash_ray = new Ray(tip_pos, Vec3.Direction(tip_pos, last_tip_pos));
float ray_dist = Vec3.Distance(tip_pos, last_tip_pos);
last_tip_pos = Vec3.Lerp(last_tip_pos, tip_pos, Time.Stepf / 0.1f);
if (true) // hit test
{
Matrix enemy_m4 = enemy_test.pose.ToMatrix();
Ray local_ray = enemy_m4.Inverse.Transform(slash_ray);
bool hit = false;
float min_dist = ray_dist;
Vec3 min_hit_pos = Vec3.Zero;
for (int i = 0; i < enemy_test.cols.Count; i++)
{
Sphere col = enemy_test.cols[i];
Vec3 hit_pos = Vec3.Zero;
if (col.Intersect(local_ray, out hit_pos))
{
float hit_dist = Vec3.Distance(hit_pos, local_ray.position);
if (hit_dist < min_dist)
{
hit = true;
min_dist = hit_dist;
min_hit_pos = hit_pos;
}
}
}
min_hit_pos = enemy_m4.Transform(min_hit_pos);
if (hit)
{
Mesh.Sphere.Draw(
mat_unlit,
Matrix.TS(
min_hit_pos,
4 * U.cm
),
Color.White
);
if (Rig.btn_select.state)
{
VFX.Play(min_hit_pos);
}
}
}
// revolver
Quat rvolv_ori = Rig.l_aim.orientation;
Vec3 rvolv_pos = Rig.l_aim.position;
@ -209,7 +302,7 @@ static class Arts
for (int i = 0; i < particles.Length; i++)
{
Particle particle = particles[i];
Mesh.Cube.Draw(
Mesh.Sphere.Draw(
mat_unlit,
Matrix.TRS(
particle.pos,

View file

@ -35,7 +35,10 @@ public static class Maths
// public static int roundi(float value) => MathF.Round(value)
public static float precision(float x, float p)
=> round(x * p) / p;
{
float ps = p < 1.0f ? 1 / p : p;
return round(x * ps) / ps;
}
public static float smooth_start(float t) => (t * t * t);
public static float smooth_stop(float t)
@ -94,6 +97,122 @@ public static class Maths
}
}
/// <summary>
/// SquirrelNoise5 - Squirrel's Raw Noise utilities (version 5)
/// Converted to C# from original C++ implementation by Squirrel Eiserloh
/// </summary>
public static class Noise
{
// Bit noise constants
private const uint SQ5_BIT_NOISE1 = 0xd2a80a3f;
private const uint SQ5_BIT_NOISE2 = 0xa884f197;
private const uint SQ5_BIT_NOISE3 = 0x6C736F4B;
private const uint SQ5_BIT_NOISE4 = 0xB79F3ABB;
private const uint SQ5_BIT_NOISE5 = 0x1b56c4f5;
// Constants for higher dimensional noise
private const int PRIME1 = 198491317;
private const int PRIME2 = 6542989;
private const int PRIME3 = 357239;
/// <summary>
/// Fast hash of an int32 into a different (unrecognizable) uint32
/// </summary>
private static uint GetNoise(int positionX, uint seed)
{
uint mangledBits = (uint)positionX;
mangledBits *= SQ5_BIT_NOISE1;
mangledBits += seed;
mangledBits ^= (mangledBits >> 9);
mangledBits += SQ5_BIT_NOISE2;
mangledBits ^= (mangledBits >> 11);
mangledBits *= SQ5_BIT_NOISE3;
mangledBits ^= (mangledBits >> 13);
mangledBits += SQ5_BIT_NOISE4;
mangledBits ^= (mangledBits >> 15);
mangledBits *= SQ5_BIT_NOISE5;
mangledBits ^= (mangledBits >> 17);
return mangledBits;
}
// 1D Noise Functions
public static uint u_int_x(int x, uint seed = 0)
{
return GetNoise(x, seed);
}
public static float u_scalar_x(int x, uint seed = 0)
{
return (float)(GetNoise(x, seed) / (double)uint.MaxValue);
}
public static float s_scalar_x(int x, uint seed = 0)
{
return (float)((int)GetNoise(x, seed) / (double)int.MaxValue);
}
private static int step;
static int stepper
{
get
{
step = (step + 1) % 100_000; // [!] magic number
return step;
}
}
public static uint u_int => u_int_x(stepper);
public static float u_scalar => u_scalar_x(stepper);
public static float s_scalar => s_scalar_x(stepper);
// // 2D Noise Functions
// public static uint Get2dNoiseUint(int indexX, int indexY, uint seed = 0)
// {
// return GetNoise(indexX + (PRIME1 * indexY), seed);
// }
// public static float Get2dNoiseZeroToOne(int indexX, int indexY, uint seed = 0)
// {
// return (float)(Get2dNoiseUint(indexX, indexY, seed) / (double)uint.MaxValue);
// }
// public static float Get2dNoiseNegOneToOne(int indexX, int indexY, uint seed = 0)
// {
// return (float)((int)Get2dNoiseUint(indexX, indexY, seed) / (double)int.MaxValue);
// }
// 3D Noise Functions
public static uint u_int_xyz(int x, int y, int z, uint seed = 0)
{
return GetNoise(x + (PRIME1 * y) + (PRIME2 * z), seed);
}
public static float u_scalar_xyz(int x, int y, int z, uint seed = 0)
{
return (float)(u_int_xyz(x, y, z, seed) / (double)uint.MaxValue);
}
public static float s_scalar_xyz(int x, int y, int z, uint seed = 0)
{
return (float)((int)u_int_xyz(x, y, z, seed) / (double)int.MaxValue);
}
// // 4D Noise Functions
// public static uint Get4dNoiseUint(int indexX, int indexY, int indexZ, int indexT, uint seed = 0)
// {
// return GetNoise(indexX + (PRIME1 * indexY) + (PRIME2 * indexZ) + (PRIME3 * indexT), seed);
// }
// public static float Get4dNoiseZeroToOne(int indexX, int indexY, int indexZ, int indexT, uint seed = 0)
// {
// return (float)(Get4dNoiseUint(indexX, indexY, indexZ, indexT, seed) / (double)uint.MaxValue);
// }
// public static float Get4dNoiseNegOneToOne(int indexX, int indexY, int indexZ, int indexT, uint seed = 0)
// {
// return (float)((int)Get4dNoiseUint(indexX, indexY, indexZ, indexT, seed) / (double)int.MaxValue);
// }
}
public class DeltaBool
{
public int delta = 0;

View file

@ -22,6 +22,7 @@ class Program
disableFlatscreenMRSim = true,
renderScaling = 2,
renderMultisample = 0,
// mode = AppMode.Simulator,
};
if (!SK.Initialize(settings))

View file

@ -33,11 +33,11 @@ static class Rig
btn_back.Step(Input.Key(Key.MouseRight).IsActive());
r_hld = new Pose(
V.XYZ(SKMath.Sin(Time.Totalf * 1f) * 0.1f, 0.5f, 1.0f),
Quat.FromAngles(0, 0, SKMath.Sin(Time.Totalf * 6f) * 30f)
V.XYZ(SKMath.Sin(Time.Totalf * 6f) * 0.6f * 0.0f, 0.5f, 1.0f),
Quat.FromAngles(0, 0, 45) * Quat.FromAngles(0, SKMath.Sin(Time.Totalf * 6f) * 60f, 0)
);
l_aim = new Pose(
V.XYZ(SKMath.Sin(Time.Totalf * 2f) * 0.6f, 0.5f, 0.5f),
V.XYZ(1.0f, 0.5f, 0.5f), // V.XYZ(SKMath.Sin(Time.Totalf * 2f) * 0.6f, 0.5f, 0.5f),
Quat.Identity
);

View file

@ -23,9 +23,9 @@ static class VFX
index = (index + 1) % particles.Length;
Particle particle = particles[index];
particle.pos = pos;
particle.vel = Quat.FromAngles(Random.Shared.NextSingle() * 360, 0, 0) * Quat.FromAngles(0, Random.Shared.NextSingle() * 360, 0) * Vec3.Forward * 6.0f;
particle.vel = Quat.FromAngles(Noise.u_scalar * 360, 0, 0) * Quat.FromAngles(0, Noise.u_scalar * 360, 0) * Vec3.Forward * 3.0f;
particle.ori = Quat.Identity;
particle.scl = (1.0f / 3) * Maths.smooth_start(Random.Shared.NextSingle());
particle.scl = (1.0f / 3) * Maths.smooth_start(Noise.u_scalar);
}
}