Create a free account to remove all ad content.

Author Topic:  PWR's PRGRSS - Learning C#  (Read 9371 times)

0 Members and 1 Guest are viewing this topic.

Craig

  • Developer
  • Extreme Member
  • *
  • Posts: 6655
  • Dig Deep
    • View Profile
    • Twitter
  • Steam: tota1miner
Re: PWR's PRGRSS - Learning C#
« Reply #150 on: March 21, 2016, 09:15:39 PM »
Sorry, I meant like text adventures in general, not just MUDs, they're both hard to program, too hard for beginners I think. With programming I think it's better to work and practice within your knowledge, only pushing out beyond that conservatively at first. Get the fundamentals down, then it becomes a lot easier to start pushing out into new ground. Without the fundamentals, you'll get stuck in a bog pretty quick. Programming text adventures requires some pretty sophisticated programming knowledge, far beyond fundamentals.

PWRBTTN

  • Legendary Member
  • *
  • Posts: 1172
  • Professional Expert, Comrade
    • View Profile
  • Xbox: PWRBTTN
  • Steam: PWRBTTN
Re: PWR's PRGRSS - Learning C#
« Reply #151 on: March 21, 2016, 09:40:53 PM »
Ah, well if that's the case, I suppose I should put IMPA on hold for a bit. In case I can manage to mess around with C# a bit more before I have to deal with my dilemma, what do you recommend I try doing?
/snail       /snail    /snail         /snail /snail      /snail   /snail                /snail        

Craig

  • Developer
  • Extreme Member
  • *
  • Posts: 6655
  • Dig Deep
    • View Profile
    • Twitter
  • Steam: tota1miner
Re: PWR's PRGRSS - Learning C#
« Reply #152 on: March 21, 2016, 10:20:54 PM »
Programming can be a bit of a slog at first, hard to make sense out of everything, too many details obscuring the basics. But once you start to get the basics down, things start to make a lot more sense, progress becomes more rapid, and it becomes a lot more fun (less frustrating).

I think you'd enjoy making IMPA a lot more once you get to that point where things start to make sense.

Maybe you could work on some subsets. Like the inventory class. Make a console app that allows you to add items to an inventory object, to list the items, to remove an item, to move an item to another position. To handle finite sized stacks of items etc.

I'm not really sure. Whatever you can think of that you think you might be able to do, with some aspects that will also require you to learn some new stuff.

For me it was all about graphics, when I started, I just wanted to make as many things appear on the screen as I could, making them move as fast as I could. In those days, that goal was relevant because the hardware was so limited. These days it's not so relevant, the hardware now allows us to draw tens of thousands of almost screen sized sprites in a singe frame, so I guess goals will be different now. I started off just getting a single sprite to move on the screen, then several, then made games like river rapids that just basically rained rocks and you had to avoid them, then moved onto games like basic space invaders (like total invaders), and derivatives, galaxians, galaga, millipede, phoenix, etc, simple 2d vertical car racing games, karate type games, dig-dug, tutankhamun, maze games, etc. all very simple versions of their arcade equivalents. Keeping it simple is really important at first.

PWRBTTN

  • Legendary Member
  • *
  • Posts: 1172
  • Professional Expert, Comrade
    • View Profile
  • Xbox: PWRBTTN
  • Steam: PWRBTTN
Re: PWR's PRGRSS - Learning C#
« Reply #153 on: March 22, 2016, 06:18:20 AM »
Do you have any old projects I could look at to study the code? Also, preferably, anything that doesn't require me to download anything extra?
/snail       /snail    /snail         /snail /snail      /snail   /snail                /snail        

Craig

  • Developer
  • Extreme Member
  • *
  • Posts: 6655
  • Dig Deep
    • View Profile
    • Twitter
  • Steam: tota1miner
Re: PWR's PRGRSS - Learning C#
« Reply #154 on: March 22, 2016, 08:58:30 AM »
Do you have any old projects I could look at to study the code? Also, preferably, anything that doesn't require me to download anything extra?
Hmm now where did I put those cassette tapes and 3.5' floppies...

Here is the Total Invaders source code:

Object.cs
Code: [Select]
using Microsoft.Xna.Framework;

namespace Craig.TotalMiner.Arcade.TotalInvaders
{
    struct Invader
    {
        public bool IsAlive;
        public Vector2 Position;
    }

    enum PickupType
    {
        None,
        PlayerShip
    }

    struct UFO
    {
        public bool IsAlive;
        public PickupType Pickup;
        public Vector2 Position;
        public Vector2 Velocity;
    }

    struct Pickup
    {
        public bool IsAlive;
        public PickupType PickupType;
        public Vector2 Position;
        public Vector2 Velocity;
    }

    struct Bullet
    {
        public Vector2 Position;
        public Vector2 Velocity;
    }

    struct Player
    {
        public bool IsAlive;
        public Vector2 Position;
        public Vector2 Velocity;
        public float Speed;
        public float ShotDelay;
        public float ShotDelayTimer;
        public Vector2 BulletVelocity;

