Âm thanh là 1 trong những thành phần quan trọng và không thể thiếu trong game, làm cho game sinh động và hấp dẫn hơn.
Cài đặt thư viện SDL_mixer
Để download thư viện tại đây, tại mục Development Libraries, download file SDL2_mixer-devel-2.0.0-VC.zip (cho môi trường Windows).
![ss_1](https://resources.stdio.vn/content/article/5ef62d8e5ef9e26f89a5c783/resources/res-1601139120-1601139120471.png)
Sau khi download về và giải nén ra, được 2 thư mục là include và lib:
![ss_2](https://resources.stdio.vn/content/article/5ef62d8e5ef9e26f89a5c783/resources/res-1601139134-1601139134279.png)
Tiếp tục sử dụng Project ở bài viết Khởi Tạo Môi Trường Lập Trình Game Sử Dụng Thư Viện SDL (Simple DirectMedia Layer), tích hợp thư viện SDL_mixer
vào project tượng tự như tích hợp thư viện SDL. Tạo thư mục SDL_Mix
trong thư mục Lib và copy 2 thư mục là include và lib vừa giải nén ở trên vào thư mục vừa tạo.
Copy tất cả các file .dll trong thư mục SDL_Mix/lib/x86 vào thư mục chứa file thực thi (.exe) là thư mục Output.
Mở project với Visual Studio, nhấn chuột phải (Right click) vào project để mở hộp thoại Properties. Chọn C/C++ > General và mở hộp thoại Additional Include Directories để thêm đường dẫn tới thư mục chứa file header của bộ thư viện SDL_mixer
.
![ss_3](https://resources.stdio.vn/content/article/5ef62d8e5ef9e26f89a5c783/resources/res-1601139148-1601139148883.png)
Tương tự, chọn Linker/General mở hộp thoại Additional Library Directories để thêm đường dẫn tới các file thư viện (.lib, .dll) của SDL_mixer nằm trong thư mục lib:
![ss_4](https://resources.stdio.vn/content/article/5ef62d8e5ef9e26f89a5c783/resources/res-1601139160-1601139160907.png)
Ở mục Linker, chọn Input và mở hộp thoại Additional Dependencies thêm vào SDL2_mixer.lib:
![ss_5](https://resources.stdio.vn/content/article/5ef62d8e5ef9e26f89a5c783/resources/res-1601139171-1601139171058.png)
Play Music và Sound Effects
Cần thêm chỉ thị #include "SDL_mixer.h"
vào đầu những file muốn sử dụng thư viện này:
#include "SDL_mixer.h"
Trước khi sử dụng các function mà SDL_mixer
cung cấp thì phải khởi tạo:
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) == -1) { printf("%s", Mix_GetError()); }
SDL_mixer
có hỗ trợ cho 2 cấu trúc để quản lý Music và Sound Effect là Mix_Music
và Mix_Chunk
:
Mix_Chunk* chunk = NULL; Mix_Music* music = NULL;
Load Music và Sound Effects
Với 2 cấu trúc trên thì có những hàm load tương ứng là Mix_LoadWAV
và Mix_LoadMUS
:
//Load Sound Effect chunk = Mix_LoadWAV("sound_effects.wav"); if (chunk == NULL) { printf("%s", Mix_GetError()); return -1; } //Load Music music = Mix_LoadMUS("background_music.mp3"); if (music == NULL) { printf("%s", Mix_GetError()); }
Play, Pause, Resume, Stop
Với Music và Sound Effects thì SDL_mixer
có cung cấp các hàm để play, pause, resume, stop cũng như các hàm kiểm tra trạng thái.
Music
Các hàm hỗ trợ play Music:
int Mix_PlayMusic(Mix_Music *music, int loops)
: Phát music được load bởi hàm Mix_LoadMUS
, vói tham số truyền vào là con trỏ tới đối tượng Mix_Music
, và số lần lặp, nếu truyền vào -1 sẽ lặp vô tận.
void Mix_PauseMusic()
: Tạm dừng phát music.void Mix_ResumeMusic()
: Tiếp tục phát lại music sau khi pause.int Mix_HaltMusic()
: Dừng phát music.
Và các hàm kiểu tra trạng thái:
int Mix_PlayingMusic()
: Trả về 1 nếu music đang phát, ngược lại trả về 0.int Mix_PausedMusic()
: Trả về 1 nếu music tạm dừng, ngược lại trả về 0.
Sound Effects
Các hàm hỗ trợ play Sound Effect:
int Mix_PlayChannel (int channel, Mix_Chunk *chunk, int loops)
: Play Sound Effect với tham số thứ nhất là channel muốn phát, thông thường là -1, tham số thứ 2 là con trỏ tới đối tượng Mix_Chunk, và cuối cùng là số lần lặp, nếu truyền vào -1 sẽ lặp vô tận.void Mix_Pause(int channel)
: Tạm dừng Sound Effects, đối số channel thông thường là -1.void Mix_Resume(int channel)
: Tiếp tục phát Sound Effects sau khi Pause, đối số channel thông thường truyền vào -1.int Mix_HaltChannel(int channel)
: Dừng phát Sound Effects, đối số channel thông thường truyền vào -1.
Các hàm kiểm tra trạng thái cũng tương tự như đối với Music là các hàm Mix_Play
, Mix_Paused
.
Ví dụ demo
#include <stdio.h> #include <SDL.h> #include "SDL_mixer.h" #undef main int main() { SDL_Window* window = NULL; SDL_Renderer* renderer = NULL; SDL_Surface* tempSurface = NULL; SDL_Texture* texture = NULL; SDL_Event mainEvent; bool isRunning = true; //Sound Effect Mix_Chunk* chunk = NULL; //Background Music Mix_Music* music = NULL; //initializes the subsystems if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { printf("Unable to initialize SDL %s\n", SDL_GetError()); return -1; } //Create window window = SDL_CreateWindow("Stdio.vn - SDL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 640, SDL_WINDOW_SHOWN); if (window == NULL) { printf("Could not create window %s", SDL_GetError()); return -1; } //create a renderer renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if (renderer == NULL) { printf("Could not create render %s", SDL_GetError()); return -1; } //create a tempSurface tempSurface = SDL_LoadBMP("background_stdio.bmp"); //create a texutre from surface texture = SDL_CreateTextureFromSurface(renderer, tempSurface); //free surface SDL_FreeSurface(tempSurface); //Init SDL_mixer if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) == -1) { printf("%s", Mix_GetError()); return -1; } //Load Sound Effect chunk = Mix_LoadWAV("sound_effects.wav"); if (chunk == NULL) { printf("%s", Mix_GetError()); return -1; } //Load Music music = Mix_LoadMUS("background_music.mp3"); if (music == NULL) { printf("%s", Mix_GetError()); } //set background color SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); //main loop while (isRunning) { // clear the window to black SDL_RenderClear(renderer); //main event while (SDL_PollEvent(&mainEvent)) { switch (mainEvent.type) { //User - requested quit case SDL_QUIT: { isRunning = false; break; } case SDL_KEYDOWN: { if (mainEvent.key.keysym.sym == SDLK_RETURN) { if (!Mix_PlayingMusic()) Mix_PlayMusic(music, 0); } if (mainEvent.key.keysym.sym == SDLK_SPACE) { if (!Mix_Playing(-1)) Mix_PlayChannel(-1, chunk, 0); } break; } default: { break; } } } // copy a portion of the texture to the current rendering target. SDL_RenderCopy(renderer, texture, NULL, NULL); //draw to the screen SDL_RenderPresent(renderer); } Mix_CloseAudio(); //Destroy a window. SDL_DestroyWindow(window); //Destroy a renderer SDL_DestroyRenderer(renderer); //cleans up all initialized subsystems SDL_Quit(); return 0; }
Nhấn phím Enter play background music và phím Space để play sound effects:
![ss_6](https://resources.stdio.vn/content/article/5ef62d8e5ef9e26f89a5c783/resources/res-1601139197-1601139197427.png)