1

my problem is that i don't have an idea on how to properly initialize an array containing blocks to drawn on a small matrix display. Initializing the first object works sometimes (block) but going through the for-loop to initialize remaining objects doesn't seem to do anything. I would be very glad for any help!

Structs:

#define MAX_POINTS 50
#define ARRAYSIZE 2

typedef enum {false, true} bool;

typedef struct tpoint {
uint8_t x;
uint8_t y;
} POINT;

typedef struct tGeometery {
int numpoints;
int sizex;
int sizey;
POINT px[ MAX_POINTS ];
} GEOMETRY, *PGEOMETRY;

typedef struct tObj {
    PGEOMETRY geo;
    int dirx,diry;
    int posx,posy;
    void (* draw_object ) (struct tObj *, bool draw);
    void (* move_object ) (struct tObj *);
    void (* set_object_speed ) (struct tObj *, int, int);
} OBJECT, *POBJECT; 

"Objects":

GEOMETRY ball_geometry = {
    12,     //Numpoints
    4,4,    //size X,Y
    {
              {1,0},{2,0},
        {0,1},{1,1},{2,1},{3,1},
        {0,2},{1,2},{2,2},{3,2},
              {1,3},{2,3}
    }
};

OBJECT ball = {
    &ball_geometry,
    0,0,    //Direction
    10,1,   //Start position
    draw_object,
    move_object,
    set_object_speed
};

GEOMETRY slab_geometry = {
    30,     //Numpoints
    10,3,   //Size X,Y
    {
        {0,0},{1,0},{2,0},{3,0},{4,0},{5,0},{6,0},{7,0},{8,0},{9,0},
        {0,1},{1,1},{2,1},{3,1},{4,1},{5,1},{6,1},{7,1},{8,1},{9,1},
        {0,2},{1,2},{2,2},{3,2},{4,2},{5,2},{6,2},{7,2},{8,2},{9,2}
    }
};

OBJECT slab = {
    &slab_geometry,
    0,0,    //Direction
    59,61,  //Start position (128/2 - 5)
    draw_object,
    move_object,
    set_object_speed
};

GEOMETRY block_geometry = {
    4,      //Numpoints
    2,2,    //Size X,Y
    {
        {0,0},{1,0},
        {1,0},{1,1}
    }
};

OBJECT block = {
    &block_geometry,
    0,0,    //Direction
    0,0,    //Start position
    draw_object,
    move_object,
    set_object_speed
};

Main:

void main(void) {
graphic_init();
keypad_init();

POBJECT bouncer = &ball;
POBJECT paddle = &slab;
POBJECT targetArray[ARRAYSIZE];
targetArray[0] = █

for (int i = 1; i < ARRAYSIZE; i++) {
    targetArray[i] = &block;
    targetArray[i]->posx = targetArray[i-1]->posx+3;
}

bouncer->set_object_speed(bouncer,4,1);
paddle->draw_object(paddle,true);
for (int i = 0; i < ARRAYSIZE; i++) {
    targetArray[i]->draw_object(targetArray[i],true);
}

while(1) {
    bouncer->move_object(bouncer);
}

}

2
  • 2
    "typedef enum {false, true} bool;" Why? C has supported real bools since 1999. Just do #include <stdbool.h>. Commented Jul 12, 2020 at 16:26
  • 2
    void main(void) This is unnecessarily nonportable. Use int main(void) instead. See What should main() return in C and C++? for more details. (And again, since C99, you've been allowed to omit return 0; from main even though it returns an int.) Commented Jul 12, 2020 at 16:29

1 Answer 1

1

Doing

POBJECT targetArray[ARRAYSIZE];
targetArray[0] = &block;

for (int i = 1; i < ARRAYSIZE; i++) {
  targetArray[i] = &block;
  targetArray[i]->posx = targetArray[i-1]->posx+3;
}

all the elements of targetArray are the same ( e.g. block ), this not what you want because to do

targetArray[i]->posx = targetArray[i-1]->posx+3;

does in fact the same as :

 targetArray[0]->posx = targetArray[0]->posx+3;

which does finally :

 block.posx = block.posx+3;

and

for (int i = 0; i < ARRAYSIZE; i++) {
  targetArray[i]->draw_object(targetArray[i],true);
}

does the same as :

 for (int i = 0; i < ARRAYSIZE; i++) {
   targetArray[0]->draw_object(targetArray[0],true);
 }

which does finally :

 for (int i = 0; i < ARRAYSIZE; i++) {
   block.draw_object(&block,true);
 }

Why are you doing

POBJECT targetArray[ARRAYSIZE];

rather than

OBJECT targetArray[ARRAYSIZE];

and in tObj

PGEOMETRY geo;

rather than

GEOMETRY geo;

?

Using POBJECT and PGEOMETRY you need a new element for each entry of targetArray and for each field geo, like

targetArray[0] = malloc(sizeof(*(targetArray[0])));
*(targetArray[0]) = block;
targetArray[0]->geo = malloc(sizeof(*(targetArray[0]->geo)));
*(targetArray[0]->geo) = *(block.geo);
for (int i = 1; i < ARRAYSIZE; i++) {
  targetArray[i] = malloc(sizeof(*(targetArray[i])));
  *(targetArray[i]) = block;
  targetArray[i]->geo = malloc(sizeof(*(targetArray[i]->geo)));
  *(targetArray[i]->geo) = *(block.geo);
  targetArray[i]->posx = targetArray[i-1]->posx+3;
}

But using OBJECT and GEOMETRY :

targetArray[0] = block;
for (int i = 1; i < ARRAYSIZE; i++) {
  targetArray[i] = block;
  targetArray[i].posx = targetArray[i-1].posx+3;
}

It is a bad idea to hide a pointer through a typedef, I encourage you to never do that to let the * visible.

I do not also understand why you do

POBJECT bouncer = &ball;
POBJECT paddle = &slab;

rather than to use ball and slab in main

Also main return an int, not void

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.