Last active
July 16, 2021 15:00
-
-
Save michaliskambi/5f9e8df6021434a0dd47508a3cac1ec3 to your computer and use it in GitHub Desktop.
Sample unit to implement randomization of sounds in Castle Game Engine. See https://github.com/castle-engine/castle-engine/wiki/Upgrading-to-Castle-Game-Engine-7.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ Sample unit to implement randomization of sounds, | |
after the feature was removed from CGE sounds XML file. | |
See https://github.com/castle-engine/castle-engine/wiki/Upgrading-to-Castle-Game-Engine-7.0 | |
for documentation. | |
Copyright 2021 Michalis Kamburelis. | |
License: modified BSD (3-clause), so basically reuse it freely (see | |
https://github.com/castle-engine/castle-engine/blob/master/doc/licenses/COPYING.BSD-3-clause.txt ). | |
Usage: | |
- replace SoundEngine.SoundFromName with TSoundChoice.Init | |
- replace TSoundType with TSoundChoice | |
- modify TSoundType.Init to implement your randomization | |
} | |
unit GameSound; | |
{$modeswitch advancedrecords} | |
interface | |
uses CastleSoundEngine; | |
type | |
{ Use this instead of TCastleSound and TSoundType. | |
The TSoundChoice supports randomization. } | |
TSoundChoice = record | |
Choices: array of TCastleSound; | |
class function Empty: TSoundChoice; static; | |
{ Use this instead of SoundEngine.SoundFromName. | |
The meaning of SoundName and Required params is the same. | |
When SoundEngine.SoundFromName would return @nil, this sets Choices to empty, | |
and then Choose will return nil. } | |
class function Init(const SoundName: String; const Required: boolean = true): TSoundChoice; static; | |
{ Return TCastleSound, doing randomization along the way. } | |
function Choose: TCastleSound; | |
{ Automatically converts TSoundChoice to TCastleSound (doing randomization along the way) | |
so that TSoundChoice can be used as a drop-in replacement of TCastleSound. | |
You can also do it explicitly by TSoundChoice.Choose. } | |
class operator := (const Value: TSoundChoice): TCastleSound; | |
end; | |
implementation | |
class function TSoundChoice.Empty: TSoundChoice; static; | |
begin | |
// SetLength(Result.Choices, 0); // actually this is default for dynamic arrays | |
Assert(Length(Result.Choices) = 0); | |
end; | |
class function TSoundChoice.Init(const SoundName: String; const Required: boolean): TSoundChoice; static; | |
procedure InitializeChoice(const Names: array of String); | |
var | |
I: Integer; | |
begin | |
SetLength(Result.Choices, High(Names) + 1); | |
{ This can place nil inside Result.Choices. | |
That is OK, let it (TSoundChoice.Choose will then return nil for them). } | |
for I := Low(Names) to High(Names) do | |
Result.Choices[I] := SoundEngine.SoundFromName(Names[I], Required); | |
end; | |
var | |
Sound: TCastleSound; | |
begin | |
case SoundName of | |
'fight/playerhurt': InitializeChoice([ | |
'fight/playerhurt1', | |
'fight/playerhurt2' | |
]); | |
'hotel_room/roseanne_attack': InitializeChoice([ | |
'hotel_room/pr_fight_sukkub_attack_1', | |
'hotel_room/pr_fight_sukkub_attack_2', | |
'hotel_room/pr_fight_sukkub_attack_3' | |
]); | |
else | |
begin | |
Sound := SoundEngine.SoundFromName(SoundName, Required); | |
if Sound <> nil then | |
begin | |
SetLength(Result.Choices, 1); | |
Result.Choices[0] := Sound; | |
end else | |
SetLength(Result.Choices, 0); | |
end; | |
end; | |
end; | |
function TSoundChoice.Choose: TCastleSound; | |
begin | |
if Length(Choices) > 0 then | |
Result := Choices[Random(Length(Choices))] | |
else | |
Result := nil; | |
end; | |
class operator TSoundChoice.:= (const Value: TSoundChoice): TSoundType; | |
begin | |
Result := Value.Choose; | |
end; | |
end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment