From c975599251c5f810dd3eb7cce800fe37bf1473bf Mon Sep 17 00:00:00 2001 From: John McCardle Date: Sun, 28 Apr 2024 22:01:59 -0400 Subject: [PATCH] Animated wander demo (working out integer grid positions for entities), not exactly working --- src/UIEntity.cpp | 27 ++++++++++++++++++++++++--- src/UIEntity.h | 1 + src/scripts/game.py | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/UIEntity.cpp b/src/UIEntity.cpp index 01ebd83..d88fbe2 100644 --- a/src/UIEntity.cpp +++ b/src/UIEntity.cpp @@ -95,6 +95,10 @@ PyObject* sfVector2f_to_PyObject(sf::Vector2f vector) { return Py_BuildValue("(ff)", vector.x, vector.y); } +PyObject* sfVector2i_to_PyObject(sf::Vector2i vector) { + return Py_BuildValue("(ii)", vector.x, vector.y); +} + sf::Vector2f PyObject_to_sfVector2f(PyObject* obj) { float x, y; if (!PyArg_ParseTuple(obj, "ff", &x, &y)) { @@ -103,6 +107,14 @@ sf::Vector2f PyObject_to_sfVector2f(PyObject* obj) { return sf::Vector2f(x, y); } +sf::Vector2i PyObject_to_sfVector2i(PyObject* obj) { + int x, y; + if (!PyArg_ParseTuple(obj, "ii", &x, &y)) { + return sf::Vector2i(); // TODO / reconsider this default: Return default vector on parse error + } + return sf::Vector2i(x, y); +} + // TODO - deprecate / remove this helper PyObject* UIGridPointState_to_PyObject(const UIGridPointState& state) { return PyObject_New(PyObject, (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "GridPointState")); @@ -125,11 +137,19 @@ PyObject* UIGridPointStateVector_to_PyList(const std::vector& } PyObject* UIEntity::get_position(PyUIEntityObject* self, void* closure) { - return sfVector2f_to_PyObject(self->data->position); + if (reinterpret_cast(closure) == 0) { + return sfVector2f_to_PyObject(self->data->position); + } else { + return sfVector2i_to_PyObject(self->data->collision_pos); + } } int UIEntity::set_position(PyUIEntityObject* self, PyObject* value, void* closure) { - self->data->position = PyObject_to_sfVector2f(value); + if (reinterpret_cast(closure) == 0) { + self->data->position = PyObject_to_sfVector2f(value); + } else { + self->data->collision_pos = PyObject_to_sfVector2i(value); + } return 0; } @@ -158,7 +178,8 @@ PyMethodDef UIEntity::methods[] = { }; PyGetSetDef UIEntity::getsetters[] = { - {"position", (getter)UIEntity::get_position, (setter)UIEntity::set_position, "Entity position", NULL}, + {"draw_pos", (getter)UIEntity::get_position, (setter)UIEntity::set_position, "Entity position (graphically)", (void*)0}, + {"pos", (getter)UIEntity::get_position, (setter)UIEntity::set_position, "Entity position (integer grid coordinates)", (void*)1}, {"gridstate", (getter)UIEntity::get_gridstate, NULL, "Grid point states for the entity", NULL}, {"sprite_number", (getter)UIEntity::get_spritenumber, (setter)UIEntity::set_spritenumber, "Sprite number (index) on the texture on the display", NULL}, {NULL} /* Sentinel */ diff --git a/src/UIEntity.h b/src/UIEntity.h index 94b700a..d65678c 100644 --- a/src/UIEntity.h +++ b/src/UIEntity.h @@ -40,6 +40,7 @@ public: std::vector gridstate; UISprite sprite; sf::Vector2f position; //(x,y) in grid coordinates; float for animation + sf::Vector2i collision_pos; //(x, y) in grid coordinates: int for collision //void render(sf::Vector2f); //override final; UIEntity(); diff --git a/src/scripts/game.py b/src/scripts/game.py index 962fc91..43989b3 100644 --- a/src/scripts/game.py +++ b/src/scripts/game.py @@ -40,6 +40,7 @@ print("Lol, did it segfault?") s = mcrfpy.Sprite(25, 384+19, texture, 86, 9.0) # pos (LinkedVector / Vector): s.pos # texture (Texture): s.texture +s.click = lambda *args, **kwargs: print("clicky", args, kwargs) # Grid g = mcrfpy.Grid(10, 10, texture, 512+25, 384+19, 462, 346) @@ -54,6 +55,43 @@ g.zoom = 2.0 [ui.append(d) for d in (f, c, s, g)] +# Entity +e = mcrfpy.Entity(5, 5, mcrfpy.default_texture, 86) +e.pos = e.draw_pos # TODO - sync draw/collision positions on init +g.entities.append(e) +import random +def wander(*args, **kwargs): + p = e.pos + new_p = (p[0] + random.randint(-1, 1), p[1] + random.randint(-1, 1)) + if g.grid_size[0] >= new_p[0] >= 0 and g.grid_size[1] >= new_p[1] >= 0: + e.pos = new_p + #print(e.pos) + +mcrfpy.setTimer("wander", wander, 400) + +last_anim = None +def anim(t, *args, **kwargs): + global last_anim + if last_anim is None: + last_anim = t + return + duration = t - last_anim + + entity_speed = 1 / 250 # 250 milliseconds to move one square + if e.pos == e.draw_pos: + return + tx, ty = e.pos #"target" position - entity is already occupying that spot, animate them moving there. + dx, dy = e.draw_pos #"draw" position + newx = tx if (abs(dx - tx) < entity_speed * duration) else entity_speed * duration + if tx < dx: newx *= -1 + newy = ty if (abs(dy - ty) < entity_speed * duration) else entity_speed * duration + if ty < dy: newx *= -1 + + print(f"({dx}, {dy}) -> ({tx}, {ty}) = ({newx}, {newy}) ; @{entity_speed} * {duration} = {entity_speed * duration}") + e.draw_pos = (newx, newy) + +mcrfpy.setTimer("anim", anim, 67) + print("built!") # tests