#Piszemy gre w SFML’u – Lekcja 5

W tej lekcji zajmiemy się dosyć ważnym elementem każdej gry, czyli dodaniem muzyki i dźwięków.

!UWAGA! Kurs leży w kategorii ‚Obsolete’ co oznacza, że może być nieaktualny, zawierać błędy i nie polecam z niego korzystać. [INFO]

Kod z poprzedniej lekcji


Tak jak wspomniałem na początku, muzyka jest ważnym i nieodłącznym fragmentem gier, to ona decyduje o sposobie w jaki odbiera użytkownik to co chcemy mu przekazać. Muzyka potrafi zdecydować czy gracz będzie podchodził do naszej gry poważnie (będzie się wczuwał) czy też będzie traktował grę mniej poważnie, jest to dokładnie tak jak w filmach jeżeli oglądamy poważną scenę, lecz muzyka będzie np wesoła to widz nie będzie traktował tej sceny poważnie, ale jeśli będzie odpowiednio dobrana do tej sceny muzyka to wtedy widz bardziej się skupi. Podsumowując mój wywód muzyka buduje klimat gry i warto o tym pamiętać przy dobieraniu muzyki


Muzyka i dźwięki wypełniają pustkę w grze nadając jej nieraz tempo, przy wyborze muzyki trzeba nie tylko kierować się własnymi preferencjami, ale także charakterem gry. Przy szukaniu soundtracku do gry trzeba także zwracać uwagę na licencję na jakiej jest udostępniana, w przypadku darmowych gier nie ma wielkiego problemu zwykle wystarczy dodać gdzieś link do strony autora muzyki. Osobiście polecam mimo wszystko napisać do autora o zgodę użycia danej muzyki w projekcie.

Jednak skąd brać muzykę do gier? Polecam serwisy

Osobiście korzystam głównie z pierwszego i ostatniego linku.

Jak pewnie zauważysz większość utworów zajmuje więcej niż nasza gra co może być problemem jeśli chcemy aby nasza gra była jak najlżejsza. Jeżeli chcemy aby nasza gra (w znaczeniu wszystkie pliki gry) zajmowała jak najmniej miejsca to powinniśmy poszukać muzyki która jest „pętlą” loop, czyli mimo że dany utwór jest krótki to nie nudzi się szybko i mało zajmuje, przykładem może być ten utwór.


Na samym początku wybierzemy jakiś soundtrack, najlepiej pętlę, aby nie zajmowała zbyt dużo miejsca. Muzyka musi pasować do klimatu, czyli w jakiś sposób musi kojarzyć się nam z kosmosem, wybrałem parę utworów, nic nie stoi na przeszkodzie abyś wybrał w tej lekcji jakieś inne, ale zanim je „zobaczysz” to zastanówmy się jak ma to wyglądać. Chcemy aby można było dźwięki i muzykę włączać lub wyłączać, muzyka będzie inna dla menu i samej gry.

Tworzymy klasę Audio, będzie ona obsługiwała zarówno dźwięki, jak i soundtrack. Jeżeli przeglądałeś kod ze SQUARE to ten kod będzie analogiczny do tamtego z małą różnicą ale o tym za chwilę.

Oto jak wyglądają odpowiednio pliki Audio.h i Audio.cpp:

Skupmy się na zawartości pliku nagłówkowego i przeanalizujmy co mamy. Pierwszą ciekawą rzeczą jest konstruktor, który ma argument load_everything, jak łatwo można się domyślić oznacza on ładowanie zarówno muzyki, jak i soundtracku. Argument menu jest konsekwencją tego, że chcemy aby był inny soundtrack w menu i grze, dlatego nie ma sensu ładować całej muzyki, skoro skorzystamy na pewno tylko z jednej. Kod wygląda następująco:

Następnie mamy metodę loadMusic, która ma za zadanie wczytanie muzyki do naszej gry, zależnie od tego czy jesteśmy w menu czy nie. Należy pamiętać o respektowaniu licencji pod jaką mamy nasz utwór, my skorzystamy z muzyki freeware, czyli takiej jaka jest za darmo, ale nasza gra musi być za darmo, nie możemy czerpać z tego korzyści (pieniędzy) i należy umieścić gdzieś link do strony autora, czyli jakiś credits. Zależnie od licencji nie można też czasami w jakikolwiek sposób zmieniać danego utworu np go konwertować na inny format, my skorzystamy z SpaceExploration by Richard Wurth (w menu) oraz Boss Battle by skater007 lub 8 Bit Fighter by PhatBoiJ lub Techno Space by HelpThePoor. Specjalnie dałem tutaj ich tyle do wyboru, abyśmy mogli zauważyć jak mocno zależny jest charakter grania od muzyki. Należy pamiętać, że SFML nie wspiera formatu „.mp3”, dlatego należy przekonwertować muzykę np na „.ogg”.

