This commit is contained in:
shweet 2023-08-26 09:28:06 -04:00
parent 0f6f83adef
commit ddb156ac69
108 changed files with 1858 additions and 270 deletions

View File

@ -27,7 +27,10 @@ file(GLOB src
"${PROJECT_SOURCE_DIR}/src/game/render/*.c"
"${PROJECT_SOURCE_DIR}/src/game/resource/*.c"
"${PROJECT_SOURCE_DIR}/src/game/state/*.c"
"${PROJECT_SOURCE_DIR}/src/game/state/game_over/*.c"
"${PROJECT_SOURCE_DIR}/src/game/state/play/*.c"
"${PROJECT_SOURCE_DIR}/src/game/state/results/*.c"
"${PROJECT_SOURCE_DIR}/src/game/state/title/*.c"
)
add_executable(cc2 ${src})

View File

@ -0,0 +1,28 @@
# "Calamity Cobra in "A Sweeter Reprise"
My entry for the 2023 WeightGaming Gain Jam; a sequel to my last entry. A top down arcade shooter with some fetishy elements.
## Build
### Dependencies
- SDL2
- SDL_image
- SDL_mixer
- SDL_ttf
### Linux
This repository uses CMake to compile, so:
`mkdir build`
`cd build`
`cmake ..`
`make`
### Windows
I used MinGW for the Windows build, so basically the same as Linux but you'll need to use MSYS, MinGW, etc. to compile it.

View File

@ -31,8 +31,15 @@
#define STRING_WINDOW_TITLE "Calamity Cobra in 'A Sweeter Reprise'"
#define STRING_TUTORIAL_TEXT "The Dessert Elemental is restless, and won't be calmed unless she's gotten her fill of goodies! Slaughter foes that come your way with your trusty Snekgun. Fire using LMB/space, use right mouse button/R to redirect snakes for additional damage, lock snakes in place with Q and aim them with your mouse for a damage multiplier, and recall all airborne snakes with SHIFT. You can collect goodies with your snakes, too!\n" \
#define STRING_TUTORIAL_TEXT "The Dessert Elemental is restless, and won't be calmed unless she's gotten her fill of goodies! Slaughter foes that come your way with your trusty Snekgun. Fire using left mouse button/space, use right mouse button/R to redirect snakes for additional damage, lock snakes in place with Q and aim them with your mouse for a damage multiplier, and recall all airborne snakes with SHIFT. You can collect goodies with your snakes, too!\n" \
"\n" \
"The Sweet Heart she left beats fervently...if you give it a squeeze with the H key, you will gain a goodie multiplier. The next wave of enemies will come right after, though, and the enemies will be more aggressive...so use with caution!\n" \
"The Sweet Heart she left beats fervently...if you give it a squeeze with the H key, you will gain a goodie multiplier. The more times you push its limits, the better! The next wave of enemies will come right after, though, and the enemies will be more aggressive...so use with great caution!\n" \
"\n" \
"PROTIP: Dealing twice an enemy's max health will net double the goodies...\n"
"You don't have much time to satisfy the Dessert Elemental...make this quick! Approach her to exchange goodies for upgrades, to restore your health, or to feed her.\n" \
"\n" \
"Good luck!\n"
#define STRING_GAME_OVER_TITLE_TEXT "GAME OVER\n"
#define STRING_GAME_OVER_TEXT "The bounty on Calamity Cobra's head remains forever uncollected...\n"
#define STRING_RESULTS_TEXT "Congratulations on satisfying the Dessert Elemental! I would've given you a medal and told you your completion time, but I'm tired...\n"
#define STRING_TITLE_CREDITS_TEXT "WeightGaming Gain Jam 2023\nArt, Programming & Sounds: ShweetMagnet\nMusic: Nebby\nSoftware licensed under GPLv3; art licensed under CC0.\n"

View File

@ -20,14 +20,30 @@ typedef enum ECSComponentType
{
ECS_COMPONENT_ACTION_ON_DELETE_GIVE_AMMO,
ECS_COMPONENT_ACTION_ON_DELETE_DROP_GOODIES,
ECS_COMPONENT_ENEMY,
ECS_COMPONENT_ACTION_SPAWN,
ECS_COMPONENT_ACTION_ON_HEIGHT_DAMAGE_DISABLE,
ECS_COMPONENT_ANIMATION_IDLE,
ECS_COMPONENT_ANIMATION_COLOR_CHANGE,
ECS_COMPONENT_ANIMATION_LEVITATE,
ECS_COMPONENT_ANIMATION_MOVE,
ECS_COMPONENT_ANIMATION_ROTATE,
ECS_COMPONENT_ANIMATION_CURSOR,
ECS_COMPONENT_ANIMATION_STRETCH,
ECS_COMPONENT_ANIMATION_SQUASH,
ECS_COMPONENT_CONTROL_MOVE,
ECS_COMPONENT_CONTROL_SHOOT,
ECS_COMPONENT_CONTROL_AIM,
ECS_COMPONENT_CONTROL_FACE,
ECS_COMPONENT_CONTROL_REDIRECT,
ECS_COMPONENT_CONTROL_LOCK,
ECS_COMPONENT_CONTROL_RECALL,
ECS_COMPONENT_CONTROL_HEART,
ECS_COMPONENT_CONTROL_PLAYER,
ECS_COMPONENT_ACTION_SHOOT,
ECS_COMPONENT_ACTION_GRIP,
ECS_COMPONENT_ACTION_GRIPPED,
ECS_COMPONENT_PICKUP,
ECS_COMPONENT_PHYSICS,
ECS_COMPONENT_CIRCLE_COLLISION,
ECS_COMPONENT_ACTION_KEEP_IN_RECTANGLE,
@ -35,32 +51,21 @@ typedef enum ECSComponentType
ECS_COMPONENT_TEXT,
ECS_COMPONENT_GAME_OBJECT,
ECS_COMPONENT_CHARACTER,
ECS_COMPONENT_ENEMY,
ECS_COMPONENT_PICKUP,
ECS_COMPONENT_BEHAVIOR_ACT_IN_RECTANGLE,
ECS_COMPONENT_BEHAVIOR_FACE_TARGET,
ECS_COMPONENT_BEHAVIOR_HOP,
ECS_COMPONENT_BEHAVIOR_BOOMERANG,
ECS_COMPONENT_BEHAVIOR_CHASE,
ECS_COMPONENT_BEHAVIOR_APPROACH_AND_SHOOT,
ECS_COMPONENT_ACTION_ANGLE,
ECS_COMPONENT_ACTION_ON_COMBAT_HIDE,
ECS_COMPONENT_ACTION_SHOOT,
ECS_COMPONENT_ACTION_LOCK,
ECS_COMPONENT_ACTION_FOLLOW,
ECS_COMPONENT_ACTION_POINT_TO_MOUSE,
ECS_COMPONENT_ACTION_RETURN,
ECS_COMPONENT_ACTION_REDIRECT,
ECS_COMPONENT_ACTION_DAMAGE,
ECS_COMPONENT_ACTION_GRIP,
ECS_COMPONENT_ACTION_GRIPPED,
ECS_COMPONENT_ACTION_WAVE,
ECS_COMPONENT_CONTROL_MOVE,
ECS_COMPONENT_CONTROL_SHOOT,
ECS_COMPONENT_CONTROL_AIM,
ECS_COMPONENT_CONTROL_REDIRECT,
ECS_COMPONENT_CONTROL_LOCK,
ECS_COMPONENT_CONTROL_RECALL,
ECS_COMPONENT_CONTROL_HEART,
ECS_COMPONENT_CONTROL_PLAYER,
ECS_COMPONENT_SHOP,
ECS_COMPONENT_SHOP_ITEM,
ECS_COMPONENT_ACT_ENTITY,
@ -85,6 +90,7 @@ typedef enum ECSComponentType
ECS_COMPONENT_ACTION_ON_TOUCH_GIVE_GOODIES,
ECS_COMPONENT_ACTION_DELETE_ON_DEAD,
ECS_COMPONENT_ACTION_DELETE_ON_TIMER,
ECS_COMPONENT_ACTION_DELETE_ON_HEART,
ECS_COMPONENT_ACTION_DELETE_ON_TOUCH_ENTITY,
ECS_COMPONENT_ACTION_DELETE_ON_TOUCH_GAME_ENTITY_TYPE,
ECS_COMPONENT_ACTION_ON_OUT_OF_BOUNDS_DELETE

View File

@ -0,0 +1,84 @@
#include "component_action_angle.h"
/* DEPENDENCIES: Physics, AnimationIdle */
/* Ticks action angle component. */
void
component_action_angle_tick(ComponentActionAngle* self, ECS* ecs)
{
ComponentPhysics* physics;
ComponentSprite* sprite;
ComponentAnimationIdle* animationIdle;
physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->component.id);
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->component.id);
animationIdle = ecs_component_get(ecs, ECS_COMPONENT_ANIMATION_IDLE, self->component.id);
animationIdle->component.isDisabled = true;
if
(
physics->angle >= 0.0f && physics->angle < PI_FOURTH
)
{
animationIdle->baseIndex = 0;
sprite->atlas.index = 0;
}
else if
(
physics->angle >= PI_FOURTH && physics->angle < PI_HALF
)
{
animationIdle->baseIndex = 2;
sprite->atlas.index = 2;
}
else if
(
physics->angle >= PI_HALF && physics->angle < (PI_HALF + PI_FOURTH)
)
{
animationIdle->baseIndex = 4;
sprite->atlas.index = 4;
}
else if
(
physics->angle >= (PI_HALF + PI_FOURTH) && physics->angle < PI
)
{
animationIdle->baseIndex = 6;
sprite->atlas.index = 6;
}
else if
(
physics->angle >= -PI && physics->angle < -(PI_HALF + PI_FOURTH)
)
{
animationIdle->baseIndex = 8;
sprite->atlas.index = 8;
}
else if
(
physics->angle >= -(PI_HALF + PI_FOURTH) && physics->angle < -PI_HALF
)
{
animationIdle->baseIndex = 10;
sprite->atlas.index = 10;
}
else if
(
physics->angle >= -PI_HALF && physics->angle < -PI_FOURTH
)
{
animationIdle->baseIndex = 12;
sprite->atlas.index = 12;
}
else if
(
physics->angle >= -PI_FOURTH && physics->angle < 0.0f
)
{
animationIdle->baseIndex = 14;
sprite->atlas.index = 14;
}
}

View File

@ -0,0 +1,30 @@
#pragma once
#include "../component_physics.h"
#include "../component_sprite.h"
#include "../animation/component_animation_idle.h"
typedef struct ComponentActionAngle
{
ECSComponent component;
} ComponentActionAngle;
void component_action_angle_tick(ComponentActionAngle* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_ACTION_ANGLE_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_action_angle_tick,
NULL
}
},
.type = ECS_COMPONENT_ACTION_ANGLE,
.size = sizeof(ComponentActionAngle)
};

View File

@ -5,6 +5,27 @@
static void _dead_sound(ComponentActionDeleteOnDead* self, ECS* ecs);
/* Spawns a puff particle. */
static void
_puff_spawn(ComponentActionDeleteOnDead* self, ECS* ecs)
{
ComponentSprite* sprite;
vec3 position;
vec2 size;
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->component.id);
glm_vec3_copy(sprite->position, position);
size[0] = sprite->size[1];
size[1] = sprite->size[1];
position[1] -= (sprite->size[1] / 2);
position[2] += COMPONENT_ACTION_DELETE_ON_DEAD_PUFF_Z_OFFSET;
entity_puff_init(ecs, ecs_entity_add(ecs), position, size);
}
static void
_dead_sound(ComponentActionDeleteOnDead* self, ECS* ecs)
{
@ -47,6 +68,7 @@ component_action_delete_on_dead_tick(ComponentActionDeleteOnDead* self, ECS* ecs
if (health->isDead)
{
_puff_spawn(self, ecs);
_dead_sound(self, ecs);
ecs_entity_delete(ecs, self->component.id);

View File

@ -6,6 +6,10 @@
#include "../stat/component_health.h"
#include "../stat/component_game_entity_type.h"
#include "../../entity/play/entity_puff.h"
#define COMPONENT_ACTION_DELETE_ON_DEAD_PUFF_Z_OFFSET -0.01f
typedef struct ComponentActionDeleteOnDead
{
ECSComponent component;

View File

@ -0,0 +1,23 @@
#include "component_action_delete_on_heart.h"
/* DEPENDENCIES: Heart */
/* This entity associated with this component will be deleted if the heart component is used. */
/* Initializes action delete on heart component. */
void
component_action_delete_on_heart_init(ComponentActionDeleteOnHeart* self, u32 heartID)
{
self->heartID = heartID;
}
/* Ticks action delete on heart component. */
void
component_action_delete_on_heart_tick(ComponentActionDeleteOnHeart* self, ECS* ecs)
{
ComponentHeart* heart;
heart = ecs_component_get(ecs, ECS_COMPONENT_HEART, self->heartID);
if (heart->uses > 0)
ecs_entity_delete(ecs, self->component.id);
}

View File

@ -0,0 +1,33 @@
#pragma once
#include "../../../GAME_COMMON.h"
#include "../../ecs_entity.h"
#include "../stat/component_heart.h"
typedef struct ComponentActionDeleteOnHeart
{
ECSComponent component;
u32 heartID;
} ComponentActionDeleteOnHeart;
void component_action_delete_on_heart_init(ComponentActionDeleteOnHeart* self, u32 value);
void component_action_delete_on_heart_tick(ComponentActionDeleteOnHeart* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_ACTION_DELETE_ON_HEART_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_action_delete_on_heart_tick,
NULL
}
},
.type = ECS_COMPONENT_ACTION_DELETE_ON_HEART,
.size = sizeof(ComponentActionDeleteOnHeart)
};

View File

@ -37,13 +37,12 @@ _component_action_gripped_set(ComponentActionGripped* self, ECS* ecs)
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->component.id);
glm_vec3_copy(gripperPhysics->position, physics->position);
glm_vec3_copy(gripperPhysics->velocity, physics->velocity);
gameObject->height = gripperGameObject->height + (physics->size[1] * 2);
sprite->offset[2] = gripperPhysics->position[2] + COMPONENT_ACTION_GRIPPED_Z_OFFSET;
sprite->offset[2] = COMPONENT_ACTION_GRIPPED_Z_OFFSET;
gameObject->isBounce = gripperGameObject->isBounce;
gameObject->isAffectedByGravity = gripperGameObject->isAffectedByGravity;
}

View File

