tests/interactive-ascii: improve padshapes1.c
authorMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 13 Apr 2023 11:14:46 +0000 (11:14 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 13 Apr 2023 11:14:46 +0000 (11:14 +0000)
- Less erratic object movement
- Shapes x/y position now based around their center
- Shapes clipped when outside of the intended frame

tests/interactive-ascii/padshapes1.c

index e7892f2..c44ec75 100644 (file)
@@ -14,9 +14,6 @@
  * - If we wanted collision detection of a small projectile against a
  *   complex text shape, it would be possible to first check the rectangle,
  *   then if in, to check if it hits a non-space character in the pad.
- * - The drawing and move routines could ensure not to draw large shapes
- *   outside of the intended window.
- * - We may want shape positions to be based on the center of a shape.
  *
  * $ cc -Wall -O0 -g -o padshapes1 padshapes1.c -lcurses
  */
@@ -89,12 +86,14 @@ typedef struct aobject {
        int             t, x, y, col;
        char            c;
        int             s;
+       int             d;
 } aobject_t;
 
 
 int                    main(void);
 static void            cleanup(void);
 static void            shape_init(int);
+static inline int      int_min(int, int);
 static void            shape_draw(int, int, int);
 static void            anim_init(void);
 static void            anim_redraw(void);
@@ -108,7 +107,7 @@ static WINDOW               *w = NULL;
 static aobject_t       objects[NOBJECTS];
 static aobject_t       avatar = { AOT_AVATAR,
                            TERM_COLUMNS / 2, TERM_LINES / 2,
-                           0, '?', -1 };
+                           0, '?', -1, -1 };
 
 
 int
@@ -308,15 +307,29 @@ shape_init(int attr)
        }
 }
 
+static inline int
+int_min(int a, int b)
+{
+
+       return (a < b ? a : b);
+}
+
 static void
 shape_draw(int shape, int y, int x)
 {
-       int xs, ys;
+       int xs, ys, xo, yo;
        WINDOW *pad;
 
        pad = spads[shape];
+
        getmaxyx(pad, ys, xs);
-       (void)copywin(pad, w, 0, 0, y, x, y + ys - 1, x + xs - 1, TRUE);
+       xo = xs / 2;
+       yo = ys / 2;
+
+       (void)copywin(pad, w, 0, 0, y - yo, x - xo,
+           int_min(y + ys - 1, TERM_LINES - 1),
+           int_min(x + xs - 1, TERM_COLUMNS - 1),
+           TRUE);
 }
 
 static void
@@ -334,16 +347,19 @@ anim_init(void)
                        o->c = 'A' + i;
                        o->col = ++col % 7;
                        o->s = -1;
+                       o->d = random() % 4;
                } else if (i < 46) {
                        o->t = AOT_STAR;
                        o->c = '.';
                        o->col = 0;
                        o->s = -1;
+                       o->d = -1;
                } else {
                        o->t = AOT_SHAPE;
                        o->c = '\0';
                        o->col = -1;
                        o->s = random() % SHAPE_MAX;
+                       o->d = random() % 4;
                }
                o->x = random() % (TERM_COLUMNS - 1);
                o->y = random() % (TERM_LINES - 1);
@@ -383,7 +399,7 @@ anim_update(void)
 
        for (i = 0; i < NOBJECTS; i++) {
                aobject_t *o = &objects[i];
-               int x = o->x, y = o->y, d = random() % 4;
+               int x = o->x, y = o->y, d = random() % 16;
 
                if (o->t == AOT_STAR) {
                        if (x > 0)
@@ -391,7 +407,10 @@ anim_update(void)
                        else
                                x = TERM_COLUMNS - 1;
                } else {
-                       switch (d) {
+                       /* Change direction */
+                       if (d > -1 && d < 4)
+                               o->d = d;
+                       switch (o->d) {
                        case 0: /* Up */
                                if (y > 0)
                                        y--;