Teraz odpowiemy sobie na pytanie czym jest nasz enum SoundType, jest to po prostu rodzaj dźwięku, który ma być odegrany w danym momencie, ale więcej o tym już za moment. Obiekt buffer ma za zadanie przetrzymywanie w pamięci danego dźwięku,  a sound może odtworzyć odpowiedni dźwięk (korzystamy z MenuSelect, MenuMouseOverElectronicBeep)

Kolejne metody, to po prostu użycie ich normalne użycie:

Za to teraz dopiero możemy zobaczyć do czego nam służy SoundType, jest to po prostu wygodniejsza forma odtworzenia dźwięku, po prostu w momencie gdy chcemy użyć dźwięku wpisujemy funkcję playSound oraz jako argument rodzaj pożądanego przez nas dźwięku:

Utworzymy jeszcze metodę, która będzie mogła wyciszyć naszą grę:

Teraz możemy zająć się włączeniem tego kodu do gry. W klasie Engine wpisujemy #include „Audio.h” i na chwilę przechodzimy do Game, gdzie tworzymy w pliku nagłówkowym obiekt Audio audio i dopisujemy odpowiednio linijki w metodach:

To tyle, jeżeli chodzi o klasę Game, przechodzimy do Engine, konstruktor i destruktor wygląda niemal identycznie, jedynie z tą różnicą, że w argumencie dla loadMusic podajemy false, reszte dopisujemy w odpowiednich miejscach:

Nie ma jeszcze dźwięku dla trafienia w asteroidę, ale to jest taka łatwa prac domowa dla ciebie 😉 Nie ma jeszcze ważnej rzeczy związanej z dźwiękami: nie można ich wyłączyć (jeżeli chcesz wiedzieć jak można zrobić bardziej zaawansowane sterowanie dźwiękiem polecam kod SQUARE).

My posłużymy się systemem gier bez kategorii opcje i zrobimy możliwość włączania/wyłączania dźwięków z poziomu głównego menu poprzez kliknięcie w odpowiedni napis. Rozwiązanie tego ma swoje plusy, ponieważ może się zdarzyć, że nie chcemy aby gracz zmieniał poziomu głośności dźwięków bo to mogłoby mu zepsuć rozgrywkę (np. w grze gdzie dźwięki mogą być wskazówką, a odpowiednio podgłośnione sprawiałyby że gra jest za łatwa).

Pracujemy na klasie Game, w menu() zmieniamy odpowiednio:

Wczytujemy tutaj z pliku ustawienie czy dźwięk ma być wyciszony, następnie sprawdzamy kliknięcia analogicznie do sprawdzenia czy wciśnięto opcję w menu, nic nowego tutaj się nie pojawia.

W destruktorze dopisujemy linie, które zapisują nasze ustawienie do pliku:

W konstruktorze Engine doszedł nam argument typu bool, oto jak wygląda po zmianach

Jak widać rzeczy przedstawione tutaj, nie wiele się różnią od rzeczy przedstawionych w przykładach na SFML, dlatego nie ma tutaj zbyt wiele wyjaśnień. Następna lekcja powinna byś dla ciebie ciekawsza, ponieważ w następnej lekcji dowiemy się jak urozmaicić naszą grę o specjalne efekty typu: przejścia, loading screeny, a także sprawimy że nasza gra nabierze nieco więcej sensu (obecnie mamy symulator strzelania do jednej asteroidy).

W razie pytań, problemów, ewentualnych błędów w kodzie zapraszam do komentowania. Zapraszam także do subskrypcji bloga przez email (ewentualnie na twitterze).

Kod źródłowy
>>Pobierz<< | >>GitHub<<

Dodatkowe materiały (muzyka, dźwięki)
>>Pobierz<<

Następna lekcja ->


  • Fen

    Witam
    Warto tutaj zmienić poniższą linijkę
    //runEngine if, dla klawisza Control
    audio.playSound(Audio::T_STRZAL);

    gdyż przy sprawdzeniu warunku wcisniecia klawisza oznacza, że nie patrząc na częstotliwość wystrzału dzwiek bedzie zawsze odtwarzany(przed stworzeniem, w trakcie , po stworzeniu pocisku), a my chcemy tylko przy tworzeniu odtworzyc.
    Najlepiej stworzyc wskaznik ktory wskazuje na „audio” i wyslac do funkcji add i dopiero tam odtworzyc w dokladnym momencie tworzenia pocisku.
    Pozdrawiam

    • Witaj, możliwe że masz rację, jednak ciężko jest mi się wypowiedzieć na projekt sprzed kilku lat. Można też zastosować timer, który będzie blokował odgrywanie dźwięku na jakiś czas.