Compare commits
22 commits
a59110067e
...
352535eaa2
Author | SHA1 | Date | |
---|---|---|---|
352535eaa2 | |||
f2fa87dbe9 | |||
5f01f6a0cc | |||
9e9dfdddd3 | |||
745e7ece53 | |||
509449da84 | |||
bf66637bce | |||
91b3f69bf4 | |||
659c30abcf | |||
e31f5e184f | |||
cb9342d4d2 | |||
ca8849818f | |||
6fc7e38851 | |||
b4d0551cb5 | |||
ea2dfbffd0 | |||
eea0d766c8 | |||
eccb2836c2 | |||
84f2933c6f | |||
6181e4ae49 | |||
8167ab990b | |||
41ae92a37e | |||
6c3b1a2ae0 |
9 changed files with 148 additions and 34 deletions
33
Assets/justcolor.hlsl
Normal file
33
Assets/justcolor.hlsl
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "stereokit.hlsli"
|
||||
|
||||
//--name = dofdev/justcolor
|
||||
//--color:color = 1, 1, 1, 1
|
||||
|
||||
float4 color;
|
||||
|
||||
struct vsIn {
|
||||
float4 pos : SV_Position;
|
||||
float3 norm : NORMAL0;
|
||||
};
|
||||
struct psIn {
|
||||
float4 pos : SV_POSITION;
|
||||
float4 color : COLOR0;
|
||||
uint view_id : SV_RenderTargetArrayIndex;
|
||||
};
|
||||
|
||||
psIn vs(vsIn input, uint id : SV_InstanceID) {
|
||||
psIn o;
|
||||
o.view_id = id % sk_view_count;
|
||||
id = id / sk_view_count;
|
||||
|
||||
float3 world = mul(float4(input.pos.xyz, 1), sk_inst[id].world).xyz;
|
||||
o.pos = mul(float4(world, 1), sk_viewproj[o.view_id]);
|
||||
|
||||
float3 normal = normalize(mul(input.norm, (float3x3)sk_inst[id].world));
|
||||
|
||||
o.color = color * sk_inst[id].color;
|
||||
return o;
|
||||
}
|
||||
float4 ps(psIn input) : SV_TARGET {
|
||||
return input.color;
|
||||
}
|
BIN
Assets/meshes/assets.glb
(Stored with Git LFS)
BIN
Assets/meshes/assets.glb
(Stored with Git LFS)
Binary file not shown.
|
@ -2,8 +2,8 @@
|
|||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.dofdev.snake"
|
||||
android:versionCode="7"
|
||||
android:versionName="1.07"
|
||||
android:versionCode="11"
|
||||
android:versionName="1.15"
|
||||
android:installLocation="auto"
|
||||
>
|
||||
<uses-sdk android:minSdkVersion="29" android:targetSdkVersion="32" />
|
||||
|
|
37
readme.md
37
readme.md
|
@ -23,9 +23,10 @@ adb shell ip -f inet addr show wlan0
|
|||
adb connect 192.168.1.219
|
||||
|
||||
# publish build
|
||||
# increment version in Platforms/Android/AndroidManifest.xml
|
||||
dotnet publish -c Release Projects/Android/snake.Android.csproj
|
||||
|
||||
adb install Projects/Android/bin/Release/net7.0-android/com.dofdev.snake-Signed.apk
|
||||
# adb install Projects/Android/bin/Release/net7.0-android/com.dofdev.snake-Signed.apk
|
||||
|
||||
# upload quest
|
||||
source .env
|
||||
|
@ -41,16 +42,30 @@ sdkmanager "platforms;android-33" "build-tools;33.0.0"
|
|||
|
||||
```
|
||||
todo
|
||||
track steps out of box
|
||||
if > x then snake get's pulled/slips out of the box
|
||||
reprioritize beta testing (new user exp)
|
||||
i want the player to feel clever weighing options to balance risk and reward as they live with their choices(tail)
|
||||
meaning they should only fail due to their own choices/shortsightedness
|
||||
*breaking out of the box is sort of like thinking out of the box which give them the feeling of being clever
|
||||
|
||||
check to see how far out of box (with some warning)
|
||||
if (too far out || more segments out of box than in)than slip out of box from gravity
|
||||
if going up slipping out due to gravity doesn't make sense so
|
||||
just prevent the snake from going too far up instead (soft pause)?
|
||||
target audience/experience
|
||||
~13-18-year-olds who enjoy competitive, skill-based, solo gaming
|
||||
seated experience on the Meta Quest 3/3S
|
||||
moderate learning curve
|
||||
stylized visuals
|
||||
fun to play daily for a couple weeks or so
|
||||
|
||||
start outside of the box (about 6-9 segments long)
|
||||
snake is moving like normal but is parented to an offset pose that keeps their head centered
|
||||
so you can easily get a feel for how the snake moves
|
||||
(sort of like writhing around in zero g)
|
||||
*dreamlike*
|
||||
wake up in box
|
||||
|
||||
mount/unmount box for orbital_view || handheld || desk/space view
|
||||
if placed within 15 degree cone of head view then
|
||||
mount (zero out relative x offset)
|
||||
|
||||
bug(s)
|
||||
food.spawn fails to find a spot and defaults to zero
|
||||
|
||||
this means gravity could affect things even when in box
|
||||
and breaking through the box and coiling up on yourself allows you to fill the space strategically
|
||||
the food could even be affected by gravity so everything kind of starts of 2d
|
||||
and 3d feels like an awesome treat/clever trick the user can play rather than an overwhelming paradigm shift
|
||||
```
|
57
src/Arts.cs
57
src/Arts.cs
|
@ -10,9 +10,15 @@ static class Arts
|
|||
static Material mat_mono = new Material("mono.hlsl");
|
||||
static Material mat_unlit = new Material("unlit.hlsl");
|
||||
static Material mat_backbox = new Material("backbox.hlsl");
|
||||
static Material mat_justcolor = new Material("justcolor.hlsl");
|
||||
|
||||
static Quat food_ori = Quat.Identity;
|
||||
|
||||
static XYZi last_headpos = new(0, 0, 0);
|
||||
static DeltaBool headmove = new(false);
|
||||
static XYZi last_tailpos = new(0, 0, 0);
|
||||
static DeltaBool tailmove = new(false);
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
foreach (ModelNode node in assets_model.Nodes)
|
||||
|
@ -55,7 +61,17 @@ static class Arts
|
|||
Hierarchy.Push(Mono.box_pose.ToMatrix(Mono.box_scale));
|
||||
meshes["InsideOut"].Draw(mat_unlit, Matrix.Identity);
|
||||
meshes["InsideOut"].Draw(mat_backbox, Matrix.Identity);
|
||||
meshes["Corrugation"].Draw(mat_unlit, Matrix.Identity);
|
||||
meshes["Corrugation"].Draw(
|
||||
Mono.in_dist.state ? mat_justcolor : mat_unlit,
|
||||
Matrix.Identity
|
||||
);
|
||||
if (Mono.in_cone.state)
|
||||
{
|
||||
meshes["Hanging"].Draw(
|
||||
mat_unlit,
|
||||
Matrix.Identity
|
||||
);
|
||||
}
|
||||
if (Mono.menu)
|
||||
{
|
||||
meshes["Tape"].Draw(mat_mono, Matrix.Identity);
|
||||
|
@ -76,7 +92,7 @@ static class Arts
|
|||
}
|
||||
|
||||
// snake
|
||||
float snake_t = Maths.smooth_stop((float)Mono.step_t);
|
||||
float snake_t = headmove.state ? Maths.u_clamp(Maths.smooth_stop((float)Mono.step_t) * 3.0f) : 1.0f;
|
||||
bool food_next = (Mono.snake[0] + Mono.snake_dir) == Mono.food;
|
||||
if (!food_next)
|
||||
{
|
||||
|
@ -100,7 +116,7 @@ static class Arts
|
|||
)
|
||||
);
|
||||
|
||||
for (int i = 1; i < Mono.snake_len - 1; i++)
|
||||
for (int i = 1; i < Mono.snake_len; i++)
|
||||
{
|
||||
float scale = 1.0f;
|
||||
if ((int)((Time.Total - Mono.eat_timestamp) * Mono.snake_len / Mono.step_step) == i)
|
||||
|
@ -116,18 +132,19 @@ static class Arts
|
|||
)
|
||||
);
|
||||
}
|
||||
// tail
|
||||
if (Mono.grow_buffer > 0) { snake_t = 0.0f; }
|
||||
int i_tail = Mono.snake_len - 1;
|
||||
Vec3 tail_dir = Vec3.Direction(Mono.snake[i_tail - 1].ToVec3, Mono.snake[i_tail].ToVec3);
|
||||
meshes["Segment"].Draw(
|
||||
mat_mono,
|
||||
Matrix.TRS(
|
||||
Mono.snake[i_tail].ToVec3 + (tail_dir * (float)(snake_t) * 0.7f),
|
||||
Quat.LookDir(tail_dir),
|
||||
V.XYZ(1, 1, (float)(1.0 - snake_t))
|
||||
)
|
||||
);
|
||||
// false tail
|
||||
if (tailmove.state && snake_t < 1.0f) {
|
||||
int i_tail = Maths.min(Mono.snake_len, Mono.snake.Length - 1);
|
||||
Vec3 tail_dir = Vec3.Direction(Mono.snake[i_tail - 1].ToVec3, Mono.snake[i_tail].ToVec3);
|
||||
meshes["Segment"].Draw(
|
||||
mat_mono,
|
||||
Matrix.TRS(
|
||||
Mono.snake[i_tail].ToVec3 + (tail_dir * (float)(snake_t) * 0.7f),
|
||||
Quat.LookDir(tail_dir),
|
||||
V.XYZ(1, 1, (float)(1.0 - snake_t))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// holes
|
||||
foreach (KeyValuePair<XYZi, XYZi> hole in Mono.holes)
|
||||
|
@ -181,4 +198,14 @@ static class Arts
|
|||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public static void Step()
|
||||
{
|
||||
XYZi snake_head = Mono.snake[0];
|
||||
XYZi snake_tail = Mono.snake[Mono.snake_len -1];
|
||||
headmove.Step(snake_head != last_headpos);
|
||||
tailmove.Step(snake_tail != last_tailpos);
|
||||
last_headpos = snake_head;
|
||||
last_tailpos = snake_tail;
|
||||
}
|
||||
}
|
|
@ -10,8 +10,8 @@ public static class Maths
|
|||
public static int u_index(int s_index, int s_len) => s_len + s_index;
|
||||
public static int s_index(int u_index, int u_len) => u_index - u_len;
|
||||
|
||||
public static float s_scalar(float u_scalar) => (u_scalar * 2.0f) - 1.0f;
|
||||
public static float u_scalar(float s_scalar) => (1.0f + s_scalar) * 0.5f;
|
||||
public static float s_scalar(float u_scalar) => (u_scalar * 2.0f) - 1.0f;
|
||||
|
||||
public static int min(int a, int b) => Math.Min(a, b);
|
||||
public static float min(float a, float b) => Math.Min(a, b);
|
||||
|
@ -20,6 +20,11 @@ public static class Maths
|
|||
public static float max(float a, float b) => Math.Max(a, b);
|
||||
public static double max(double a, double b) => Math.Max(a, b);
|
||||
|
||||
public static float u_clamp(float x, float cap = 1.0f) => min(cap, max(0.0f, x));
|
||||
public static double u_clamp(double x, double cap = 1.0) => min(cap, max(0.0, x));
|
||||
public static float s_clamp(float x, float cap = 1.0f) => min(cap, max(-cap, x));
|
||||
public static double s_clamp(double x, double cap = 1.0) => min(cap, max(-cap, x));
|
||||
|
||||
public static int abs(int x) => Math.Abs(x);
|
||||
public static float abs(float x) => Math.Abs(x);
|
||||
public static double abs(double x) => Math.Abs(x);
|
||||
|
|
35
src/Mono.cs
35
src/Mono.cs
|
@ -30,11 +30,22 @@ static class Mono
|
|||
public static XYZi food = new(2, 0, 0);
|
||||
public static double eat_timestamp = 0.0;
|
||||
|
||||
public enum BoxMode
|
||||
{
|
||||
Float = -1,
|
||||
Hold = 0,
|
||||
Mount = 1,
|
||||
}
|
||||
// start mounted & in_cone
|
||||
public static BoxMode box_mode = BoxMode.Mount;
|
||||
public static DeltaBool in_cone = new(true);
|
||||
public static DeltaBool in_dist = new(false);
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
for (int i = 0; i < snake.Length; i++)
|
||||
{
|
||||
snake[i] = new XYZi(0, 1, 0);
|
||||
snake[i] = new XYZi(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,7 +69,27 @@ static class Mono
|
|||
}
|
||||
else
|
||||
{
|
||||
box_pose.position = Rig.head.position + Rig.head.orientation * V.XYZ(0, -(SD_Y + 0.5f) * box_scale, -32 * U.cm);
|
||||
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;
|
||||
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, -32 * U.cm);
|
||||
if (pickup) { box_mode = BoxMode.Hold; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XYZi next_pos = snake[0] + Rig.new_dir;
|
||||
|
|
|
@ -52,6 +52,7 @@ class Program
|
|||
Mono.step_time -= Mono.step_step;
|
||||
|
||||
Mono.Step();
|
||||
Arts.Step();
|
||||
}
|
||||
|
||||
Arts.Frame();
|
||||
|
|
|
@ -7,6 +7,7 @@ static class Rig
|
|||
public static Pose head = Pose.Identity;
|
||||
|
||||
public static DeltaBool btn_trigger = new(false);
|
||||
public static DeltaBool btn_grip = new(false);
|
||||
|
||||
public static Vec3 fullstick = Vec3.Up;
|
||||
public static Pose r_con_stick = Pose.Identity;
|
||||
|
@ -37,9 +38,10 @@ static class Rig
|
|||
}
|
||||
else
|
||||
{
|
||||
Hand r_hand = Input.Hand(Handed.Right);
|
||||
// Hand r_hand = Input.Hand(Handed.Right);
|
||||
Controller r_con = Input.Controller(Handed.Right);
|
||||
btn_trigger.Step(r_con.trigger > 0.5f);
|
||||
btn_grip.Step(r_con.grip > 0.5f);
|
||||
|
||||
bool con_tracked = r_con.trackedPos > TrackState.Lost;
|
||||
Input.HandVisible(Handed.Max, !con_tracked);
|
||||
|
|
Loading…
Add table
Reference in a new issue