'Project1.Player'是'type',但像'variable'一样使用



我正在通过改进一个基于C#文本的开源冒险来学习一些C#。我正在努力保存所有的播放器数据到一个文件并加载它。

当我尝试序列化播放器类时,编译器抛出错误:

'Project1.Player' is a 'type' but is used like a 'variable' Program.cs:72

更新好的,为了让事情变得更容易,我将所有代码更新到了当前状态。每次我提到玩家时,我都会遇到一个新错误:The name 'player' does not exist in the current context

程序.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace Project1
{
    class Program
    {
        public static int windowWidth = 80;
        public static int windowHeight = 35;
        public static bool run = true;
        public static string errorMessage;
        public static bool isError = false;
        static void Main(string[] args)
        {
            // setup console window
            Console.Clear(); 
            // set size
            Console.SetWindowSize(windowWidth, windowHeight);
            // remove scroll bar with buffer size equal to window size
            Console.BufferWidth = windowWidth;
            Console.BufferHeight = windowHeight;
            // generate world
            Player player = new Player();
            World.GenerateWorld();
            // begin character creation
            string name = Text.Prompt("Welcome stranger.  What is your name?");
            player.name = name;
            player.inventory.Add(new Item("Candle", "A single white candle.", 22));
            Text.WriteLine("Thanks, " + name);
            Text.WriteLine("Press any key to get started.");
            Console.ReadKey();
            Console.Clear();
            Text.WriteLine("The last thing you remember is battling the Ancient LichLord deep within a cavern beneath Death Mountain.   Now suddenly, you are surrounded by the darkness of true night as you stand in front of an ancient stone castle of complex architecture.  Looking up, you notice the faint glow of a light coming from an old clock tower, high above the castle.  The doors to the castle are large and covered in an ancient mold. Unsure of what to do, you drag open the large wooden door, light the candle you found in your pocket, and step into the castle. n nPress a key...");
            Console.ReadKey();
            Console.Clear();
            while (run)
            {
                if (!isError)
                {
                    Text.SetPrompt();
                    World.LocationDescription();
                    string temp = Text.Prompt("");
                    Console.Clear();
                    player.Do(temp);
                }
                // there is an error
                else
                {
                    DisplayError();
                }
            }
        }
        // stream writer to write to file.
        public static void SaveGame()
        {
            try
            {
                using (Stream stream = File.Open("save.dat", FileMode.Create))
                {
                    BinaryFormatter bin = new BinaryFormatter();
                    bin.Serialize(stream, player);
                }
            }
            catch (IOException)
            {
            }
        }
        public static void LoadGame()
        {
            if (File.Exists("save.dat"))
            {
                try
                {
                using (Stream stream = File.Open("save.dat", FileMode.Open))
                    {
                        BinaryFormatter bin = new BinaryFormatter();
                        var player = bin.Deserialize(stream);
                    }
                }
                catch (IOException)
                {
                }
            }
            else
            {
                Program.SetError("The savegame does not exist!");
            }
        }
        // stream reader to find file
        //public static void LoadGame()
        //{
        //    try
        //    {
        //        using (Stream stream = File.Open("data.bin", FileMode.Open))
        //        {
        //            BinaryFormatter bin = new BinaryFormatter();
        //            World.map = (List<Location>)bin.Deserialize(stream);
        //        }
        //    }
        //    catch (IOException)
        //    {
        //    }
        //}
        public static void WinGame()
        {
            run = false;
            Text.WriteLine("As you place the crown upon your head, your vision begins to blur and you fall to the floor.   You wake up in a hot cavern, lit by a few torches on the wall.  This is the cavern of the Ancient LichLord, and you have escaped his twisted maze. ");
        }
        #region Error Handling
        public static void SetError(string aText)
        {
            isError = true;
            errorMessage = aText;
        }
        public static void UnsetError()
        {
            isError = false;
            errorMessage = "";
        }
        public static void DisplayError()
        {
            Text.WriteColor("|r|" + errorMessage + "|g|");
            Text.BlankLines(2);
            UnsetError();
        }
        #endregion
    }
}

