Nội dung bài viết
Đăng ký học lập trình C++
Tại STDIO bạn được dạy nền tảng lập trình tốt nhất.
Đăng ký học
Â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.

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).

ss_1

Sau khi download về và giải nén ra chúng ta được hai thư mục là includelib:

ss_2

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à includelib 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

ss_3

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

Ở mục Linker, chọn Input và mở hộp thoại Additional Dependencies thêm vào SDL2_mixer.lib:

ss_5

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:

#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:

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 Sound EffectMix_MusicMix_Chunk:

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:

//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

#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;
}

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:

ss_6

Download demo

Stdio_SDL_PlayAudio_VS2013.zip

THẢO LUẬN