From 70d097a1730339118d15bfad8064b222b2ee8f38 Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Mon, 6 Mar 2023 18:56:46 +0100 Subject: [PATCH] - Colisions, movibles, reactius... --- source/actor.cpp | 211 ++++++++++++++++++++++++++++++++++++++++++++--- source/actor.h | 39 ++++++++- source/main.cpp | 23 ++++-- 3 files changed, 256 insertions(+), 17 deletions(-) diff --git a/source/actor.cpp b/source/actor.cpp index a6335e1..8187beb 100644 --- a/source/actor.cpp +++ b/source/actor.cpp @@ -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; } diff --git a/source/actor.h b/source/actor.h index 35614e0..92c0468 100644 --- a/source/actor.h +++ b/source/actor.h @@ -1,6 +1,32 @@ #pragma once #include +#define FLAG_NONE 0 +#define FLAG_HERO 1 +#define FLAG_PUSHABLE 2 +#define FLAG_REACTIVE 4 +#define FLAG_MOVING 8 +#define FLAG_ANIMATED 16 +#define FLAG_ORIENTABLE 32 +#define FLAG_DEADLY 64 + +#define PUSH_NONE 0 +#define PUSH_XP 1 +#define PUSH_XN 2 +#define PUSH_YP 4 +#define PUSH_YN 8 +#define PUSH_ZP 16 +#define PUSH_ZN 32 + +#define MOV_NONE 0 +#define MOV_X 1 +#define MOV_Y 2 +#define MOV_Z 3 +#define MOV_CW 4 +#define MOV_CCW 5 +#define MOV_RAND 6 +#define MOV_HUNT 7 + namespace actor { struct vec3_t @@ -16,8 +42,15 @@ namespace actor vec3_t pos; vec3_t size; + uint8_t flags; uint8_t push; + uint8_t react_mask; + uint8_t react_push; + + uint8_t movement; + uint8_t mov_push; + actor_t *prev; actor_t *next; }; @@ -26,14 +59,16 @@ namespace actor actor_t *create(vec3_t p, vec3_t s, SDL_Rect r, SDL_Point o); - void setDirty(actor_t *act); + void setDirty(actor_t *act, const bool force=false); void reorder(); - void update(actor_t *act); + void update(actor_t *act, const bool update_all=true); void draw(actor_t *act, const bool draw_all=true); + actor_t *find_at(const int x, const int y, const int z); + actor_t *get_collision(actor_t *act); const bool check_collision(actor_t *obj1, actor_t *obj2); diff --git a/source/main.cpp b/source/main.cpp index 25b99f1..8c7c761 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -16,9 +16,20 @@ void game::init() game::setUpdateTicks(64); box = actor::create({16,16,0}, {8,8,8}, {32,0,32,32}, {0,32}); - actor::setDirty(box); - box = actor::create({8,0,0}, {8,8,8}, {32,0,32,32}, {0,32}); - actor::setDirty(box); + box->flags = FLAG_MOVING;// | FLAG_PUSHABLE; + box->movement = MOV_Z; + box->mov_push = PUSH_ZP; + actor::setDirty(box, true); + + box = actor::create({32,32,16}, {8,8,8}, {32,0,32,32}, {0,32}); + box->flags = FLAG_PUSHABLE; + box->movement = MOV_CW; + box->mov_push = PUSH_XN; + actor::setDirty(box, true); + + box = actor::create({16,16,16}, {8,8,8}, {32,0,32,32}, {0,32}); + box->flags = FLAG_HERO | FLAG_PUSHABLE; + actor::setDirty(box, true); actor::reorder(); } @@ -26,7 +37,7 @@ int sx=1, sy=0; bool game::loop() { - if (input::keyDown(SDL_SCANCODE_LEFT) && box->pos.x>0) { + /*if (input::keyDown(SDL_SCANCODE_LEFT) && box->pos.x>0) { box->pos.x--; actor::actor_t *other = actor::get_collision(box); if (other) @@ -44,7 +55,9 @@ bool game::loop() if (input::keyDown(SDL_SCANCODE_UP) && box->pos.y>0) { box->pos.y--; actor::setDirty(box); } if (input::keyDown(SDL_SCANCODE_DOWN) && box->pos.y<42) { box->pos.y++; actor::setDirty(box); } if (input::keyDown(SDL_SCANCODE_Z) && box->pos.z>0) { box->pos.z--; actor::setDirty(box); } - if (input::keyDown(SDL_SCANCODE_A) && box->pos.z<42) { box->pos.z++; actor::setDirty(box); } + if (input::keyDown(SDL_SCANCODE_A) && box->pos.z<42) { box->pos.z++; actor::setDirty(box); }*/ + + actor::update(actor::getFirst()); actor::reorder(); draw::cls(8);