@ -6,7 +6,7 @@
#include "../component_game_object.h"
#define COMPONENT_ACTION_GRIPPED_TIMER 15
#define COMPONENT_ACTION_GRIPPED_Z_OFFSET -0.01f
#define COMPONENT_ACTION_GRIPPED_Z_OFFSET -0.001f
typedef struct ComponentActionGripped
{

View File

@ -119,22 +119,32 @@ component_action_lock_lock(ComponentActionLock* self, ECS* ecs)
ComponentActionReturn* actionReturn;
ComponentActionDamage* actionDamage;
ComponentActionDeleteOnTouchEntity* actionDeleteOnTouchEntity;
ComponentActionAngle* actionAngle;
ComponentAnimationIdle* animationIdle;
ComponentSprite* sprite;
physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->component.id);
actionReturn = ecs_component_get(ecs, ECS_COMPONENT_ACTION_RETURN, self->component.id);
actionDamage = ecs_component_get(ecs, ECS_COMPONENT_ACTION_DAMAGE, self->component.id);
actionDeleteOnTouchEntity = ecs_component_get(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TOUCH_ENTITY, self->component.id);
actionAngle = ecs_component_get(ecs, ECS_COMPONENT_ACTION_ANGLE, self->component.id);
animationIdle = ecs_component_get(ecs, ECS_COMPONENT_ANIMATION_IDLE, self->component.id);
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->component.id);
glm_vec3_copy(physics->velocity, self->velocity);
actionReturn->component.isDisabled = true;
actionDeleteOnTouchEntity->component.isDisabled = false;
actionDamage->component.isDisabled = true;
actionAngle->component.isDisabled = true;
self->cooldown = self->cooldownMax;
self->isLocked = true;
animationIdle->baseIndex = 16;
sprite->atlas.index = 16;
sound_play(&ecs->game->resources.sounds[SOUND_LOCK], SOUND_NO_PRIORITY);
}
@ -146,15 +156,20 @@ component_action_lock_unlock(ComponentActionLock* self, ECS* ecs)
ComponentActionReturn* actionReturn;
ComponentActionDamage* actionDamage;
ComponentActionDeleteOnTouchEntity* actionDeleteOnTouchEntity;
ComponentActionAngle* actionAngle;
ComponentAnimationIdle* animationIdle;
physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->component.id);
actionReturn = ecs_component_get(ecs, ECS_COMPONENT_ACTION_RETURN, self->component.id);
actionDamage = ecs_component_get(ecs, ECS_COMPONENT_ACTION_DAMAGE, self->component.id);
actionDeleteOnTouchEntity = ecs_component_get(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TOUCH_ENTITY, self->component.id);
actionAngle = ecs_component_get(ecs, ECS_COMPONENT_ACTION_ANGLE, self->component.id);
animationIdle = ecs_component_get(ecs, ECS_COMPONENT_ANIMATION_IDLE, self->component.id);
glm_vec3_copy(self->velocity, physics->velocity);
actionReturn->component.isDisabled = false;
actionDamage->component.isDisabled = false;
actionAngle->component.isDisabled = false;
actionDeleteOnTouchEntity->component.isDisabled = true;
@ -162,6 +177,8 @@ component_action_lock_unlock(ComponentActionLock* self, ECS* ecs)
self->isRedirectAngleGiven = false;
self->isLocked = false;
animationIdle->baseIndex = 0;
sound_play(&ecs->game->resources.sounds[SOUND_UNLOCK], SOUND_NO_PRIORITY);
if (self->isRedirectArrowInit)

View File

@ -9,6 +9,8 @@
#include "component_action_return.h"
#include "component_action_delete_on_touch_entity.h"
#include "../stat/component_redirects.h"
#include "../action/component_action_angle.h"
#include "../animation/component_animation_idle.h"
#include "../../entity/play/entity_redirect_arrow.h"

View File

@ -8,6 +8,28 @@
static void _hide(ComponentActionOnCombatHide* self, ECS* ecs);
static void _unhide(ComponentActionOnCombatHide* self, ECS* ecs);
static void _puff_spawn(ComponentActionOnCombatHide* self, ECS* ecs);
/* Spawns a puff particle. */
static void
_puff_spawn(ComponentActionOnCombatHide* self, ECS* ecs)
{
ComponentSprite* sprite;
vec3 position;
vec2 size;
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->component.id);
glm_vec3_copy(sprite->position, position);
size[0] = sprite->size[1];
size[1] = sprite->size[1];
position[1] -= (sprite->size[1] / 2);
position[2] += COMPONENT_ACTION_ON_COMBAT_HIDE_PUFF_Z_OFFSET;
entity_puff_init(ecs, ecs_entity_add(ecs), position, size);
}
/* "Hides" this component (disables drawing + collisions) */
static void
@ -29,6 +51,8 @@ _hide(ComponentActionOnCombatHide* self, ECS* ecs)
shadowSprite->component.isDisabled = true;
vector_clear(&physics->collisions);
_puff_spawn(self, ecs);
}
/* "Unhides" this component (enables drawing + collisions) */
@ -49,6 +73,8 @@ _unhide(ComponentActionOnCombatHide* self, ECS* ecs)
physics->component.isDisabled = false;
sprite->component.isDisabled = false;
shadowSprite->component.isDisabled = false;
_puff_spawn(self, ecs);
}
/* Initializes ActionOnCombatHide component. */

View File

@ -6,6 +6,10 @@
#include "component_action_spawn.h"
#include "../component_game_object.h"
#include "../../entity/play/entity_puff.h"
#define COMPONENT_ACTION_ON_COMBAT_HIDE_PUFF_Z_OFFSET -0.01f
typedef struct ComponentActionOnCombatHide
{
ECSComponent component;

View File

@ -5,6 +5,7 @@
#include "../../entity/play/entity_goodie.h"
#include "../stat/component_game_entity_type.h"
#include "../entity/component_enemy.h"
#define COMPONENT_ACTION_ON_DELETE_DROP_GOODIES_VELOCITY_MIN -10.0f
#define COMPONENT_ACTION_ON_DELETE_DROP_GOODIES_VELOCITY_MAX 10.0f

View File

@ -14,7 +14,6 @@ component_action_on_touch_give_goodies_init(ComponentActionOnTouchGiveGoodies* s
void
component_action_on_touch_give_goodies_tick(ComponentActionOnTouchGiveGoodies* self, ECS* ecs)
{
ComponentActEntity* actEntity;
ComponentPhysics* physics;
if (self->isGivenGoodies)
@ -25,20 +24,17 @@ component_action_on_touch_give_goodies_tick(ComponentActionOnTouchGiveGoodies* s
if (physics->collisions.count == 0)
return;
actEntity = ecs_component_get(ecs, ECS_COMPONENT_ACT_ENTITY, self->component.id);
for (s32 i = 0; i < (s32)physics->collisions.count; i++)
{
ComponentGoodies* goodies;
u32 id;
id = *(u32*)vector_get(&physics->collisions, i);
if (id == actEntity->id)
{
ComponentGoodies* goodies;
goodies = ecs_component_get(ecs, ECS_COMPONENT_GOODIES, actEntity->id);
goodies = ecs_component_get(ecs, ECS_COMPONENT_GOODIES, id);
if (goodies)
{
goodies->value += self->value *= goodies->multiplier;
sound_play(&ecs->game->resources.sounds[SOUND_GOODIE], SOUND_NO_PRIORITY);

View File

@ -100,14 +100,16 @@ component_action_return_tick(ComponentActionReturn* self, ECS* ecs)
angle = ATAN
(
physics->position[0],
senderPhysics->position[0],
physics->position[1],
senderPhysics->position[1]
physics->position[0],
senderPhysics->position[1],
physics->position[1]
);
speed = self->speed * (self->timer * self->multiplier);
physics->velocity[0] = cos(angle) * speed;
physics->velocity[1] = sin(angle) * speed;
physics->velocity[0] = -cos(angle) * speed;
physics->velocity[1] = -sin(angle) * speed;
physics->angle = angle;
}

View File

@ -136,7 +136,6 @@ _spawn_entity(ComponentActionSpawn* self, ECS* ecs)
u32 usedLevel;
id = ecs_entity_add(ecs);
vector_push(&self->entities, &id);
glm_vec2_zero(size);
glm_vec3_zero(position);
@ -189,7 +188,7 @@ _spawn_entity(ComponentActionSpawn* self, ECS* ecs)
switch (type)
{
case GAME_ENTITY_CUPPER:
entity_cupper_init(ecs, id, position, self->targetID, usedLevel, &self->entities);
entity_cupper_init(ecs, id, position, self->targetID, usedLevel);
break;
case GAME_ENTITY_CHIP:
entity_chip_init(ecs, id, position, -1);
@ -217,30 +216,27 @@ _spawn_entity(ComponentActionSpawn* self, ECS* ecs)
break;
case GAME_ENTITY_CHIPPER:
entity_chipper_init(ecs, id, position, self->targetID, usedLevel, &self->entities);
entity_chipper_init(ecs, id, position, self->targetID, usedLevel);
break;
case GAME_ENTITY_CUSTARPEDO:
entity_custarpedo_init(ecs, id, position, self->targetID, usedLevel, &self->entities);
entity_custarpedo_init(ecs, id, position, self->targetID, usedLevel);
break;
case GAME_ENTITY_CRUMBLER:
entity_crumbler_init(ecs, id, position, usedLevel, &self->entities);
entity_crumbler_init(ecs, id, position, usedLevel);
break;
case GAME_ENTITY_EXCORSANT:
entity_excorsant_init(ecs, id, position, self->targetID, usedLevel, &self->entities);
entity_excorsant_init(ecs, id, position, self->targetID, usedLevel);
break;
default:
break;
}
}
/* Ticks action_spawn component. */
void
component_action_spawn_add(ComponentActionSpawn* self, ECS* ecs)
{
vector_init(&self->types, sizeof(GameEntityType));
vector_init(&self->entities, sizeof(u32));
ecs_component_add(ecs, ECS_COMPONENT_LEVEL, self->component.id);
ecs_component_add(ecs, ECS_COMPONENT_WAVE, self->component.id);
_spawn_timer_set(self, ecs);
@ -251,7 +247,6 @@ void
component_action_spawn_delete(ComponentActionSpawn* self, ECS* ecs)
{
vector_free(&self->types);
vector_free(&self->entities);
ecs_component_delete(ecs, ECS_COMPONENT_LEVEL, self->component.id);
ecs_component_delete(ecs, ECS_COMPONENT_WAVE, self->component.id);
}
@ -309,6 +304,7 @@ component_action_spawn_wave_add(ComponentActionSpawn* self, ECS* ecs, const Spaw
music_play(&ecs->game->resources.music[MUSIC_COMBAT_ONE], true);
self->isCombat = true;
self->mercyTimer = COMPONENT_ACTION_SPAWN_MERCY_TIMER_MAX;
wave->value++;
}
@ -321,28 +317,24 @@ component_action_spawn_tick(ComponentActionSpawn* self, ECS* ecs)
{
self->combatTimer--;
self->timer--;
if (self->timer <= 0)
{
self->timer = 0;
if (self->combatTimer > 0)
{
_spawn_entity(self, ecs);
_spawn_timer_set(self, ecs);
}
}
if (self->combatTimer <= 0 )
self->combatTimer = 0;
}
if (self->combatTimer <= 0 && self->entities.count == 0)
if (self->combatTimer <= 0)
{
self->mercyTimer--;
if (self->mercyTimer <= 0)
{
ecs_component_list_clear(&ecs->lists[ECS_COMPONENT_ENEMY]);
self->mercyTimer = COMPONENT_ACTION_SPAWN_MERCY_TIMER_MAX;
}
}
if (self->combatTimer <= 0 && ecs->lists[ECS_COMPONENT_ENEMY].components.count == 0)
{
if (self->isCombat)
music_play(&ecs->game->resources.music[MUSIC_CALM], true);
vector_clear(&self->types);
self->levelBonus = 0;
self->isCombat = false;
@ -350,4 +342,15 @@ component_action_spawn_tick(ComponentActionSpawn* self, ECS* ecs)
}
if (self->timer <= 0)
{
if (self->combatTimer > 0)
{
_spawn_entity(self, ecs);
_spawn_timer_set(self, ecs);
}
}
if (self->combatTimer <= 0 )
self->combatTimer = 0;
}

View File

@ -16,6 +16,7 @@
#define COMPONENT_ACTION_SPAWN_TIMER_BASE 100
#define COMPONENT_ACTION_SPAWN_TIMER_LEVEL_MULTIPLIER 10
#define COMPONENT_ACTION_SPAWN_TIMER_MINIMUM 20
#define COMPONENT_ACTION_SPAWN_MERCY_TIMER_MAX 1800
#define COMPONENT_ACTION_SPAWN_CHIP_SPEED 10
#define COMPONENT_ACTION_SPAWN_CHIP_LEVEL_VELOCITY_MULTIPLIER 1.5
@ -61,7 +62,7 @@ typedef struct ComponentActionSpawn
s32 timer;
u32 targetID;
u32 levelBonus;
Vector entities; /* u32 */
u32 mercyTimer;
Vector types; /* GameEntityType */
bool isSpawn;
bool isCombat;

View File

@ -12,6 +12,7 @@ _timer_set(ComponentActionWave* self, ECS* ecs)
level = ecs_component_get(ecs, ECS_COMPONENT_LEVEL, self->component.id);
self->timer = COMPONENT_ACTION_WAVE_SPAWN_TIMER_BASE;
self->timer += SPAWN_WAVES[self->index].timer * COMPONENT_ACTION_WAVE_SPAWN_TIMER_MULITPLIER;
self->timer -= ((level->value - 1) * COMPONENT_ACITON_WAVE_SPAWN_TIMER_LEVEL_MULTIPLIER);
self->timer = MIN(self->timer, COMPONENT_ACTION_WAVE_SPAWN_TIMER_MIN);

View File

@ -6,9 +6,10 @@
#include "component_action_spawn.h"
#include "../stat/component_game_entity_type.h"
#define COMPONENT_ACTION_WAVE_SPAWN_TIMER_BASE 3600
#define COMPONENT_ACTION_WAVE_SPAWN_TIMER_BASE 1800
#define COMPONENT_ACITON_WAVE_SPAWN_TIMER_LEVEL_MULTIPLIER 300
#define COMPONENT_ACTION_WAVE_SPAWN_TIMER_MIN 1800
#define COMPONENT_ACTION_WAVE_SPAWN_TIMER_MULITPLIER 0.5
#define COMPONENT_ACTION_WAVE_COUNT 30
@ -47,13 +48,13 @@ static const SpawnWave SPAWN_WAVES[COMPONENT_ACTION_WAVE_COUNT] =
{
{ .types = (GameEntityType*)WAVE_ONE_ENEMIES, .typeCount = 1, .timer = 1800},
{ .types = (GameEntityType*)WAVE_TWO_ENEMIES, .typeCount = 1, .timer = 1800},
{ .types = (GameEntityType*)WAVE_THREE_ENEMIES, .typeCount = 1, .timer = 3600},
{ .types = (GameEntityType*)WAVE_THREE_ENEMIES, .typeCount = 1, .timer = 1800},
{ .types = (GameEntityType*)WAVE_FOUR_ENEMIES, .typeCount = 2, .timer = 1800},
{ .types = (GameEntityType*)WAVE_FIVE_ENEMIES, .typeCount = 2, .timer = 3600},
{ .types = (GameEntityType*)WAVE_SIX_ENEMIES, .typeCount = 2, .timer = 3600},
{ .types = (GameEntityType*)WAVE_SEVEN_ENEMIES, .typeCount = 3, .timer = 3600},
{ .types = (GameEntityType*)WAVE_FIVE_ENEMIES, .typeCount = 2, .timer = 1800},
{ .types = (GameEntityType*)WAVE_SIX_ENEMIES, .typeCount = 2, .timer = 1800},
{ .types = (GameEntityType*)WAVE_SEVEN_ENEMIES, .typeCount = 3, .timer = 1800},
{ .types = (GameEntityType*)WAVE_EIGHT_ENEMIES, .typeCount = 3, .timer = 1800},
{ .types = (GameEntityType*)WAVE_NINE_ENEMIES, .typeCount = 1, .timer = 1800},
{ .types = (GameEntityType*)WAVE_NINE_ENEMIES, .typeCount = 1, .timer = 3600},
{ .types = (GameEntityType*)WAVE_TEN_ENEMIES, .typeCount = 4, .timer = 3600},
{ .types = (GameEntityType*)WAVE_ELEVEN_ENEMIES, .typeCount = 1, .timer = 1800},
{ .types = (GameEntityType*)WAVE_TWELVE_ENEMIES, .typeCount = 2, .timer = 1800},

View File

@ -0,0 +1,33 @@
#include "component_animation_idle.h"
/* Initializes animation idle component. */
void
component_animation_idle_init(ComponentAnimationIdle* self, u32 baseIndex, u32 timer)
{
self->baseIndex = baseIndex;
self->timerMax = timer;
self->timer = self->timerMax;
}
/* Ticks animation idle component. */
void
component_animation_idle_tick(ComponentAnimationIdle* self, ECS* ecs)
{
ComponentSprite* sprite;
self->timer--;
if (self->timer <= 0)
{
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->component.id);
self->isAnimate = !self->isAnimate;
if (self->isAnimate)
sprite->atlas.index = self->baseIndex + 1;
else
sprite->atlas.index = self->baseIndex;
self->timer = self->timerMax;
}
}

View File

@ -0,0 +1,35 @@
#pragma once
#include "ANIMATION_COMMON.h"
#include "../../../GAME_COMMON.h"
#include "../../ecs_entity.h"
#include "../component_sprite.h"
typedef struct ComponentAnimationIdle
{
ECSComponent component;
u32 baseIndex;
s32 timer;
s32 timerMax;
bool isAnimate;
} ComponentAnimationIdle;
void component_animation_idle_init(ComponentAnimationIdle* self, u32 baseIndex, u32 timer);
void component_animation_idle_tick(ComponentAnimationIdle* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_ANIMATION_IDLE_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_animation_idle_tick,
NULL
}
},
.type = ECS_COMPONENT_ANIMATION_IDLE,
.size = sizeof(ComponentAnimationIdle)
};

View File

@ -0,0 +1,19 @@
#include "component_animation_rotate.h"
/* Initializes animation rotate component. */
void
component_animation_rotate_init(ComponentAnimationRotate* self, f32 speed)
{
self->speed = speed;
}
/* Ticks animation rotate component. */
void
component_animation_rotate_tick(ComponentAnimationRotate* self, ECS* ecs)
{
ComponentSprite* sprite;
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->component.id);
sprite->rotation += self->speed;
}

View File

@ -0,0 +1,36 @@
#pragma once
#include "ANIMATION_COMMON.h"
#include "../component_sprite.h"
typedef struct ComponentAnimationRotate
{
ECSComponent component;
f32 speed;
} ComponentAnimationRotate;
void component_animation_rotate_init
(
ComponentAnimationRotate* self,
f32 speed
);
void component_animation_rotate_init(ComponentAnimationRotate* self, f32 speed);
void component_animation_rotate_tick(ComponentAnimationRotate* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_ANIMATION_ROTATE_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_animation_rotate_tick,
NULL
}
},
.type = ECS_COMPONENT_ANIMATION_ROTATE,
.size = sizeof(ComponentAnimationRotate)
};

