- Colisions, movibles, reactius...

This commit is contained in:
2023-03-06 18:56:46 +01:00
parent 2942b85de7
commit 70d097a173
3 changed files with 256 additions and 17 deletions

View File

@@ -23,12 +23,15 @@ namespace actor
return act;
}
void setDirty(actor_t *act)
void setDirty(actor_t *act, const bool force)
{
if (act->prev==nullptr && act != first && !force) return;
if (act->prev) act->prev->next = act->next;
if (act->next) act->next->prev = act->prev;
if (act == first) first = act->next;
act->prev = nullptr;
act->next = dirty;
dirty = act;
}
@@ -80,34 +83,195 @@ namespace actor
}
}
void update(actor_t *act)
void updateUserInput(actor_t *act)
{
if (input::keyDown(SDL_SCANCODE_LEFT) && act->pos.x>0) {
bool moving = false;
if (input::keyDown(SDL_SCANCODE_LEFT) && act->pos.x>0) { act->push |= PUSH_XN; moving = true; }
if (input::keyDown(SDL_SCANCODE_RIGHT) && act->pos.x<56) { act->push |= PUSH_XP; moving = true; }
if (input::keyDown(SDL_SCANCODE_UP) && act->pos.y>0) { act->push |= PUSH_YN; moving = true; }
if (input::keyDown(SDL_SCANCODE_DOWN) && act->pos.y<56) { act->push |= PUSH_YP; moving = true; }
if (moving)
{
act->flags |= FLAG_ANIMATED;
}
else
{
act->flags &= uint8_t(~FLAG_ANIMATED);
}
}
void updateMoving(actor_t *act)
{
act->push |= act->mov_push;
}
void changeMoving(actor_t *act)
{
switch(act->movement)
{
case MOV_X:
act->mov_push = act->mov_push==PUSH_XP ? PUSH_XN : PUSH_XP;
break;
case MOV_Y:
act->mov_push = act->mov_push==PUSH_YP ? PUSH_YN : PUSH_YP;
break;
case MOV_Z:
act->mov_push = act->mov_push==PUSH_ZP ? PUSH_ZN : PUSH_ZP;
break;
case MOV_CW:
switch (act->mov_push)
{
case PUSH_XP: act->mov_push=PUSH_YN; break;
case PUSH_YN: act->mov_push=PUSH_XN; break;
case PUSH_XN: act->mov_push=PUSH_YP; break;
case PUSH_YP: act->mov_push=PUSH_XP; break;
}
break;
case MOV_CCW:
switch (act->mov_push)
{
case PUSH_XP: act->mov_push=PUSH_YP; break;
case PUSH_YP: act->mov_push=PUSH_XN; break;
case PUSH_XN: act->mov_push=PUSH_YN; break;
case PUSH_YN: act->mov_push=PUSH_XP; break;
}
break;
case MOV_RAND:
switch (rand()%4)
{
case 0: act->mov_push=PUSH_YP; break;
case 1: act->mov_push=PUSH_XN; break;
case 2: act->mov_push=PUSH_YN; break;
case 3: act->mov_push=PUSH_XP; break;
}
break;
case MOV_HUNT:
// TODO
break;
}
}
void updatePushable(actor_t *act)
{
if (act->push & PUSH_XN) {
act->pos.x--;
actor::actor_t *other = actor::get_collision(act);
if (other)
if (act->pos.x<0 || other)
{
other->push |= 1;
if (other && other->flags & FLAG_PUSHABLE) other->push |= PUSH_XN;
act->pos.x++;
if (act->flags & FLAG_MOVING) changeMoving(act);
}
else
{
actor::setDirty(act);
}
}
if (input::keyDown(SDL_SCANCODE_LEFT) && act->pos.x>0) {
act->pos.x--;
if (act->push & PUSH_XP) {
act->pos.x++;
actor::actor_t *other = actor::get_collision(act);
if (other)
if (act->pos.x>56 || other)
{
other->push |= 1;
act->pos.x++;
if (other && other->flags & FLAG_PUSHABLE) other->push |= PUSH_XP;
act->pos.x--;
if (act->flags & FLAG_MOVING) changeMoving(act);
}
else
{
actor::setDirty(act);
}
}
if (act->push & PUSH_YN) {
act->pos.y--;
actor::actor_t *other = actor::get_collision(act);
if (act->pos.y<0 || other)
{
if (other && other->flags & FLAG_PUSHABLE) other->push |= PUSH_YN;
act->pos.y++;
if (act->flags & FLAG_MOVING) changeMoving(act);
}
else
{
actor::setDirty(act);
}
}
if (act->push & PUSH_YP) {
act->pos.y++;
actor::actor_t *other = actor::get_collision(act);
if (act->pos.y>56 ||other)
{
if (other && other->flags & FLAG_PUSHABLE) other->push |= PUSH_YP;
act->pos.y--;
if (act->flags & FLAG_MOVING) changeMoving(act);
}
else
{
actor::setDirty(act);
}
}
if (act->push & PUSH_ZN) {
act->pos.z--;
actor::actor_t *other = actor::get_collision(act);
if (act->pos.z<0 || other)
{
if (other && other->flags & FLAG_PUSHABLE) other->push |= PUSH_ZN;
act->pos.z++;
if (act->flags & FLAG_MOVING) changeMoving(act);
}
else
{
actor::setDirty(act);
}
}
if (act->push & PUSH_ZP) {
act->pos.z++;
actor::actor_t *other = actor::get_collision(act);
if (other && other->flags & FLAG_PUSHABLE) other->push |= PUSH_ZP;
if (act->pos.z>56)
{
act->pos.z--;
if (act->flags & FLAG_MOVING) changeMoving(act);
}
else
{
actor::setDirty(act);
}
}
}
void updateReactive(actor_t *act)
{
if (act->push & act->react_mask)
{
actor_t *other = nullptr;
if (act->push == PUSH_XP) { act->pos.x--; other = get_collision(act); act->pos.x++; }
else if (act->push == PUSH_XN) { act->pos.x++; other = get_collision(act); act->pos.x--; }
else if (act->push == PUSH_YP) { act->pos.y--; other = get_collision(act); act->pos.y++; }
else if (act->push == PUSH_YN) { act->pos.y++; other = get_collision(act); act->pos.y--; }
if (other) other->push |= act->react_push;
}
}
void update(actor_t *act, const bool update_all)
{
actor_t *next = act->next;
if (act->flags & FLAG_HERO) updateUserInput(act);
if (act->flags & FLAG_MOVING) updateMoving(act);
//if (act->flags & FLAG_PUSHABLE)
updatePushable(act);
if (act->flags & FLAG_REACTIVE) updateReactive(act);
act->push = PUSH_NONE;
if (update_all && next) update(next);
}
void draw(actor_t *act, const bool draw_all)
@@ -119,6 +283,19 @@ namespace actor
if (draw_all && act->next) draw(act->next);
}
actor_t *find_at(const int x, const int y, const int z)
{
actor_t *act = first;
while (act)
{
if (act->pos.x==x && act->pos.y==y && act->pos.z==z)
{
return act;
}
}
return nullptr;
}
actor_t *get_collision(actor_t *act)
{
actor_t *other = first;
@@ -133,6 +310,20 @@ namespace actor
}
other = other->next;
}
other = dirty;
while (other)
{
if (other != act)
{
if (check_collision(act, other))
{
return other;
}
}
other = other->next;
}
return nullptr;
}