        public Player(bool isAlive)
        {
            IsAlive = isAlive;
            Position = new Vector2(10, 220);
            Velocity = Vector2.Zero;
            Speed = 0.8f;
            ShotDelay = 0.5f;
            ShotDelayTimer = 0;
            BulletVelocity = new Vector2(0f, -7);
        }
    }

    struct Particle
    {
        public float Age;
        public Vector2 Position;
        public Vector2 Velocity;
        public Color Color;
    }
}

InvaderWave.cs
Code: [Select]
using System;
using Microsoft.Xna.Framework;
using Craig.Engine;

namespace Craig.TotalMiner.Arcade.TotalInvaders
{
    class InvaderWave
    {
        #region Fields

        public Vector2 Position;
        public Vector2 Velocity;
        public Rectangle Box;
        public Invader[] Invaders;

        TotalInvaders instance;
        bool dropDown;
        float dropStartY;
        int invaderCount;
        float newWavePauseTimer;
        Vector2 invaderBulletVelocity;

        #endregion

        #region Initialization

        public InvaderWave(TotalInvaders instance)
        {
            this.instance = instance;
            Invaders = new Invader[55];
        }

        #endregion

        #region Reset Wave

        public void ResetWave()
        {
            newWavePauseTimer = 2f;

            for (int i = 0; i < Invaders.Length; i++)
                Invaders[i].IsAlive = false;
        }

        void NewWave()
        {
            newWavePauseTimer = 0f;
            dropDown = false;
            Position = new Vector2(0f, Math.Min(instance.Wave, 30));
            Velocity = new Vector2(-MathHelper.Lerp(0.05f, 1f, instance.Wave / 30f), 0.1f);
            invaderBulletVelocity = new Vector2(0f, 1f);

            int i = 0;
            for (int y = 0; y < 97; y += 24)
            {
                for (int x = 0; x < 264; x += 24)
                {
                    Invaders[i].IsAlive = true;
                    Invaders[i++].Position = new Vector2(x + 50, y + 30);
                }
            }

            invaderCount = i;
            RecalcBoxSize();

            instance.FrameCounter = (int)(10 / System.Math.Abs(Velocity.X));
            instance.AnimFrame = 0;
        }

        #endregion

        #region Box

        void RecalcBoxSize()
        {
            Vector2 min = new Vector2(float.MaxValue, float.MaxValue);
            Vector2 max = new Vector2(float.MinValue, float.MinValue);

            foreach (var invader in Invaders)
            {
                if (invader.IsAlive)
                {
                    if (invader.Position.X < min.X) min.X = invader.Position.X;
                    if (invader.Position.Y < min.Y) min.Y = invader.Position.Y;
                    if (invader.Position.X + TotalInvaders.InvaderWidth > max.X) max.X = invader.Position.X + TotalInvaders.InvaderWidth;
                    if (invader.Position.Y + TotalInvaders.InvaderHeight > max.Y) max.Y = invader.Position.Y + TotalInvaders.InvaderHeight;
                }
            }

            float oldx = Position.X;
            float oldy = Position.Y;

            Position.X += min.X;
            Position.Y += min.Y;

            Box.Width = (int)(max.X - min.X);
            Box.Height = (int)(max.Y - min.Y);

            float diffx = Position.X - oldx;
            float diffy = Position.Y - oldy;

            for (int i = 0; i < Invaders.Length; i++)
            {
                if (Invaders[i].IsAlive)
                {
                    Invaders[i].Position.X -= diffx;
                    Invaders[i].Position.Y -= diffy;
                }
            }
        }

        #endregion

        #region Check Hit

        public bool CheckHit(Bullet b)
        {
            for (int k = 0; k < Invaders.Length; k++)
            {
                var i = Invaders[k];
                if (i.IsAlive)
                {
                    if (b.Position.X <= i.Position.X + TotalInvaders.InvaderWidth - 2 + Position.X &&
                        b.Position.X + TotalInvaders.BulletWidth > i.Position.X + Position.X &&
                        b.Position.Y < i.Position.Y + TotalInvaders.InvaderHeight + Position.Y &&
                        b.Position.Y + TotalInvaders.BulletHeight > i.Position.Y + Position.Y)
                    {
                        instance.AddExplosionParticles(Position + i.Position + new Vector2(TotalInvaders.InvaderWidth / 2, TotalInvaders.InvaderHeight / 2), Velocity * 0.5f, new Color(39, 216, 17), 10);
                        Invaders[k].IsAlive = false;
                        RecalcBoxSize();
                        Velocity.X *= 1.05f;
                        Velocity.Y *= 1.05f;
                        if (--invaderCount == 0)
                        {
                            newWavePauseTimer = 2f;
                        }
                        return true;
                    }
                }
            }

            return false;
        }

        #endregion

        #region Update

        public void Update()
        {
            if (newWavePauseTimer > 0)
            {
                newWavePauseTimer -= Services.ElapsedTime;
                if (newWavePauseTimer <= 0)
                {
                    instance.Wave++;
                    instance.WaveText = "Wave: " + instance.Wave.ToString();
                    NewWave();
                }
            }
            else
            {
                CheckForBoundaryBounce();
                BombPlayers();
            }
        }

        void BombPlayers()
        {
            if (instance.State == TotalInvaders.GameState.Play)
            {
                if (instance.Random.Next(2) == 0)
                {
                    int i = instance.Random.Next(Invaders.Length);
                    var invader = Invaders[i];

                    if (invader.IsAlive && invader.Position.Y == Box.Height - TotalInvaders.InvaderHeight)
                    {
                        instance.InvaderBullets.Add(new Bullet());
                        ActivateBullet(invader, instance.InvaderBullets.Count - 1);
                    }
                }
            }
        }

        void ActivateBullet(Invader invader, int i)
        {
            var b = instance.InvaderBullets[i];
            b.Position.X = Position.X + invader.Position.X + TotalInvaders.InvaderWidth / 2 - TotalInvaders.InvaderWidth / 2;
            b.Position.Y = Position.Y + invader.Position.Y + TotalInvaders.InvaderHeight / 2;
            b.Velocity = invaderBulletVelocity;
            instance.InvaderBullets[i] = b;
        }

        void CheckForBoundaryBounce()
        {
            if (dropDown)
            {
                Position.Y += Velocity.Y;

                if (Position.Y > dropStartY + 6)
                {
                    dropDown = false;
                }
            }
            else
            {
                Position.X += Velocity.X;
            }

            Box.X = (int)Position.X;
            Box.Y = (int)Position.Y;

            if (Box.Y + Box.Height >= 230)
            {
                instance.GameOver(true);
            }
            else if (!dropDown)
            {
                if (Velocity.X < 0)
                {
                    if (Box.X < 5)
                    {
                        Velocity.X = -Velocity.X;
                        dropDown = true;
                        dropStartY = Position.Y;
                    }
                }
                else if (Velocity.X > 0)
                {
                    if (Box.X + Box.Width > instance.ScreenSize.X - 5)
                    {
                        Velocity.X = -Velocity.X;
                        dropDown = true;
                        dropStartY = Position.Y;
                    }
                }
            }
        }


        #endregion
    }
}

TotalInvaders.cs
Code: [Select]
using System;
using System.Collections.Generic;
using Craig.BlockWorld;
using Craig.Engine;
using Craig.Engine.Integration;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Craig.TotalMiner.Arcade.TotalInvaders
{
    class TotalInvaders : ArcadeMachine
    {
        #region Enum

        public enum GameState
        {
            Play,
            GameOverTransition,
            GameOver
        }

        #endregion

        #region Fields

        public const int InvaderWidth = 16;
        public const int InvaderHeight = 14;
        public const int PlayerWidth = 18;
        public const int PlayerHeight = 12;
        public const int UFOWidth = 22;
        public const int UFOHeight = 8;
        public const int BulletWidth = 2;
        public const int BulletHeight = 10;
        public const int PickupWidth = 8;
        public const int PickupHeight = 6;
        public const int ParticleWidth = 1;
        public const int ParticleHeight = 1;
        public static int HighScore = 0;
        public static string HighScoreText;
        public static string HighScoreGamer = "";
        public static string HighScoreVersion = "";
        public GameState State;
        public InvaderWave InvaderWave;
        public Point ScreenSize;
        public int Score;
        public int Lives;
        public int Wave;
        public List<Player> Players;
        public List<Bullet> PlayerBullets;
        public List<Bullet> InvaderBullets;
        public List<Pickup> Pickups;
        public List<Particle> Particles;
        public UFO UFO;
        public Random Random;
        public int FrameCounter;
        public int AnimFrame;

        public string ScoreText;
        public string WaveText;

        float ufoSpeed;
        float pickupSpeed;
        float gameOverTransitionTimer;
        bool highscoreGamerUpdated;
        Color[] explosionColors = new Color[] { Color.Red, Color.Yellow, Color.Orange };

        #endregion

        #region Properties

        public override bool CanDeactivate { get { return State == GameState.GameOver; } }

        #endregion

        #region Initialization

        public TotalInvaders(GameInstance instance, Map map, Craig.TotalMiner.Player player, GlobalPoint3D point, BlockFace face)
            : base(instance, map, player, point, face)
        {
            GpPerCredit = 1;
        }

        public override void LoadContent(InitState state)
        {
            base.LoadContent(state);

            ScreenSize = new Point(renderTarget.Width, renderTarget.Height);
            InvaderWave = new InvaderWave(this);

            State = GameState.GameOver;
            Random = new Random();

            ufoSpeed = 1.4f;
            pickupSpeed = 0.8f;

            PlayerBullets = new List<Bullet>(10);
            InvaderBullets = new List<Bullet>(10);
            Players = new List<Player>();
            Particles = new List<Particle>();
            Pickups = new List<Pickup>();

            ResetHud();
        }

        void ResetHud()
        {
            Score = 0;
            Lives = 3;
            Wave = 1;

            WaveText = "Wave: 1";
            ScoreText = "Score: 0";

            HighScoreText = "High Score: " + HighScore.ToString();
            highscoreGamerUpdated = false;
        }

        public override void StartGame()
        {
            if (State != GameState.Play)
            {
                if (Credits > 0)
                {
                    ChangeCredits(-1);

                    ResetHud();

                    State = GameState.Play;

                    Players.Clear();
                    var p = new Player(true);
                    Players.Add(p);

                    Wave = 0;
                    InvaderWave.ResetWave();
                    UFO.IsAlive = false;
                }
            }
            else
            {
                GameOver(false);
            }
        }

        public void GameOver(bool transition)
        {
            if (transition)
            {
                State = GameState.GameOverTransition;
                gameOverTransitionTimer = 3;
            }
            else
            {
                State = GameState.GameOver;
                PlayerBullets.Clear();
                InvaderBullets.Clear();
                Particles.Clear();
                Pickups.Clear();
            }

            if (highscoreGamerUpdated)
            {
                instance.NetworkManager.SendArcadeState();
                highscoreGamerUpdated = false;
            }
        }

        #endregion

        #region Input

        public override bool HandleInput(GamePadState pad, GamePadState lastpad)
        {
            var result = OnLeftStick(pad.ThumbSticks.Left);
            result |= OnAButton(pad.Buttons.A == ButtonState.Pressed && lastpad.Buttons.A == ButtonState.Released); ;
            if (pad.Buttons.B == ButtonState.Pressed && lastpad.Buttons.B == ButtonState.Released) { GameOver(false); result = true; }
            if (pad.Buttons.Start == ButtonState.Pressed) return false; // let game process them
            return result;
        }

        bool OnLeftStick(Vector2 stick)
        {
            if (State == GameState.Play)
            {
                var p = Players[0];
                if (stick.X < 0) p.Velocity.X = -p.Speed;
                else if (stick.X > 0) p.Velocity.X = p.Speed;
                else p.Velocity.X = 0;
                Players[0] = p;
                return true;
            }
            else if (State == GameState.GameOverTransition)
            {
                return true;
            }

            return false;
        }

        bool OnAButton(bool newPress)
        {
            if (State == GameState.Play)
            {
                var p = Players[0];
                p.ShotDelayTimer += Services.ElapsedTime;

                if (newPress)
                {
                    p.ShotDelayTimer = p.ShotDelay;
                }

                if (p.ShotDelayTimer >= p.ShotDelay)
                {
                    FirePlayerBullet();
                    p.ShotDelayTimer = 0;
                }

                return true;
            }
            else if (State == GameState.GameOverTransition)
            {
                return true;
            }

            return false;
        }

        void FirePlayerBullet()
        {
            for (int i = 0; i < Players.Count; i++)
            {
                PlayerBullets.Add(new Bullet());
                ActivateBullet(Players[i], PlayerBullets.Count - 1);
            }
            CoreGlobals.AudioManager.PlaySound("InvadersFire");
        }

        void ActivateBullet(Player player, int i)
        {
            var b = PlayerBullets[i];
            b.Position.X = player.Position.X + TotalInvaders.PlayerWidth / 2 - TotalInvaders.BulletWidth / 2;
            b.Position.Y = player.Position.Y;
            b.Velocity = Players[0].BulletVelocity;
            PlayerBullets[i] = b;
        }

        #endregion

        #region Update

        protected override void UpdateCore()
        {
            if (!tmPlayer.IsInputEnabled) return;

            try
            {
                switch (State)
                {
                    case GameState.Play:
                        UpdatePlayState();
                        break;

                    case GameState.GameOverTransition:
                        UpdateGameOverTransitionState();
                        break;
                }

                if (tmPlayer.IsGod && Players.Count > 0)
                {
                    var pad = GamePad.GetState(tmPlayer.PlayerIndex);
                    if (pad.Buttons.Y == ButtonState.Pressed && lastpad.Buttons.Y == ButtonState.Released)
                    {
                        AddPlayerShip();
                    }
                    lastpad = pad;
                }
            }
            catch (Exception e)
            {
                Services.ExceptionReporter.ReportExceptionCaught(1, e);
                GameOver(false);
            }
        }

        GamePadState lastpad;

        void UpdatePlayState()
        {
            if (--FrameCounter < 0)
            {
                FrameCounter = (int)Math.Max(10f / Math.Abs(InvaderWave.Velocity.X), 10);
                ++AnimFrame;
            }


            UpdatePlayers();
            InvaderWave.Update();
            UpdateUFO();
            UpdatePlayerBullets();
            UpdateInvaderBullets();
            UpdatePickups();
            UpdateParticles();
        }

        void UpdateGameOverTransitionState()
        {
            gameOverTransitionTimer -= Services.ElapsedTime;
            if (gameOverTransitionTimer > 0)
            {
                UpdateUFO();
                UpdatePlayerBullets();
                UpdateInvaderBullets();
                UpdatePickups();
                UpdateParticles();
            }
            else
            {
                GameOver(false);
            }
        }

        void UpdateUFO()
        {
            if (UFO.IsAlive)
            {
                UFO.Position += UFO.Velocity;
                if (UFO.Position.X + TotalInvaders.UFOWidth < 0 || UFO.Position.X > ScreenSize.X)
                {
                    UFO.IsAlive = false;
                }
            }
            else if (State == GameState.Play)
            {
                if (Random.Next(800) == 0)
                {
                    UFO.IsAlive = true;
                    if (Random.Next(2) == 0)
                    {
                        UFO.Position.X = -TotalInvaders.UFOWidth;
                        UFO.Velocity.X = ufoSpeed;
                    }
                    else
                    {
                        UFO.Position.X = ScreenSize.X;
                        UFO.Velocity.X = -ufoSpeed;
                    }
                    UFO.Position.Y = 14;
                    UFO.Pickup = (PickupType)Random.Next(2);
                    CoreGlobals.AudioManager.PlaySound("InvadersUfo");
                }
            }
        }

        void UpdatePlayers()
        {
            bool move = false;

            if (Players[0].Velocity.X < 0)
            {
                move = Players[0].Position.X > 4;
            }
            else if (Players[0].Velocity.X > 0)
            {
                move = Players[Players.Count - 1].Position.X + PlayerWidth < ScreenSize.X - 4;
            }

            if (move)
            {
                for (int i = 0; i < Players.Count; i++)
                {
                    var p = Players[i];
                    p.Position += Players[0].Velocity;
                    Players[i] = p;
                }
            }
        }

        void UpdatePlayerBullets()
        {
            for (int i = PlayerBullets.Count - 1; i >= 0; i--)
            {
                var b = PlayerBullets[i];
                b.Position += b.Velocity;

                if (InvaderWave.CheckHit(b))
                {
                    PlayerBullets.RemoveAt(i);
                    UpdateScore(10);
                    CoreGlobals.AudioManager.PlaySound("InvadersExplosion");
                }
                else
                {
                    if (UFO.IsAlive)
                    {
                        if (b.Position.X <= UFO.Position.X + TotalInvaders.UFOWidth - 2 &&
                            b.Position.X + TotalInvaders.BulletWidth > UFO.Position.X &&
                            b.Position.Y < UFO.Position.Y + TotalInvaders.UFOHeight &&
                            b.Position.Y + TotalInvaders.BulletHeight > UFO.Position.Y)
                        {
                            UFODestroyed(i);
                            PlayerBullets.RemoveAt(i);
                            continue;
                        }
                    }

                    if (b.Position.Y < -TotalInvaders.BulletHeight)
                    {
                        PlayerBullets.RemoveAt(i);
                    }
                    else
                    {
                        PlayerBullets[i] = b;
                    }
                }
            }
        }

        void UFODestroyed(int i)
        {
            AddExplosionParticles(UFO.Position + new Vector2(TotalInvaders.InvaderWidth / 2, TotalInvaders.InvaderHeight / 2), UFO.Velocity, new Color(181, 0, 208), 30);
            CoreGlobals.AudioManager.PlaySound("InvadersPlayerExplosion");
            UFO.IsAlive = false;
            UpdateScore(50);

            if (Random.Next(3) == 0)
            {
                int pk = Random.Next(2);
                if (pk > 0)
                {
                    Vector2 pos = UFO.Position;
                    pos.X += TotalInvaders.UFOWidth / 2 - TotalInvaders.PickupWidth / 2;

                    var pickup = new Pickup()
                    {
                        IsAlive = true,
                        PickupType = (PickupType)pk,
                        Position = pos,
                        Velocity = new Vector2(0f, pickupSpeed)
                    };
                    Pickups.Add(pickup);
                }
            }
        }

        void UpdateInvaderBullets()
        {
            for (int i = InvaderBullets.Count - 1; i >= 0; i--)
            {
                var b = InvaderBullets[i];
                b.Position += b.Velocity;

                if (CheckHitOnPlayer(b))
                {
                    InvaderBullets.RemoveAt(i);
                }
                else
                {
                    if (b.Position.Y > ScreenSize.Y)
                    {
                        InvaderBullets.RemoveAt(i);
                    }
                    else
                    {
                        InvaderBullets[i] = b;
                    }
                }
            }
        }

        void UpdatePickups()
        {
            for (int i = Pickups.Count - 1; i >= 0; i--)
            {
                var p = Pickups[i];
                p.Position += p.Velocity;

                if (CheckHitOnPlayer(p))
                {
                    PlayerGotPickup(p.PickupType);
                    Pickups.RemoveAt(i);
                }
                else
                {
                    if (p.Position.Y > ScreenSize.Y)
                    {
                        Pickups.RemoveAt(i);
                    }
                    else
                    {
                        Pickups[i] = p;
                    }
                }
            }
        }

        void PlayerGotPickup(PickupType type)
        {
            switch (type)
            {
                case PickupType.PlayerShip:
                    AddPlayerShip();
                    break;
            }
        }

        bool CheckHitOnPlayer(Bullet b)
        {
            for (int i = Players.Count - 1; i >= 0; i--)
            {
                var p = Players[i];
                if (b.Position.X <= p.Position.X + TotalInvaders.PlayerWidth - 2 &&
                    b.Position.X + TotalInvaders.BulletWidth > p.Position.X &&
                    b.Position.Y < p.Position.Y + TotalInvaders.PlayerHeight - 1 &&
                    b.Position.Y + TotalInvaders.BulletHeight > p.Position.Y + 4)
                {
                    AddExplosionParticles(p.Position + new Vector2(TotalInvaders.PlayerWidth / 2, TotalInvaders.PlayerHeight / 2), p.Velocity, new Color(192, 192, 192), 120);
                    Players.RemoveAt(i);
                    CoreGlobals.AudioManager.PlaySound("InvadersPlayerExplosion");
                    if (Players.Count == 0) GameOver(true);
                    return true;
                }
            }

            return false;
        }

        bool CheckHitOnPlayer(Pickup p)
        {
            for (int i = 0; i < Players.Count; i++)
            {
                var pl = Players[i];
                if (p.Position.X <= pl.Position.X + TotalInvaders.PlayerWidth - 2 &&
                    p.Position.X + TotalInvaders.PickupWidth > pl.Position.X &&
                    p.Position.Y < pl.Position.Y + TotalInvaders.PlayerHeight &&
                    p.Position.Y + TotalInvaders.PickupHeight > pl.Position.Y)
                {
                    return true;
                }
            }

            return false;
        }

        void UpdateParticles()
        {
            for (int i = Particles.Count - 1; i >= 0; i--)
            {
                var p = Particles[i];
                p.Position += p.Velocity;

                if (p.Position.Y < 0 || p.Position.X < 0 || p.Position.Y > ScreenSize.Y || p.Position.X > ScreenSize.X)
                {
                    Particles.RemoveAt(i);
                }
                else
                {
                    p.Age -= Services.ElapsedTime;
                    if (p.Age < 0)
                    {
                        Particles.RemoveAt(i);
                    }
                    else
                    {
                        p.Velocity.X *= 0.99f;
                        p.Velocity.Y *= 0.99f;
                        Particles[i] = p;
                    }
                }
            }
        }

        void UpdateCollisions()
        {
            //for (int i = 0; i < playerBullets.Array.Length; i++)
            //{
            //    if (playerBullets.Array[i].IsAlive)
            //    {
            //    }
            //}
        }

        void UpdateScore(int inc)
        {
            if (inc != 0)
            {
                Score += inc;
                ScoreText = "Score: " + Score.ToString();

                if (Score > TotalInvaders.HighScore)
                {
                    TotalInvaders.HighScore = Score;
                    TotalInvaders.HighScoreText = "High Score: " + TotalInvaders.HighScore.ToString();

                    if (!highscoreGamerUpdated)
                    {
                        TotalInvaders.HighScoreGamer = tmPlayer.Gamertag;
                        highscoreGamerUpdated = true;
                    }
                }

                tmPlayer.Raise_TotalInvadersScore(Score);
            }
        }

        void AddPlayerShip()
        {
            if (Players.Count < 14)
            {
                var player = new Player(true);
                player.Position = Players[Players.Count - 1].Position;
                Players.Add(player);

                float x = (Players.Count == 1 ? TotalInvaders.PlayerWidth + 4 : Players[0].Position.X - (TotalInvaders.PlayerWidth + 4) / 2);

                for (int i = 0; i < Players.Count; i++)
                {
                    var p = Players[i];
                    p.Position.X = x;
                    Players[i] = p;
                    x += TotalInvaders.PlayerWidth + 4;
                }
            }
        }

        public void AddExplosionParticles(Vector2 position, Vector2 velocity, Color color, int count)
        {
            int ecl = explosionColors.Length;

            while (count-- > 0)
            {
                var p = new Particle();
                p.Position = position;
                p.Age = (float)(Random.NextDouble() * 0.5 + 1.0);
                p.Velocity = velocity * 0.5f;
                p.Velocity.X += (float)(Random.NextDouble() * 2.5 - 1.25);
                p.Velocity.Y += (float)(Random.NextDouble() * 2.5 - 1.25);
                int r = Random.Next(ecl * 2);
                p.Color = r < ecl ? explosionColors[r] : color;
                Particles.Add(p);
            }
        }

        #endregion
    }
}