View File

@ -69,6 +69,7 @@ component_behavior_approach_and_shoot_init
self->distance = distance;
self->timerMax = timer;
self->timer = self->timerMax;
self->targetID = targetID;
}
/* Sets behavior_approach_and_shoot component info. */

View File

@ -12,9 +12,13 @@ _begin(ComponentBehaviorBoomerang* self, ECS* ecs)
ComponentPhysics* physics;
ComponentPhysics* targetPhysics;
ComponentAnimationLevitate* animationLevitate;
ComponentAnimationIdle* animationIdle;
ComponentBehaviorFaceTarget* behaviorFaceTarget;
physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->component.id);
animationLevitate = ecs_component_get(ecs, ECS_COMPONENT_ANIMATION_LEVITATE, self->component.id);
animationIdle = ecs_component_get(ecs, ECS_COMPONENT_ANIMATION_IDLE, self->component.id);
behaviorFaceTarget = ecs_component_get(ecs, ECS_COMPONENT_BEHAVIOR_FACE_TARGET, self->component.id);
targetPhysics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->targetID);
@ -34,6 +38,11 @@ _begin(ComponentBehaviorBoomerang* self, ECS* ecs)
physics->velocity[0] = -cos(self->angle) * self->initialSpeed;
physics->velocity[1] = -sin(self->angle) * self->initialSpeed;
animationIdle->baseIndex = 2;
animationIdle->timerMax = COMPONENT_BEHAVIOR_BOOMERANG_ANIMATION_IDLE_TIMER_MAX;
animationIdle->timer = COMPONENT_BEHAVIOR_BOOMERANG_ANIMATION_IDLE_TIMER_MAX;
behaviorFaceTarget->component.isDisabled = true;
if (animationLevitate)
{
ComponentGameObject* gameObject;

View File

@ -8,11 +8,14 @@
#include "../behavior/component_behavior_chase.h"
#include "../stat/component_level.h"
#include "../behavior/component_behavior_act_in_rectangle.h"
#include "../behavior/component_behavior_face_target.h"
#include "../animation/component_animation_idle.h"
#define COMPONENT_BEHAVIOR_BOOMERANG_SOUND_TIMER_MAX 10
#define COMPONENT_BEHAVIOR_BOOMERANG_LEVEL_TIMER_MULTIPLIER 5
#define COMPONENT_BEHAVIOR_BOOMERANG_TIMER_MAX 30
#define COMPONENT_BEHAVIOR_BOOMERANG_ANIMATION_IDLE_TIMER_MAX 5
typedef struct ComponentBehaviorBoomerang
{

View File

@ -23,17 +23,19 @@ _chase(ComponentBehaviorChase* self, ECS* ecs)
angle = ATAN
(
physics->position[0],
targetPhysics->position[0],
physics->position[1],
targetPhysics->position[1]
physics->position[0],
targetPhysics->position[1],
physics->position[1]
);
speed = self->speed * ((COMPONENT_BEHAVIOR_CHASE_LEVEL_SPEED_MULTIPLIER * (level->value - 1)) + 1);
speed = MAX(speed, COMPONENT_BEHAVIOR_CHASE_SPEED_MAX);
physics->velocity[0] = cos(angle) * speed;
physics->velocity[1] = sin(angle) * speed;
physics->velocity[0] = -cos(angle) * speed;
physics->velocity[1] = -sin(angle) * speed;
physics->angle = angle;
self->soundTimer--;

View File

@ -0,0 +1,26 @@
#include "component_behavior_face_target.h"
/* DEPENDENCIES: Sprite */
/* Sets behavior_face_target component info. */
void
component_behavior_face_target_init(ComponentBehaviorFaceTarget* self, u32 targetID)
{
self->targetID = targetID;
}
/* Ticks behavior_face_target component. */
void
component_behavior_face_target_tick(ComponentBehaviorFaceTarget* self, ECS* ecs)
{
ComponentSprite* sprite;
ComponentSprite* targetSprite;
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->component.id);
targetSprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->targetID);
if (sprite->position[0] > targetSprite->position[0])
sprite->isFlipHorizontal = true;
else
sprite->isFlipHorizontal = false;
}

View File

@ -0,0 +1,33 @@
#pragma once
#include "../../../GAME_COMMON.h"
#include "../../ecs_entity.h"
#include "../component_sprite.h"
typedef struct ComponentBehaviorFaceTarget
{
ECSComponent component;
u32 targetID;
} ComponentBehaviorFaceTarget;
void component_behavior_face_target_init(ComponentBehaviorFaceTarget* self, u32 targetID);
void component_behavior_face_target_tick(ComponentBehaviorFaceTarget* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_BEHAVIOR_FACE_TARGET_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_behavior_face_target_tick,
NULL
}
},
.type = ECS_COMPONENT_BEHAVIOR_FACE_TARGET,
.size = sizeof(ComponentBehaviorFaceTarget)
};

View File

@ -32,7 +32,8 @@ _component_game_object_sprite_tick(ComponentGameObject* self, ECS* ecs)
/* (0.9f, 1.0f) reserved for HUD elements, etc. */
spriteYPercent = (sprite->position[1] / ecs->game->renderer.camera.orthographic.size[1]);
sprite->position[2] = (1 - (COMPONENT_GAME_OBJECT_DEPTH_MAX * spriteYPercent)) + sprite->offset[2];
sprite->position[2] = COMPONENT_GAME_OBJECT_DEPTH_MAX - ((COMPONENT_GAME_OBJECT_DEPTH_RANGE) * spriteYPercent);
sprite->position[2] += sprite->offset[2];
}
/* Tick's a game object's height and related properties. */
@ -74,7 +75,7 @@ _component_game_object_shadow_tick(ComponentGameObject* self, ECS* ecs)
glm_vec2_copy(physics->size, shadowSprite->size);
glm_vec3_copy(physics->position, shadowSprite->position);
shadowSprite->position[2] = sprite->position[2] + COMPONENT_GAME_OBJECT_SHADOW_Z_OFFSET;
shadowSprite->position[2] = sprite->position[2] - COMPONENT_GAME_OBJECT_SHADOW_Z_OFFSET;
heightPercent = 1 - (self->height / COMPONENT_GAME_OBJECT_HEIGHT_MAX);

View File

@ -10,11 +10,12 @@
#include "../entity/play/entity_shadow.h"
#define COMPONENT_GAME_OBJECT_DEPTH_MAX 0.9f
#define COMPONENT_GAME_OBJECT_DEPTH_MIN 0.1f
#define COMPONENT_GAME_OBJECT_DEPTH_MIN 0.8f
#define COMPONENT_GAME_OBJECT_DEPTH_RANGE COMPONENT_GAME_OBJECT_DEPTH_MAX - COMPONENT_GAME_OBJECT_DEPTH_MIN
#define COMPONENT_GAME_OBJECT_GRAVITY -1.0f
#define COMPONENT_GAME_OBJECT_BOUNCE_FRICTION 0.8f
#define COMPONENT_GAME_OBJECT_HEIGHT_MAX 2500.0f
#define COMPONENT_GAME_OBJECT_SHADOW_Z_OFFSET 0.01f
#define COMPONENT_GAME_OBJECT_SHADOW_Z_OFFSET -0.01f
typedef struct ComponentGameObject
{

View File

@ -111,6 +111,7 @@ component_sprite_draw(ComponentSprite* self, ECS* ecs)
&self->atlas,
model,
size,
self->color
self->color,
self->isFlipHorizontal
);
}

View File

@ -21,6 +21,8 @@ typedef struct ComponentSprite
Atlas atlas;
vec2 size;
f32 rotation;
bool isFlipHorizontal;
bool isFlipVertical;
} ComponentSprite;
void component_sprite_rectangle_get(ComponentSprite* self, Rectangle* rectangle);

View File

@ -56,7 +56,8 @@ _component_text_glyph_draw(ComponentText* self, ECS* ecs, Texture texture, vec3
&atlas,
model,
size,
self->color
self->color,
false
);
}

View File

@ -0,0 +1,17 @@
#include "component_control_face.h"
/* DEPENDENCIES: Physics, Sprite */
/* Ticks control_face component. Flips sprite based on mouse position. */
void
component_control_face_tick(ComponentControlFace* self, ECS* ecs)
{
ComponentSprite* sprite;
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->component.id);
if (input_held(&ecs->game->input, INPUT_LEFT))
sprite->isFlipHorizontal = true;
else if (input_held(&ecs->game->input, INPUT_RIGHT))
sprite->isFlipHorizontal = false;
}

View File

@ -0,0 +1,32 @@
#pragma once
#include "../../../GAME_COMMON.h"
#include "../../ecs_entity.h"
#include "../../../input/input.h"
#include "../component_physics.h"
#include "../component_sprite.h"
typedef struct ComponentControlFace
{
ECSComponent component;
} ComponentControlFace;
void component_control_face_tick(ComponentControlFace* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_CONTROL_FACE_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_control_face_tick,
NULL
}
},
.type = ECS_COMPONENT_CONTROL_FACE,
.size = sizeof(ComponentControlFace)
};

View File

@ -47,6 +47,7 @@ void
component_control_move_init(ComponentControlMove* self, f32 speed)
{
self->speed = speed;
self->timer = COMPONENT_CONTROL_MOVE_TIMER_MAX;
}
/* Ticks control_move component. */
@ -59,7 +60,15 @@ component_control_move_tick(ComponentControlMove* self, ECS* ecs)
if (stun)
if (stun->isStun)
{
ComponentSprite* sprite;
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->component.id);
sprite->atlas.index = COMPONENT_CONTROL_STUN_SPRITE_INDEX;
return;
}
if
(
@ -81,5 +90,21 @@ component_control_move_tick(ComponentControlMove* self, ECS* ecs)
physics->velocity[0] += delta[0];
physics->velocity[1] += delta[1];
self->timer--;
if (self->timer <= 0)
{
ComponentSprite* sprite;
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->component.id);
self->timer = COMPONENT_CONTROL_MOVE_TIMER_MAX;
if (sprite->atlas.index != 0)
sprite->atlas.index = 0;
else
sprite->atlas.index = 1;
}
}
}

View File

@ -5,13 +5,18 @@
#include "../../../input/input.h"
#include "../component_physics.h"
#include "../component_sprite.h"
#include "../stat/component_stun.h"
#define COMPONENT_CONTROL_MOVE_TIMER_MAX 10
#define COMPONENT_CONTROL_STUN_SPRITE_INDEX 2
typedef struct ComponentControlMove
{
ECSComponent component;
f32 speed;
Direction direction;
s32 timer;
bool directionInput[DIRECTION_COUNT];
bool previousDirectionInput[DIRECTION_COUNT];
} ComponentControlMove;

