Giới thiệu
Âm thanh là một trong những thành phần không thể thiếu và nó có vai trò quan trọng trong game, làm cho game chúng ta sinh động và hấp dẫn hơn. Trong phạm vi bài viết này tôi sẽ hướng dẫn các bạn play Sound Effects cũng như Music sử dụng thư viện mở rộng của SDL có tên là SDL_mixer.
Tiền đề bài viết
Tiếp nối những bài viết hướng dẫn lập trình với framework SDL (Simple DirectMedia Layer).
Đối tượng hướng đến
Những lập trình viên đã có kiến thức vững chắc về ngôn ngữ lập trình C++, mong muốn xây dựng game cơ bản sử dụng framework SDL.
Cài đặt thư viện SDL_mixer
Để download thư viện này ta truy cập vào https://www.libsdl.org/projects/SDL_mixer/. Tại mục Development Libraries download file SDL2_mixer-devel-2.0.0-VC.zip (vì ở đây tôi đang sử dụng nền tảng Windows).
Sau khi download về và giải nén ra chúng ta được hai thư mục là include và lib:
Việc tích hợp thư viện SDL_mixer vào project tượng tự như tích hợp thư viện SDL. Các bạn có thể xem lại bài Khởi Tạo Môi Trường Lập Trình Game Sử Dụng Thư Viện SDL (Simple DirectMedia Layer) để biết rõ thêm.
Tiếp tục sử dụng Project ở bài viết trước, tôi tạo thư mục SDL_Mix trong thư mục Lib và copy hai thư mục là include và lib vừa giải nén ở trên vào thư mục vừa tạo này.
Và 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.
Ở project mở 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 thới thư mục chứa file header của bộ thư viện SDL_mixer là thư mục
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:
Ở mục Linker, chọn Input và mở hộp thoại Additional Dependencies thêm vào SDL2_mixer.lib:
Play Music và Sound Effects
Ta 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:
1 |
#include "SDL_mixer.h" |
trước khi sử dụng các function mà SDL_mixer cung cấp thì chúng ta phải khởi tạo:
1 2 3 4 |
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) == -1) { printf("%s", Mix_GetError()); } |
SDL_mixer có hổ trợ cho chúng hai cấu trúc để quản lý Music và Sound Effect là Mix_Music và Mix_Chunk:
1 2 |
Mix_Chunk* chunk = NULL; Mix_Music* music = NULL; |
Load Music và Sound Effects
Với hai cấu trúc trên thì có những hàm load tương ứng là Mix_LoadWAV và Mix_LoadMUS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//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 cho chúng ta 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 SoundEffect:
int Mix_PlayChannel (int channel, Mix_Chunk *chunk, int loops): Play SoundEffect với tham số thứ nhất là channel muốn phát, thông thường là -1, tham số thứ hai 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
#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("Eitguide.com - 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; } |
Dòng số 17 và 19: Khai báo hai đối tượng quản lý Music và Sound Effects là Mix_Music và Mix_Chunk.
Dòng số 52: Khởi tạo SDL_mixer.
Dòng số 59: Load Sound Effects.
Dòng số 67: Load Background Music.
Dòng số 95 và 96: Kiểm tra trạng thái và play Background Music.
Dòng số 101 và 102: Kiểm tra trạng thái và play Sound Effects.
Dòng 120: Giải phóng SDL_mixer .
Nhấn phím Enter play background music và phím Space để play sound effects:
Anh ơi cho em hỏi với ạ. dòng 45 có file đuôi .bmp dùng làm gì vậy ạ? Và nếu không viết dòng đấy có ảnh hưởng như thế nào hả anh?