Draw the touch ring in engine instead of a particle
This commit is contained in:
1 parent
dcd3006f24
commit
4e3abaa381
11 files changed
+33
-78
No files matched your search
+2
-4
@@ -174,7 +174,6 @@ The first expand area is treated as the belly: it breathes, jiggles when smacked
|
|||||||
| `scaleCycles` | float | How many oscillations the scale effect performs. Defaults to 1. |
|
| `scaleCycles` | float | How many oscillations the scale effect performs. Defaults to 1. |
|
||||||
| `scaleTime` | float, seconds | How long the scale effect lasts. Defaults to a third of a second. |
|
| `scaleTime` | float, seconds | How long the scale effect lasts. Defaults to a third of a second. |
|
||||||
| `sounds` | paths | Sounds played when interacting. |
|
| `sounds` | paths | Sounds played when interacting. |
|
||||||
| `particles` | strings | Particles (see `particles`) spawned when interacting. |
|
|
||||||
|
|
||||||
### sounds
|
### sounds
|
||||||
| Key | Meaning |
|
| Key | Meaning |
|
||||||
@@ -186,12 +185,11 @@ The first expand area is treated as the belly: it breathes, jiggles when smacked
|
|||||||
How items move in the background (`gfx/area.anm2`): `gravity` (applied to items' velocities per tick), `friction` (applied when items are grounded or hit walls) and `airResistance`.
|
How items move in the background (`gfx/area.anm2`): `gravity` (applied to items' velocities per tick), `friction` (applied when items are grounded or hit walls) and `airResistance`.
|
||||||
|
|
||||||
### cursor
|
### cursor
|
||||||
The cursor's sounds and particles. Its look is `gfx/cursor.anm2` (see "Fixed files and names").
|
The cursor's sounds. Its look is `gfx/cursor.anm2` (see "Fixed files and names").
|
||||||
|
|
||||||
| Key | Meaning |
|
| Key | Meaning |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `sounds` | `grab` (grabbing an item), `release` (letting go) and `throw` (letting go while dragging quickly). |
|
| `sounds` | `grab` (grabbing an item), `release` (letting go) and `throw` (letting go while dragging quickly). |
|
||||||
| `particles` | `grab`: particles spawned when grabbing an item. |
|
|
||||||
|
|
||||||
### menu
|
### menu
|
||||||
The UI's sounds.
|
The UI's sounds.
|
||||||
@@ -201,7 +199,7 @@ The UI's sounds.
|
|||||||
| `sounds` | `open` and `close` (the taskbar or one of its windows), `hover` and `select` (a widget), and `cheats` (after entering a special code to activate cheats). |
|
| `sounds` | `open` and `close` (the taskbar or one of its windows), `hover` and `select` (a widget), and `cheats` (after entering a special code to activate cheats). |
|
||||||
|
|
||||||
### particles
|
### particles
|
||||||
An object of particles by name, each with the `anm2` and `animation` it plays once where spawned. The `Circle` particle is also spawned where an item lands hard.
|
An object of particles by name, each with the `anm2` and `animation` it plays once where spawned. (The ring where something is touched, grabbed or lands hard is drawn by the game, not a particle.)
|
||||||
|
|
||||||
# items.json
|
# items.json
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,7 @@
|
|||||||
"isHold": true,
|
"isHold": true,
|
||||||
"cursorHover": "Hover",
|
"cursorHover": "Hover",
|
||||||
"cursorActive": "Rub",
|
"cursorActive": "Rub",
|
||||||
"sounds": ["sfx/rub.ogg"],
|
"sounds": ["sfx/rub.ogg"]
|
||||||
"particles": ["Circle"]
|
|
||||||
},
|
},
|
||||||
"Smack": {
|
"Smack": {
|
||||||
"icon": "smack",
|
"icon": "smack",
|
||||||
@@ -30,21 +29,18 @@
|
|||||||
"dialogueCooldown": 0.6667,
|
"dialogueCooldown": 0.6667,
|
||||||
"scaleAmplitude": 1,
|
"scaleAmplitude": 1,
|
||||||
"scaleCycles": 3,
|
"scaleCycles": 3,
|
||||||
"sounds": "sfx/smack*.ogg",
|
"sounds": "sfx/smack*.ogg"
|
||||||
"particles": ["Circle"]
|
|
||||||
},
|
},
|
||||||
"Kiss": {
|
"Kiss": {
|
||||||
"icon": "kiss",
|
"icon": "kiss",
|
||||||
"cursorHover": "KissHover",
|
"cursorHover": "KissHover",
|
||||||
"cursorActive": "Kiss",
|
"cursorActive": "Kiss",
|
||||||
"sounds": "sfx/kiss*.ogg",
|
"sounds": "sfx/kiss*.ogg"
|
||||||
"particles": ["Circle"]
|
|
||||||
},
|
},
|
||||||
"Turn Around": {"icon": "turn", "sounds": ["sfx/turn.ogg"], "particles": ["Circle"]}
|
"Turn Around": {"icon": "turn", "sounds": ["sfx/turn.ogg"]}
|
||||||
},
|
},
|
||||||
"cursor": {
|
"cursor": {
|
||||||
"sounds": {"grab": ["sfx/grab.ogg"], "release": ["sfx/release.ogg"], "throw": "sfx/throw*.ogg"},
|
"sounds": {"grab": ["sfx/grab.ogg"], "release": ["sfx/release.ogg"], "throw": "sfx/throw*.ogg"}
|
||||||
"particles": {"grab": ["Circle"]}
|
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"sounds": {
|
"sounds": {
|
||||||
@@ -56,7 +52,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"particles": {
|
"particles": {
|
||||||
"Circle": {"anm2": "gfx/circle.anm2", "animation": "Main"},
|
|
||||||
"Puff": {"anm2": "gfx/puff.anm2", "animation": "Main"}
|
"Puff": {"anm2": "gfx/puff.anm2", "animation": "Main"}
|
||||||
},
|
},
|
||||||
"area": {"gravity": 0.95, "friction": 0.75, "airResistance": 0.975}
|
"area": {"gravity": 0.95, "friction": 0.75, "airResistance": 0.975}
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
{
|
|
||||||
"anm2ed": 1,
|
|
||||||
"info": {},
|
|
||||||
"spritesheets": [
|
|
||||||
{
|
|
||||||
"path": "circle.png",
|
|
||||||
"regions": [
|
|
||||||
{
|
|
||||||
"name": "Main",
|
|
||||||
"size": [128, 128],
|
|
||||||
"pivot": [64, 64],
|
|
||||||
"origin": "center"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"layers": [
|
|
||||||
{"name": "Main"}
|
|
||||||
],
|
|
||||||
"defaultAnimation": "Spawn",
|
|
||||||
"animations": {
|
|
||||||
"Spawn": {
|
|
||||||
"length": 11,
|
|
||||||
"loop": false,
|
|
||||||
"root": [
|
|
||||||
{"delay": 11}
|
|
||||||
],
|
|
||||||
"layers": [
|
|
||||||
{
|
|
||||||
"layer": 0,
|
|
||||||
"frames": [
|
|
||||||
{
|
|
||||||
"region": 0,
|
|
||||||
"scale": [10, 10],
|
|
||||||
"delay": 10,
|
|
||||||
"interpolation": "linear"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"region": 0,
|
|
||||||
"tint": [255, 255, 255, 0],
|
|
||||||
"interpolation": "linear"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.5 KiB |
+2
-8
@@ -118,7 +118,7 @@ static void interact_parse(object source, InteractArea& area, Character& charact
|
|||||||
json_keys_check(source,
|
json_keys_check(source,
|
||||||
{"type", "null", "layer", "icon", "isHold", "animation", "idleOnEnd", "cursorHover", "cursorActive",
|
{"type", "null", "layer", "icon", "isHold", "animation", "idleOnEnd", "cursorHover", "cursorActive",
|
||||||
"dialoguePool", "dialogueCooldown", "digestionClick", "digestionHover",
|
"dialoguePool", "dialogueCooldown", "digestionClick", "digestionHover",
|
||||||
"scaleAmplitude", "scaleCycles", "scaleTime", "sounds", "particles"},
|
"scaleAmplitude", "scaleCycles", "scaleTime", "sounds"},
|
||||||
"an interact area");
|
"an interact area");
|
||||||
area.animation = json_string(source, "animation", area.animation);
|
area.animation = json_string(source, "animation", area.animation);
|
||||||
area.cursorActive = json_string(source, "cursorActive", area.cursorActive);
|
area.cursorActive = json_string(source, "cursorActive", area.cursorActive);
|
||||||
@@ -137,8 +137,6 @@ static void interact_parse(object source, InteractArea& area, Character& charact
|
|||||||
area.layer = character.anm2 ? character.anm2->layer_get(json_string(source, "layer")) : -1;
|
area.layer = character.anm2 ? character.anm2->layer_get(json_string(source, "layer")) : -1;
|
||||||
if (!source["null"].error())
|
if (!source["null"].error())
|
||||||
area.null = character.anm2 ? character.anm2->null_get(json_string(source, "null")) : -1;
|
area.null = character.anm2 ? character.anm2->null_get(json_string(source, "null")) : -1;
|
||||||
if (!source["particles"].error())
|
|
||||||
area.particles = json_strings(source, "particles");
|
|
||||||
if (!source["sounds"].error())
|
if (!source["sounds"].error())
|
||||||
area.sounds = audio.sounds_get(character.roots, json_strings(source, "sounds"));
|
area.sounds = audio.sounds_get(character.roots, json_strings(source, "sounds"));
|
||||||
}
|
}
|
||||||
@@ -259,11 +257,7 @@ static void character_parse(object root, Character& character, Renderer& rendere
|
|||||||
float_read(area, "friction", character.area.friction);
|
float_read(area, "friction", character.area.friction);
|
||||||
float_read(area, "airResistance", character.area.airResistance);
|
float_read(area, "airResistance", character.area.airResistance);
|
||||||
|
|
||||||
object cursor = json_object(root, "cursor");
|
json_keys_check(json_object(root, "cursor"), {"sounds"}, "cursor");
|
||||||
object cursorParticles = json_object(cursor, "particles");
|
|
||||||
json_keys_check(cursor, {"sounds", "particles"}, "cursor");
|
|
||||||
if (!cursorParticles["grab"].error())
|
|
||||||
character.cursor.grabParticles = json_strings(cursorParticles, "grab");
|
|
||||||
json_keys_check(json_object(root, "menu"), {"sounds"}, "menu");
|
json_keys_check(json_object(root, "menu"), {"sounds"}, "menu");
|
||||||
|
|
||||||
for (auto [name, value] : json_object(root, "particles"))
|
for (auto [name, value] : json_object(root, "particles"))
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ struct InteractArea
|
|||||||
std::string icon;
|
std::string icon;
|
||||||
std::string idleOnEnd;
|
std::string idleOnEnd;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<std::string> particles;
|
|
||||||
Sounds sounds;
|
Sounds sounds;
|
||||||
float digestionClick = 0;
|
float digestionClick = 0;
|
||||||
float digestionHover = 0;
|
float digestionHover = 0;
|
||||||
@@ -283,7 +282,6 @@ struct Swap
|
|||||||
|
|
||||||
struct Cursor
|
struct Cursor
|
||||||
{
|
{
|
||||||
std::vector<std::string> grabParticles;
|
|
||||||
Anm2* anm2 = nullptr;
|
Anm2* anm2 = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "effects.h"
|
#include "effects.h"
|
||||||
|
|
||||||
|
constexpr Spark RING_SPARK = {WHITE, {}, {}, {}, 0, 64, 20, 0, SPARK_RING};
|
||||||
constexpr float FLASH_FADE = 0.04f;
|
constexpr float FLASH_FADE = 0.04f;
|
||||||
constexpr float FLOATER_RISE = 0.8f;
|
constexpr float FLOATER_RISE = 0.8f;
|
||||||
constexpr float SPARK_DRAG = 0.95f;
|
constexpr float SPARK_DRAG = 0.95f;
|
||||||
@@ -36,6 +37,14 @@ void Effects::spark_add(Spark spark)
|
|||||||
sparks.push_back(spark);
|
sparks.push_back(spark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A white ring growing and fading where something was touched or hit.
|
||||||
|
void Effects::ring_add(Vec2 position)
|
||||||
|
{
|
||||||
|
Spark spark = RING_SPARK;
|
||||||
|
spark.position = position;
|
||||||
|
spark_add(spark);
|
||||||
|
}
|
||||||
|
|
||||||
// Throws count copies of a spark out in every direction, at up to speed.
|
// Throws count copies of a spark out in every direction, at up to speed.
|
||||||
void Effects::burst_add(Spark spark, int count, float speed)
|
void Effects::burst_add(Spark spark, int count, float speed)
|
||||||
{
|
{
|
||||||
|
|||||||
+4
-2
@@ -15,6 +15,7 @@ enum SparkShape
|
|||||||
{
|
{
|
||||||
SPARK_CIRCLE,
|
SPARK_CIRCLE,
|
||||||
SPARK_LINE,
|
SPARK_LINE,
|
||||||
|
SPARK_RING,
|
||||||
SPARK_STAR
|
SPARK_STAR
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -27,8 +28,8 @@ struct Floater
|
|||||||
FloaterType type = FLOATER_CALORIES;
|
FloaterType type = FLOATER_CALORIES;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A glint, puff or line (from its position to its end) that drifts, falls (or rises) by its gravity, and fades over its
|
// A glint, puff, line (from its position to its end) or ring (growing to its size) that drifts, falls (or rises) by its
|
||||||
// life.
|
// gravity, and fades over its life.
|
||||||
struct Spark
|
struct Spark
|
||||||
{
|
{
|
||||||
Color color;
|
Color color;
|
||||||
@@ -54,4 +55,5 @@ public:
|
|||||||
void floater_add(Vec2 position, float value, FloaterType type);
|
void floater_add(Vec2 position, float value, FloaterType type);
|
||||||
void spark_add(Spark spark);
|
void spark_add(Spark spark);
|
||||||
void burst_add(Spark spark, int count, float speed);
|
void burst_add(Spark spark, int count, float speed);
|
||||||
|
void ring_add(Vec2 position);
|
||||||
};
|
};
|
||||||
+1
-1
@@ -62,7 +62,7 @@ void Interactions::update(Play& play, Pointer pointer)
|
|||||||
}
|
}
|
||||||
play.audio->play(entry.sounds);
|
play.audio->play(entry.sounds);
|
||||||
body.idle_override_set(entry.idleOnEnd);
|
body.idle_override_set(entry.idleOnEnd);
|
||||||
play.particles_spawn(entry.particles, pointer.position);
|
play.effects.ring_add(pointer.position);
|
||||||
if (entry.digestionClick > 0 && body.stats.calories > 0 && !body.stats.isDigesting)
|
if (entry.digestionClick > 0 && body.stats.calories > 0 && !body.stats.isDigesting)
|
||||||
body.stats.digestionProgress += entry.digestionClick;
|
body.stats.digestionProgress += entry.digestionClick;
|
||||||
body.actor.pulse_add(entry.layer, entry.scaleAmplitude, entry.scaleCycles, entry.scaleTime);
|
body.actor.pulse_add(entry.layer, entry.scaleAmplitude, entry.scaleCycles, entry.scaleTime);
|
||||||
|
|||||||
+2
-3
@@ -10,7 +10,6 @@ constexpr float CRUMB_SPEED_Y_MIN = 2;
|
|||||||
constexpr float CRUMB_SPIN = 15;
|
constexpr float CRUMB_SPIN = 15;
|
||||||
constexpr Color GOLD = {1, 0.85f, 0.3f, 1};
|
constexpr Color GOLD = {1, 0.85f, 0.3f, 1};
|
||||||
constexpr Color TRAIL_COLOR = {1, 1, 1, 0.35f};
|
constexpr Color TRAIL_COLOR = {1, 1, 1, 0.35f};
|
||||||
constexpr const char* IMPACT_PARTICLE = "Circle";
|
|
||||||
constexpr float BITE_JIGGLE = 4;
|
constexpr float BITE_JIGGLE = 4;
|
||||||
constexpr float IMPACT_SPEED = 12;
|
constexpr float IMPACT_SPEED = 12;
|
||||||
constexpr float FANFARE_MIN = 0.75f;
|
constexpr float FANFARE_MIN = 0.75f;
|
||||||
@@ -360,7 +359,7 @@ void Items::update(Play& play, Pointer pointer)
|
|||||||
if (pointer.isClicked)
|
if (pointer.isClicked)
|
||||||
{
|
{
|
||||||
audio.play(character.sounds[SOUND_GRAB]);
|
audio.play(character.sounds[SOUND_GRAB]);
|
||||||
play.particles_spawn(character.cursor.grabParticles, pointer.position);
|
play.effects.ring_add(pointer.position);
|
||||||
isJustHeld = true;
|
isJustHeld = true;
|
||||||
}
|
}
|
||||||
if (pointer.isDown)
|
if (pointer.isDown)
|
||||||
@@ -394,7 +393,7 @@ void Items::update(Play& play, Pointer pointer)
|
|||||||
if (impact > 0)
|
if (impact > 0)
|
||||||
audio.play(character.sounds[SOUND_BOUNCE]);
|
audio.play(character.sounds[SOUND_BOUNCE]);
|
||||||
if (impact >= IMPACT_SPEED)
|
if (impact >= IMPACT_SPEED)
|
||||||
play.particles_spawn({IMPACT_PARTICLE}, position);
|
play.effects.ring_add(position);
|
||||||
entity.isThrown &= vec2_length(entity.velocity) >= TRAIL_SPEED;
|
entity.isThrown &= vec2_length(entity.velocity) >= TRAIL_SPEED;
|
||||||
if (entity.isThrown)
|
if (entity.isThrown)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ constexpr float BAR_SHAKE_SPEED = 40;
|
|||||||
constexpr float FLOATER_SHADOW = 3;
|
constexpr float FLOATER_SHADOW = 3;
|
||||||
constexpr float OVERSTUFFED_PULSE = 0.35f;
|
constexpr float OVERSTUFFED_PULSE = 0.35f;
|
||||||
constexpr float OVERSTUFFED_SPEED = 6;
|
constexpr float OVERSTUFFED_SPEED = 6;
|
||||||
|
constexpr float RING_START = 0.1f;
|
||||||
|
constexpr float RING_THICKNESS = 3;
|
||||||
constexpr float STAR_WAIST = 0.3f;
|
constexpr float STAR_WAIST = 0.3f;
|
||||||
constexpr float BAR_WIDTH_MIN = 120;
|
constexpr float BAR_WIDTH_MIN = 120;
|
||||||
constexpr float BUTTON_SIZE_MAX = 96;
|
constexpr float BUTTON_SIZE_MAX = 96;
|
||||||
@@ -741,6 +743,12 @@ void Ui::effects_draw(Play& play, ImVec2 screen)
|
|||||||
drawList->AddCircleFilled({at.x, at.y}, size, color);
|
drawList->AddCircleFilled({at.x, at.y}, size, color);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (spark.shape == SPARK_RING)
|
||||||
|
{
|
||||||
|
float radius = spark.size * view.a * (RING_START + (1 - RING_START) * (1 - fade));
|
||||||
|
drawList->AddCircle({at.x, at.y}, radius, color, 0, RING_THICKNESS * view.a);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (spark.shape == SPARK_LINE)
|
if (spark.shape == SPARK_LINE)
|
||||||
{
|
{
|
||||||
Vec2 end = view * spark.end;
|
Vec2 end = view * spark.end;
|
||||||
|
|||||||
Reference in new issue
Block a user