View File

@ -41,6 +41,7 @@ component_control_player_add(ComponentControlPlayer* self, ECS* ecs)
ecs_component_add(ecs, ECS_COMPONENT_CONTROL_LOCK, self->component.id);
ecs_component_add(ecs, ECS_COMPONENT_CONTROL_RECALL, self->component.id);
ecs_component_add(ecs, ECS_COMPONENT_CONTROL_HEART, self->component.id);
ecs_component_add(ecs, ECS_COMPONENT_CONTROL_FACE, self->component.id);
}
/* Ticks control_player component. */
@ -54,4 +55,5 @@ component_control_player_delete(ComponentControlPlayer* self, ECS* ecs)
ecs_component_delete(ecs, ECS_COMPONENT_CONTROL_LOCK, self->component.id);
ecs_component_delete(ecs, ECS_COMPONENT_CONTROL_RECALL, self->component.id);
ecs_component_delete(ecs, ECS_COMPONENT_CONTROL_HEART, self->component.id);
ecs_component_delete(ecs, ECS_COMPONENT_CONTROL_FACE, self->component.id);
}

View File

@ -11,6 +11,7 @@
#include "component_control_recall.h"
#include "component_control_lock.h"
#include "component_control_heart.h"
#include "component_control_face.h"
typedef struct ComponentControlPlayer
{

View File

@ -21,8 +21,7 @@ component_enemy_init
bool isAffectedByGravity,
bool isSolid,
u32 goodieCount,
u32 levelValue,
Vector* entityList
u32 levelValue
)
{
ComponentCharacter* character;
@ -73,8 +72,6 @@ component_enemy_init
);
component_level_init(level, levelValue);
self->entityList = entityList;
}
/* Runs on character add. */
@ -93,20 +90,6 @@ component_enemy_add(ComponentEnemy* self, ECS* ecs)
void
component_enemy_delete(ComponentEnemy* self, ECS* ecs)
{
if (self->entityList)
{
for (s32 i = 0; i < (s32)self->entityList->count; i++)
{
u32 id;
id = *(u32*)vector_get(self->entityList, i);
if (id == self->component.id)
vector_remove(self->entityList, i);
}
}
ecs_component_delete(ecs, ECS_COMPONENT_ACTION_DELETE_ON_DEAD, self->component.id);
ecs_component_delete(ecs, ECS_COMPONENT_CHARACTER, self->component.id);
ecs_component_delete(ecs, ECS_COMPONENT_ACTION_ON_OUT_OF_BOUNDS_DELETE, self->component.id);

View File

@ -19,7 +19,6 @@
typedef struct ComponentEnemy
{
ECSComponent component;
Vector* entityList;
} ComponentEnemy;
void
@ -40,8 +39,7 @@ component_enemy_init
bool isAffectedByGravity,
bool isSolid,
u32 goodieCount,
u32 levelValue,
Vector* entityList
u32 levelValue
);
static const Rectangle ENEMY_ACTION_ON_OUT_OF_BOUNDS_DELETE_RECTANGLE =

View File

@ -1,8 +1,48 @@
#include "component_fatness.h"
/* Sets fatness level. */
static void
_fatness_set(ComponentFatness* self, ECS* ecs)
{
ComponentAnimationIdle* animationIdle;
animationIdle = ecs_component_get(ecs, ECS_COMPONENT_ANIMATION_IDLE, self->component.id);
animationIdle->baseIndex = animationIdle->baseIndex + 2;
animationIdle->timerMax = animationIdle->timerMax * 2;
sound_play(&ecs->game->resources.sounds[SOUND_GROW], SOUND_SPECIAL);
}
/* Initializes fatness component. */
void
component_fatness_init(ComponentFatness* self, u32* thresholds, u32 thresholdCount)
{
self->thresholds = thresholds;
self->thresholdCount = thresholdCount;
}
/* Ticks fatness component. */
void
component_fatness_tick(ComponentFatness* self, ECS* ecs)
{
ComponentGoodies* goodies;
goodies = ecs_component_get(ecs, ECS_COMPONENT_GOODIES, self->component.id);
for (s32 i = 0; i < (s32)self->thresholdCount; i++)
{
if
(
goodies->value >= self->thresholds[i] &&
(s32)self->previousValue < i
)
{
self->value = i;
_fatness_set(self, ecs);
}
}
self->previousValue = self->value;
}

View File

@ -3,12 +3,19 @@
#include "../../../GAME_COMMON.h"
#include "../../ecs_entity.h"
#include "../animation/component_animation_idle.h"
#include "component_goodies.h"
typedef struct ComponentFatness
{
ECSComponent component;
u32 value;
u32 previousValue;
u32* thresholds;
u32 thresholdCount;
} ComponentFatness;
void component_fatness_init(ComponentFatness* self, u32* thresholds, u32 thresholdCount);
void component_fatness_tick(ComponentFatness* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_FATNESS_INFO =

View File

@ -33,7 +33,7 @@ component_heart_tick(ComponentHeart* self, ECS* ecs)
goodies = ecs_component_get(ecs, ECS_COMPONENT_GOODIES, self->component.id);
if (self->concurrentUses > 1)
self->multiplier = self->uses + self->concurrentUses;
self->multiplier = self->uses + pow(self->concurrentUses, 2);
else
self->multiplier = self->uses + 1;

View File

@ -2,12 +2,12 @@
static void _shop_item_init(ComponentShop* self, ECS* ecs);
static void _shop_button_init(ComponentShop* self, ECS* ecs);
static void _disable(ComponentShop* self, ECS* ecs);
static void _enable(ComponentShop* self, ECS* ecs);
static void _shop_disable(ComponentShop* self, ECS* ecs);
static void _shop_enable(ComponentShop* self, ECS* ecs);
/* Disables shop. */
static void
_disable(ComponentShop* self, ECS* ecs)
_shop_disable(ComponentShop* self, ECS* ecs)
{
ComponentShopButton* buttonUpgradeLifetime;
ComponentShopButton* buttonUpgradeRedirects;
@ -30,7 +30,7 @@ _disable(ComponentShop* self, ECS* ecs)
/* Enables shop. */
static void
_enable(ComponentShop* self, ECS* ecs)
_shop_enable(ComponentShop* self, ECS* ecs)
{
ComponentShopButton* buttonUpgradeLifetime;
ComponentShopButton* buttonUpgradeRedirects;
@ -84,7 +84,7 @@ component_shop_init(ComponentShop* self, ECS* ecs, u32 affectedID, u32 affectedI
_shop_item_init(self, ecs);
_shop_button_init(self, ecs);
_disable(self, ecs);
_shop_disable(self, ecs);
}
/* Runs on addition of component shop entity. */
@ -156,9 +156,9 @@ component_shop_tick(ComponentShop* self, ECS* ecs)
if (self->isActive != self->isActivePrevious)
{
if (self->isActive)
_enable(self, ecs);
_shop_enable(self, ecs);
else
_disable(self, ecs);
_shop_disable(self, ecs);
}
self->isActivePrevious = self->isActive;

View File

@ -76,7 +76,7 @@ _shop_item_bought(ComponentShopItem* self, ECS* ecs)
self->purchaseCount++;
self->price = pow(self->basePrice, self->exponent * self->purchaseCount);
self->price = self->basePrice * pow((self->purchaseCount + 1), self->exponent);
sound_play(&ecs->game->resources.sounds[SOUND_UPGRADE], SOUND_SPECIAL);
}

View File

@ -87,6 +87,7 @@ ecs_draw(ECS* self)
drawFunction = drawEntry->drawFunction;
drawFunction(drawEntry->componentPointer, self);
}
vector_free(&drawEntries);
@ -108,6 +109,8 @@ ecs_clear(ECS* self)
{
for (s32 i = 0 ; i < ECS_COMPONENT_COUNT; i++)
ecs_component_list_clear(&self->lists[i]);
self->nextID = 0;
}
/* Frees ECS. */

View File

@ -1,8 +1,10 @@
#pragma once
#include "component/action/component_action_angle.h"
#include "component/action/component_action_damage.h"
#include "component/action/component_action_delete_on_dead.h"
#include "component/action/component_action_delete_on_timer.h"
#include "component/action/component_action_delete_on_heart.h"
#include "component/action/component_action_delete_on_touch_entity.h"
#include "component/action/component_action_delete_on_touch_game_entity_type.h"
#include "component/action/component_action_grip.h"
@ -21,13 +23,16 @@
#include "component/action/component_action_shoot.h"
#include "component/action/component_action_spawn.h"
#include "component/action/component_action_wave.h"
#include "component/animation/component_animation_idle.h"
#include "component/animation/component_animation_color_change.h"
#include "component/animation/component_animation_cursor.h"
#include "component/animation/component_animation_levitate.h"
#include "component/animation/component_animation_move.h"
#include "component/animation/component_animation_rotate.h"
#include "component/animation/component_animation_squash.h"
#include "component/animation/component_animation_stretch.h"
#include "component/behavior/component_behavior_act_in_rectangle.h"
#include "component/behavior/component_behavior_face_target.h"
#include "component/behavior/component_behavior_approach_and_shoot.h"
#include "component/behavior/component_behavior_boomerang.h"
#include "component/behavior/component_behavior_chase.h"
@ -38,6 +43,7 @@
#include "component/component_sprite.h"
#include "component/component_text.h"
#include "component/control/component_control_aim.h"
#include "component/control/component_control_face.h"
#include "component/control/component_control_lock.h"
#include "component/control/component_control_move.h"
#include "component/control/component_control_player.h"
@ -83,14 +89,30 @@ static const ECSComponentInfo ECS_COMPONENT_INFO[ECS_COMPONENT_COUNT] =
{
COMPONENT_ACTION_ON_DELETE_GIVE_AMMO_INFO,
COMPONENT_ACTION_ON_DELETE_DROP_GOODIES_INFO,
COMPONENT_ENEMY_INFO,
COMPONENT_ACTION_SPAWN_INFO,
COMPONENT_ACTION_ON_HEIGHT_DAMAGE_DISABLE_INFO,
COMPONENT_ANIMATION_IDLE_INFO,
COMPONENT_ANIMATION_COLOR_CHANGE_INFO,
COMPONENT_ANIMATION_LEVITATE_INFO,
COMPONENT_ANIMATION_MOVE_INFO,
COMPONENT_ANIMATION_ROTATE_INFO,
COMPONENT_ANIMATION_CURSOR_INFO,
COMPONENT_ANIMATION_STRETCH_INFO,
COMPONENT_ANIMATION_SQUASH_INFO,
COMPONENT_CONTROL_MOVE_INFO,
COMPONENT_CONTROL_SHOOT_INFO,
COMPONENT_CONTROL_AIM_INFO,
COMPONENT_CONTROL_FACE_INFO,
COMPONENT_CONTROL_REDIRECT_INFO,
COMPONENT_CONTROL_LOCK_INFO,
COMPONENT_CONTROL_RECALL_INFO,
COMPONENT_CONTROL_HEART_INFO,
COMPONENT_CONTROL_PLAYER_INFO,
COMPONENT_ACTION_SHOOT_INFO,
COMPONENT_ACTION_GRIP_INFO,
COMPONENT_ACTION_GRIPPED_INFO,
COMPONENT_PICKUP_INFO,
COMPONENT_PHYSICS_INFO,
COMPONENT_CIRCLE_COLLISION_INFO,
COMPONENT_ACTION_KEEP_IN_RECTANGLE_INFO,
@ -98,32 +120,21 @@ static const ECSComponentInfo ECS_COMPONENT_INFO[ECS_COMPONENT_COUNT] =
COMPONENT_TEXT_INFO,
COMPONENT_GAME_OBJECT_INFO,
COMPONENT_CHARACTER_INFO,
COMPONENT_ENEMY_INFO,
COMPONENT_PICKUP_INFO,
COMPONENT_BEHAVIOR_ACT_IN_RECTANGLE_INFO,
COMPONENT_BEHAVIOR_FACE_TARGET_INFO,
COMPONENT_BEHAVIOR_HOP_INFO,
COMPONENT_BEHAVIOR_BOOMERANG_INFO,
COMPONENT_BEHAVIOR_CHASE_INFO,
COMPONENT_BEHAVIOR_APPROACH_AND_SHOOT_INFO,
COMPONENT_ACTION_ANGLE_INFO,
COMPONENT_ACTION_ON_COMBAT_HIDE_INFO,
COMPONENT_ACTION_SHOOT_INFO,
COMPONENT_ACTION_LOCK_INFO,
COMPONENT_ACTION_FOLLOW_INFO,
COMPONENT_ACTION_POINT_TO_MOUSE_INFO,
COMPONENT_ACTION_RETURN_INFO,
COMPONENT_ACTION_REDIRECT_INFO,
COMPONENT_ACTION_DAMAGE_INFO,
COMPONENT_ACTION_GRIP_INFO,
COMPONENT_ACTION_GRIPPED_INFO,
COMPONENT_ACTION_WAVE_INFO,
COMPONENT_CONTROL_MOVE_INFO,
COMPONENT_CONTROL_SHOOT_INFO,
COMPONENT_CONTROL_AIM_INFO,
COMPONENT_CONTROL_REDIRECT_INFO,
COMPONENT_CONTROL_LOCK_INFO,
COMPONENT_CONTROL_RECALL_INFO,
COMPONENT_CONTROL_HEART_INFO,
COMPONENT_CONTROL_PLAYER_INFO,
COMPONENT_SHOP_INFO,
COMPONENT_SHOP_ITEM_INFO,
COMPONENT_ACT_ENTITY_INFO,
@ -148,6 +159,7 @@ static const ECSComponentInfo ECS_COMPONENT_INFO[ECS_COMPONENT_COUNT] =
COMPONENT_ACTION_ON_TOUCH_GIVE_GOODIES_INFO,
COMPONENT_ACTION_DELETE_ON_DEAD_INFO,
COMPONENT_ACTION_DELETE_ON_TIMER_INFO,
COMPONENT_ACTION_DELETE_ON_HEART_INFO,
COMPONENT_ACTION_DELETE_ON_TOUCH_ENTITY_INFO,
COMPONENT_ACTION_DELETE_ON_TOUCH_GAME_ENTITY_TYPE_INFO,
COMPONENT_ACTION_ON_OUT_OF_BOUNDS_DELETE_INFO

View File

@ -0,0 +1,26 @@
#include "entity_menu_button.h"
/* Initializes a menu_button entity. */
void
entity_menu_button_init(ECS* ecs, u32 id, vec3 position, MenuButtonType type)
{
ComponentButton* button;
ComponentSprite* sprite;
button = ecs_component_add(ecs, ECS_COMPONENT_BUTTON, id);
component_button_init
(
button,
ecs,
ecs->game->resources.textures[TEXTURE_MENU_BUTTONS],
(s32*)MENU_BUTTON_FRAME_SIZE,
(s32*)MENU_BUTTON_ATLAS_SIZE,
(f32*)MENU_BUTTON_SIZE,
position
);
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, id);
sprite->atlas.index = type;
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "../ecs_component.h"
#include "../component/hud/component_button.h"
typedef enum MenuButtonType
{
MENU_BUTTON_START = 0,
MENU_BUTTON_RETRY = 1,
MENU_BUTTON_OK = 2,
MENU_BUTTON_NEXT = 3
} MenuButtonType;
static const ivec2 MENU_BUTTON_FRAME_SIZE = {512, 512};
static const ivec2 MENU_BUTTON_ATLAS_SIZE = {1, 4};
static const vec2 MENU_BUTTON_SIZE = {256.0f, 256.0f};
void entity_menu_button_init(ECS* ecs, u32 id, vec3 position, MenuButtonType type);

View File

@ -0,0 +1,47 @@
#include "entity_state_fade.h"
/* Initializes a state_fade entity. */
void
entity_state_fade_init(ECS* ecs, u32 id, bool isFadeIn)
{
ComponentSprite* sprite;
ComponentAnimationColorChange* animationColorChange;
sprite = ecs_component_add(ecs, ECS_COMPONENT_SPRITE, id);
animationColorChange = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_COLOR_CHANGE, id);
component_sprite_init
(
sprite,
ecs->game->resources.textures[TEXTURE_STATE_FADE],
(f32*)STATE_FADE_SIZE,
(f32*)STATE_FADE_POSITION
);
if (isFadeIn)
{
component_animation_color_change_init
(
animationColorChange,
(f32*)COLOR_TRANSPARENT,
(f32*)COLOR_OPAQUE,
STATE_FADE_TIMER,
ANIMATION_COLOR_CHANGE_MODE_STICK
);
glm_vec4_copy((f32*)COLOR_OPAQUE, sprite->color);
}
else
{
component_animation_color_change_init
(
animationColorChange,
(f32*)COLOR_OPAQUE,
(f32*)COLOR_TRANSPARENT,
STATE_FADE_TIMER,
ANIMATION_COLOR_CHANGE_MODE_STICK
);
glm_vec4_copy((f32*)COLOR_TRANSPARENT, sprite->color);
}
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "../ecs_component.h"
#include "../component/component_sprite.h"
#include "../component/animation/component_animation_color_change.h"
#define STATE_FADE_TIMER 30
static const vec2 STATE_FADE_SIZE = {1920.0f, 1080.0f};
static const vec3 STATE_FADE_POSITION = {960.0f, 540.0f, 0.0f};
void entity_state_fade_init(ECS* ecs, u32 id, bool isFadeIn);

View File

@ -6,9 +6,12 @@ entity_chip_init(ECS* ecs, u32 id, vec3 position, u32 sender)
{
ComponentEnemy* enemy;
ComponentActionDeleteOnTouchGameEntityType* actionDeleteOnTouchGameEntityType;
ComponentAnimationRotate* animationRotate;
ComponentSprite* sprite;
enemy = ecs_component_add(ecs, ECS_COMPONENT_ENEMY, id);
actionDeleteOnTouchGameEntityType = ecs_component_add(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TOUCH_GAME_ENTITY_TYPE, id);
animationRotate = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_ROTATE, id);
component_enemy_init
(
@ -27,10 +30,11 @@ entity_chip_init(ECS* ecs, u32 id, vec3 position, u32 sender)
CHIP_IS_AFFECTED_BY_GRAVITY,
CHIP_IS_SOLID,
CHIP_GOODIE_COUNT,
1,
NULL
1
);
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, id);
component_action_delete_on_touch_game_entity_type_init
(
actionDeleteOnTouchGameEntityType,
@ -46,4 +50,7 @@ entity_chip_init(ECS* ecs, u32 id, vec3 position, u32 sender)
gameEntityType,
GAME_ENTITY_CHIP
);
sprite->rotation = RANDOM_F32(0, TAU);
component_animation_rotate_init(animationRotate, CHIP_ROTATION_SPEED);
}

