0

我一直在做这个平台化的 Allegro 5 测试,稍后我将把它变成一个游戏。到目前为止,Allegro 的每个附加组件都运行良好,当时我尝试使用音频播放我在 Audacity 中制作的 .ogg 文件。我正在使用 MinGW 版本,并将所有内容与 Code::Blocks 静态链接。它只有一个文件 main.cpp:

#include <stdio.h>                              // Good library to always have on hand
#include <math.h>                               // C++ math library
#include <allegro5/allegro.h>                   // Allegro base library
#include <allegro5/allegro_audio.h>             // Allegro audio library
#include <allegro5/allegro_acodec.h>            // Library used to load different audio codecs
#include <allegro5/allegro_image.h>             // You MUST load the image library for anything bitmap-image related
#include <allegro5/allegro_primitives.h>        // Allegro primitives addon, for drawing shapes n' stuff
#include <allegro5/allegro_native_dialog.h>     // You load this for the native message box feature (see below)

enum MYKEYS {
   KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT
};

int main() {
   ALLEGRO_DISPLAY *display = NULL;
   ALLEGRO_DISPLAY_MODE disp_info;
   ALLEGRO_SAMPLE *sound_effect = NULL;
   ALLEGRO_BITMAP *manLeft = NULL; // Maximum texture size is a minimum of 1024 * 1024
   ALLEGRO_EVENT_QUEUE *event_queue = NULL;
   ALLEGRO_TIMER *fpsTimer = NULL;

   const float FPS = 60; // This global variable "FPS" is how many times per second the screen will redraw
   const char window_title[] = "Neil's Box Game"; // This is the window's title
   int window_width = 800; // This is the display's in-window width
   int window_height = 600; // This is the display's in-window height
   int display_width = window_width;
   int display_height = window_height;

   bool redraw = true;
   bool doexit = false;
   bool manFlipped = false;
   bool prevUp = false;
   bool isFullscreen = false;

   int manWidth = 19; // The "man" sprite's pixel width
   int manHeight = 48; // The "man" sprite's pixel height
   int manX = (display_width / 2) - (manWidth / 2); // This is the man's drawn x-value
   int manY = display_height - manHeight; // Same for y

   float manXVel = 0.0; // For our "platformer", this is the player character's x-axis velocity
   float manXVelCap = 200.0 / FPS; // This "caps" the x-velocity to how much we want our character to move, 200 is how much in 1 second
   float manYVel = 0.0; // Etc. for y
   float manYVelCap = 400.0 / FPS; // Etc.

   bool key[4] = { false, false, false, false };

   if(!al_init()) { // Initialise Allegro, test it's working
      fprintf(stderr, "ERROR: Failed to initialize Allegro library!\n");
      return -1;
   }

   if(!al_install_audio()){
      fprintf(stderr, "ERROR: Failed to initialize Allegro audio add-on!\n");
      return -1;
   }

   if(!al_init_acodec_addon()){
      fprintf(stderr, "ERROR: Failed to initialize Allegro audio codecs!\n");
      return -1;
   }

   if(!al_install_keyboard()) { // Initialises the keyboard control, test if it's working
      fprintf(stderr, "ERROR: Failed to initialize the keyboard!\n");
      return -1;
   }

   if(!al_init_image_addon()) { // Initialise Allegro's image addon, make sure it works
      fprintf(stderr, "ERROR: Failed to initialize Allegro's image add-on!\n");
      return -1;
   }

   if (!al_init_primitives_addon()) { // Initialise the Allegro primitives addon
      fprintf(stderr, "ERROR: Failed to initialize Allegro's primitives add-on!\n");
      return -1;
   }

   // "al_reserve_samples" sets how many audio samples you can load

   if (!al_reserve_samples(1)){
      fprintf(stderr, "ERROR: Failed to reserve Allegro audio samples!\n");
      return -1;
   }

   fpsTimer = al_create_timer(1.0 / FPS); // Create our FPS timer, and make sure it's working
   if(!fpsTimer) {
      fprintf(stderr, "ERROR: Failed to create timer!\n");
      return -1;
   }

   sound_effect = al_load_sample("pitchshift.ogg");

   if (!sound_effect){
      fprintf(stderr, "ERROR: Audio sample \"pitchshift.ogg\" not loaded!\n" );
      return -1;
   }

   al_get_display_mode(al_get_num_display_modes() - 1, &disp_info);

   display = al_create_display(display_width, display_height);

   if(!display) {
      al_show_native_message_box(display, "Error", "Error", "Failed to create display!", NULL, ALLEGRO_MESSAGEBOX_ERROR);
      return -1;
   }

   // Set it to the efficient blender mode

   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);

   // This loads the event queue, and verifies it's working

   event_queue = al_create_event_queue();
   if(!event_queue) {
      al_show_native_message_box(display, "Error", "Error", "Failed to create event queue!", NULL, ALLEGRO_MESSAGEBOX_ERROR);
      al_destroy_display(display); // If failed, always destroy EVERYTHING that has been allegro-created, like displays and timers
      al_destroy_timer(fpsTimer);
      return -1;
   }

   // Always load images AFTER the creation of the display

   manLeft = al_load_bitmap("Left.png"); // Load our man png

   if(!manLeft) { // Check to make sure if it loaded right, if not say "!@#$ THIS" and gtfo
      al_show_native_message_box(display, "Error", "Error", "Failed to load image!", NULL, ALLEGRO_MESSAGEBOX_ERROR);
      al_destroy_display(display);
      al_destroy_timer(fpsTimer);
      return 0;
   }

   al_set_window_title(display, window_title); // Sets the window's caption title

   al_register_event_source(event_queue, al_get_display_event_source(display)); // This attaches the event_queue to the "display" display iten

   al_register_event_source(event_queue, al_get_timer_event_source(fpsTimer)); // Bind the fpsTimer object to the event handler

   al_register_event_source(event_queue, al_get_keyboard_event_source()); // Bind the keyboard to the Allegro event handler

   al_clear_to_color(al_map_rgb(255,255,255)); // Setting the mood...

   al_draw_bitmap(manLeft, manX, manY, 0); // Draw the "left" sprite, (imagename, x, y, FLAGS) FLAGS is either 0 for nothing, "ALLEGRO_FLIP_HORIZONTAL" or "ALLEGRO_FLIP_VERTICAL", purdy self explanatory

   al_start_timer(fpsTimer); // After we've refreshed the display, begin the FPS timer

   while (!doexit) {
       ALLEGRO_EVENT ev;
       al_wait_for_event(event_queue, &ev);

       switch(ev.type) {
            case ALLEGRO_EVENT_DISPLAY_CLOSE:
                doexit = true;
                break;

            case ALLEGRO_EVENT_KEY_DOWN:
                switch(ev.keyboard.keycode) {
                    case ALLEGRO_KEY_UP:
                        key[KEY_UP] = true;
                        break;

                    case ALLEGRO_KEY_DOWN:
                        key[KEY_DOWN] = true;
                        break;

                    case ALLEGRO_KEY_LEFT:
                        key[KEY_LEFT] = true;
                        break;

                    case ALLEGRO_KEY_RIGHT:
                        key[KEY_RIGHT] = true;
                        break;

                    case ALLEGRO_KEY_ESCAPE:
                        doexit = true;

                    case ALLEGRO_KEY_F11:
                        if (isFullscreen) {
                            manX *= ((float)window_width / (float)disp_info.width);
                            manY *= ((float)window_height / (float)disp_info.height);
                            al_set_new_display_flags(ALLEGRO_WINDOWED);
                            al_destroy_display(display);
                            display = al_create_display(window_width, window_height);
                            al_set_window_title(display, window_title);
                            al_register_event_source(event_queue, al_get_display_event_source(display)); // After re-creating the display, we need to again bind it to the event queue
                            display_width = window_width;
                            display_height = window_height;
                            isFullscreen = false;
                        } else {
                            manX *= ((float)disp_info.width / (float)window_width);
                            manY *= ((float)disp_info.height / (float)window_height);
                            al_set_new_display_flags(ALLEGRO_FULLSCREEN);
                            al_destroy_display(display);
                            display = al_create_display(disp_info.width, disp_info.height);
                            al_set_window_title(display, window_title);
                            al_register_event_source(event_queue, al_get_display_event_source(display)); // After re-creating the display, we need to again bind it to the event queue
                            display_width = disp_info.width;
                            display_height = disp_info.height;
                            isFullscreen = true;
                        }
                }
                break;

            case ALLEGRO_EVENT_KEY_UP:
                switch(ev.keyboard.keycode) {
                case ALLEGRO_KEY_UP:
                    key[KEY_UP] = false;
                    break;

                case ALLEGRO_KEY_DOWN:
                    key[KEY_DOWN] = false;
                    break;

                case ALLEGRO_KEY_LEFT:
                    key[KEY_LEFT] = false;
                    break;

                case ALLEGRO_KEY_RIGHT:
                    key[KEY_RIGHT] = false;
                    break;

                case ALLEGRO_KEY_ESCAPE:
                    doexit = true;
                    break;
                }
                break;

                case ALLEGRO_EVENT_TIMER:
                    if(key[KEY_UP] && !prevUp) {
                        if (manY >= display_height - manHeight) {
                            manYVel = -10.0;
                            al_play_sample(sound_effect, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL);
                        }
                    }
                    if(key[KEY_LEFT]) {
                        manXVel -= 0.5;
                        manFlipped = false; // Change the sprite
                    }
                    if(key[KEY_RIGHT]) {
                        manXVel += 0.5;
                        manFlipped = true; // Change the sprite
                    }

                    // Cap the velocity to make sure he doesn't get moving TOO fast...

                    if (manXVel > manXVelCap) {
                        manXVel = manXVelCap;
                    }
                    if (manXVel < -manXVelCap) {
                        manXVel = -manXVelCap;
                    }
                    if (manYVel > manYVelCap) {
                        manYVel = manYVelCap;
                    }
                    if (manYVel < -manYVelCap) {
                        manYVel = -manYVelCap;
                    }

                    if (manXVel * FPS > -5.0 && manXVel * FPS < 5.0) {
                        manXVel = 0;
                    }

                    // Add some horizontal ground friction

                    if ((!key[KEY_LEFT] || !key[KEY_RIGHT]) && manY >= display_height - manHeight) { // Make sure that he's "sliding" and he's touching the ground
                        manXVel *= pow(10, log (0.4) / FPS); // The 0.4 is how much x friction we want every second
                    }

                    // Adding gravity

                    manYVel += 0.15;

                    redraw = true;
                    prevUp = key[KEY_UP];
                    break;

                default:
                    break;
       }
        if(redraw && al_is_event_queue_empty(event_queue)) {
            if (manX > display_width - manWidth) {
                manX = display_width - manWidth;
            }
            if (manX < 0) {
                manX = 0;
            }
            if (manY > display_height - manHeight) {
                manY = display_height - manHeight;
            }
            if (manY < 0) {
                manY = 0;
            }

            al_clear_to_color(al_map_rgb(255,255,255)); // Clear screen
            if (manFlipped) {
                al_draw_bitmap(manLeft, (int)manX, (int)manY, ALLEGRO_FLIP_HORIZONTAL); // Draw our "man sprite"
            } else {
                al_draw_bitmap(manLeft, (int)manX, (int)manY, 0); // Draw our "man sprite"
            }
            al_flip_display(); // Refresh screen

            // Put the x and y refreshes AFTER the screen update to preserve collision checking is working

            redraw = false;

            manX += manXVel; // Assign the respective velocities to their axes
            manY += manYVel; // Same for y
        }
   }

   //   ON CLOSURE OF THE PROGRAM, YOU MUST DESTROY EVERYTHING THAT IS ALLEGRO CREATED, IN THE FOLLOWING ORDER:
   //   - Bitmaps
   //   - Timers
   //   - Displays
   //   - Event queues

   al_destroy_bitmap(manLeft);          // Destroy the bimaps
   al_destroy_timer(fpsTimer);          // Destroy the timer
   al_destroy_display(display);         // Delete the display
   al_destroy_event_queue(event_queue); // You have to destroy an event queue after you've created it

   return 0;                            // nitey nite
}

