Line trails, ring on impact, colored shadowed numbers, subtler pitch, no digest rumble
This commit is contained in:
1 parent
4fac37b7f5
commit
ee3430d5cb
8 files changed
+33
-40
No files matched your search
+2
-2
@@ -150,7 +150,7 @@ The areas which will expand based on how full the character is and their progres
|
|||||||
| `null` | The null that will expand. |
|
| `null` | The null that will expand. |
|
||||||
| `scaleMax` | The scale (in percent) that will be added at maximum. Know that a scale of 100 is the normal scale of an animation. |
|
| `scaleMax` | The scale (in percent) that will be added at maximum. Know that a scale of 100 is the normal scale of an animation. |
|
||||||
|
|
||||||
The first expand area is treated as the belly: it breathes, jiggles when smacked, rubbed or fed, and is where digestion and stage-up effects come from.
|
The first expand area is treated as the belly: it breathes, jiggles when smacked, rubbed or fed, and is where stage-up effects and gained weight come from.
|
||||||
|
|
||||||
### interactTypes, interactAreas
|
### interactTypes, interactAreas
|
||||||
`interactTypes` is an object of interaction types by name, giving each type's defaults. Rub, Smack, Kiss and Turn Around come from common. A type gets a button on the taskbar only if one of the character's areas uses it. `interactAreas` is a list of the concrete areas on a character which can be interacted with; usually for belly rubs, kisses, etc. Each area names its `type` and takes all of that type's settings, changing whichever it gives itself.
|
`interactTypes` is an object of interaction types by name, giving each type's defaults. Rub, Smack, Kiss and Turn Around come from common. A type gets a button on the taskbar only if one of the character's areas uses it. `interactAreas` is a list of the concrete areas on a character which can be interacted with; usually for belly rubs, kisses, etc. Each area names its `type` and takes all of that type's settings, changing whichever it gives itself.
|
||||||
@@ -201,7 +201,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 `Puff` particle is also used for the dust when an item lands hard.
|
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.
|
||||||
|
|
||||||
# items.json
|
# items.json
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <stb_vorbis.c>
|
#include <stb_vorbis.c>
|
||||||
|
|
||||||
constexpr float PITCH_VARIATION = 0.06f;
|
constexpr float PITCH_VARIATION = 0.025f;
|
||||||
|
|
||||||
void Audio::init()
|
void Audio::init()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -246,7 +246,6 @@ void Body::update(std::vector<Event>& events)
|
|||||||
stats.isDigesting = true;
|
stats.isDigesting = true;
|
||||||
stats.digestionTimer = traits.digestionTime;
|
stats.digestionTimer = traits.digestionTime;
|
||||||
audio->play(character->sounds[SOUND_DIGEST]);
|
audio->play(character->sounds[SOUND_DIGEST]);
|
||||||
events.push_back(EVENT_DIGEST_START);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
values_clamp();
|
values_clamp();
|
||||||
|
|||||||
+4
-1
@@ -14,6 +14,7 @@ enum FloaterType
|
|||||||
enum SparkShape
|
enum SparkShape
|
||||||
{
|
{
|
||||||
SPARK_CIRCLE,
|
SPARK_CIRCLE,
|
||||||
|
SPARK_LINE,
|
||||||
SPARK_STAR
|
SPARK_STAR
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -26,10 +27,12 @@ struct Floater
|
|||||||
FloaterType type = FLOATER_CALORIES;
|
FloaterType type = FLOATER_CALORIES;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A glint or puff that drifts, falls (or rises) by its gravity, and fades over its life.
|
// A glint, puff or line (from its position to its end) that drifts, falls (or rises) by its gravity, and fades over its
|
||||||
|
// life.
|
||||||
struct Spark
|
struct Spark
|
||||||
{
|
{
|
||||||
Color color;
|
Color color;
|
||||||
|
Vec2 end;
|
||||||
Vec2 position;
|
Vec2 position;
|
||||||
Vec2 velocity;
|
Vec2 velocity;
|
||||||
float gravity = 0;
|
float gravity = 0;
|
||||||
|
|||||||
+10
-8
@@ -10,9 +10,9 @@ 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* DUST_PARTICLE = "Puff";
|
constexpr const char* IMPACT_PARTICLE = "Circle";
|
||||||
constexpr float BITE_JIGGLE = 4;
|
constexpr float BITE_JIGGLE = 4;
|
||||||
constexpr float DUST_IMPACT = 12;
|
constexpr float IMPACT_SPEED = 12;
|
||||||
constexpr float FANFARE_MIN = 0.75f;
|
constexpr float FANFARE_MIN = 0.75f;
|
||||||
constexpr float FANFARE_SHAKE = 0.015f;
|
constexpr float FANFARE_SHAKE = 0.015f;
|
||||||
constexpr float FANFARE_SPEED = 5;
|
constexpr float FANFARE_SPEED = 5;
|
||||||
@@ -23,9 +23,9 @@ constexpr float SQUASH_DECAY = 0.82f;
|
|||||||
constexpr float SQUASH_MAX = 0.35f;
|
constexpr float SQUASH_MAX = 0.35f;
|
||||||
constexpr float SQUASH_PER_SPEED = 0.025f;
|
constexpr float SQUASH_PER_SPEED = 0.025f;
|
||||||
constexpr float TRAIL_SPEED = 12;
|
constexpr float TRAIL_SPEED = 12;
|
||||||
constexpr Spark FANFARE_SPARK = {GOLD, {}, {}, 0.05f, 16, 50, 0, SPARK_STAR};
|
constexpr Spark FANFARE_SPARK = {GOLD, {}, {}, {}, 0.05f, 16, 50, 0, SPARK_STAR};
|
||||||
constexpr Spark RARE_SPARK = {GOLD, {}, {}, 0, 10, 40, 0, SPARK_STAR};
|
constexpr Spark RARE_SPARK = {GOLD, {}, {}, {}, 0, 10, 40, 0, SPARK_STAR};
|
||||||
constexpr Spark TRAIL_SPARK = {TRAIL_COLOR, {}, {}, 0, 7, 14, 0, SPARK_CIRCLE};
|
constexpr Spark TRAIL_SPARK = {TRAIL_COLOR, {}, {}, {}, 0, 6, 18, 0, SPARK_LINE};
|
||||||
constexpr int FANFARE_COUNT = 20;
|
constexpr int FANFARE_COUNT = 20;
|
||||||
constexpr int FANFARE_SHAKE_TIME = 12;
|
constexpr int FANFARE_SHAKE_TIME = 12;
|
||||||
constexpr int CRUMB_COUNT = 6;
|
constexpr int CRUMB_COUNT = 6;
|
||||||
@@ -389,16 +389,18 @@ void Items::update(Play& play, Pointer pointer)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Vec2 previous = position;
|
||||||
float impact = motion_update(play, entity);
|
float impact = motion_update(play, entity);
|
||||||
if (impact > 0)
|
if (impact > 0)
|
||||||
audio.play(character.sounds[SOUND_BOUNCE]);
|
audio.play(character.sounds[SOUND_BOUNCE]);
|
||||||
if (impact >= DUST_IMPACT)
|
if (impact >= IMPACT_SPEED)
|
||||||
play.particles_spawn({DUST_PARTICLE}, position);
|
play.particles_spawn({IMPACT_PARTICLE}, position);
|
||||||
entity.isThrown &= vec2_length(entity.velocity) >= TRAIL_SPEED;
|
entity.isThrown &= vec2_length(entity.velocity) >= TRAIL_SPEED;
|
||||||
if (entity.isThrown)
|
if (entity.isThrown)
|
||||||
{
|
{
|
||||||
Spark spark = TRAIL_SPARK;
|
Spark spark = TRAIL_SPARK;
|
||||||
spark.position = position;
|
spark.position = previous;
|
||||||
|
spark.end = position;
|
||||||
play.effects.spark_add(spark);
|
play.effects.spark_add(spark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-14
@@ -11,12 +11,8 @@ constexpr ImGuiKey CHEAT_KEYS[] = {ImGuiKey_UpArrow, ImGuiKey_DownArrow, ImGu
|
|||||||
ImGuiKey_RightArrow, ImGuiKey_B, ImGuiKey_A};
|
ImGuiKey_RightArrow, ImGuiKey_B, ImGuiKey_A};
|
||||||
constexpr const char* KEY_DISCOVERED = "discovered";
|
constexpr const char* KEY_DISCOVERED = "discovered";
|
||||||
constexpr const char* KEY_ITEM = "item";
|
constexpr const char* KEY_ITEM = "item";
|
||||||
constexpr Spark DIGEST_SPARK = {{1, 1, 1, 0.5f}, {}, {}, -0.06f, 10, 50, 0, SPARK_CIRCLE};
|
constexpr Spark STAGE_SPARK = {{1, 0.85f, 0.3f, 1}, {}, {}, {}, 0.06f, 18, 70, 0, SPARK_STAR};
|
||||||
constexpr Spark STAGE_SPARK = {{1, 0.85f, 0.3f, 1}, {}, {}, 0.06f, 18, 70, 0, SPARK_STAR};
|
|
||||||
constexpr float AUTOSAVE_TIME = 30;
|
constexpr float AUTOSAVE_TIME = 30;
|
||||||
constexpr float DIGEST_JIGGLE = 3;
|
|
||||||
constexpr float DIGEST_SHAKE = 0.006f;
|
|
||||||
constexpr float DIGEST_SPEED = 2;
|
|
||||||
constexpr float PUNCH_DECAY = 0.93f;
|
constexpr float PUNCH_DECAY = 0.93f;
|
||||||
constexpr float PUNCH_EPSILON = 0.001f;
|
constexpr float PUNCH_EPSILON = 0.001f;
|
||||||
constexpr float STAGE_FLASH = 0.7f;
|
constexpr float STAGE_FLASH = 0.7f;
|
||||||
@@ -24,8 +20,6 @@ constexpr float STAGE_JIGGLE = 15;
|
|||||||
constexpr float STAGE_PUNCH = 0.08f;
|
constexpr float STAGE_PUNCH = 0.08f;
|
||||||
constexpr float STAGE_SHAKE = 0.04f;
|
constexpr float STAGE_SHAKE = 0.04f;
|
||||||
constexpr float STAGE_SPEED = 8;
|
constexpr float STAGE_SPEED = 8;
|
||||||
constexpr int DIGEST_COUNT = 10;
|
|
||||||
constexpr int DIGEST_SHAKE_TIME = 40;
|
|
||||||
constexpr int STAGE_COUNT = 28;
|
constexpr int STAGE_COUNT = 28;
|
||||||
constexpr int STAGE_FREEZE = 5;
|
constexpr int STAGE_FREEZE = 5;
|
||||||
constexpr int STAGE_SHAKE_TIME = 30;
|
constexpr int STAGE_SHAKE_TIME = 30;
|
||||||
@@ -193,16 +187,10 @@ void Play::events_handle(Vec2 screenSize)
|
|||||||
Dialogue& dialogue = character->dialogue;
|
Dialogue& dialogue = character->dialogue;
|
||||||
for (Event event : events)
|
for (Event event : events)
|
||||||
{
|
{
|
||||||
Spark spark = event == EVENT_STAGE_START ? STAGE_SPARK : DIGEST_SPARK;
|
Spark spark = STAGE_SPARK;
|
||||||
spark.position = body.belly_get();
|
spark.position = body.belly_get();
|
||||||
if (event == EVENT_GAINED && body.gained > 0)
|
if (event == EVENT_GAINED && body.gained > 0)
|
||||||
effects.floater_add(spark.position, body.gained, FLOATER_WEIGHT);
|
effects.floater_add(spark.position, body.gained, FLOATER_WEIGHT);
|
||||||
if (event == EVENT_DIGEST_START)
|
|
||||||
{
|
|
||||||
effects.burst_add(spark, DIGEST_COUNT, DIGEST_SPEED);
|
|
||||||
camera.shake_add(DIGEST_SHAKE, DIGEST_SHAKE_TIME);
|
|
||||||
body.jiggle_add(DIGEST_JIGGLE);
|
|
||||||
}
|
|
||||||
if (event == EVENT_STAGE_START)
|
if (event == EVENT_STAGE_START)
|
||||||
{
|
{
|
||||||
effects.burst_add(spark, STAGE_COUNT, STAGE_SPEED);
|
effects.burst_add(spark, STAGE_COUNT, STAGE_SPEED);
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ enum Hold
|
|||||||
// What happened to the body in a tick, answered once it's done.
|
// What happened to the body in a tick, answered once it's done.
|
||||||
enum Event
|
enum Event
|
||||||
{
|
{
|
||||||
EVENT_DIGEST_START,
|
|
||||||
EVENT_DIGESTED,
|
EVENT_DIGESTED,
|
||||||
EVENT_GAINED,
|
EVENT_GAINED,
|
||||||
EVENT_STAGE_START,
|
EVENT_STAGE_START,
|
||||||
|
|||||||
+14
-12
@@ -25,11 +25,11 @@ constexpr float INDICATOR_SIZE = 0.35f;
|
|||||||
constexpr float INDICATOR_SPEED = 2;
|
constexpr float INDICATOR_SPEED = 2;
|
||||||
constexpr float ITEM_SIZE = 96;
|
constexpr float ITEM_SIZE = 96;
|
||||||
constexpr float ROUNDING = 10;
|
constexpr float ROUNDING = 10;
|
||||||
constexpr ImVec4 CALORIES_COLOR = {1, 0.85f, 0.3f, 1};
|
|
||||||
constexpr float BAR_EASE = 6;
|
constexpr float BAR_EASE = 6;
|
||||||
constexpr float BAR_SHAKE = 2;
|
constexpr float BAR_SHAKE = 2;
|
||||||
constexpr float BAR_SHAKE_SPEED = 40;
|
constexpr float BAR_SHAKE_SPEED = 40;
|
||||||
constexpr float FLOATER_OUTLINE = 2;
|
constexpr float FLOATER_SHADOW = 3;
|
||||||
|
constexpr float FLOATER_SHADOW_ALPHA = 0.6f;
|
||||||
constexpr float OVERSTUFFED_PULSE = 0.35f;
|
constexpr float OVERSTUFFED_PULSE = 0.35f;
|
||||||
constexpr float OVERSTUFFED_SPEED = 6;
|
constexpr float OVERSTUFFED_SPEED = 6;
|
||||||
constexpr float STAR_WAIST = 0.3f;
|
constexpr float STAR_WAIST = 0.3f;
|
||||||
@@ -724,7 +724,8 @@ void Ui::text_draw(Play& play, ImVec2 screen)
|
|||||||
ImGui::PopFont();
|
ImGui::PopFont();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The flourishes over the world: sparks, rising numbers (outlined so they read on anything), and the screen's flash.
|
// The flourishes over the world: sparks, rising numbers (in the character's color, shadowed so they read on anything),
|
||||||
|
// and the screen's flash.
|
||||||
void Ui::effects_draw(Play& play, ImVec2 screen)
|
void Ui::effects_draw(Play& play, ImVec2 screen)
|
||||||
{
|
{
|
||||||
Effects& effects = play.effects;
|
Effects& effects = play.effects;
|
||||||
@@ -741,6 +742,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_LINE)
|
||||||
|
{
|
||||||
|
Vec2 end = view * spark.end;
|
||||||
|
drawList->AddLine({at.x, at.y}, {end.x, end.y}, color, size);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
float waist = size * STAR_WAIST;
|
float waist = size * STAR_WAIST;
|
||||||
drawList->AddQuadFilled({at.x, at.y - size}, {at.x + waist, at.y}, {at.x, at.y + size}, {at.x - waist, at.y},
|
drawList->AddQuadFilled({at.x, at.y - size}, {at.x + waist, at.y}, {at.x, at.y + size}, {at.x - waist, at.y},
|
||||||
color);
|
color);
|
||||||
@@ -754,18 +761,13 @@ void Ui::effects_draw(Play& play, ImVec2 screen)
|
|||||||
std::string text = floater.type == FLOATER_CALORIES ? text_format("+%.0f kcal", floater.value)
|
std::string text = floater.type == FLOATER_CALORIES ? text_format("+%.0f kcal", floater.value)
|
||||||
: "+" + weight_format(floater.value, *measurement);
|
: "+" + weight_format(floater.value, *measurement);
|
||||||
float alpha = std::min(1.0f, (float)floater.life / (FLOATER_LIFE / 2));
|
float alpha = std::min(1.0f, (float)floater.life / (FLOATER_LIFE / 2));
|
||||||
ImVec4 color = floater.type == FLOATER_CALORIES ? CALORIES_COLOR : ImGui::GetStyleColorVec4(ImGuiCol_PlotHistogram);
|
Color tint = play.character->color;
|
||||||
color.w = alpha;
|
ImVec4 color = {tint.r, tint.g, tint.b, alpha};
|
||||||
ImVec2 size = font->CalcTextSizeA(FONT_HEADER_2, FLT_MAX, 0, text.c_str());
|
ImVec2 size = font->CalcTextSizeA(FONT_HEADER_2, FLT_MAX, 0, text.c_str());
|
||||||
Vec2 at = view * floater.position;
|
Vec2 at = view * floater.position;
|
||||||
ImVec2 position = {at.x - size.x / 2, at.y - size.y / 2};
|
ImVec2 position = {at.x - size.x / 2, at.y - size.y / 2};
|
||||||
ImU32 outline = ImGui::GetColorU32(ImVec4(0, 0, 0, alpha));
|
drawList->AddText(font, FONT_HEADER_2, {position.x + FLOATER_SHADOW, position.y + FLOATER_SHADOW},
|
||||||
for (int x = -1; x <= 1; x++)
|
ImGui::GetColorU32(ImVec4(0, 0, 0, alpha * FLOATER_SHADOW_ALPHA)), text.c_str());
|
||||||
for (int y = -1; y <= 1; y++)
|
|
||||||
if (x != 0 || y != 0)
|
|
||||||
drawList->AddText(font, FONT_HEADER_2,
|
|
||||||
{position.x + x * FLOATER_OUTLINE, position.y + y * FLOATER_OUTLINE}, outline,
|
|
||||||
text.c_str());
|
|
||||||
drawList->AddText(font, FONT_HEADER_2, position, ImGui::GetColorU32(color), text.c_str());
|
drawList->AddText(font, FONT_HEADER_2, position, ImGui::GetColorU32(color), text.c_str());
|
||||||
}
|
}
|
||||||
if (effects.flash > 0)
|
if (effects.flash > 0)
|
||||||
|
|||||||
Reference in new issue
Block a user