View File

@ -2,6 +2,7 @@
#include "../../ecs_component.h"
#include "../../component/entity/component_enemy.h"
#include "../../component/animation/component_animation_rotate.h"
#include "../../component/action/component_action_delete_on_touch_game_entity_type.h"
#include "../../component/stat/component_game_entity_type.h"
@ -13,6 +14,7 @@
#define CHIP_IS_BOUNCE false
#define CHIP_IS_SOLID false
#define CHIP_GOODIE_COUNT 0
#define CHIP_ROTATION_SPEED 0.05
#define CHIP_ACTION_DELETE_ON_TOUCH_GAME_ENTITY_TYPE GAME_ENTITY_PLAYER

View File

@ -2,15 +2,17 @@
/* Initializes a Chipper entity. */
void
entity_chipper_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level, Vector* entityList)
entity_chipper_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level)
{
ComponentEnemy* enemy;
ComponentBehaviorApproachAndShoot* behaviorApproachAndShoot;
ComponentBehaviorActInRectangle* behaviorActInRectangle;
ComponentBehaviorFaceTarget* behaviorFaceTarget;
enemy = ecs_component_add(ecs, ECS_COMPONENT_ENEMY, id);
behaviorApproachAndShoot = ecs_component_add(ecs, ECS_COMPONENT_BEHAVIOR_APPROACH_AND_SHOOT, id);
behaviorActInRectangle = ecs_component_add(ecs, ECS_COMPONENT_BEHAVIOR_ACT_IN_RECTANGLE, id);
behaviorFaceTarget = ecs_component_add(ecs, ECS_COMPONENT_BEHAVIOR_FACE_TARGET, id);
component_enemy_init
(
@ -29,8 +31,7 @@ entity_chipper_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level, Ve
CHIPPER_GAME_OBJECT_IS_AFFECTED_BY_GRAVITY,
CHIPPER_GAME_OBJECT_IS_SOLID,
CHIPPER_GOODIE_COUNT,
level,
entityList
level
);
component_behavior_approach_and_shoot_init
@ -48,6 +49,7 @@ entity_chipper_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level, Ve
);
component_behavior_act_in_rectangle_init(behaviorActInRectangle, CHIPPER_ACT_RECTANGLE);
component_behavior_face_target_init(behaviorFaceTarget, targetID);
ComponentGameEntityType* gameEntityType;

View File

@ -4,11 +4,12 @@
#include "../../component/entity/component_enemy.h"
#include "../../component/behavior/component_behavior_approach_and_shoot.h"
#include "../../component/behavior/component_behavior_act_in_rectangle.h"
#include "../../component/behavior/component_behavior_face_target.h"
#include "../../component/stat/component_game_entity_type.h"
#include "entity_chip.h"
#define CHIPPER_BEHAVIOR_APPROACH_AND_SHOOT_DISTANCE 1000.0f
#define CHIPPER_BEHAVIOR_APPROACH_AND_SHOOT_DISTANCE 750.0f
#define CHIPPER_BEHAVIOR_APPROACH_AND_SHOOT_HEIGHT 10.0f
#define CHIPPER_BEHAVIOR_APPROACH_AND_SHOOT_OFFSET 30.0f
#define CHIPPER_BEHAVIOR_APPROACH_AND_SHOOT_PROJECTILE_SPEED 10.0f
@ -35,8 +36,8 @@ static const Rectangle CHIPPER_ACT_RECTANGLE =
};
static const ivec2 CHIPPER_FRAME_SIZE = {512, 512};
static const ivec2 CHIPPER_ATLAS_SIZE = {1, 1};
static const vec2 CHIPPER_SIZE = {100.0f, 100.0f};
static const ivec2 CHIPPER_ATLAS_SIZE = {1, 5};
static const vec2 CHIPPER_SIZE = {150.0f, 150.0f};
static const vec2 CHIPPER_PHYSICS_SIZE = {75.0f, 25.0f};
void entity_chipper_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level, Vector* entityList);
void entity_chipper_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level);

View File

@ -2,11 +2,12 @@
/* Initializes a Crumbler entity. */
void
entity_crumbler_init(ECS* ecs, u32 id, vec3 position, u32 level, Vector* entityList)
entity_crumbler_init(ECS* ecs, u32 id, vec3 position, u32 level)
{
ComponentEnemy* enemy;
ComponentLevel* componentLevel;
ComponentGameObject* gameObject;
ComponentSprite* sprite;
ComponentActionOnHeightDamageDisable* actionOnHeightDamageDisable;
enemy = ecs_component_add(ecs, ECS_COMPONENT_ENEMY, id);
@ -30,8 +31,7 @@ entity_crumbler_init(ECS* ecs, u32 id, vec3 position, u32 level, Vector* entityL
CRUMBLER_IS_AFFECTED_BY_GRAVITY,
CRUMBLER_IS_SOLID,
CRUMBLER_GOODIE_COUNT,
level,
entityList
level
);
componentLevel = ecs_component_get(ecs, ECS_COMPONENT_LEVEL, id);
@ -43,6 +43,10 @@ entity_crumbler_init(ECS* ecs, u32 id, vec3 position, u32 level, Vector* entityL
component_action_on_height_damage_disable_init(actionOnHeightDamageDisable, CRUMBLER_DAMAGE_HEIGHT);
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, id);
sprite->atlas.index = 2;
ComponentGameEntityType* gameEntityType;
gameEntityType = ecs_component_add(ecs, ECS_COMPONENT_GAME_ENTITY_TYPE, id);

View File

@ -19,8 +19,8 @@
#define CRUMBLER_DAMAGE_HEIGHT 100.0f
static const ivec2 CRUMBLER_FRAME_SIZE = {512, 512};
static const ivec2 CRUMBLER_ATLAS_SIZE = {1, 1};
static const vec2 CRUMBLER_SIZE = {200.0f, 125.0f};
static const ivec2 CRUMBLER_ATLAS_SIZE = {1, 3};
static const vec2 CRUMBLER_SIZE = {200.0f, 200.0f};
static const vec2 CRUMBLER_PHYSICS_SIZE = {150.0f, 50.0f};
void entity_crumbler_init(ECS* ecs, u32 id, vec3 position, u32 level, Vector* entityList);
void entity_crumbler_init(ECS* ecs, u32 id, vec3 position, u32 level);

View File

@ -2,13 +2,17 @@
/* Initializes a Cupper entity. */
void
entity_cupper_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level, Vector* entityList)
entity_cupper_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level)
{
ComponentEnemy* enemy;
ComponentBehaviorHop* behaviorHop;
ComponentBehaviorFaceTarget* behaviorFaceTarget;
ComponentAnimationIdle* animationIdle;
behaviorHop = ecs_component_add(ecs, ECS_COMPONENT_BEHAVIOR_HOP, id);
behaviorFaceTarget = ecs_component_add(ecs, ECS_COMPONENT_BEHAVIOR_FACE_TARGET, id);
enemy = ecs_component_add(ecs, ECS_COMPONENT_ENEMY, id);
animationIdle = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_IDLE, id);
component_enemy_init
(
@ -27,8 +31,7 @@ entity_cupper_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level, Vec
CUPPER_IS_AFFECTED_BY_GRAVITY,
CUPPER_IS_SOLID,
CUPPER_GOODIE_COUNT,
level,
entityList
level
);
component_behavior_hop_init
@ -40,6 +43,15 @@ entity_cupper_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level, Vec
targetID
);
component_animation_idle_init
(
animationIdle,
CUPPER_ANIMATION_IDLE_BASE_INDEX,
CUPPER_ANIMATION_IDLE_TIMER
);
component_behavior_face_target_init(behaviorFaceTarget, targetID);
ComponentGameEntityType* gameEntityType;
gameEntityType = ecs_component_add(ecs, ECS_COMPONENT_GAME_ENTITY_TYPE, id);

View File

@ -2,8 +2,10 @@
#include "../../component/entity/component_enemy.h"
#include "../../component/behavior/component_behavior_hop.h"
#include "../../component/behavior/component_behavior_face_target.h"
#include "../../ecs_component.h"
#include "../../component/stat/component_game_entity_type.h"
#include "../../component/animation/component_animation_idle.h"
#define CUPPER_IS_SOLID false
#define CUPPER_IS_BOUNCE false
@ -15,10 +17,12 @@
#define CUPPER_HEALTH_MAX 3
#define CUPPER_FRICTION 0.9
#define CUPPER_GOODIE_COUNT 1
#define CUPPER_ANIMATION_IDLE_TIMER 10
#define CUPPER_ANIMATION_IDLE_BASE_INDEX 0
static const ivec2 CUPPER_FRAME_SIZE = {512, 512};
static const ivec2 CUPPER_ATLAS_SIZE = {1, 1};
static const vec2 CUPPER_SIZE = {75.0f, 75.0f};
static const ivec2 CUPPER_ATLAS_SIZE = {1, 4};
static const vec2 CUPPER_SIZE = {100.0f, 100.0f};
static const vec2 CUPPER_PHYSICS_SIZE = {60.0f, 20.0f};
void entity_cupper_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level, Vector* entityList);
void entity_cupper_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level);

View File

@ -2,16 +2,21 @@
/* Initializes a Custarpedo entity. */
void
entity_custarpedo_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level, Vector* entityList)
entity_custarpedo_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level)
{
ComponentEnemy* enemy;
ComponentBehaviorChase* behaviorChase;
ComponentAnimationIdle* animationIdle;
ComponentGameObject* gameObject;
behaviorChase = ecs_component_add(ecs, ECS_COMPONENT_BEHAVIOR_CHASE, id);
enemy = ecs_component_add(ecs, ECS_COMPONENT_ENEMY, id);
animationIdle = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_IDLE, id);
gameObject = ecs_component_get(ecs, ECS_COMPONENT_GAME_OBJECT, id);
ecs_component_add(ecs, ECS_COMPONENT_ACTION_ANGLE, id);
component_enemy_init
(
enemy,
@ -29,8 +34,7 @@ entity_custarpedo_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level,
CUSTARPEDO_IS_AFFECTED_BY_GRAVITY,
CUSTARPEDO_IS_SOLID,
CUSTARPEDO_GOODIE_COUNT,
level,
entityList
level
);
component_behavior_chase_init
@ -40,6 +44,13 @@ entity_custarpedo_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level,
targetID
);
component_animation_idle_init
(
animationIdle,
CUSTARPEDO_ANIMATION_IDLE_BASE_INDEX,
CUSTARPEDO_ANIMATION_IDLE_TIMER
);
gameObject->height = CUSTARPEDO_HEIGHT;
ComponentGameEntityType* gameEntityType;

View File

