我的print_random_sprites函数出了什么问题?

时间:2021-12-22 03:58:28

I'm writing some code in C that randomly displays sprites on an LCD screen on a microprocessor. Currently when I run this code it produces 8 lines running from the top to bottom. So it's printing something in random order but not the sprite. Why is this? Could anyone help me? (NOTE: rand is seeded in a separate function which works fine, the problem is just within this code.)

我在C中编写一些代码,在微处理器的LCD屏幕上随机显示精灵。目前,当我运行此代码时,它会生成从上到下运行的8行。所以它是以随机顺序打印的东西,而不是精灵。为什么是这样?谁能帮助我? (注意:rand是在一个单独的函数中播种,工作正常,问题就在这段代码中。)

void zombies() {

    Sprite zombie_sprite;
    Sprite * zombie_sprite_pointer = &zombie_sprite;
    byte zombie_bitmap [] = {
    BYTE( 11100000 ),
    BYTE( 01000000 ),
    BYTE( 11100000 )
};

    for (int i = 0; i < 8; i++) {
        Sprite * zombie_sprites = &zombie_sprites[i];
        init_sprite(zombie_sprites, rand()%76, rand()%42, 3, 3, zombie_bitmap);
        }
    create_zombies();       
}

void create_zombies(Sprite * zombie_sprites) {
    while(1) {
    clear();
    draw_sprite( &zombie_sprites );
    refresh();
    }
    return 0;
}

1 个解决方案

#1


The main problem is that Sprite zombie_sprite is only one object. Make this an array of objects and you can start looking at other problems. Next there is a fair bit of confusion over pointers to the Sprite objects. To simplify things a bit we can tweak the variables in the zombies function, along with some 'tidying up' for best practices.

主要问题是Sprite zombie_sprite只是一个对象。将它作为一个对象数组,您可以开始查看其他问题。接下来,对Sprite对象的指针有一些混乱。为了简化一些事情,我们可以调整僵尸函数中的变量,以及一些“整理”最佳实践。

// Start by using a compile-time constant to define the number of zombies.
// This could be changed to a vriable in the, once the simple case is working.
#define NUMBER_OF_ZOMBIES 8

void zombies()
{
    // Eight zombies are required, so define an array of eight sprites.
    Sprite zombie_sprites[NUMBER_OF_ZOMBIES];
    byte zombie_bitmap [] = 
    {
        BYTE( 11100000 ),
        BYTE( 01000000 ),
        BYTE( 11100000 )
    };

// Continued below...

This makes the rest of the function to initialise the sprites easier. This time, it is possible to get the pointer to the ith element in the array. Also, you will see that the create_zombies function requires an argument: the address of a Sprite object, so pass it the address of the first sprite in the same array that has just been initialised.

这使得函数的其余部分更容易初始化精灵。这次,可以获得指向数组中第i个元素的指针。此外,您将看到create_zombies函数需要一个参数:Sprite对象的地址,因此将刚刚初始化的同一个数组中的第一个sprite的地址传递给它。

Again, with a bit of housekeeping, the rest of the function would look like this:

再次,通过一些内务处理,函数的其余部分将如下所示:

    // ...continued from above

    for (int i = 0; i < NUMBER_OF_ZOMBIES; i++)
    {
        // Initialise the ith sprite using the address of its element
        // in the zombie_sprites array.
        init_sprite(&zombie_sprites[i], rand()%76, rand()%42,
                    3, 3, zombie_bitmap);
    }

    // Animate the zombies in the array.
    create_zombies(&zombie_sprites[0]);       
}

Finally, the create_zombies function itself needs a minor change to loop through all of the sprites in the array passed as its parameter. Also, being of type void it does not have a return statement.

最后,create_zombies函数本身需要一个小的改动来循环遍历作为参数传递的数组中的所有sprite。此外,类型为void,它没有return语句。

void create_zombies(Sprite * zombie_sprites)
{
    while(1)
    {
        clear();

        // loop round drawing all of the sprites.
        for(int zombie_index = 0; zombie_index < NUMBER_OF_ZOMBIES; zombie_index++)
        {
            draw_sprite( &zombie_sprites[zombie_index] );
        }

        refresh();
    }
}