Player.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace Project1
{
    [Serializable()]
    class Player
    {
        public string name;
        //public static string desc;
        //public static int[] stats;
        public int location;
        public List<Item> inventory = new List<Item>();
        public string[] possibleActions = new string[] { "move", "m", "look", "l", "take", "t", "drop", "d", "use", "u", "inventory", "i", "help", "h", "quit", "exit", "save", "load", "name" };
        /// <summary>
        /// Player action, array of predicate and target
        /// </summary>
        /// <param name="aAction"></param>
        /// <returns></returns>
        public void Do(string aText)
        {
            string verb = "";
            string noun = "";
            // check if there is a space in the given command
            if (aText.IndexOf(' ') != -1)
            {
                // split the string into the verb and noun
                string[] temp = aText.Split(new char[] { ' ' }, 2);
                verb = temp[0].ToLower();
                noun = temp[1].ToLower();
            }
            else
            {
                // verb only
                verb = aText.ToLower();
            }
            if (IsAction(verb))
            {
                // do whatever action
                switch (verb)
                {
                    case "move":
                    case "m":
                        if (noun == "")
                            Program.SetError("You must specify a location to move.");
                        else
                            MoveTo(noun);
                        break;
                    case "look":
                    case "l":
                        if (noun == "")
                            noun = World.map[player.location].name;
                        LookAt(noun);
                        break;
                    case "take":
                    case "t":
                        if (noun == "")
                            Program.SetError("You must specify an item to take.");
                        else
                            PickUpItem(noun);
                        break;
                    case "drop":
                    case "d":
                        if (noun == "")
                            Program.SetError("You must specify an item to drop.");
                        else
                            DropItem(noun);
                        break;
                    case "use":
                    case "u":
                        if (noun == "")
                            Program.SetError("You must specify an item to use.");
                        else
                            UseItem(noun);
                        break;
                    case "inventory":
                    case "i":
                        ListInventory();
                        break;
                    case "help":
                    case "h":
                        ListActions();
                        break;
                    case "quit":
                    case "exit":
                        QuitPrompt();
                        break;
                    case "save":
                        Program.SaveGame();
                        break;
                    case "load":
                        Program.LoadGame();
                        break;
                    case "name":
                        Console.WriteLine("Your name is {0}", player.name);
                        Console.WriteLine("");
                        break;
                }
            }
            else
            {
                // not a real action
                Program.SetError("Action not found.");
            }
        }
        public void MoveTo(string location)
        {
            // is location?
            if (World.IsLocation(location))
            {
                int locationId = World.GetLocationIdByName(location);
                if (World.IsLocationExit(location))
                {
                    // set the player's new location
                    player.location = locationId;
                }
                else
                {
                    Program.SetError("You can't get there from here.");
                }
            }
            else
            {
                Program.SetError("That is not a real location.");
            }
        }
        public void LookAt(string noun)
        {
            // is location?  
            if (World.IsLocation(noun))
            {
                Console.Clear();
                World.ShowHiddenItems();
                Text.BlankLines(2);
            }
            // is item?
            else if (Item.IsItemInInventory(noun) || Item.IsItemInLocation(noun))
            {
                Console.Clear();
                Text.WriteLine(Item.GetItemDescByName(noun));
                Text.BlankLines(2);
            }
        }
        public void PickUpItem(string item)
        {
            // is item?
            if (Item.IsItemInLocation(item))
            {
                // get description
                string desc = Item.GetItemDescByName(item);
                int actionLocationId = Item.GetItemActionLocationIdByName(item);
                // remove item from location
                Item.RemoveItemFromLocation(item);
                // add item to inventory
                player.inventory.Add(new Item(item, desc, actionLocationId));
            }
            else
            {
                Program.SetError("Item not found in this location.");
            }
        }
        public void DropItem(string item)
        {
            //is item?
            if (Item.IsItemInInventory(item))
            {
                string desc = Item.GetItemDescByName(item);
                int actionLocationId = Item.GetItemActionLocationIdByName(item);
                // remove item from inventory
                RemoveInventoryItem(item);
                // add item to location
                World.map[player.location].items.Add(new Item(item, desc, actionLocationId));
            }
            else
            {
                Program.SetError("Item not in inventory.");
            }
        }
        public void RemoveInventoryItem(string item)
        {
            for (int i = 0; i < player.inventory.Count; i++)
            {
                if (player.inventory[i].name.ToLower() == item.ToLower())
                {
                    player.inventory.RemoveAt(i);
                }
            }
        }
        public void UseItem(string item)
        {
            // is item?
            if (Item.IsItemInInventory(item))
            {
                // get item actionLocationId
                int itemActionLocationId = Item.GetItemActionLocationIdByName(item);
                if (itemActionLocationId == player.location)
                {
                    World.UseItemInLocation(item);
                }
                else
                {
                    Program.SetError("You're not sure how that helps here.");
                }
            }
            else
            {
                Program.SetError("Item not in inventory");
            }
        }
        public void ListInventory()
        {
            Text.WriteLine("n-- Inventory -- n");
            for (int i = 0; i < player.inventory.Count; i++)
            {
                Text.WriteLine(i.ToString() + ": "+ player.inventory[i].name);
            }
            Text.BlankLines(2);
        }
        public void ListActions()
        {
            Text.BlankLines(2);
            //"move", "look", "take", "drop", "use", "inventory", "help"
            Text.WriteLine("n-- Actions -- n");
            Text.WriteLine("move - travel to another location.   usage: move entrance hall (or) m entrance hall");
            Text.WriteLine("look - look at a location or an item.   usage: look entrance hall (or) look sword (or) l entrance hall (or) l sword");
            Text.WriteLine("take - pick up an item in a location.   usage: take sword (or) t sword");
            Text.WriteLine("drop - drop an item from your inventory.   usage: drop sword (or) d sword");
            Text.WriteLine("use - use an item in your inventory.   usage: use key (or) u key");
            Text.WriteLine("inventory - show items in your inventory.   usage: inventory (or) i");
            Text.WriteLine("help - show this screen.   usage: help (or) h");
            Text.WriteLine("exit - quit the game.    usage: quit (or) exit");
            Text.BlankLines(2);
        }
        /// <summary>
        /// Check the legitmacy of the action
        /// </summary>
        /// <param name="aText"></param>
        /// <returns></returns>
        public bool IsAction(string aText)
        {
            for (int i = 0; i < possibleActions.Length; i++)
            {
                if (aText == possibleActions[i])
                {
                    return true;
                }
            }
            return false;
        }
        public void QuitPrompt()
        {
            Text.WriteLine("Are you sure you want to leave?  y/n");
            string answer = Console.ReadLine().ToLower();
            if (answer == "y" || answer == "yes")
            {
                Program.run = false;
            }
        }
    }
}