@ -1,6 +1,8 @@
#pragma once
#include "../../component/animation/component_animation_idle.h"
#include "../../component/behavior/component_behavior_chase.h"
#include "../../component/action/component_action_angle.h"
#include "../../component/entity/component_enemy.h"
#include "../../ecs_component.h"
#include "../../component/stat/component_game_entity_type.h"
@ -14,10 +16,12 @@
#define CUSTARPEDO_HEALTH_MAX 2
#define CUSTARPEDO_GOODIE_COUNT 1
#define CUSTARPEDO_HEIGHT 30
#define CUSTARPEDO_ANIMATION_IDLE_BASE_INDEX 0
#define CUSTARPEDO_ANIMATION_IDLE_TIMER 30
static const ivec2 CUSTARPEDO_FRAME_SIZE = {512, 512};
static const ivec2 CUSTARPEDO_ATLAS_SIZE = {1, 1};
static const ivec2 CUSTARPEDO_ATLAS_SIZE = {8, 2};
static const vec2 CUSTARPEDO_SIZE = {100.0f, 100.0f};
static const vec2 CUSTARPEDO_PHYSICS_SIZE = {60.0f, 20.0f};
void entity_custarpedo_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level, Vector* entityList);
void entity_custarpedo_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level);

View File

@ -12,6 +12,7 @@ entity_damage_number_init(ECS* ecs, u32 id, vec3 position, u32 damage)
ComponentText* text;
char string[ENTITY_DAMAGE_NUMBER_TEXT_MAX];
f32 base;
vec3 numberPosition;
base = ENTITY_DAMAGE_NUMBER_SCALE + ((damage - 1) * ENTITY_DAMAGE_NUMBER_SCALE_MULTIPLIER);
@ -24,6 +25,10 @@ entity_damage_number_init(ECS* ecs, u32 id, vec3 position, u32 damage)
animationSquash = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_SQUASH, id);
animationStretch = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_STRETCH, id);
glm_vec3_copy(position, numberPosition);
numberPosition[2] += ENTITY_DAMAGE_NUMBER_Z_OFFSET;
snprintf
(
string,
@ -39,7 +44,7 @@ entity_damage_number_init(ECS* ecs, u32 id, vec3 position, u32 damage)
string,
strlen(string),
-1,
position,
numberPosition,
(f32*)ENTITY_DAMAGE_NUMBER_COLOR
);

View File

@ -18,6 +18,7 @@
#define ENTITY_DAMAGE_NUMBER_SQUASH_SPEED 0.05f
#define ENTITY_DAMAGE_NUMBER_STRETCH_MULTIPLIER 0.5f
#define ENTITY_DAMAGE_NUMBER_STRETCH_SPEED 0.05f
#define ENTITY_DAMAGE_NUMBER_Z_OFFSET -0.01f
static const vec4 ENTITY_DAMAGE_NUMBER_COLOR = {1.0f, 0.0f, 0.0f, 1.0f};
static const vec3 ENTITY_DAMAGE_NUMBER_MOVE_VELOCITY = {0.0f, -1.0f, 0.0f};

View File

@ -11,16 +11,18 @@ entity_elemental_init(ECS* ecs, u32 id, vec3 position, u32 spawnID, u32 playerID
ComponentGoodies* goodies;
ComponentShop* shop;
ComponentAnimationStretch* animationStretch;
ComponentAnimationIdle* animationIdle;
ComponentFatness* fatness;
gameObject = ecs_component_add(ecs, ECS_COMPONENT_GAME_OBJECT, id);
actionOnCombatHide = ecs_component_add(ecs, ECS_COMPONENT_ACTION_ON_COMBAT_HIDE, id);
animationSquash = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_SQUASH, id);
animationStretch = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_STRETCH, id);
animationIdle = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_IDLE, id);
circleCollision = ecs_component_add(ecs, ECS_COMPONENT_CIRCLE_COLLISION, id);
goodies = ecs_component_add(ecs, ECS_COMPONENT_GOODIES, id);
shop = ecs_component_add(ecs, ECS_COMPONENT_SHOP, id);
ecs_component_add(ecs, ECS_COMPONENT_FATNESS, id);
fatness = ecs_component_add(ecs, ECS_COMPONENT_FATNESS, id);
component_game_object_atlas_init
(
@ -66,6 +68,13 @@ entity_elemental_init(ECS* ecs, u32 id, vec3 position, u32 spawnID, u32 playerID
ELEMENTAL_ANIMATION_STRETCH_SPEED
);
component_animation_idle_init
(
animationIdle,
ELEMENTAL_ANIMATION_IDLE_BASE_INDEX,
ELEMENTAL_ANIMATION_IDLE_TIMER
);
component_circle_collision_init
(
circleCollision,
@ -73,6 +82,13 @@ entity_elemental_init(ECS* ecs, u32 id, vec3 position, u32 spawnID, u32 playerID
ELEMENTAL_CIRCLE_RADIUS
);
component_fatness_init
(
fatness,
(u32*)ELEMENTAL_FATNESS_THRESHOLDS,
ELEMENTAL_FATNESS_THRESHOLD_COUNT
);
goodies->max = ELEMENTAL_GOODIES_MAX;
entity_elemental_goodie_display_init(ecs, ecs_entity_add(ecs), id);

View File

@ -3,6 +3,7 @@
#include "../../component/action/component_action_on_combat_hide.h"
#include "../../component/animation/component_animation_squash.h"
#include "../../component/animation/component_animation_stretch.h"
#include "../../component/animation/component_animation_idle.h"
#include "../../component/component_game_object.h"
#include "../../component/stat/component_fatness.h"
#include "../../component/stat/component_game_entity_type.h"
@ -20,17 +21,26 @@
#define ELEMENTAL_GAME_OBJECT_IS_SOLID true
#define ELEMENTAL_ACTION_ON_COMBAT_HIDE_TIMER 60
#define ELEMENTAL_ANIMATION_SQUASH_BASE 1.0f
#define ELEMENTAL_ANIMATION_SQUASH_MULTIPLIER 0.05f
#define ELEMENTAL_ANIMATION_SQUASH_SPEED 0.05f
#define ELEMENTAL_ANIMATION_SQUASH_MULTIPLIER 0.025f
#define ELEMENTAL_ANIMATION_SQUASH_SPEED 0.01f
#define ELEMENTAL_ANIMATION_STRETCH_BASE 1.0f
#define ELEMENTAL_ANIMATION_STRETCH_MULTIPLIER 0.05f
#define ELEMENTAL_ANIMATION_STRETCH_SPEED 0.05f
#define ELEMENTAL_ANIMATION_STRETCH_MULTIPLIER 0.025f
#define ELEMENTAL_ANIMATION_STRETCH_SPEED 0.01f
#define ELEMENTAL_GOODIES_MAX 1000000
#define ELEMENTAL_CIRCLE_RADIUS 300.0f
#define ELEMENTAL_CIRCLE_RADIUS 150.0f
#define ELEMENTAL_ANIMATION_IDLE_BASE_INDEX 0
#define ELEMENTAL_ANIMATION_IDLE_TIMER 30
#define ELEMENTAL_FATNESS_THRESHOLD_COUNT 2
static const ivec2 ELEMENTAL_FRAME_SIZE = {512, 512};
static const ivec2 ELEMENTAL_ATLAS_SIZE = {1, 1};
static const vec2 ELEMENTAL_SIZE = {75.0f, 150.0f};
static const vec2 ELEMENTAL_PHYSICS_SIZE = {60.0f, 20.0f};
static const ivec2 ELEMENTAL_FRAME_SIZE = {1024, 1024};
static const ivec2 ELEMENTAL_ATLAS_SIZE = {1, 6};
static const vec2 ELEMENTAL_SIZE = {300.0f, 300.0f};
static const vec2 ELEMENTAL_PHYSICS_SIZE = {120.0f, 40.0f};
static const u32 ELEMENTAL_FATNESS_THRESHOLDS[ELEMENTAL_FATNESS_THRESHOLD_COUNT] =
{
10000,
100000,
};
void entity_elemental_init(ECS* ecs, u32 id, vec3 position, u32 spawnID, u32 playerID);

View File

@ -2,18 +2,22 @@
/* Initializes an Excorsant entity. */
void
entity_excorsant_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level, Vector* entityList)
entity_excorsant_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level)
{
ComponentEnemy* enemy;
ComponentBehaviorBoomerang* behaviorBoomerang;
ComponentBehaviorActInRectangle* behaviorActInRectangle;
ComponentAnimationLevitate* animationLevitate;
ComponentAnimationIdle* animationIdle;
ComponentBehaviorFaceTarget* behaviorFaceTarget;
behaviorBoomerang = ecs_component_add(ecs, ECS_COMPONENT_BEHAVIOR_BOOMERANG, id);
behaviorActInRectangle = ecs_component_add(ecs, ECS_COMPONENT_BEHAVIOR_ACT_IN_RECTANGLE, id);
enemy = ecs_component_add(ecs, ECS_COMPONENT_ENEMY, id);
animationLevitate = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_LEVITATE, id);
animationIdle = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_IDLE, id);
behaviorFaceTarget = ecs_component_add(ecs, ECS_COMPONENT_BEHAVIOR_FACE_TARGET, id);
component_enemy_init
(
@ -32,8 +36,7 @@ entity_excorsant_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level,
EXCORSANT_IS_AFFECTED_BY_GRAVITY,
EXCORSANT_IS_SOLID,
EXCORSANT_GOODIE_COUNT,
level,
entityList
level
);
component_behavior_boomerang_init
@ -55,6 +58,14 @@ entity_excorsant_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level,
EXCORSANT_ANIMATION_LEVITATE_SPEED
);
component_animation_idle_init
(
animationIdle,
EXCORSANT_ANIMATION_IDLE_BASE_INDEX,
EXCORSANT_ANIMATION_IDLE_TIMER
);
component_behavior_face_target_init(behaviorFaceTarget, targetID);
component_behavior_act_in_rectangle_init(behaviorActInRectangle, EXCORSANT_ACT_RECTANGLE);
ComponentGameEntityType* gameEntityType;

View File

@ -2,11 +2,15 @@
#include "../../component/animation/component_animation_levitate.h"
#include "../../component/behavior/component_behavior_boomerang.h"
#include "../../component/animation/component_animation_idle.h"
#include "../../component/behavior/component_behavior_act_in_rectangle.h"
#include "../../component/behavior/component_behavior_face_target.h"
#include "../../component/entity/component_enemy.h"
#include "../../ecs_component.h"
#include "../../component/stat/component_game_entity_type.h"
#define EXCORSANT_ANIMATION_IDLE_BASE_INDEX 0
#define EXCORSANT_ANIMATION_IDLE_TIMER 15
#define EXCORSANT_IS_SOLID false
#define EXCORSANT_IS_BOUNCE false
#define EXCORSANT_IS_AFFECTED_BY_GRAVITY false
@ -31,8 +35,8 @@ static const Rectangle EXCORSANT_ACT_RECTANGLE =
};
static const ivec2 EXCORSANT_FRAME_SIZE = {512, 512};
static const ivec2 EXCORSANT_ATLAS_SIZE = {1, 1};
static const vec2 EXCORSANT_SIZE = {100.0f, 100.0f};
static const ivec2 EXCORSANT_ATLAS_SIZE = {1, 4};
static const vec2 EXCORSANT_SIZE = {150.0f, 150.0f};
static const vec2 EXCORSANT_PHYSICS_SIZE = {60.0f, 20.0f};
void entity_excorsant_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level, Vector* entityList);
void entity_excorsant_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level);

View File

@ -15,6 +15,8 @@ entity_player_init(ECS* ecs, u32 id, vec3 position, u32 spawnID)
ComponentRedirects* redirects;
ComponentCircleCollision* circleCollision;
ComponentStun* stun;
ComponentAnimationSquash* animationSquash;
ComponentAnimationStretch* animationStretch;
actionShoot = ecs_component_add(ecs, ECS_COMPONENT_ACTION_SHOOT, id);
actionKeepInRectangle = ecs_component_add(ecs, ECS_COMPONENT_ACTION_KEEP_IN_RECTANGLE, id);
@ -26,6 +28,8 @@ entity_player_init(ECS* ecs, u32 id, vec3 position, u32 spawnID)
redirects = ecs_component_add(ecs, ECS_COMPONENT_REDIRECTS, id);
stun = ecs_component_add(ecs, ECS_COMPONENT_STUN, id);
circleCollision = ecs_component_add(ecs, ECS_COMPONENT_CIRCLE_COLLISION, id);
animationSquash = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_SQUASH, id);
animationStretch = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_STRETCH, id);
ecs_component_add(ecs, ECS_COMPONENT_GOODIES, id);
ecs_component_add(ecs, ECS_COMPONENT_UPGRADES, id);
@ -69,6 +73,22 @@ entity_player_init(ECS* ecs, u32 id, vec3 position, u32 spawnID)
spawnID
);
component_animation_squash_init
(
animationSquash,
PLAYER_ANIMATION_SQUASH_BASE,
PLAYER_ANIMATION_SQUASH_MULTIPLIER,
PLAYER_ANIMATION_SQUASH_SPEED
);
component_animation_stretch_init
(
animationStretch,
PLAYER_ANIMATION_STRETCH_BASE,
PLAYER_ANIMATION_STRETCH_MULTIPLIER,
PLAYER_ANIMATION_STRETCH_SPEED
);
component_ammo_init(ammo, PLAYER_AMMO_START);
component_invincibility_init(invincibility, PLAYER_INVINCIBILITY_TIMER);
component_stun_init(stun, PLAYER_STUN_TIMER);

View File

@ -27,8 +27,8 @@
#define PLAYER_FRICTION 0.875
#define PLAYER_VELOCITY_MAX 10
#define PLAYER_ACTION_SHOOT_SPEED 15
#define PLAYER_ACTION_SHOOT_HEIGHT 25.0f
#define PLAYER_ACTION_SHOOT_OFFSET 100.0f
#define PLAYER_ACTION_SHOOT_HEIGHT 60.0f
#define PLAYER_ACTION_SHOOT_OFFSET 225.0f
#define PLAYER_CONTROL_SHOOT_COOLDOWN 12
#define PLAYER_CONTROL_REDIRECT_ANGLE_THRESHOLD 20 // Degrees
#define PLAYER_AMMO_START 1
@ -39,6 +39,12 @@
#define PLAYER_INVINCIBILITY_TIMER 120
#define PLAYER_STUN_TIMER 30
#define PLAYER_CIRCLE_RADIUS 75.0f
#define PLAYER_ANIMATION_SQUASH_BASE 1.0f
#define PLAYER_ANIMATION_SQUASH_MULTIPLIER 0.01f
#define PLAYER_ANIMATION_SQUASH_SPEED 0.01f
#define PLAYER_ANIMATION_STRETCH_BASE 1.0f
#define PLAYER_ANIMATION_STRETCH_MULTIPLIER 0.01f
#define PLAYER_ANIMATION_STRETCH_SPEED 0.01f
static const Rectangle PLAYER_ACTION_KEEP_IN_RECTANGLE =
{
@ -48,9 +54,9 @@ static const Rectangle PLAYER_ACTION_KEEP_IN_RECTANGLE =
.h = 930
};
static const ivec2 PLAYER_FRAME_SIZE = {512, 512};
static const ivec2 PLAYER_ATLAS_SIZE = {1, 1};
static const vec2 PLAYER_SIZE = {75.0f, 150.0f};
static const ivec2 PLAYER_FRAME_SIZE = {1024, 1024};
static const ivec2 PLAYER_ATLAS_SIZE = {1, 3};
static const vec2 PLAYER_SIZE = {300.0f, 300.0f};
static const vec2 PLAYER_PHYSICS_SIZE = {60.0f, 20.0f};
void entity_player_init(ECS* ecs, u32 id, vec3 position, u32 spawnID);