Future enhancements might include:

未来的改进可能包括:

  • Changing NUMBER_OF_ZOMBIES to be a variable.
  • 将NUMBER_OF_ZOMBIES更改为变量。

  • Replacing the static array with a dynamically allocated array using malloc and free.
  • 使用malloc和free替换动态分配的数组的静态数组。

  • Replacing the array with a more complex abstract data type such as a list or doubly linked list, so that zombies can be added or removed at run-time.
  • 用更复杂的抽象数据类型(如列表或双向链表)替换数组,以便在运行时添加或删除僵尸。

  • Renaming the functions and restructuring where each gets called.
  • 重命名函数并重新调整每个函数的调用。

#1


The main problem is that Sprite zombie_sprite is only one object. Make this an array of objects and you can start looking at other problems. Next there is a fair bit of confusion over pointers to the Sprite objects. To simplify things a bit we can tweak the variables in the zombies function, along with some 'tidying up' for best practices.

主要问题是Sprite zombie_sprite只是一个对象。将它作为一个对象数组,您可以开始查看其他问题。接下来,对Sprite对象的指针有一些混乱。为了简化一些事情,我们可以调整僵尸函数中的变量,以及一些“整理”最佳实践。

// Start by using a compile-time constant to define the number of zombies.
// This could be changed to a vriable in the, once the simple case is working.
#define NUMBER_OF_ZOMBIES 8

void zombies()
{
    // Eight zombies are required, so define an array of eight sprites.
    Sprite zombie_sprites[NUMBER_OF_ZOMBIES];
    byte zombie_bitmap [] = 
    {
        BYTE( 11100000 ),
        BYTE( 01000000 ),
        BYTE( 11100000 )
    };

// Continued below...

This makes the rest of the function to initialise the sprites easier. This time, it is possible to get the pointer to the ith element in the array. Also, you will see that the create_zombies function requires an argument: the address of a Sprite object, so pass it the address of the first sprite in the same array that has just been initialised.

这使得函数的其余部分更容易初始化精灵。这次,可以获得指向数组中第i个元素的指针。此外,您将看到create_zombies函数需要一个参数:Sprite对象的地址,因此将刚刚初始化的同一个数组中的第一个sprite的地址传递给它。

Again, with a bit of housekeeping, the rest of the function would look like this:

再次,通过一些内务处理,函数的其余部分将如下所示:

    // ...continued from above

    for (int i = 0; i < NUMBER_OF_ZOMBIES; i++)
    {
        // Initialise the ith sprite using the address of its element
        // in the zombie_sprites array.
        init_sprite(&zombie_sprites[i], rand()%76, rand()%42,
                    3, 3, zombie_bitmap);
    }

    // Animate the zombies in the array.
    create_zombies(&zombie_sprites[0]);       
}

Finally, the create_zombies function itself needs a minor change to loop through all of the sprites in the array passed as its parameter. Also, being of type void it does not have a return statement.

最后,create_zombies函数本身需要一个小的改动来循环遍历作为参数传递的数组中的所有sprite。此外,类型为void,它没有return语句。

void create_zombies(Sprite * zombie_sprites)
{
    while(1)
    {
        clear();

        // loop round drawing all of the sprites.
        for(int zombie_index = 0; zombie_index < NUMBER_OF_ZOMBIES; zombie_index++)
        {
            draw_sprite( &zombie_sprites[zombie_index] );
        }

        refresh();
    }
}

Future enhancements might include:

未来的改进可能包括:

  • Changing NUMBER_OF_ZOMBIES to be a variable.
  • 将NUMBER_OF_ZOMBIES更改为变量。

  • Replacing the static array with a dynamically allocated array using malloc and free.
  • 使用malloc和free替换动态分配的数组的静态数组。

  • Replacing the array with a more complex abstract data type such as a list or doubly linked list, so that zombies can be added or removed at run-time.
  • 用更复杂的抽象数据类型(如列表或双向链表)替换数组,以便在运行时添加或删除僵尸。

  • Renaming the functions and restructuring where each gets called.
  • 重命名函数并重新调整每个函数的调用。