Added sound effects example.

This commit is contained in:
Lasse Öörni 2013-08-25 09:20:56 +00:00
parent 463ce2a65d
commit 056acfcc68
13 changed files with 334 additions and 49 deletions

View File

@ -20,15 +20,15 @@
// THE SOFTWARE.
//
#include "Button.h"
#include "CheckBox.h"
#include "CoreEvents.h"
#include "Engine.h"
#include "Input.h"
#include "LineEdit.h"
#include "Text.h"
#include "UI.h"
#include "UIEvents.h"
#include "LineEdit.h"
#include "CheckBox.h"
#include "Button.h"
#include "Text.h"
#include "HelloGUI.h"
@ -142,19 +142,6 @@ void HelloGUI::SubscribeToEvents()
{
// Subscribe handler; invoked whenever a mouse click event is dispatched
SubscribeToEvent(E_UIMOUSECLICK, HANDLER(HelloGUI, HandleControlClicked));
// Subscribe to logic update events
SubscribeToEvent(E_UPDATE, HANDLER(HelloGUI, HandleUpdate));
}
void HelloGUI::HandleUpdate(StringHash eventType, VariantMap& eventData)
{
// Determine whether the escape key was pressed..
if (GetSubsystem<Input>()->GetKeyDown(KEY_ESC))
{
// .. if so, request Engine exit
GetSubsystem<Engine>()->Exit();
}
}
void HelloGUI::HandleClosePressed(StringHash eventType, VariantMap& eventData)

View File

@ -53,9 +53,6 @@ private:
/// Convenience method for event subscription.
void SubscribeToEvents();
/// Callback method invoked when a logic update event is dispatched.
void HandleUpdate(StringHash eventType, VariantMap& eventData);
/// Callback method invoked whenever any control is clicked.
void HandleControlClicked(StringHash eventType, VariantMap& eventData);

View File