View File

@ -3,6 +3,6 @@
#include "../../component/hud/component_stat_display.h"
#include "../../ecs_component.h"
static const vec3 PLAYER_AMMO_DISPLAY_OFFSET = {0.0f, -200.0f, 0.095f};
static const vec3 PLAYER_AMMO_DISPLAY_OFFSET = {0.0f, -225.0f, 0.095f};
void entity_player_ammo_display_init(ECS* ecs, u32 id, u32 playerID);

View File

@ -5,6 +5,6 @@
#include "entity_icon.h"
static const vec3 PLAYER_HEALTH_DISPLAY_OFFSET = {0.0f, -225.0f, 0.1f};
static const vec3 PLAYER_HEALTH_DISPLAY_OFFSET = {0.0f, -250.0f, 0.09f};
void entity_player_health_display_init(ECS* ecs, u32 id, u32 playerID);

View File

@ -3,6 +3,6 @@
#include "../../component/hud/component_stat_display.h"
#include "../../ecs_component.h"
static const vec3 PLAYER_REDIRECT_DISPLAY_OFFSET = {0.0f, -175.0f, 0.090f};
static const vec3 PLAYER_REDIRECT_DISPLAY_OFFSET = {0.0f, -200.0f, 0.090f};
void entity_player_redirect_display_init(ECS* ecs, u32 id, u32 playerID);

View File

@ -0,0 +1,37 @@
#include "entity_puff.h"
/* Initializes a puff entity. */
void
entity_puff_init(ECS* ecs, u32 id, vec3 position, vec2 size)
{
ComponentActionDeleteOnTimer* actionDeleteOnTimer;
ComponentAnimationColorChange* animationColorChange;
ComponentSprite* sprite;
sprite = ecs_component_add(ecs, ECS_COMPONENT_SPRITE, id);
actionDeleteOnTimer = ecs_component_add(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TIMER, id);
animationColorChange = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_COLOR_CHANGE, id);
component_sprite_init
(
sprite,
ecs->game->resources.textures[TEXTURE_PUFF],
size,
position
);
component_action_delete_on_timer_init
(
actionDeleteOnTimer,
ENTITY_PUFF_TIMER
);
component_animation_color_change_init
(
animationColorChange,
(f32*)COLOR_TRANSPARENT,
(f32*)COLOR_OPAQUE,
ENTITY_PUFF_TIMER,
ANIMATION_COLOR_CHANGE_MODE_STICK
);
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "../../component/action/component_action_delete_on_timer.h"
#include "../../component/animation/component_animation_color_change.h"
#include "../../ecs_component.h"
#define ENTITY_PUFF_TIMER 15
static const vec3 ENTITY_PUFF_MOVE_VELOCITY = {0.0f, -1.0f, 0.0f};
static const vec2 ENTITY_PUFF_SIZE = {64.0f, 64.0f};
void entity_puff_init(ECS* ecs, u32 id, vec3 position, vec2 size);

View File

@ -3,7 +3,7 @@
#include "../../ecs_component.h"
#include "../../component/stat/component_shop_item.h"
#define ENTITY_SHOP_ITEM_HEALTH_PRICE 100
#define ENTITY_SHOP_ITEM_HEALTH_EXPONENT 1.15
#define ENTITY_SHOP_ITEM_HEALTH_PRICE 300
#define ENTITY_SHOP_ITEM_HEALTH_EXPONENT 4
void entity_shop_item_health_init(ECS* ecs, u32 id, u32 affectedID, u32 affectedID2);

View File

@ -4,6 +4,6 @@
#include "../../component/stat/component_shop_item.h"
#define ENTITY_SHOP_ITEM_UPGRADE_AMMO_PRICE 100
#define ENTITY_SHOP_ITEM_UPGRADE_AMMO_EXPONENT 1.15
#define ENTITY_SHOP_ITEM_UPGRADE_AMMO_EXPONENT 4
void entity_shop_item_upgrade_ammo_init(ECS* ecs, u32 id, u32 affectedID, u32 affectedID2);

View File

@ -4,6 +4,6 @@
#include "../../component/stat/component_shop_item.h"
#define ENTITY_SHOP_ITEM_UPGRADE_LIFETIME_PRICE 100
#define ENTITY_SHOP_ITEM_UPGRADE_LIFETIME_EXPONENT 1.15
#define ENTITY_SHOP_ITEM_UPGRADE_LIFETIME_EXPONENT 4
void entity_shop_item_upgrade_lifetime_init(ECS* ecs, u32 id, u32 affectedID, u32 affectedID2);

View File

@ -4,6 +4,6 @@
#include "../../component/stat/component_shop_item.h"
#define ENTITY_SHOP_ITEM_UPGRADE_REDIRECTS_PRICE 100
#define ENTITY_SHOP_ITEM_UPGRADE_REDIRECTS_EXPONENT 1.15
#define ENTITY_SHOP_ITEM_UPGRADE_REDIRECTS_EXPONENT 4
void entity_shop_item_upgrade_redirects_init(ECS* ecs, u32 id, u32 affectedID, u32 affectedID2);

View File