cont next post...
« Last Edit: March 22, 2016, 09:15:19 AM by Craig »

Craig

  • Developer
  • Extreme Member
  • *
  • Posts: 6655
  • Dig Deep
    • View Profile
    • Twitter
  • Steam: tota1miner
Re: PWR's PRGRSS - Learning C#
« Reply #155 on: March 22, 2016, 09:15:31 AM »
TotalInvadersRenderer.cs
Code: [Select]
using Craig.Engine;
using Craig.Engine.Integration;
using Craig.Engine.Core;
using Craig.TotalMiner.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Craig.TotalMiner.Arcade.TotalInvaders
{
    class TotalInvadersRenderer : IHasContent
    {
        #region Fields

        SpriteBatchSafe spriteBatch;
        TotalInvaders game;
        Texture2D texture;

        #endregion

        #region Initialization

        public void LoadContent(InitState state)
        {
            spriteBatch = CoreGlobals.SpriteBatch;
            texture = CoreGlobals.Content.Load<Texture2D>(@"Textures\TotalInvaders");
        }

        public void UnloadContent()
        {
        }

        #endregion

        #region Draw

        public void Draw(TotalInvaders game)
        {
            this.game = game;
            CoreGlobals.GraphicsDevice.SetRenderTarget(game.RenderTarget);
            CoreGlobals.GraphicsDevice.Clear(Color.Black);

            spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, DepthStencilState.None, null);

            if (game.State == TotalInvaders.GameState.GameOver)
            {
                DrawGameOver();
                DrawHud();
            }
            else
            {
                DrawWave();
                DrawPlayer();
                DrawBullets();
                DrawPickups();
                DrawParticles();
                DrawHud();
            }

            spriteBatch.End();
        }

        void DrawWave()
        {
            int y = (game.AnimFrame % 2) == 0 ? 0 : 15;
            var rect = new Rectangle() { Width = TotalInvaders.InvaderWidth, Height = TotalInvaders.InvaderHeight };
            var srcrect = new Rectangle() { X = 0, Y = y, Width = TotalInvaders.InvaderWidth, Height = TotalInvaders.InvaderHeight };
            var wave = game.InvaderWave;

            foreach (var invader in wave.Invaders)
            {
                if (invader.IsAlive)
                {
                    rect.X = (int)(invader.Position.X + wave.Position.X);
                    rect.Y = (int)(invader.Position.Y + wave.Position.Y);
                    spriteBatch.Draw(texture, rect, srcrect, Color.White);
                }
            }

            if (game.UFO.IsAlive)
            {
                rect.X = (int)game.UFO.Position.X;
                rect.Y = (int)game.UFO.Position.Y;
                rect.Width = TotalInvaders.UFOWidth;
                rect.Height = TotalInvaders.UFOHeight;
                srcrect.X = 17;
                srcrect.Y = 13;
                srcrect.Width = TotalInvaders.UFOWidth;
                srcrect.Height = TotalInvaders.UFOHeight;
                spriteBatch.Draw(texture, rect, srcrect, Color.White);
            }
        }

        void DrawPlayer()
        {
            var rect = new Rectangle() { Width = TotalInvaders.PlayerWidth, Height = TotalInvaders.PlayerHeight };
            var srcrect = new Rectangle() { X = 17, Y = 0, Width = TotalInvaders.PlayerWidth, Height = TotalInvaders.PlayerHeight };

            for (int i = 0; i < game.Players.Count; i++)
            {
                rect.X = (int)game.Players[i].Position.X;
                rect.Y = (int)game.Players[i].Position.Y;
                spriteBatch.Draw(texture, rect, srcrect, Color.White);
            }
        }

        void DrawBullets()
        {
            Rectangle rect = new Rectangle();
            rect.Width = TotalInvaders.BulletWidth;
            rect.Height = TotalInvaders.BulletHeight;

            foreach (var bullet in game.PlayerBullets)
            {
                rect.X = (int)bullet.Position.X;
                rect.Y = (int)bullet.Position.Y;
                spriteBatch.Draw(CoreGlobals.BlankTexture, rect, Color.White);
            }

            foreach (var bullet in game.InvaderBullets)
            {
                rect.X = (int)bullet.Position.X;
                rect.Y = (int)bullet.Position.Y;
                spriteBatch.Draw(CoreGlobals.BlankTexture, rect, Color.White);
            }
        }


        void DrawPickups()
        {
            Rectangle rect = new Rectangle();
            rect.Width = TotalInvaders.PickupWidth;
            rect.Height = TotalInvaders.PickupHeight;
            var srcrect = new Rectangle() { X = 17, Y = 22, Width = TotalInvaders.PickupWidth, Height = TotalInvaders.PickupHeight };

            foreach (var pickup in game.Pickups)
            {
                rect.X = (int)pickup.Position.X;
                rect.Y = (int)pickup.Position.Y;
                spriteBatch.Draw(texture, rect, srcrect, Color.White);
            }
        }

        void DrawParticles()
        {
            Rectangle rect = new Rectangle();
            rect.Width = 2;
            rect.Height = 2;
            float alpha = 1f;

            foreach (var p in game.Particles)
            {
                rect.X = (int)p.Position.X;
                rect.Y = (int)p.Position.Y;
                alpha = p.Age < 0.5f ? p.Age * 2f : 1f;
                spriteBatch.Draw(CoreGlobals.BlankTexture, rect, p.Color * alpha);
            }
        }

        void DrawHud()
        {
            spriteBatch.DrawString(GraphicStatics.InvadersFont, game.ScoreText, new Vector2(4f, 0f), Color.White, 0f, Vector2.Zero, 0.7f, SpriteEffects.None, 0f);
            spriteBatch.DrawString(GraphicStatics.InvadersFont, TotalInvaders.HighScoreText, new Vector2(110f, 0f), Color.White, 0f, Vector2.Zero, 0.7f, SpriteEffects.None, 0f);
            spriteBatch.DrawString(GraphicStatics.InvadersFont, game.WaveText, new Vector2(250f, 0f), Color.White, 0f, Vector2.Zero, 0.7f, SpriteEffects.None, 0f);
        }

        void DrawGameOver()
        {
            int v = TotalMinerGame.ExeVersion;
            string vtext = string.Format("V{0}.{1}.{2:D3}", v / 10000, (v % 10000) / 1000, v % 1000);
            spriteBatch.DrawString(GraphicStatics.InvadersFont, vtext, new Vector2(4f, 10f), Color.White, 0f, Vector2.Zero, 0.7f, SpriteEffects.None, 1f);
            spriteBatch.DrawString(GraphicStatics.InvadersFont, TotalInvaders.HighScoreGamer, new Vector2(110f, 10f), Color.White, 0f, Vector2.Zero, 0.7f, SpriteEffects.None, 1f);
            spriteBatch.DrawStringCentered(GraphicStatics.InvadersFont, "Total", 35, Color.White, 2.2f);
            spriteBatch.DrawStringCentered(GraphicStatics.InvadersFont, "Invaders", 65, Color.White, 2.2f);
            spriteBatch.DrawStringCentered(GraphicStatics.InvadersFont, "Game Over", 130, Color.White, 1.6f);
            spriteBatch.DrawStringCentered(GraphicStatics.InvadersFont, game.CreditText, 170, Color.White, 1f);
        }

        #endregion
    }
}