@ -29,7 +29,7 @@ using namespace Urho3D;
/// Custom component for rotating a scene node.
class Rotator : public Component
{
{
OBJECT(Rotator);
public:

View File

@ -29,7 +29,7 @@ using namespace Urho3D;
/// Custom component for moving the animated model and rotating at area edges.
class Mover : public Component
{
{
OBJECT(Mover);
public:

View File

@ -138,7 +138,7 @@ void Decals::CreateScene()
boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
boxObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml"));
boxObject->SetCastShadows(true);
if (size >= 5.0f)
if (size >= 3.0f)
boxObject->SetOccluder(true);
}

View File

@ -139,7 +139,7 @@ void MultipleViewports::CreateScene()
boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
boxObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml"));
boxObject->SetCastShadows(true);
if (size >= 5.0f)
if (size >= 3.0f)
boxObject->SetOccluder(true);
}
@ -154,6 +154,10 @@ void MultipleViewports::CreateScene()
rearCameraNode_->Rotate(Quaternion(180.0f, Vector3::UP));
Camera* rearCamera = rearCameraNode_->CreateComponent<Camera>();
rearCamera->SetFarClip(300.0f);
// Because the rear viewport is rather small, disable occlusion culling from it. Use the camera's
// "view override flags" for this. We could also disable eg. shadows or force low material quality
// if we wanted
rearCamera->SetViewOverrideFlags(VO_DISABLE_OCCLUSION);
// Set an initial position for the front camera scene node above the plane
cameraNode_->SetPosition(Vector3(0.0f, 5.0f, 0.0f));

View File

@ -29,7 +29,7 @@ using namespace Urho3D;
/// Custom component for rotating a scene node.
class Rotator : public Component
{
{
OBJECT(Rotator);
public:

View File

@ -1,25 +1,25 @@
//
// Copyright (c) 2008-2013 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//
// Copyright (c) 2008-2013 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#pragma once
#include "CollisionShape.h"

View File

@ -0,0 +1,10 @@
# Define target name
set (TARGET_NAME 14_SoundEffects)
# Define source files
file (GLOB CPP_FILES *.cpp)
file (GLOB H_FILES *.h)
set (SOURCE_FILES ${CPP_FILES} ${H_FILES} ${COMMON_SAMPLE_H_FILES})
# Setup target with resource copying
setup_main_executable ()

View File

@ -0,0 +1,214 @@
//
// Copyright (c) 2008-2013 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#include "Audio.h"
#include "Engine.h"
#include "Font.h"
#include "Input.h"
#include "Log.h"
#include "ResourceCache.h"
#include "Scene.h"
#include "Sound.h"
#include "Text.h"
#include "UI.h"
#include "UIEvents.h"
#include "SoundEffects.h"
#include "DebugNew.h"
// Custom variable identifier for storing sound effect name within the UI element
static const ShortStringHash VAR_SOUNDRESOURCE("SoundResource");
static const unsigned NUM_SOUNDS = 3;
static String soundNames[] = {
"Fist",
"Explosion",
"Power-up"
};
static String soundResourceNames[] = {
"Sounds/PlayerFistHit.wav",
"Sounds/BigExplosion.wav",
"Sounds/Powerup.wav"
};
// Expands to this example's entry-point
DEFINE_APPLICATION_MAIN(SoundEffects)
SoundEffects::SoundEffects(Context* context) :
Sample(context)
{
}
void SoundEffects::Start()
{
// Execute base class startup
Sample::Start();
// Enable OS cursor
GetSubsystem<Input>()->SetMouseVisible(true);
// Create the user interface
CreateUI();
}
void SoundEffects::CreateUI()
{
// Create a scene which will not be actually rendered, but is used to hold SoundSource components while they play sounds
scene_ = new Scene(context_);
// Create buttons for playing back sounds
for (unsigned i = 0; i < NUM_SOUNDS; ++i)
{
Button* button = CreateButton(i * 140 + 20, 20, 120, 40, soundNames[i]);
// Store the sound effect resource name as a custom variable into the button
button->SetVar(VAR_SOUNDRESOURCE, soundResourceNames[i]);
SubscribeToEvent(button, E_PRESSED, HANDLER(SoundEffects, HandlePlaySound));
}
// Create buttons for playing/stopping music
Button* button = CreateButton(20, 80, 120, 40, "Play Music");
SubscribeToEvent(button, E_PRESSED, HANDLER(SoundEffects, HandlePlayMusic));
button = CreateButton(160, 80, 120, 40, "Stop Music");
SubscribeToEvent(button, E_PRESSED, HANDLER(SoundEffects, HandleStopMusic));
Audio* audio = GetSubsystem<Audio>();
// Create sliders for controlling sound and music master volume
Slider* slider = CreateSlider(20, 140, 200, 20, "Sound Volume");
slider->SetValue(audio->GetMasterGain(SOUND_EFFECT));
SubscribeToEvent(slider, E_SLIDERCHANGED, HANDLER(SoundEffects, HandleSoundVolume));
slider = CreateSlider(20, 200, 200, 20, "Music Volume");
slider->SetValue(audio->GetMasterGain(SOUND_MUSIC));
SubscribeToEvent(slider, E_SLIDERCHANGED, HANDLER(SoundEffects, HandleMusicVolume));
}
Button* SoundEffects::CreateButton(int x, int y, int xSize, int ySize, const String& text)
{
UIElement* root = GetSubsystem<UI>()->GetRoot();
ResourceCache* cache = GetSubsystem<ResourceCache>();
XMLFile* defaultStyle = cache->GetResource<XMLFile>("UI/DefaultStyle.xml");
Font* font = cache->GetResource<Font>("Fonts/Anonymous Pro.ttf");
// Create the button and center the text onto it
Button* button = root->CreateChild<Button>();
button->SetStyleAuto(defaultStyle);
button->SetPosition(x, y);
button->SetSize(xSize, ySize);
Text* buttonText = button->CreateChild<Text>();
buttonText->SetAlignment(HA_CENTER, VA_CENTER);
buttonText->SetFont(font, 12);
buttonText->SetText(text);
return button;
}
Slider* SoundEffects::CreateSlider(int x, int y, int xSize, int ySize, const String& text)
{
UIElement* root = GetSubsystem<UI>()->GetRoot();
ResourceCache* cache = GetSubsystem<ResourceCache>();
XMLFile* defaultStyle = cache->GetResource<XMLFile>("UI/DefaultStyle.xml");
Font* font = cache->GetResource<Font>("Fonts/Anonymous Pro.ttf");
// Create text and slider below it
Text* sliderText = root->CreateChild<Text>();
sliderText->SetPosition(x, y);
sliderText->SetFont(font, 12);
sliderText->SetText(text);
Slider* slider = root->CreateChild<Slider>();
slider->SetStyleAuto(defaultStyle);
slider->SetPosition(x, y + 20);
slider->SetSize(xSize, ySize);
// Use 0-1 range for controlling sound/music master volume
slider->SetRange(1.0f);
return slider;
}
void SoundEffects::HandlePlaySound(StringHash eventType, VariantMap& eventData)
{
Button* button = static_cast<Button*>(GetEventSender());
const String& soundResourceName = button->GetVar(VAR_SOUNDRESOURCE).GetString();
// Get the sound resource
ResourceCache* cache = GetSubsystem<ResourceCache>();
Sound* sound = cache->GetResource<Sound>(soundResourceName);
if (sound)
{
// Create a scene node with a SoundSource component for playing the sound. The SoundSource component plays
// non-positional audio, so its 3D position in the scene does not matter. For positional sounds the
// SoundSource3D component would be used instead
Node* soundNode = scene_->CreateChild("Sound");
SoundSource* soundSource = soundNode->CreateComponent<SoundSource>();
soundSource->Play(sound);
// In case we also play music, set the sound volume below maximum so that we don't clip the output
soundSource->SetGain(0.75f);
// Set the sound component to automatically remove its scene node from the scene when the sound is done playing
soundSource->SetAutoRemove(true);
}
}
void SoundEffects::HandlePlayMusic(StringHash eventType, VariantMap& eventData)
{
// Check if the music player node/component already exist
if (scene_->GetChild("Music"))
return;
ResourceCache* cache = GetSubsystem<ResourceCache>();
Sound* music = cache->GetResource<Sound>("Music/Ninja Gods.ogg");
// Set the song to loop
music->SetLooped(true);
// Create a scene node and a sound source for the music
Node* musicNode = scene_->CreateChild("Music");
SoundSource* musicSource = musicNode->CreateComponent<SoundSource>();
// Set the sound type to music so that master volume control works correctly
musicSource->SetSoundType(SOUND_MUSIC);
musicSource->Play(music);
}
void SoundEffects::HandleStopMusic(StringHash eventType, VariantMap& eventData)
{
// Remove the music player node from the scene
scene_->RemoveChild(scene_->GetChild("Music"));
}
void SoundEffects::HandleSoundVolume(StringHash eventType, VariantMap& eventData)
{
using namespace SliderChanged;
float newVolume = eventData[P_VALUE].GetFloat();
GetSubsystem<Audio>()->SetMasterGain(SOUND_EFFECT, newVolume);
}
void SoundEffects::HandleMusicVolume(StringHash eventType, VariantMap& eventData)
{
using namespace SliderChanged;
float newVolume = eventData[P_VALUE].GetFloat();
GetSubsystem<Audio>()->SetMasterGain(SOUND_MUSIC, newVolume);
}

View File

@ -0,0 +1,69 @@
//
// Copyright (c) 2008-2013 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#pragma once
#include "Button.h"
#include "Sample.h"
#include "Slider.h"
#include "SoundSource.h"
using namespace Urho3D;
/// Sound effects example
/// This sample demonstrates:
/// - Playing sound effects and music;
/// - Controlling sound and music master volume;
class SoundEffects : public Sample
{
OBJECT(SoundEffects);
public:
/// Construct.
SoundEffects(Context* context);
/// Setup after engine initialization and before running the main loop.
virtual void Start();
private:
/// Creates the UI and subscribes to UI events.
void CreateUI();
/// Creates a button at position with specified text in it.
Button* CreateButton(int x, int y, int xSize, int ySize, const String& text);
/// Creates a horizontal slider with specified text above it.
Slider* CreateSlider(int x, int y, int xSize, int ySize, const String& text);
/// Handle a sound effect button click.
void HandlePlaySound(StringHash eventType, VariantMap& eventData);
/// Handle "play music" button click.
void HandlePlayMusic(StringHash eventType, VariantMap& eventData);
/// Handle "stop music" button click.
void HandleStopMusic(StringHash eventType, VariantMap& eventData);
/// Handle sound effects volume slider change.
void HandleSoundVolume(StringHash eventType, VariantMap& eventData);
/// Handle music volume slider change.
void HandleMusicVolume(StringHash eventType, VariantMap& eventData);
/// Scene.
SharedPtr<Scene> scene_;
};

View File

@ -24,13 +24,16 @@
set (COMMON_SAMPLE_H_FILES "${CMAKE_CURRENT_SOURCE_DIR}/Sample.h" "${CMAKE_CURRENT_SOURCE_DIR}/Sample.inl")
# Define dependency libs
set (LIBS ../../Engine/Container
set (LIBS ../../Engine/Audio
../../Engine/Container
../../Engine/Core
../../Engine/Engine
../../Engine/Graphics
../../Engine/Input
../../Engine/IO
../../Engine/Math
../../Engine/Navigation
../../Engine/Network
../../Engine/Physics
../../Engine/Resource
../../Engine/Scene
@ -52,3 +55,4 @@ add_subdirectory (10_RenderToTexture)
add_subdirectory (11_Physics)
add_subdirectory (12_PhysicsStressTest)
add_subdirectory (13_Ragdolls)
add_subdirectory (14_SoundEffects)

View File

@ -122,7 +122,7 @@ void Sample::HandleKeyDown(StringHash eventType, VariantMap& eventData)
int key = eventData[P_KEY].GetInt();
// Close console (if open) or when ESC is pressed
// Close console (if open) or exit when ESC is pressed
if (key == KEY_ESC)
{
Console* console = GetSubsystem<Console>();