@ -11,6 +11,7 @@ entity_snake_init(ECS* ecs, u32 id, vec3 position, u32 sender)
ComponentActionOnDeleteGiveAmmo* actionOnDeleteGiveAmmo;
ComponentActionDamage* actionDamage;
ComponentAllegiance* allegiance;
ComponentAnimationIdle* animationIdle;
gameObject = ecs_component_add(ecs, ECS_COMPONENT_GAME_OBJECT, id);
actionReturn = ecs_component_add(ecs, ECS_COMPONENT_ACTION_RETURN, id);
@ -18,15 +19,19 @@ entity_snake_init(ECS* ecs, u32 id, vec3 position, u32 sender)
actionOnDeleteGiveAmmo = ecs_component_add(ecs, ECS_COMPONENT_ACTION_ON_DELETE_GIVE_AMMO, id);
actionDamage = ecs_component_add(ecs, ECS_COMPONENT_ACTION_DAMAGE, id);
actionLock = ecs_component_add(ecs, ECS_COMPONENT_ACTION_LOCK, id);
animationIdle = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_IDLE, id);
allegiance = ecs_component_add(ecs, ECS_COMPONENT_ALLEGIANCE, id);
ecs_component_add(ecs, ECS_COMPONENT_ACTION_GRIP, id);
ecs_component_add(ecs, ECS_COMPONENT_ACTION_ANGLE, id);
component_game_object_init
component_game_object_atlas_init
(
gameObject,
ecs,
ecs->game->resources.textures[TEXTURE_SNAKE],
(s32*)SNAKE_FRAME_SIZE,
(s32*)SNAKE_ATLAS_SIZE,
(f32*)SNAKE_SIZE,
(f32*)SNAKE_PHYSICS_SIZE,
position,
@ -51,6 +56,7 @@ entity_snake_init(ECS* ecs, u32 id, vec3 position, u32 sender)
component_action_redirect_init(actionRedirect, SNAKE_ACTION_REDIRECT_MULTIPLIER, sender);
component_action_lock_init(actionLock, SNAKE_ACTION_LOCK_COOLDOWN, SNAKE_ACTION_LOCK_SELECT_RADIUS, sender);
component_action_on_delete_give_ammo_init(actionOnDeleteGiveAmmo, SNAKE_ACTION_ON_DELETE_GIVE_AMMO_VALUE);
component_animation_idle_init(animationIdle, SNAKE_ANIMATION_IDLE_BASE_INDEX, SNAKE_ANIMATION_IDLE_TIMER);
component_action_damage_init
(
actionDamage,

View File

@ -4,12 +4,17 @@
#include "../../component/component_game_object.h"
#include "../../component/action/component_action_return.h"
#include "../../component/action/component_action_redirect.h"
#include "../../component/action/component_action_angle.h"
#include "../../component/animation/component_animation_idle.h"
#include "../../component/action/component_action_on_delete_give_ammo.h"
#include "../../component/action/component_action_lock.h"
#include "../../component/action/component_action_damage.h"
#include "../../component/action/component_action_grip.h"
#include "../../component/stat/component_game_entity_type.h"
#define SNAKE_ANIMATION_IDLE_BASE_INDEX 0
#define SNAKE_ANIMATION_IDLE_TIMER 5
#define SNAKE_SPEED 1
#define SNAKE_FRICTION 1
#define SNAKE_VELOCITY_MAX 50
@ -30,7 +35,9 @@
#define SNAKE_GAME_OBJECT_IS_BOUNCE false
#define SNAKE_GAME_OBJECT_IS_SOLID false
static const vec2 SNAKE_SIZE = {75.0f, 75.0f};
static const vec2 SNAKE_SIZE = {100.0f, 100.0f};
static const vec2 SNAKE_PHYSICS_SIZE = {60.0f, 20.0f};
static const ivec2 SNAKE_ATLAS_SIZE = {9, 2};
static const ivec2 SNAKE_FRAME_SIZE = {512, 512};
void entity_snake_init(ECS* ecs, u32 id, vec3 position, u32 sender);

View File

@ -4,7 +4,7 @@
#include "../../component/stat/component_timer.h"
#include "../../ecs_component.h"
#define TIMER_DISPLAY_TIME (HOUR_TICK)
#define TIMER_DISPLAY_TIME 108000
static const vec3 ENTITY_TIMER_DISPLAY_POSITION = {1724.0f, 48.0f, 0.05f};

View File

@ -2,21 +2,23 @@
/* Initializes a player entity. */
void
entity_tutorial_text_init(ECS* ecs, u32 id, vec3 position)
entity_tutorial_text_init(ECS* ecs, u32 id, vec3 position, u32 heartID)
{
ComponentActionDeleteOnTimer* actionDeleteOnTimer;
ComponentActionDeleteOnHeart* actionDeleteOnHeart;
ComponentAnimationColorChange* animationColorChange;
ComponentText* text;
f32 base;
text = ecs_component_add(ecs, ECS_COMPONENT_TEXT, id);
actionDeleteOnTimer = ecs_component_add(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TIMER, id);
actionDeleteOnHeart = ecs_component_add(ecs, ECS_COMPONENT_ACTION_DELETE_ON_HEART, id);
animationColorChange = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_COLOR_CHANGE, id);
component_text_init
(
text,
&ecs->game->resources.fonts[FONT_HUD],
&ecs->game->resources.fonts[FONT_TUTORIAL],
STRING_TUTORIAL_TEXT,
strlen(STRING_TUTORIAL_TEXT),
ENTITY_TUTORIAL_TEXT_WRAP,
@ -30,6 +32,12 @@ entity_tutorial_text_init(ECS* ecs, u32 id, vec3 position)
ENTITY_TUTORIAL_TEXT_TIMER
);
component_action_delete_on_heart_init
(
actionDeleteOnHeart,
heartID
);
component_animation_color_change_init
(
animationColorChange,

View File

@ -2,10 +2,11 @@
#include "../../component/component_text.h"
#include "../../component/action/component_action_delete_on_timer.h"
#include "../../component/action/component_action_delete_on_heart.h"
#include "../../component/animation/component_animation_color_change.h"
#include "../../ecs_component.h"
#define ENTITY_TUTORIAL_TEXT_TIMER 1800
#define ENTITY_TUTORIAL_TEXT_TIMER 1200
#define ENTITY_TUTORIAL_TEXT_WRAP 1600
void entity_tutorial_text_init(ECS* ecs, u32 id, vec3 position);
void entity_tutorial_text_init(ECS* ecs, u32 id, vec3 position, u32 heartID);

View File

@ -27,6 +27,8 @@ _game_quit(Game* self)
static void
_game_tick(Game* self)
{
state_tick(&self->state);
if (!self->isPaused)
ecs_tick(&self->ecs);
@ -83,7 +85,7 @@ game_init(Game* self)
ecs_init(&self->ecs, self);
state_init(&self->state, self, STATE_PLAY);
state_init(&self->state, self, STATE_TITLE);
}
/* Main game loop. */

View File

@ -2,22 +2,22 @@
/* Draws a textured quad. */
void
texture_quad_draw(Renderer* renderer, Shader* shader, Atlas* atlas, mat4 model, vec2 size, vec4 color)
texture_quad_draw
(
Renderer* renderer,
Shader* shader,
Atlas* atlas,
mat4 model,
vec2 size,
vec4 color,
bool isFlipHorizontal
)
{
vec2 uvMin;
vec2 uvMax;
mat4 view;
mat4 projection;
atlas_uv_get(atlas, uvMin, uvMax);
f32 vertices[4][5] =
{
{0.0f , 0.0f , 0.0f, uvMin[0], uvMin[1]},
{0.0f , size[1], 0.0f, uvMin[0], uvMax[1]},
{size[0], size[1], 0.0f, uvMax[0], uvMax[1]},
{size[0], 0.0f , 0.0f, uvMax[0], uvMin[1]},
};
f32 verticesFinal[4][5];
u32 indices[2][3] =
{
@ -25,13 +25,44 @@ texture_quad_draw(Renderer* renderer, Shader* shader, Atlas* atlas, mat4 model,
{0, 1, 3}
};
atlas_uv_get(atlas, uvMin, uvMax);
if (isFlipHorizontal)
{
f32 vertices[4][5] =
{
{size[0], 0.0f , 0.0f, uvMin[0], uvMin[1]},
{size[0], size[1], 0.0f, uvMin[0], uvMax[1]},
{0.0f, size[1], 0.0f, uvMax[0], uvMax[1]},
{0.0f, 0.0f , 0.0f, uvMax[0], uvMin[1]}
};
memcpy(verticesFinal, vertices, sizeof(verticesFinal));
}
else
{
f32 vertices[4][5] =
{
{0.0f , 0.0f , 0.0f, uvMin[0], uvMin[1]},
{0.0f , size[1], 0.0f, uvMin[0], uvMax[1]},
{size[0], size[1], 0.0f, uvMax[0], uvMax[1]},
{size[0], 0.0f , 0.0f, uvMax[0], uvMin[1]}
};
memcpy(verticesFinal, vertices, sizeof(verticesFinal));
}
camera_view_get(&renderer->camera, view);
camera_projection_get(&renderer->camera, projection);
vec3 scale = {1, 1, 1};
glm_scale(projection, scale);
vao_bind(&renderer->vao);
vbo_bind(&renderer->vbo);
vbo_buffer(&renderer->vbo, sizeof(vertices), vertices);
vbo_buffer(&renderer->vbo, sizeof(verticesFinal), verticesFinal);
vbo_bind(&renderer->ebo);
vbo_buffer(&renderer->ebo, sizeof(indices), indices);

View File

@ -8,4 +8,13 @@
#define TEXTURE_QUAD_UNIFORM_TEXTURE "uTexture"
#define TEXTURE_QUAD_UNIFORM_VIEW "uView"
void texture_quad_draw(Renderer* renderer, Shader* shader, Atlas* atlas, mat4 model, vec2 size, vec4 color);
void texture_quad_draw
(
Renderer* renderer,
Shader* shader,
Atlas* atlas,
mat4 model,
vec2 size,
vec4 color,
bool isFlipHorizontal
);

View File

@ -35,9 +35,14 @@ static const ShaderPaths SHADER_PATHS[SHADER_COUNT] =
#define TEXTURE_COUNT TEXTURE_GOODIES + 1
typedef enum TextureType
{
TEXTURE_BLACK,
TEXTURE_STATE_FADE,
TEXTURE_CURSOR,
TEXTURE_MENU_BUTTONS,
TEXTURE_ICONS,
TEXTURE_LOGO,
TEXTURE_GAME_OVER,
TEXTURE_PUFF,
TEXTURE_OVERLAY,
TEXTURE_REDIRECT_ARROW,
TEXTURE_STREAK,
TEXTURE_STREAK_SQUARE,
@ -62,9 +67,14 @@ typedef enum TextureType
static const char* TEXTURE_PATHS[TEXTURE_COUNT] =
{
"res/gfx/black.png",
"res/gfx/stateFade.png",
"res/gfx/cursor.png",
"res/gfx/menuButtons.png",
"res/gfx/icons.png",
"res/gfx/title/logo.png",
"res/gfx/gameOver/gameOver.png",
"res/gfx/play/puff.png",
"res/gfx/play/overlay.png",
"res/gfx/play/redirectArrow.png",
"res/gfx/play/streak.png",
"res/gfx/play/streakSquare.png",
@ -87,14 +97,18 @@ static const char* TEXTURE_PATHS[TEXTURE_COUNT] =
"res/gfx/play/goodies.png"
};
#define FONT_COUNT FONT_SHOP + 1
#define FONT_COUNT FONT_SMALL + 1
typedef enum FontType
{
FONT_NORMAL,
FONT_STAT_DISPLAY,
FONT_DAMAGE_NUMBER,
FONT_HUD,
FONT_SHOP
FONT_SHOP,
FONT_TUTORIAL,
FONT_CREDITS,
FONT_BIG,
FONT_SMALL
} FontType;
static const char* FONT_PATHS[FONT_COUNT] =
@ -104,6 +118,10 @@ static const char* FONT_PATHS[FONT_COUNT] =
"res/font/upheaval.ttf",
"res/font/upheaval.ttf",
"res/font/upheaval.ttf",
"res/font/upheaval.ttf",
"res/font/upheaval.ttf",
"res/font/upheaval.ttf",
"res/font/upheaval.ttf"
};
static const u32 FONT_SIZES[FONT_COUNT] =
@ -111,7 +129,12 @@ static const u32 FONT_SIZES[FONT_COUNT] =
64,
32,
32,
32
32,
32,
24,
24,
128,
24
};
#define SOUND_COUNT SOUND_EZ_ACHE_READY + 1

View File

@ -1,6 +1,9 @@
#pragma once
#include "play/PLAY_COMMON.h"
#include "title/TITLE_COMMON.h"
#include "game_over/GAME_OVER_COMMON.h"
#include "results/RESULTS_COMMON.h"
#define STATE_COUNT STATE_RESULTS + 1
typedef enum StateType
@ -17,8 +20,14 @@ typedef struct State
{
Game* game;
StateType type;
StateType setType;
bool isChanging;
u32 fadeID;
union
{
Play play;
};
Title title;
GameOver gameOver;
Results results;
} states;
} State;

View File

@ -0,0 +1,17 @@
#pragma once
#include "../../resource/resource_shader.h"
#include "../../resource/resource_texture.h"
typedef struct State State;
typedef struct GameOver
{
State* state;
u32 textID;
u32 imageID;
u32 descriptionID;
u32 backgroundID;
u32 menuButtonID;
bool isChange;
} GameOver;

View File

@ -0,0 +1,92 @@
#include "game_over.h"
static void _game_over_entity_init(GameOver* self);
/* Initializes entities for the gameover state. */
static void
_game_over_entity_init(GameOver* self)
{
self->backgroundID = ecs_entity_add(&self->state->game->ecs);
self->textID = ecs_entity_add(&self->state->game->ecs);
self->imageID = ecs_entity_add(&self->state->game->ecs);
self->descriptionID = ecs_entity_add(&self->state->game->ecs);
self->menuButtonID = ecs_entity_add(&self->state->game->ecs);
entity_sprite_init
(
&self->state->game->ecs,
self->backgroundID,
self->state->game->resources.textures[TEXTURE_STATE_FADE],
(f32*)GAME_OVER_BACKGROUND_SIZE,
(f32*)GAME_OVER_BACKGROUND_POSITION
);
entity_text_init
(
&self->state->game->ecs,
self->textID,
&self->state->game->resources.fonts[FONT_BIG],
STRING_GAME_OVER_TITLE_TEXT,
strlen(STRING_GAME_OVER_TITLE_TEXT),
-1,
(f32*)GAME_OVER_TITLE_TEXT_POSITION,
(f32*)COLOR_OPAQUE
);
entity_sprite_init
(
&self->state->game->ecs,
self->textID,
self->state->game->resources.textures[TEXTURE_GAME_OVER],
(f32*)GAME_OVER_IMAGE_SIZE,
(f32*)GAME_OVER_IMAGE_POSITION
);
entity_text_init
(
&self->state->game->ecs,
self->descriptionID,
&self->state->game->resources.fonts[FONT_SMALL],
STRING_GAME_OVER_TEXT,
strlen(STRING_GAME_OVER_TEXT),
-1,
(f32*)GAME_OVER_TEXT_POSITION,
(f32*)COLOR_OPAQUE
);
entity_menu_button_init
(
&self->state->game->ecs,
self->menuButtonID,
(f32*)GAME_OVER_MENU_BUTTON_POSITION,
MENU_BUTTON_RETRY
);
}
/* Initializes gameover state. */
void
game_over_init(GameOver* self, State* state)
{
memset(self, '\0', sizeof(GameOver));
self->state = state;
_game_over_entity_init(self);
music_play(&self->state->game->resources.music[MUSIC_GAME_OVER], true);
}
/* Ticks gameover state. */
void
game_over_tick(GameOver* self)
{
ComponentButton* button;
button = ecs_component_get(&self->state->game->ecs, ECS_COMPONENT_BUTTON, self->menuButtonID);
if (button->state == BUTTON_PRESSED)
{
sound_play(&self->state->game->resources.sounds[SOUND_SELECT], SOUND_PRIORITY);
self->isChange = true;
}
}

View File

@ -0,0 +1,56 @@
#pragma once
#include "../STATE_COMMON.h"
#include "../../ecs/ecs.h"
#include "../../ecs/entity/entity_cursor.h"
#include "../../ecs/entity/entity_sprite.h"
#include "../../ecs/entity/entity_text.h"
#include "../../ecs/entity/entity_menu_button.h"
static const vec2 GAME_OVER_BACKGROUND_SIZE = {1920.0f, 1080.0f};
static const vec3 GAME_OVER_BACKGROUND_POSITION = {960.0f, 540.0f, 0.2f};
static const vec3 GAME_OVER_TITLE_TEXT_POSITION = {600.0f, 0.0f, 0.09f};
static const vec2 GAME_OVER_IMAGE_SIZE = {1920.0f, 660.0f};
static const vec3 GAME_OVER_IMAGE_POSITION = {960.0f, 450.0f, 0.09f};
static const vec3 GAME_OVER_TEXT_POSITION = {500.0f, 800.0f, 0.1f};
static const vec3 GAME_OVER_MENU_BUTTON_POSITION = {960.0f, 950.0f, 0.1f};
#define GAME_OVER_SHADER_COUNT 2
static const ShaderType GAME_OVER_SHADERS[GAME_OVER_SHADER_COUNT] =
{
SHADER_TEXTURE_QUAD,
SHADER_COLOR_QUAD
};
#define GAME_OVER_TEXTURE_COUNT 4
static const TextureType GAME_OVER_TEXTURES[GAME_OVER_TEXTURE_COUNT] =
{
TEXTURE_STATE_FADE,
TEXTURE_CURSOR,
TEXTURE_MENU_BUTTONS,
TEXTURE_GAME_OVER
};
#define GAME_OVER_FONT_COUNT 2
static const FontType GAME_OVER_FONTS[GAME_OVER_FONT_COUNT] =
{
FONT_SMALL,
FONT_BIG
};
#define GAME_OVER_SOUND_COUNT 1
static const SoundType GAME_OVER_SOUNDS[GAME_OVER_SOUND_COUNT] =
{
SOUND_SELECT
};
#define GAME_OVER_MUSIC_COUNT 1
static const MusicType GAME_OVER_MUSIC[GAME_OVER_MUSIC_COUNT] =
{
MUSIC_GAME_OVER
};
void game_over_init(GameOver* self, State* state);
void game_over_tick(GameOver* self);

View File

@ -18,4 +18,8 @@ typedef struct Play
u32 waveDisplay;
u32 heartDisplay;
u32 waveTimerDisplay;
u32 overlay;
u32 tutorialText;
bool isGameOver;
bool isResults;
} Play;

View File

@ -15,6 +15,8 @@ _play_entity_init(Play* self)
self->waveDisplay = ecs_entity_add(&self->state->game->ecs);
self->waveTimerDisplay = ecs_entity_add(&self->state->game->ecs);
self->heartDisplay = ecs_entity_add(&self->state->game->ecs);
self->tutorialText = ecs_entity_add(&self->state->game->ecs);
self->overlay = ecs_entity_add(&self->state->game->ecs);
entity_spawner_init
(
@ -91,11 +93,19 @@ _play_entity_init(Play* self)
entity_tutorial_text_init
(
&self->state->game->ecs,
ecs_entity_add(&self->state->game->ecs),
(f32*)PLAY_TUTORIAL_TEXT_POSITION
self->tutorialText,
(f32*)PLAY_TUTORIAL_TEXT_POSITION,
self->player
);
music_play(&self->state->game->resources.music[MUSIC_CALM], true);
entity_sprite_init
(
&self->state->game->ecs,
self->overlay,
self->state->game->resources.textures[TEXTURE_OVERLAY],
(f32*)PLAY_OVERLAY_SIZE,
(f32*)PLAY_OVERLAY_POSITION
);
}
/* Initializes play state. */
@ -107,4 +117,28 @@ play_init(Play* self, State* state)
self->state = state;
_play_entity_init(self);
music_play(&self->state->game->resources.music[MUSIC_CALM], true);
}
/* Ticks play state. */
void
play_tick(Play* self)
{
ComponentGoodies* goodies;
ComponentHealth* health;
ComponentTimer* timer;
goodies = ecs_component_get(&self->state->game->ecs, ECS_COMPONENT_GOODIES, self->elemental);
health = ecs_component_get(&self->state->game->ecs, ECS_COMPONENT_HEALTH, self->player);
timer = ecs_component_get(&self->state->game->ecs, ECS_COMPONENT_TIMER, self->timerDisplay);
if (goodies->value >= goodies->max)
self->isResults = true;
else if
(
health->isDead ||
timer->isDone
)
self->isGameOver = true;
}

View File

@ -16,11 +16,15 @@
#include "../../ecs/entity/play/entity_shop_button.h"
#include "../../ecs/entity/play/entity_tutorial_text.h"
#include "../../ecs/entity/entity_cursor.h"
#include "../../ecs/entity/entity_sprite.h"
static const vec3 PLAY_PLAYER_POSITION = {960.0f, 1000.0f, 0.0f};
static const vec3 PLAY_ELEMENTAL_POSITION = {960.0f, 500.0f, 0.0f};
static const vec3 PLAY_PLAYER_POSITION = {960.0f, 1000.0f, 0.8f};
static const vec3 PLAY_ELEMENTAL_POSITION = {960.0f, 500.0f, 0.8f};
static const vec3 PLAY_TUTORIAL_TEXT_POSITION = {128.0f, 128.0f, 0.05f};
static const vec3 PLAY_OVERLAY_POSITION = {960.0f, 540.0f, 0.09999f};
static const vec3 PLAY_OVERLAY_SIZE = {1920.0f, 1080.0f};
#define PLAY_SHADER_COUNT 2
static const ShaderType PLAY_SHADERS[PLAY_SHADER_COUNT] =
{
@ -28,12 +32,15 @@ static const ShaderType PLAY_SHADERS[PLAY_SHADER_COUNT] =
SHADER_COLOR_QUAD
};
#define PLAY_TEXTURE_COUNT 22
#define PLAY_TEXTURE_COUNT 25
static const TextureType PLAY_TEXTURES[PLAY_TEXTURE_COUNT] =
{
TEXTURE_STATE_FADE,
TEXTURE_CURSOR,
TEXTURE_REDIRECT_ARROW,
TEXTURE_OVERLAY,
TEXTURE_ICONS,
TEXTURE_PUFF,
TEXTURE_REDIRECT_ARROW,
TEXTURE_STREAK,
TEXTURE_STREAK_SQUARE,
TEXTURE_SHADOW,
@ -55,14 +62,15 @@ static const TextureType PLAY_TEXTURES[PLAY_TEXTURE_COUNT] =
TEXTURE_GOODIES
};
#define PLAY_FONT_COUNT 5
#define PLAY_FONT_COUNT 6
static const FontType PLAY_FONTS[PLAY_FONT_COUNT] =
{
FONT_NORMAL,
FONT_STAT_DISPLAY,
FONT_DAMAGE_NUMBER,
FONT_HUD,
FONT_SHOP
FONT_SHOP,
FONT_TUTORIAL
};
#define PLAY_SOUND_COUNT 27
@ -110,3 +118,4 @@ static const MusicType PLAY_MUSIC[PLAY_MUSIC_COUNT] =
};
void play_init(Play* play, State* state);
void play_tick(Play* play);

Some files were not shown because too many files have changed in this diff Show More