private void InitializeWeaponOverlay(Dictionary<string, Bitmap> f) { Func<int, Bitmap> id = _id => f[_id + ".png"]; var hand = new Sprite(); var noweapon = f["hand.png"].AttachTo(hand); var gun_index = 0; var gun = new[] { id(326), id(327), id(328), id(329), id(330), }; //var hand = f["330.png"]; const int handsize = 4; var hand_x = (DefaultControlWidth - 64 * handsize) / 2; var hand_y_default = DefaultControlHeight - 64 * handsize; var hand_y = hand_y_default; hand.x = hand_x; hand.y = hand_y; hand.scaleX = handsize; hand.scaleY = handsize; hand.AttachTo(HudContainer); #region make it float (1000 / 24).AtInterval( tt => { hand.x = hand_x + Math.Cos(tt.currentCount * 0.2) * 6; hand.y = hand_y + Math.Abs(Math.Sin(tt.currentCount * 0.2)) * 4; } ); #endregion var WeaponChangeSpeed = handsize * 4; Action<Action> BringWeaponUp = ChangeDone => { (1000 / 24).AtInterval( tt => { hand_y -= WeaponChangeSpeed; if (hand_y <= hand_y_default) { tt.stop(); hand_y = hand_y_default; // ready to fire ChangeDone(); } } ); }; Action<Action, Action> BringWeaponDown = (MomentOfChange, ChangeDone) => { (1000 / 24).AtInterval( tt => { hand_y += WeaponChangeSpeed; if (hand_y >= DefaultControlHeight - (32 * handsize)) { // hand is off screen // lets switch to a weapon MomentOfChange(); tt.stop(); BringWeaponUp(ChangeDone); } } ); }; Action SwitchToWeaponDefault = delegate { // disable this function SwitchToWeapon = delegate { }; BringWeaponDown( delegate { noweapon.Orphanize(); gun.First().AttachTo(hand); } , delegate { WeaponIsActive = true; } ); }; SwitchToWeapon = SwitchToWeaponDefault; Action<Action> PlayFireAnimation = done => { (1000 / 15).AtInterval( tt => { gun[gun_index].Orphanize(); gun_index++; if (gun_index == gun.Length) { // done gun_index = 0; tt.stop(); done(); } gun[gun_index].AttachTo(hand); } ); }; FireWeapon = delegate { if (EndLevelMode) return; if (!WeaponIsActive) return; // we can fire only if the animation has stopped if (gun_index != 0) return; Assets.Default.Sounds.gunshot.play(); WeaponAmmo--; // add damage to sprites // we need to find out the one we are shooting at! // try adding damage to all //WriteLine("fire:"); var query = from k in EgoView.GetVisibleSprites(15.DegreesToRadians(), from p in EgoView.Sprites let fragile = p as SpriteInfoExtended where fragile != null where fragile.Health > 0 where fragile.TakeDamage != null select p ) orderby k.Distance let fragile = k.Sprite as SpriteInfoExtended select new { k, fragile }; var first = query.FirstOrDefault(); if (first != null) { var DamageToBeTaken = 1 / first.k.Distance; //WriteLine("hit: " + DamageToBeTaken); first.fragile.TakeDamage(DamageToBeTaken); } PlayFireAnimation( delegate { if (WeaponAmmo <= 0) { // dude, we are out of ammo!! WeaponIsActive = false; Action ReadyForMoreAmmo = delegate { SwitchToWeapon = SwitchToWeaponDefault; }; SwitchToWeapon = delegate { SwitchToWeapon = delegate { }; // the animation has not yet stopped but we found the ammo // when we are ready we switch back for the gun // this can be tested if the hand movement is really slow ReadyForMoreAmmo = SwitchToWeaponDefault; }; BringWeaponDown( delegate { gun.First().Orphanize(); noweapon.AttachTo(hand); } , delegate { ReadyForMoreAmmo(); } ); } } ); }; }