PWRBTTN

  • Legendary Member
  • *
  • Posts: 1172
  • Professional Expert, Comrade
    • View Profile
  • Xbox: PWRBTTN
  • Steam: PWRBTTN
Re: PWR's PRGRSS - Learning C#
« Reply #156 on: March 22, 2016, 05:48:56 PM »
Mind if I ask... uh... why do you use your name in the code?
/snail       /snail    /snail         /snail /snail      /snail   /snail                /snail        

Dryym

  • Supreme Member
  • *
  • Posts: 4336
  • What's yours is mine. ~TM's Resident Master Thief~
    • View Profile
  • Xbox: dryym
Re: PWR's PRGRSS - Learning C#
« Reply #157 on: March 22, 2016, 06:25:33 PM »
Mind if I ask... uh... why do you use your name in the code?

Why not? It seems to serve as both a watermark, And a way to determine what code is his, And what code is MS resources, Or something like that.

I'd say it's most likely for identification if there is a reason to it. Otherwise I'd think he just does it because he can.

Creator of the term "Deathmine "
Jared [19|Oct 07:12 PM]: "It changes everything" Dryym

Craig

  • Developer
  • Extreme Member
  • *
  • Posts: 6655
  • Dig Deep
    • View Profile
    • Twitter
  • Steam: tota1miner
Re: PWR's PRGRSS - Learning C#
« Reply #158 on: April 03, 2016, 11:10:03 PM »
You might find this interesting.

https://handmadehero.org/

He writes a game from scratch on Windows without the use of libraries, engines or frameworks, and explains everything in reasonable detail.

He programs using C rather than C++ so you won't get bogged down in OOP details.

He uses just a text editor to edit the source code, rather than an IDE, so again you won't get bogged down in IDE details.

Pretty much as basic as it gets when it comes to writing a game without an engine. A very good resource. You learn how to do real programming for yourself, rather than how to use other peoples libraries/engines/frameworks.

PWRBTTN

  • Legendary Member
  • *
  • Posts: 1172
  • Professional Expert, Comrade
    • View Profile
  • Xbox: PWRBTTN
  • Steam: PWRBTTN
Re: PWR's PRGRSS - Learning C#
« Reply #159 on: April 04, 2016, 09:06:02 AM »
Sweet, I'll check it out here in a bit. I guess I'll use that to learn C.
/snail       /snail    /snail         /snail /snail      /snail   /snail                /snail