Pokémon Text Adventure

Over dit spel...

Dit is waarschijnlijk één van de gek makendste projecten die ik ooit heb gemaakt. Dit was voordat ik echt wist hoe ik moest programmeren en bijvoorbeeld met iets zoals Unity echt overweg kon.

Het resultaat van mijn toen halve kennis en nog niet weten hoe je object georienteerd moet programmeren waren arrays in arrays in arrays om alles bij te houden. Dat was nog verwarrender dan die zin. Het kwam uiteindelijk zover dat ik zelfs over die arrays begon te dromen. Dat was dan ook het punt waarop ik het een paar dagen compleet niet heb aangeraakt.

Maar, uiteindelijk ben ik hier alsnog trots op. Ondanks het feit dat ik geen idee had wat ik aan het doen was heb ik toch het begin van het spel nagemaakt en een groot gedeelte van de combat!

Engine: Console/C#
Platform: Windows

Battle.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Pokémon_text_adventure
{

    public class Battle
    {
        //Store 'em all here to save the mess
        public static class Globals
        {
            public static string enemy;
            public static int currentPKMN;
            public static string currentPKMNNName;
            public static int[,] enemyPKMN;
            public static int currentEnemyPKMN;
            public static bool wildPKMN;
            public static string currentEnemyPKMNName;
            public static bool battleOver = false;
            public static bool win;
            public static int pokeballs = 4;
        }
                                                                      //Whether current enemy is person or wild (false = person)
        public static bool startFight(string enemy, int[,] enemyPKMN, bool wildPKMN)
        {
            Globals.currentPKMN = 10;
            Globals.enemy = enemy;
            Globals.currentPKMNNName = "";
            Globals.enemyPKMN = enemyPKMN;
            Globals.wildPKMN = wildPKMN;
            Globals.currentEnemyPKMN = 0;
            Globals.currentEnemyPKMNName = pkmn.pkmnNames[enemyPKMN[0, 0], 0];
            Globals.battleOver = false;

            txt.Typewriter(enemy + " would like to fight!\n\n");

            choosePKMN();

            bool win = looper();
            return win;
        }

        public static bool looper()
        {
            if (Globals.battleOver == true)
            {
                return false;
            }
            else
            {
                chooseMove();
            }

            if (Globals.battleOver == true)
            {
                return Globals.win;
            }
            else
            {
                enemyTurn();
            }

            looper();

            if (Globals.battleOver == true)
            {
                return Globals.win;
            }

            else
            {
                return false;
            }
        }

        public static void choosePKMN()
        {
            txt.Typewriter("Which Pokémon do you choose?\n");
            pkmnNicknameWriter();
            string chosenPKMN = txt.acceptInput().ToLower();
            int i = 0;

            while (pkmn.playerPKMN[i, 0] != -1 && i != 6)
            {
                if (chosenPKMN == pkmn.pkmnNames[pkmn.playerPKMN[i, 0], pkmn.playerPKMN[i, 6]].ToLower())
                {
                    if (i != Globals.currentPKMN)
                    {
                        txt.Typewriter("Go " + pkmn.pkmnNames[pkmn.playerPKMN[i, 0], pkmn.playerPKMN[i, 6]] + "!\n\n");
                        Globals.currentPKMN = i;
                        Globals.currentPKMNNName = pkmn.pkmnNames[pkmn.playerPKMN[Globals.currentPKMN, 0], pkmn.playerPKMN[Globals.currentPKMN, 6]];
                        return;
                    }
                    else
                    {
                        txt.Typewriter("You can't choose the same Pokémon!\n\n");
                        looper();
                    }
                }

                i++;
            }

            txt.Typewriter("Did not recognize name.\n");
            choosePKMN();
        }

        //Shows all available Pokémon
        public static void pkmnNicknameWriter()
        {
            int i = 0;
            while (pkmn.playerPKMN[i, 0] != -1 && i != 6)
            {
                if (pkmn.playerPKMN[i, 5] > 0)
                {
                    Console.WriteLine("- " + pkmn.pkmnNames[pkmn.playerPKMN[i, 0], pkmn.playerPKMN[i, 6]]);
                }

                i++;
            }
        }

        //Checks if there are any player Pokémon available
        public static int pkmnStillAvailable()
        {
            int i = 0;
            int pkmnCount = 0;
            while (pkmn.playerPKMN[i, 0] != -1 && i != 6)
            {
                if (pkmn.playerPKMN[i, 5] > 0)
                {
                    pkmnCount++;
                }

                i++;
            }

            return pkmnCount;
        }

        public static void chooseMove()
        {
            txt.Typewriter("What will you do now?\n");
            Console.WriteLine(" -Attack-     -Bag-");
            Console.Write(" -Pokémon-    -Run-");

            string answer = txt.acceptInput().ToLower();

            if (answer == "attack")
            {
                attack(pkmnMoveSelector());
            }

            else if (answer == "bag" && Globals.pokeballs != 0)
            {
                txt.Typewriter("You have " + Globals.pokeballs + " Pokéballs left. Do you want to throw one?\n");

                answer = txt.acceptInput().ToLower();

                if (answer == "yes")
                {
                    if (Globals.wildPKMN == true)
                    {
                        Random rnd = new Random();
                        txt.Typewriter(Rooms.Globals.playerName + " threw a Pokéball!\n");
                        Globals.pokeballs--;

                        if (rnd.Next(1, 4) == 2)
                        {
                            txt.Typewriter("Congratulations! You caught a " + Globals.currentEnemyPKMNName + "!\n");
                            pkmn.caughtWildPKMN(Globals.enemyPKMN[Globals.currentEnemyPKMN,0], Globals.enemyPKMN);
                            Globals.battleOver = true;
                            Globals.win = true;
                        }

                        else
                        {
                            txt.Typewriter("Aww snap, it managed to escape!\n");
                        }
                    }

                    else
                    {
                        txt.Typewriter("You can't cath another trainer's Pokémon!\n");
                    }
                }

                looper();
            }

            else if (answer.Contains("bag") && Globals.pokeballs == 0)
            {
                txt.Typewriter("There are no more Pokéballs left!\n");
                looper();
            }

            else if (answer == "pokémon" || answer == "pokemon")
            {
                choosePKMN();
            }

            else if (answer == "run")
            {
                if (Globals.wildPKMN == false)
                {
                    txt.Typewriter("You can't run from a player!\n\n");
                    chooseMove();
                }

                else
                {
                    Random rnd = new Random();

                    if (rnd.Next(0, 3) == 1)
                    {
                        txt.Typewriter("Got away safely!");
                        Globals.battleOver = true;
                        Globals.win = true;
                        return;
                    }

                    else
                    {
                        txt.Typewriter("You failed to run away!");
                    }
                }
            }

            else
            {
                txt.wrongInput();
                looper();
            }
        }

        public static int pkmnMoveSelector()
        {
            txt.Typewriter("Which move do you choose?\n");

            //Writes all move names
            int i = 1;
            while (pkmn.playerPKMN[Globals.currentPKMN, i] != -1 && i != 5)
            {
                //Arrays in arrays in arrays...
                Console.WriteLine("- " + pkmn.pkmnMovesNames[pkmn.pkmnMoves[pkmn.playerPKMN[Globals.currentPKMN, i], 2]]);

                i++;
            }

            string answer = txt.acceptInput().ToLower();

            //Checks which move the player selected
            i = 0;
            while (pkmn.pkmnMovesNames[i] != "")
            {
                if (answer == pkmn.pkmnMovesNames[i].ToLower())
                {
                    return i;
                }
                i++;
            }

            txt.wrongInput();
            pkmnMoveSelector();

            return i;
        }


        //Player attack
        public static void attack(int attack)
        {
            txt.Typewriter(Globals.currentPKMNNName + " used " + pkmn.pkmnMovesNames[attack] + "!\n");

            //Gets damage & subtracts it from enemy
            int damage = attackEnemy(attack, pkmn.playerPKMN[Globals.currentPKMN, 8]);

            if (damage < 0)
            {
                damage = 0;
            }

            Globals.enemyPKMN[Globals.currentEnemyPKMN, 5] -= damage;

            //Enemy Pokémon dead
            if (Globals.enemyPKMN[Globals.currentEnemyPKMN, 5] <= 0)
            {
                txt.Typewriter(Globals.currentEnemyPKMNName + " fainted!\n");

                //Checks if there's a next Pokémon and switches to it
                if (Globals.enemyPKMN[Globals.currentEnemyPKMN + 1, 0] != -1)
                {
                    txt.Typewriter(Globals.currentPKMNNName + " gained 10 XP.\n");
                    pkmn.playerPKMN[0, 9] += 10;

                    levelChecker();

                    Globals.currentEnemyPKMN += 1;
                    Globals.currentEnemyPKMNName = pkmn.pkmnNames[Globals.enemyPKMN[Globals.currentEnemyPKMN, 0], 0];
                    txt.Typewriter(Globals.enemy + " sent out " + Globals.currentEnemyPKMNName + "!\n");
                    return;
                }
                //Player wins
                else
                {
                    txt.Typewriter(Rooms.Globals.playerName + " has won!\n" + Globals.currentPKMNNName + " gained 10 XP.\n");
                    pkmn.playerPKMN[0, 9] += 10;

                    levelChecker();

                    Globals.battleOver = true;
                    Globals.win = true;
                    return;
                }
            }

            txt.Typewriter(Globals.currentPKMNNName + " dealt " + damage + " damage!\nThe enemy " + Globals.currentEnemyPKMNName + " has " + Globals.enemyPKMN[Globals.currentEnemyPKMN, 5] + " hp left.\n\n");    
        }

        //Handles enemy move
        public static void enemyTurn()
        {
            //Checks how many moves there are to choose from
            Random rnd = new Random();
            int i = 1;
            while (Globals.enemyPKMN[Globals.currentEnemyPKMN, i] != -1 && Globals.enemyPKMN[Globals.currentEnemyPKMN, i] != 5)
            {
                i++;
            }

            i--;


            //Picks random attack for enemy
            int attack = rnd.Next(1, i);

            txt.Typewriter("The enemy " + Globals.currentEnemyPKMNName + " used " + pkmn.pkmnMovesNames[pkmn.pkmnMoves[Globals.enemyPKMN[Globals.currentEnemyPKMN, attack], 2]] + "!\n");

            //Damages player Pokémon
            string effect = typeChecker(attack, Globals.currentEnemyPKMN);
            int damage = (pkmn.pkmnMoves[attack, 0] * Globals.enemyPKMN[Globals.currentEnemyPKMN, 7]);
            pkmn.playerPKMN[Globals.currentPKMN, 5] -= damage;

            //If player Pokémon faints
            if (pkmn.playerPKMN[Globals.currentPKMN, 5] <= 0)
            {
                txt.Typewriter("Your " + Globals.currentPKMNNName + " has fainted!\n");

                if (pkmnStillAvailable() != 0)
                {
                    choosePKMN();
                    return;
                }

                else
                {
                    txt.Typewriter(Globals.enemy + " has won!\n");
                    Globals.battleOver = true;
                    Globals.win = false;
                    return;
                }
            }

            txt.Typewriter("The enemy " + Globals.currentEnemyPKMNName + " dealt " + damage + " damage!\nYour " + Globals.currentPKMNNName + " has " + pkmn.playerPKMN[Globals.currentPKMN, 5] + " hp left.\n\n");
        }

        //Allows for easy adding of new types
        public static string typeChecker(int attack, int pokemon)
        {
            string enemyType = pkmn.pkmnMovesNames[pkmn.pkmnMoves[Globals.enemyPKMN[pokemon, 0], 1]].ToLower();
            string moveType = pkmn.pkmnMovesTypes[pkmn.pkmnMoves[attack, 1]].ToLower();

            string effect;

            if ((enemyType == moveType && moveType != "normal") || (enemyType == "fire" && moveType == "flying") || (enemyType == "grass" && moveType == "flying"))
            {
                //Not very effective
                effect = "not";
            }
            else if ((enemyType == "fire" && moveType == "water") || (enemyType == "flying" && moveType == "fire") || (enemyType == "flying" && moveType == "grass"))
            {
                //Super effective
                effect = "very";
            }
            else
            {
                effect = "normal";
            }

            return effect;
        }

        public static int attackEnemy(int attack, int level)
        {
            //Sets standard damage
            int damage = (pkmn.pkmnMoves[attack, 0] * pkmn.playerPKMN[Globals.currentPKMN, 8]);

            //Checks critical hits
            Random rnd = new Random();

            int random = rnd.Next(0, 6);

            if (random == 1)
            {
                damage += 2;
            }

            //Adds effect bonus
            string effect = typeChecker(attack, Globals.currentEnemyPKMN);

            //Adds type bonus/loss
            if (effect == "not")
            {
                //Not very effective
                damage -= 2;
            }

            else if (effect == "very")
            {
                //Very effective
                damage += 2;
            }

            //Returns damage that needs to be dealt to target. (Doesn't do it here)
            return damage;
        }

        public static void levelChecker() //!----!
        {
            if (pkmn.playerPKMN[Globals.currentPKMN, 8] == 5 && pkmn.playerPKMN[Globals.currentPKMN, 9] >= 10)
            {
                pkmn.playerPKMN[Globals.currentPKMN, 8] = 6;
                txt.Typewriter("Your " + Globals.currentPKMN + " leveled up to level 6.\n");

                if (pkmn.playerPKMN[Globals.currentPKMN, 0] == 0)
                {
                    pkmn.playerPKMN[0, 3] = 2;
                    txt.Typewriter("It learned Vine Whip!\n");
                }
                if (pkmn.playerPKMN[Globals.currentPKMN, 0] == 1)
                {
                    pkmn.playerPKMN[0, 3] = 3;
                    txt.Typewriter("It learned Bubble!\n");
                }
                if (pkmn.playerPKMN[Globals.currentPKMN, 0] == 2)
                {
                    pkmn.playerPKMN[0, 3] = 4;
                    txt.Typewriter("It learned Burn!\n");
                }
            }
        }
    }
}

Downloads

Windows
Source