项目.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Project1
{
    class Item : Entity
    {
        public bool isHidden = false;
        public int actionLocationId;
        public string actionName;
        public Item(string aName, string aDesc, int aActionLocationId, bool aIsHidden = false, string aActionName = "use")
            :base(aName, aDesc)
        {
            actionLocationId = aActionLocationId;
            actionName = aActionName;
            if (aIsHidden)
                isHidden = aIsHidden;
        }
        /// <summary>
        /// Looks for item in player.inventory
        /// </summary>
        /// <param name="aName">name of the Item</param>
        /// <returns></returns>
        public static bool IsItemInInventory(string aName)
        {
            // look for item in inventory
            for (int i = 0; i < player.inventory.Count; i++)
            {
                if (player.inventory[i].name.ToLower() == aName.ToLower())
                {
                    return true;
                }
            }
            // not found
            return false;
        }
        /// <summary>
        /// Looks for item in current location
        /// </summary>
        /// <param name="aName">name of the Item</param>
        /// <returns></returns>
        public static bool IsItemInLocation(string aName)
        {
            // look for item in location
            for (int i = 0; i < World.map[player.location].items.Count; i++)
            {
                if (World.map[player.location].items[i].name.ToLower() == aName.ToLower())
                {
                    return true;
                }
            }
            // not found
            return false;
        }

        /// <summary>
        /// Items are only items if in player.inventory or player.location
        /// </summary>
        /// <param name="aName">name of the Item</param>
        /// <returns></returns>
        public static string GetItemDescByName(string aName)
        {
            // look for item in location
            for (int i = 0; i < World.map[player.location].items.Count; i++)
            {
                if (World.map[player.location].items[i].name.ToLower() == aName.ToLower())
                {
                    return World.map[player.location].items[i].description;
                }
            }
            // look for item in inventory
            for (int i = 0; i < player.inventory.Count; i++)
            {
                if (player.inventory[i].name.ToLower() == aName.ToLower())
                {
                    return player.inventory[i].description;
                }
            }
            // not found
            return "Item not found";
        }
        public static int GetItemActionLocationIdByName(string aName)
        {
            // look for item in inventory
            for (int i = 0; i < player.inventory.Count; i++)
            {
                if (player.inventory[i].name.ToLower() == aName.ToLower())
                {
                    return player.inventory[i].actionLocationId;
                }
            }
            // look for item in location
            for (int i = 0; i < World.map[player.location].items.Count; i++)
            {
                if (World.map[player.location].items[i].name.ToLower() == aName.ToLower())
                {
                    return World.map[player.location].items[i].actionLocationId;
                }
            }
            return -1;
        }
        public static void RemoveItemFromLocation(string item)
        {
            for (int i = 0; i < World.map[player.location].items.Count; i++ )
            {
                if (World.map[player.location].items[i].name.ToLower() == item.ToLower())
                {
                    World.map[player.location].items.RemoveAt(i);
                }
            }
        }
    }
}