当我尝试构建我的代码时,它给了我这个奇怪的错误序列,我在 Google 上没有找到任何解决方案:

||=== box - Allegro Visual Thingy, Default ===|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourcei'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetError'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetSourcei'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetError'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetSourcei'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alDeleteBuffers'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alDeleteSources'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetError'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourceStop'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetError'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alDeleteSources'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alDeleteBuffers'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGenSources'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetError'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGenBuffers'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetError'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourcef'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetError'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourcePlay'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetError'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alDeleteSources'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alDeleteSources'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alDeleteBuffers'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alDeleteSources'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGenSources'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetError'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGenBuffers'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetError'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alBufferData'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourcei'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourcei'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourcef'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetError'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alDeleteSources'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alDeleteSources'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alDeleteBuffers'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alDeleteSources'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourcei'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alBufferData'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourceQueueBuffers'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourcePlay'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetSourcei'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourceUnqueueBuffers'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alBufferData'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourceQueueBuffers'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetSourcei'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourcePlay'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alSourceStop'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alGetError'|
C:\Allegro\allegro-5.0.7-mingw-4.6.2\lib\liballegro_audio-5.0.7-static-mt.a(openal.o):openal.c|| undefined reference to `alcGetError'|
||More errors follow but not being shown.|
||Edit the max errors limit in compiler options...|
||=== Build finished: 50 errors, 0 warnings ===|

我将发布Code::Blocks 项目,以便您可以看到我正在链接的内容,但我只是不明白为什么音频库是唯一不起作用的东西!

感谢您的帮助,

-尼尔

4

1 回答 1

2

错误消息中非常清楚,您需要 LD_LIBRAY 中的 openal libray

这是OpenAL

于 2012-12-14T05:06:58.210 回答