0

I've started a new XNA project and am having some issues communicating between classes. Essentially, I'm laying down framework for a tile-based platformer and have two very simple classes at the moment.

One class, Tile(Tile.cs) contains and enum, named TileCollision and a struct named Tile.

The other, Level(Level.cs). Any time I try to reference TileCollision or try to create a Tile, it says it doesn't exist in the current context.

Is there anything else I need to do to get these two classes to talk? They're in the same namespace and don't need references added since they're not compiled DLL's or anything. Not sure what I've missed.

Here's the code for Tile.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace PoriPlatformer
{
class Tile
{
    // Controls the collision detection and response behavior of a tile.
    enum TileCollision
    {
        // A passable tile is one which does not hinder player motion at all, Example: Air
        Passable = 0,

        // An impassible tile is one which does not allow the player to move through it at all
        // It is completely solid.
        Impassable = 1,

        // A platform tile is one which behaves like a passable tile except when the player
        // is above it. A player can jump up through the platform as well as move past it
        // to the left and right, but can not fall through the top of it. 
        Platform = 2,
    }

    struct Tile
    {
        public Texture2D Texture;
        public TileCollision Collision;

        public const int Width = 40;
        public const int Height = 32;

        public static readonly Vector2 Size = new Vector2(Width, Height);


        // Constructs a new tile
        public Tile(Texture2D texture, TileCollision collision)
        {
            Texture = texture;
            Collision = collision;
        }


    }

}
 }

Here's the offending code in Level.cs:

// Loads an individual tile's appearance and behavior.
    private Tile LoadTile(char tileType, int x, int y)
    {
        switch (tileType)
        {
            // Blank space
            case '.':
                return new Tile(null, TileCollision.Passable);

            // Passable platform
            case '~':
                return LoadTile("platform", TileCollision.Platform);

            // Impassable block
            case '#':
                return LoadTile("block", TileCollision.Impassable);

            case '_':
                return LoadTile("ground", TileCollision.Impassable);


            default:
                throw new NotSupportedException(String.Format("Unsupported tile type character '{0}' at position {1}, {2}.", tileType, x, y));
        }
    }

underlined portions in Level.cs would be TileCollision

Eric
  • 2,201
  • 5
  • 29
  • 35
  • Show us your code. That error message speaks something else. – tnw Apr 30 '13 at 19:49
  • You're error states that you're trying to access a `Tile` that doesn't exist. We would need more code to fully help you. – PiousVenom Apr 30 '13 at 19:56
  • 3
    What namespaces are in Level.cs? – joe Apr 30 '13 at 19:56
  • 1
    You're trying to access an enum (`TileCollision`) that is defined in a class. You need to access that that enum through a class instance (or move the enum outside of the class). I.e., `Tile tiles = new Tile(); tiles.TileCollision` – Tim Apr 30 '13 at 19:58
  • Edit: @Tim was right. I actually didn't even MEAN to put it inside the class. It just sort of happened that way. – Eric Apr 30 '13 at 20:00

3 Answers3

2

Please see this post.

The default scope for the enum and struct defined inside your Tile class is private, so they're only accessible from the Tile class. You need to change them to internal or public for them to be visible from another class in the same namespace.

Community
  • 1
  • 1
Chris
  • 21
  • 1
2

As I put in my comment, TileCollision is a member of class Tile. To access it you would have to have an instance of Tile.

A better way would be to move the enum declaration for TileCollision outside of the class, like this:

public enum TileCollision
{
       Passable = 0,
       Impassable = 1,
       Platform = 2,
}

class Tile { ... }

Then, assuming Level.cs is in the same namespace, statements like:

return new Tile(null, TileCollision.Passable);

Should work.

Tim
  • 28,212
  • 8
  • 63
  • 76
  • You don't need an instance of `Tile`, you just need to reference it as `Tile.TileCollision` – Cemafor Apr 30 '13 at 20:04
  • You were exactly right. I was grabbing a bit of code from another project and just pasted it right into the newly created file, so it was inadvertently added to the class instead of just creating the enum and struct. – Eric Apr 30 '13 at 20:04
  • Don't even need to do `Tile.TileCollision`. `TileCollision` works just fine. Though, technically it doesn't hurt. – Eric Apr 30 '13 at 20:05
  • @Eric: Did you move `TileCollision` outside of Tile before trying that? You should need the `Tile.` if it is still nested, assuming you are accessing it from outside `Tile`. – Cemafor Apr 30 '13 at 20:09
  • @Cemafor I got rid of the class in Tile.cs all-together. It now contains only the enum and struct. I was able to run the project and was able to load all my tiles successfully. No errors, but I don't have a player or anything to physically test collision. We'll see later today. But if I do have problems, that'll be the first thing I try. – Eric Apr 30 '13 at 20:32
  • If you removed the outer `Tile` class, then the `Tile.` is no longer nessesary (and the outer class was a bit pointless anyway). And if you like, you can demote the enum and struct back down to private if they are no longer nested. – Cemafor Apr 30 '13 at 20:40
1

TileCollision and Tile (the nested struct) needs to be public to be seen outside of the class. Also, you need to reference them using there outer class first:

...
return LoadTile("block", Tile.TileCollision.Impassable);
...

and

...
new Tile.Tile();
...
Cemafor
  • 1,633
  • 12
  • 27