请注意3件事:

  1. 我正在学习C#,我来自JS背景
  2. 我意识到我试图保存球员数据的方式有一些严重的问题,但这就是我来这里的原因
  3. 这是我第一次尝试在程序中保存大量数据,所以这里有很多实验

在使用Player对象之前,您需要实例化它,因此:

Player.name = name;
Player.inventory.Add(new Item("Candle", "A single white candle.", 22));

应该是这样的:

var player = new Player();
player.name = name;
player.inventory.Add(new Item("Candle", "A single white candle.", 22));
// etc...

在实例化Player对象(使用new关键字)后,只需将所有Player.调用替换为player.(或您决定调用播放器变量的任何调用)。

更新

Player类实际上是静态的(意味着一次只能定义一个)。我建议将其更改为类似的内容

class Player
{
    public string name;
    public int location;
    public List<Item> inventory = new List<Item>();
    public string[] possibleActions = new string[] { "move", "m", "look", "l", "take", "t", "drop", "d", "use", "u", "inventory", "i", "help", "h", "quit", "exit", "save", "load", "name" };
    /// <summary>
    /// Player action, array of predicate and target
    /// </summary>
    /// <param name="aAction"></param>
    /// <returns></returns>
    public void Do(string aText)
    {
        // ...
    }
    public void MoveTo(string location)
    {
        // ...
    }
    public void LookAt(string noun)
    {
        // ...
    }
    public void PickUpItem(string item)
    {
        // ...
    }
    public void DropItem(string item)
    {
        // ...
    }
    public void RemoveInventoryItem(string item)
    {
        // ...
    }
    public void UseItem(string item)
    {
        // ...
    }
    public void ListInventory()
    {
        // ...
    }
    public void ListActions()
    {
        // ...
    }
    /// <summary>
    /// Check the legitmacy of the action
    /// </summary>
    /// <param name="aText"></param>
    /// <returns></returns>
    public bool IsAction(string aText)
    {
        // ...
    }
    public void QuitPrompt()
    {
        // ...
    }
}

然后,如果您真的只需要Player的一个全局实例,那么在Program:中将其定义为静态

public static Player CurrentPlayer = new Player();

如果你这样做,那么你可以访问Player实例,比如:

CurrentPlayer.name = name;
CurrentPlayer.inventory.Add(new Item("Candle", "A single white candle.", 22));

另一方面,如果只处理Player的一个实例并不重要,那么您可以从Player类中删除所有static关键字。这应该可以让你克服错误。

更新

我在下面的评论中推荐的解决方案大致如下(没有你问题中代码的所有细节):

public class Player
{
    public static Player CurrentPlayer = new Player(); // This is your global instance
    public string name;
    // All of your other content here
}
public class Program
{
    public static void Main()
    {
        // In here we can access our global instance of `Player` to change it as needed
        Player.CurrentPlayer.name = "Some Name Here";
    }
}

将静态CurrentPlayer字段添加到Player类后,您可以将所有三个代码文件中对player的所有引用更改为Player.CurrentPlayer

要使代码正常工作,您必须将Player类实现为静态类。但是,只有在必要时才使用静态类。

否则,你必须创建一个Player类的实例来处理它

Player player = new Player();
player.name = name;
....

正如错误消息明确指出的那样,您需要将变量作为参数(播放器的实例),而不是类,例如播放器类。

你似乎误解了类的使用,因为播放器类中的所有东西都是静态的,所以类的每个实例都共享,所以实例化变得毫无用处。如果您只希望拥有一个播放器实例,那么您应该了解singleton模式。

在您的示例中,正确的方法是删除播放器类中的静态声明,并在游戏中使用它之前初始化播放器类的新实例。

示例:

Player p = new Player(); 
p.Name = "Something"
...
try
{
    using (Stream stream = File.Open("save.dat", FileMode.Create))
    {
        BinaryFormatter bin = new BinaryFormatter();
        bin.Serialize(stream, p);
    }
}
catch (IOException)
{
}

最新更新