Пример #1
0
        public SFXCoordinator(AVAudioEnvironmentNode audioEnvironment) : base()
        {
            this.AudioEnvironment = audioEnvironment;

            this.loadQueue.DispatchAsync(() =>
            {
                foreach (var file in preloadAudioFiles)
                {
                    this.PrepareAudioFile(file);
                }
            });

            // Because the coordinate space is scaled, let's apply some adjustments to the
            // distance attenuation parameters to make the distance rolloff sound more
            // realistic.

            this.AudioEnvironment.DistanceAttenuationParameters.ReferenceDistance        = 5f;
            this.AudioEnvironment.DistanceAttenuationParameters.MaximumDistance          = 40f;
            this.AudioEnvironment.DistanceAttenuationParameters.RolloffFactor            = 1f;
            this.AudioEnvironment.DistanceAttenuationParameters.DistanceAttenuationModel = AVAudioEnvironmentDistanceAttenuationModel.Inverse;

            this.UpdateEffectsVolume();

            // When the route changes, we need to reload our audio samplers because sometimes those
            // audio units are being reset.
            NSNotificationCenter.DefaultCenter.AddObserver(AVAudioSession.RouteChangeNotification, this.HandleRouteChange);

            // Subscribe to notifications of user defaults changing so that we can apply them to
            // sound effects.
            NSNotificationCenter.DefaultCenter.AddObserver(NSUserDefaults.DidChangeNotification, this.HandleDefaultsDidChange);

            NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidEnterBackgroundNotification, this.HandleAppDidEnterBackground);
        }
Пример #2
0
        public Catapult(SCNNode node, SFXCoordinator sfxCoordinator, int identifier, Dictionary <string, object> gamedefs) : base(node, null, gamedefs, true, false)
        {
            this.Base             = node;
            this.audioEnvironment = sfxCoordinator.AudioEnvironment;

            // Base teamID and name off looking up teamA or teamB folder in the level parents
            // This won't work on the old levels.
            this.Team     = this.Base.GetTeam();
            this.TeamName = this.Team.GetDescription();

            // have team id established
            this.Base.SetPaintColors();

            // correct for the pivot point to place catapult flat on ground
            this.Base.Position = new SCNVector3(this.Base.Position.X, this.Base.Position.Y - 0.13f, this.Base.Position.Z);

            // highlight setup
            this.HighlightObject = node.FindChildNode("Highlight", true);
            if (this.HighlightObject != null)
            {
                this.HighlightObject = this.HighlightObject.FindNodeWithGeometry();
            }

            // hide the highlights on load
            if (this.HighlightObject != null)
            {
                this.HighlightObject.Hidden = true;
            }

            if (this.HighlightObject?.Geometry?.FirstMaterial?.Diffuse?.Contents is UIColor color)
            {
                this.highlightColor = color;
            }

            // they should only have y orientation, nothing in x or z
            // current scene files have the catapults with correct orientation, but the
            // eulerAngles are different - x and z are both π, y is within epsilon of 0
            // That's from bad decomposition of the matrix.  Need to restore the eulerAngles from the source.
            // Especially if we have animations tied to the euler angles.
            if (Math.Abs(node.EulerAngles.X) > 0.001f || Math.Abs(node.EulerAngles.Z) > 0.001f)
            {
                //Console.WriteLine("Catapult can only have y rotation applied");
            }

            // where to place the ball so it sits on the strap
            this.catapultStrap = this.Base.FindChildNode("catapultStrap", true);
            if (this.catapultStrap == null)
            {
                throw new Exception("No node with name catapultStrap");
            }

            // this only rotates, and represents the center of the catapult through which to fire
            this.pullOrigin = this.Base.FindChildNode("pullOrigin", true);
            if (this.pullOrigin == null)
            {
                throw new Exception("No node with name pullOrigin");
            }

            // This is a rope simulation meant for a fixed catapult, the catapult rotates.
            this.rope = new CatapultRope(node);

            // attach ball to the inactive strap, search for ballOriginInactiveBelow
            this.ballOriginInactiveBelow = this.Base.FindChildNode("ballOriginInactiveBelow", true);
            if (this.ballOriginInactiveBelow == null)
            {
                throw new Exception("No node with name ballOriginInactiveBelow");
            }

            this.ballOriginInactiveAbove = this.Base.FindChildNode("ballOriginInactiveAbove", true);
            if (this.ballOriginInactiveAbove == null)
            {
                throw new Exception("No node with name ballOriginInactiveAbove");
            }

            // ball will be made visible and drop once projectile is set and cooldown exceeded
            this.StrapVisible = StrapVisible.Visible;

            this.CatapultId = identifier;

            this.Base.SetValueForKey(NSObject.FromObject(this.CatapultId), new NSString(Catapult.CollisionKey));

            this.AudioPlayer = new CatapultAudioSampler(this.Base, sfxCoordinator);

            // use the teamID to set the collision category mask
            if (this.PhysicsNode?.PhysicsBody != null)
            {
                if (this.Team == Team.TeamA)
                {
                    this.PhysicsNode.PhysicsBody.CategoryBitMask = (int)CollisionMask.CatapultTeamA;
                    var collisionBitMask = (CollisionMask)(int)this.PhysicsNode.PhysicsBody.CollisionBitMask;
                    this.PhysicsNode.PhysicsBody.CollisionBitMask = (nuint)(int)(collisionBitMask | CollisionMask.CatapultTeamB);
                }
                else if (this.Team == Team.TeamB)
                {
                    this.PhysicsNode.PhysicsBody.CategoryBitMask = (int)CollisionMask.CatapultTeamB;
                    var collisionBitMask = (CollisionMask)(int)this.PhysicsNode.PhysicsBody.CollisionBitMask;
                    this.PhysicsNode.PhysicsBody.CollisionBitMask = (nuint)(int)(collisionBitMask | CollisionMask.CatapultTeamA);
                }
            }
        }