none
problem beim einfügen eines Menüs RRS feed

  • Frage

  • Hallo,

    ich habe nun (endlich ;) ) mein Spiel fertig gestellt und wollte nun noch zu guter letzt ein menü einfügen, was sich in der reihenfolge als nicht ideal heraufgestellt hat wie ich finde, denn nun habe  ich das problem das ich immer eine Null referece Exeption bekomme, wenn ich meinen Content laden will in der GameplayScreen klasse.

    Wie man merkt habe ich beim menü einfach das MS Tutorial genommen und etwas angepasst.

    Weiss jemand Rat für mich und kann mir sagen wie ich diesen (hoffentlich) letzten Bug geheben kann?

    lg Droggel

    Dienstag, 21. Februar 2012 12:51

Antworten

  • Holzweg.

    Für die Zukunft: Reindebuggen ^^

    Setz einen Breakpoint beim get vom Contentmanager. Du wirst sehen dass du da bereits null zurücklieferst.

    Wieso?

    Weil dein

    public ContentManager Content // kannst du auch private machen, wa?
            {
                get { return content; }
            }

    auf deine Variable

    ContentManager content;

    verweist, die aber wohl nie gesetzt wird.

    Ich denke in deiner Game.cs wird dein Levelobjekt initialisiert. Richtig?

    Dann änder den Konstruktor von Level ab

    public Level(ContentManager manager)
    {
    this.Content = manager;
    }

    und beim erstellen des Levels einfach

    Level level = new Level(Content);

    • Als Antwort markiert Droggel Freitag, 24. Februar 2012 11:55
    Donnerstag, 23. Februar 2012 17:02

Alle Antworten

  • Hi,

    ohne die entsprechende (einigermaßen vollständige) Fehlermeldung und den relevanten Code wird es schwer dir zu helfen. Kannst du die relevanten Teile bitte posten?


    Best Regards. When you see answers and helpful posts, please click Vote As Helpful, Propose As Answer, and/or Mark As Answer. This helps us build a healthy and positive community.

    Dienstag, 21. Februar 2012 14:19
  • Also das ist meine Game.cs bzw. durch das menu GamePlayScreen.cs:

    using System;
    using System.IO;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using Microsoft.Xna.Framework.Input.Touch;
    using System.Collections.Generic;
    using Microsoft.Xna.Framework.Audio;
    using System.Threading;
    using Microsoft.Xna.Framework.Content;
    
    
    namespace GameStateManagement.Screens
    {
        class GameplayScreen : GameScreen
        {
            ContentManager content;
    
            //Resources for drawing
            private GraphicsDeviceManager graphics;
            private SpriteBatch spriteBatch;
            private SpriteFont hudFont;
            private Texture2D winOverlay;
            private Texture2D loseOverlay;
            private Texture2D diedOverlay;
            private Texture2D buttonNormal;
            private Texture2D buttonPressed;
            private Texture2D buttonNormalFire;
            private Texture2D buttonPressedFire;
            private Texture2D startScreen;
    
            private SoundEffect door;
    
            //Meta-level game state
            private int levelIndex = -1;
            private Level level;
            private int tempScore;
            private bool wasContinuePressed;
            
    
            //When the time remaining is less than the warning time, it blinks on the hud
            private static readonly TimeSpan WarningTime = TimeSpan.FromSeconds(30);
            private TouchCollection touchState;
            private AccelerometerState accelerometerState;
    
    
            private const int numberOfLevels = 3;
       
            public GameplayScreen()
            {
                TransitionOnTime = TimeSpan.FromSeconds(1.5);
                TransitionOffTime = TimeSpan.FromSeconds(0.5);
    
                Accelerometer.Initialize();
            }
    
    
            public static int score;
    
            public int Score
            {
                get { return score; }
                set { score = value; }
            }
    
    
            public static int numberoflifes = 3;
            private IServiceProvider Services;
    
            public int NumberOfLifes
            {
                get { return numberoflifes; }
                set { numberoflifes = value; }
            }
    
    
            public override void LoadContent()
            {
                //Create a new SpriteBatch, which can be used to draw textures
                SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
    
                //Load fonts
                hudFont = content.Load<SpriteFont>("Fonts/Hud");
                
                //Load Textures
                startScreen = content.Load<Texture2D>("Background");
                winOverlay = content.Load<Texture2D>("Overlays/you_win");
                loseOverlay = content.Load<Texture2D>("Overlays/you_lose");
                diedOverlay = content.Load<Texture2D>("Overlays/you_died");
                buttonNormal = content.Load<Texture2D>("Sprites/ButtonNormal");
                buttonPressed = content.Load<Texture2D>("Sprites/ButtonPressed");
                buttonNormalFire = content.Load<Texture2D>("Sprites/ButtonNormal");
                buttonPressedFire = content.Load<Texture2D>("Sprites/ButtonPressed");
    
                //Load Sounds
                door = content.Load<SoundEffect>("Sounds/door");
    
                try
                {
                    MediaPlayer.IsRepeating = true;
                    MediaPlayer.Play(content.Load<Song>("Sounds/Music"));
                }
                catch { }
    
                LoadNextLevel();
    
                ScreenManager.Game.ResetElapsedTime();
            }
    
    
            public override void UnloadContent()
            {
                
            }
    
    
            public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                           bool coveredByOtherScreen)
            {
                base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
                {        
                    //Handle polling for our input and handling high-level input
                    HandleInput();
    
                    //update our level, passing down the GameTime along with all of our input states
                    level.Update(gameTime, touchState,
                        accelerometerState, DisplayOrientation.LandscapeLeft);
    
                    base.Update(gameTime, false, false);
                }
            }
    
    
            private void HandleInput()
            {
    
    ...

    und das sind die fehler:

    vor dem Compilen:

    Warnung    1    Dem Feld "GameStateManagement.Screens.GameplayScreen.content" wird nie etwas zugewiesen, und es hat immer seinen Standardwert von "null".    C:\Users\Droggelbecher\Desktop\GSMSample_4_0_PHONE\GameStateManagementSample\Screens\GameplayScreen.cs    18    24    GameStateManagementSample (Phone)
    Warnung    2    Dem Feld "GameStateManagement.Screens.GameplayScreen.graphics" wird nie etwas zugewiesen, und es hat immer seinen Standardwert von "null".    C:\Users\Droggelbecher\Desktop\GSMSample_4_0_PHONE\GameStateManagementSample\Screens\GameplayScreen.cs    21    39    GameStateManagementSample (Phone)
    Warnung    4    Dem Feld "GameStateManagement.Screens.GameplayScreen.hudFont" wird nie etwas zugewiesen, und es hat immer seinen Standardwert von "null".    C:\Users\Droggelbecher\Desktop\GSMSample_4_0_PHONE\GameStateManagementSample\Screens\GameplayScreen.cs    23    28    GameStateManagementSample (Phone)
    Warnung    5    Dem Feld "GameStateManagement.Screens.GameplayScreen.Services" wird nie etwas zugewiesen, und es hat immer seinen Standardwert von "null".    C:\Users\Droggelbecher\Desktop\GSMSample_4_0_PHONE\GameStateManagementSample\Screens\GameplayScreen.cs    69    34    GameStateManagementSample (Phone)
    Warnung    3    Dem Feld "GameStateManagement.Screens.GameplayScreen.spriteBatch" wird nie etwas zugewiesen, und es hat immer seinen Standardwert von "null".    C:\Users\Droggelbecher\Desktop\GSMSample_4_0_PHONE\GameStateManagementSample\Screens\GameplayScreen.cs    22    29    GameStateManagementSample (Phone)

    und nach dem comilen beim "in das spiel springen"

    und das kommt auch bei jeder nachfolgenden textur die ich laden will.

    Dienstag, 21. Februar 2012 15:52
  • Wenn Du Dich an die Fehlermeldung hälst und content zuweisst wird es klappen.

    Im Original wir ja in der Activate Methode der ContentManager initialisiert.

    content = new ContentManager(ScreenManager.Game.Services, "Content");

    Gleiches gilt laut Screenshot für grpahics und Services. Du hast irgendwie die initialisierung vergessen (Im Konstruktor oder wie im Orignial in der Activate Methode), daher sind alle Objekte noch NULL.

    http://patrickgetzmann.wordpress.com/

    • Als Antwort vorgeschlagen Horizon_Net Dienstag, 21. Februar 2012 18:10
    Dienstag, 21. Februar 2012 17:59
  • Hallo Patrick,

    das hat soweit wirklich schon gut geholfen vielen dank dafür und ich bin alle Warnings vor dem Compilen los :)

    nun geht es aber leider weiter :S in meiner Level.cs:

    using System;
    using System.Collections.Generic;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Audio;
    using System.IO;
    using Microsoft.Xna.Framework.Input.Touch;
    using Microsoft.Xna.Framework.Input;
    
    namespace GameStateManagement.Screens
    {
        class Level : IDisposable
        {
            //Physical structure of the level
            private Tile[,] tiles;
            private Layer[] layers;
            private bool Complete;
    
            //The layer which entities are drawn on top of
            private const int EntityLayer = 2;
    
    
            //Entities in the level
            public Player Player
            {
                get { return player; }
            }
            Player player;
    
            private List<Gem> gems = new List<Gem>();
            public List<Enemy> enemies = new List<Enemy>();
    
    
            //Key locations in the level
            private Vector2 start;
            private Point exit = InvalidPosition;
            private static readonly Point InvalidPosition = new Point(-1, -1);
            //Arbitrary, but constant seed
            private Random random = new Random(354668);
            private float cameraPosition;
    
            public int Score
            {
                get { return score; }
            }
            int score;
    
            public bool ReachedExit
            {
                get { return reachedExit; }
            }
            bool reachedExit;
    
            public bool LevelComplete
            {
                get { return levelComplete; }
                set { levelComplete = value; }
            }
            bool levelComplete;
    
            public bool LastLevel
            {
                get { return lastLevel; }
                set { lastLevel = value; }
            }
            bool lastLevel;
    
            public TimeSpan TimeRemaining
            {
                get { return timeRemaining; }
            }
            TimeSpan timeRemaining;
    
            private const int PointsPerSecond = 5;
    
    
            //Level content    
            public ContentManager Content
            {
                get { return content; }
            }
            ContentManager content;
    
            private SoundEffect exitReachedSound;
    
            #region Loading
    
            //Constructs a new level
            public Level(IServiceProvider serviceProvider, Stream fileStream, int levelIndex)
            {
                [ ... ]
            }
    
    
            private void LoadTiles(Stream fileStream)
            {
                [ ... ]
            }
    
    
            private Tile LoadTile(char tileType, int x, int y)
            {
                switch (tileType)
                {
    				[ ... ]
                }
            }
    
            //Creates a new tile
            private Tile LoadTile(string name, TileCollision collision)
            {
                return new Tile(Content.Load<Texture2D>("Tiles/" + name), collision);
            }
    
            //Loads a tile with a random appearance
            private Tile LoadVarietyTile(string baseName, int variationCount, TileCollision collision)
            {
                int index = random.Next(variationCount);
                return LoadTile(baseName + index, collision);
            }

    undzwar, dass die methode

    private Tile LoadTile(string name, TileCollision collision) { return new Tile(Content.Load<Texture2D>("Tiles/" + name), collision); }

    eine unbehandelte  NULLReferece Exeption ist.

    Gibt es nicht zufällig "einen Trick" woran ich merke was der unterschied zwischen meinem "nur Spiel" und dem "Menü mit Spiel" ist? denn ich muss zugeben ich dachte ich hätte es langsam geblickt aber jetzt grad steh ich wieder komplett auf dem Schlauch, denn das "nur Spiel" läuft an sich wie eine 1 :S

    Mittwoch, 22. Februar 2012 14:09
  • Selbes Problem mit dem ContentManager.

    Du kannst nicht einfach drauf zugreifen, ohne es initialisiert zu haben.

    Debug doch mal rein, dann siehst du ja was null ist ;-)

    Mittwoch, 22. Februar 2012 16:38
  • Da Du den Code nicht vollständig gepostet hast kann ich nur vermuten dass Du den Konstruktor angepasst hast, und dort den ContentManager nicht initialisierts, oder dort etwas fehlschlägt weil Du bspw. den GameServiceContainer nicht angelegt hast o.ä.

    Ich würde jetzt mit einem Tool wie Notepad++(Compare Plugin) oder Sourcesafe/TFS Compare die einzelnen Dateien des Platformer Samples mit Deinen geänderten Version vergleichen, dann solltest Du sehen könnnen ob Du etwas überschrieben oder zu viel gelöscht hast.


    http://patrickgetzmann.wordpress.com/

    Mittwoch, 22. Februar 2012 17:04
  • das tut mir leid ich wolte es  nur etwas kürzer machen ;)

    using System;
    using System.Collections.Generic;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Audio;
    using System.IO;
    using Microsoft.Xna.Framework.Input.Touch;
    using Microsoft.Xna.Framework.Input;
    
    namespace GameStateManagement.Screens
    {
        class Level : IDisposable
        {
            //Physical structure of the level
            private Tile[,] tiles;
            private Layer[] layers;
            private bool Complete;
    
            //The layer which entities are drawn on top of
            private const int EntityLayer = 2;
    
    
            //Entities in the level
            public Player Player
            {
                get { return player; }
            }
            Player player;
    
            private List<Gem> gems = new List<Gem>();
            public List<Enemy> enemies = new List<Enemy>();
    
    
            //Key locations in the level
            private Vector2 start;
            private Point exit = InvalidPosition;
            private static readonly Point InvalidPosition = new Point(-1, -1);
            //Arbitrary, but constant seed
            private Random random = new Random(354668);
            private float cameraPosition;
    
            public int Score
            {
                get { return score; }
            }
            int score;
    
            public bool ReachedExit
            {
                get { return reachedExit; }
            }
            bool reachedExit;
    
            public bool LevelComplete
            {
                get { return levelComplete; }
                set { levelComplete = value; }
            }
            bool levelComplete;
    
            public bool LastLevel
            {
                get { return lastLevel; }
                set { lastLevel = value; }
            }
            bool lastLevel;
    
            public TimeSpan TimeRemaining
            {
                get { return timeRemaining; }
            }
            TimeSpan timeRemaining;
    
            private const int PointsPerSecond = 5;
    
    
            //Level content    
            public ContentManager Content
            {
                get { return content; }
            }
            ContentManager content;
    
            private SoundEffect exitReachedSound;
    
            #region Loading
    
            //Constructs a new level
            public Level(IServiceProvider serviceProvider, Stream fileStream, int levelIndex)
            {
                //Create a new content manager to load content used just by this level
                //content = new ContentManager(serviceProvider, "Content");
    
                timeRemaining = TimeSpan.FromMinutes(2.0);
    
                LoadTiles(fileStream);
    
                //Load background layer textures
                layers = new Layer[3];
                layers[0] = new Layer(Content, "Backgrounds/Layer0", 0.2f);
                layers[1] = new Layer(Content, "Backgrounds/Layer1", 0.5f);
                layers[2] = new Layer(Content, "Backgrounds/Layer2", 0.8f);
    
                //Load sounds
                exitReachedSound = Content.Load<SoundEffect>("Sounds/ExitReached");
            }
    
    
            private void LoadTiles(Stream fileStream)
            {
                //Load the level and ensure all of the lines are the same length
                int width;
                List<string> lines = new List<string>();
                using (StreamReader reader = new StreamReader(fileStream))
                {
                    string line = reader.ReadLine();
                    width = line.Length;
                    while (line != null)
                    {
                        lines.Add(line);
                        if (line.Length != width)
                            throw new Exception(String.Format("line {0} is different", lines.Count));
                        line = reader.ReadLine();
                    }
                }
    
    
                //Allocate the tile grid
                tiles = new Tile[width, lines.Count];
    
                //Loop over every tile position
                for (int y = 0; y < Height; ++y)
                {
                    for (int x = 0; x < Width; ++x)
                    {
                        //to load each tile
                        char tileType = lines[y][x];
                        tiles[x, y] = LoadTile(tileType, x, y);
                    }
                }
    
                //Verify that the level has a beginning and an end
                if (Player == null)
                    throw new NotSupportedException("A level must have a starting point.");
                if ((exit == InvalidPosition) && (Complete == false))
                    throw new NotSupportedException("A level must have an exit.");
            }
    
    
            private Tile LoadTile(char tileType, int x, int y)
            {
                switch (tileType)
                {
                    // Blank space
                    case '.':
                        return new Tile(null, TileCollision.Passable);
    
                    //Exit
                    case 'X':
                        LoadExit2Tile(x, y);
                        return LoadExit2Tile(x, y);
    
                    //Complete
                    case 'Y':
                        LoadExitTile(x, y);
                        Complete = true;
                        return LoadCompleteTile(x, y);
    
                    // Gem
                    case 'G':
                        return LoadGemTile(x, y, false);
    
                    //PowerUp
                    case 'P':
                        return LoadGemTile(x, y, true);
    
                    //Floating platform
                    case '-':
                        return LoadTile("Platform", TileCollision.Platform);
    
                    //Various enemies
                    case 'A':
                        return LoadEnemyTile(x, y, "MonsterA");
                    case 'B':
                        return LoadEnemyTile(x, y, "MonsterB");
                    case 'C':
                        return LoadEnemyTile(x, y, "MonsterC");
                    case 'D':
                        return LoadEnemyTile(x, y, "MonsterD");
    
    
                    //Platform block
                    case '~':
                        return LoadVarietyTile("BlockB", 2, TileCollision.Platform);
    
                    //Passable block
                    case ':':
                        return LoadVarietyTile("BlockB", 2, TileCollision.Passable);
    
                    //Player 1 start point
                    case '1':
                        return LoadStartTile(x, y);
    
                    //Impassable block
                    case '#':
                        return LoadVarietyTile("BlockA", 7, TileCollision.Impassable);
    
                    //Unknown tile type character
                    default:
                        throw new NotSupportedException(String.Format("Unsupported tile type character '{0}' at position {1}, {2}.", tileType, x, y));
                }
            }
    
            //Creates a new tile
            private Tile LoadTile(string name, TileCollision collision)
            {
                return new Tile(Content.Load<Texture2D>("Tiles/" + name), collision);
            }
    
            //Loads a tile with a random appearance
            private Tile LoadVarietyTile(string baseName, int variationCount, TileCollision collision)
            {
                int index = random.Next(variationCount);
                return LoadTile(baseName + index, collision);
            }
    
            //Instantiates a player, puts him in the level, and remembers where to put him when he is resurrected
            private Tile LoadStartTile(int x, int y)
            {
                if (Player != null)
                    throw new NotSupportedException("A level may only have one starting point.");
    
                start = RectangleExtensions.GetBottomCenter(GetBounds(x, y));
                player = new Player(this, start);
    
                return new Tile(null, TileCollision.Passable);
            }
    
            //Remembers the location of the level's exit
            private Tile LoadCompleteTile(int x, int y)
            {
                exit = GetBounds(x, y).Center;
                lastLevel = true;
    
                return LoadTile("Complete", TileCollision.Passable);
            }
    
            //Remembers the location of the level's exit
            private Tile LoadExitTile(int x, int y)
            {
                return LoadTile("Exit", TileCollision.Passable);
            }
    
            //Remembers the location of the level's exit
            private Tile LoadExit2Tile(int x, int y)
            {
                exit = GetBounds(x, y).Center;
    
                return LoadTile("Exit2", TileCollision.Passable);
            }
    
            //Instantiates an enemy and puts him in the level
            private Tile LoadEnemyTile(int x, int y, string spriteSet)
            {
                Vector2 position = RectangleExtensions.GetBottomCenter(GetBounds(x, y));
                enemies.Add(new Enemy(this, position, spriteSet));
    
                return new Tile(null, TileCollision.Passable);
            }
    
            //Instantiates a gem and puts it in the level
            private Tile LoadGemTile(int x, int y, bool isPowerUp)
            {
                Point position = GetBounds(x, y).Center;
                gems.Add(new Gem(this, new Vector2(position.X, position.Y), isPowerUp));
    
                return new Tile(null, TileCollision.Passable);
            }
    
            //Unloads the level content
            public void Dispose()
            {
                Content.Unload();
            }
    
            #endregion
    
    
            #region Bounds and collision
            public TileCollision GetCollision(int x, int y)
            {
                // Prevent escaping past the level ends
                if (x < 0 || x >= Width)
                    return TileCollision.Impassable;
    
                //Allow jumping past the level top and falling through the bottom
                if (y < 0 || y >= Height)
                    return TileCollision.Passable;
    
                return tiles[x, y].Collision;
            }
    
            public Rectangle GetBounds(int x, int y)
            {
                return new Rectangle(x * Tile.Width, y * Tile.Height, Tile.Width, Tile.Height);
            }
    
    
            public int Width
            {
                get { return tiles.GetLength(0); }
            }
    
    
            public int Height
            {
                get { return tiles.GetLength(1); }
            }
            #endregion
    
            #region Update
            public void Update(
                GameTime gameTime,
                TouchCollection touchState,
                AccelerometerState accelState,
                DisplayOrientation orientation)
            {
                //Pause while the player is dead or time is expired
                if (!Player.Life || TimeRemaining == TimeSpan.Zero)
                {
                    //Still want to perform physics on the player
                    Player.ApplyPhysics(gameTime);
                }
                else if (ReachedExit && touchState.FireButtonTouch())
                {
                    timeRemaining = TimeSpan.Zero;
                }
                else if (LevelComplete)
                {
                    timeRemaining = TimeSpan.Zero;
                }
                else
                {
                    timeRemaining -= gameTime.ElapsedGameTime;
                    Player.Update(gameTime, touchState, accelState, orientation);
                    UpdateGems(gameTime);
    
    
                    //Falling off the bottom of the level kills the player
                    if (Player.BoundingRectangle.Top >= Height * Tile.Height)
                    {
                        OnPlayerKilled(null);
                        score = 0;
                    }
    
                    UpdateEnemies(gameTime);
    
                    if (Player.Life &&
                        Player.IsOnGround &&
                        Player.BoundingRectangle.Contains(exit))
                    {
                        OnExitReached();
                    }
                    else if (Player.Life &&
                      Player.IsOnGround &&
                      !Player.BoundingRectangle.Contains(exit))
                    {
                        reachedExit = false;
                    }
                }
    
                //Clamp the time remaining at zero
                if (timeRemaining < TimeSpan.Zero)
                    timeRemaining = TimeSpan.Zero;
            }
    
            //Animates each gem and checks to allows the player to collect them
            private void UpdateGems(GameTime gameTime)
            {
                for (int i = 0; i < gems.Count; ++i)
                {
                    Gem gem = gems[i];
    
                    gem.Update(gameTime);
    
                    if (gem.BoundingCircle.Intersects(Player.BoundingRectangle))
                    {
                        gems.RemoveAt(i--);
                        OnGemCollected(gem, Player);
                    }
                }
            }
    
            //Animates each enemy and allow them to kill the player
            private void UpdateEnemies(GameTime gameTime)
            {
                foreach (Enemy enemy in enemies)
                {
                    enemy.Update(gameTime);
    
                    //Player Killed by Enemy or Powerup and Enemy gets Killed
                    if (enemy.Life && enemy.BoundingRectangle.Intersects(Player.BoundingRectangle))
                    {
                        if (Player.IsPoweredUp)
                        {
                            OnEnemyKilled(enemy, Player);
                        }
                        else
                        {
                            OnPlayerKilled(enemy);
                        }
                    }
                }
            }
    
            private void OnEnemyKilled(Enemy enemy, Player killedBy)
            {
                enemy.OnKilled(killedBy);
            }
    
    
            private void OnGemCollected(Gem gem, Player collectedBy)
            {
                score += gem.PointValue;
    
                gem.OnCollected(collectedBy);
            }
    
    
            private void OnPlayerKilled(Enemy killedBy)
            {
                Player.OnKilled(killedBy);
            }
    
    
            //Called when the player reaches the level's exit
            private void OnExitReached()
            {
                Player.OnReachedExit();
                //exitReachedSound.Play();
                reachedExit = true;
            }
    
    
            //Called when the player reaches the level's exit
            private void LevelColmplete()
            {
                Player.OnReachedExit();
                exitReachedSound.Play();
                reachedExit = true;
            }
    
            //Restores the player to the starting point to try the level again
            public void StartNewLife()
            {
                Player.Reset(start);
            }
    
            #endregion
    
    
            #region Draw
    
            //Draw everything in the level from background to foreground
            public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
            {
                spriteBatch.Begin();
                for (int i = 0; i <= EntityLayer; ++i)
                    layers[i].Draw(spriteBatch, cameraPosition);
                spriteBatch.End();
    
                ScrollCamera(spriteBatch.GraphicsDevice.Viewport);
                Matrix cameraTransform = Matrix.CreateTranslation(-cameraPosition, 0.0f, 0.0f);
                spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default,
                                    RasterizerState.CullCounterClockwise, null, cameraTransform);
    
                DrawTiles(spriteBatch);
    
                foreach (Gem gem in gems)
                    gem.Draw(gameTime, spriteBatch);
    
                Player.Draw(gameTime, spriteBatch);
    
                foreach (Enemy enemy in enemies)
                    enemy.Draw(gameTime, spriteBatch);
    
                spriteBatch.End();
    
                spriteBatch.Begin();
                for (int i = EntityLayer + 1; i < layers.Length; ++i)
                    layers[i].Draw(spriteBatch, cameraPosition);
                spriteBatch.End();
            }
    
            private void ScrollCamera(Viewport viewport)
            {
    #if WINDOWS_PHONE
                const float ViewMargin = 0.45f;
    #else
                const float ViewMargin = 0.35f;
    #endif
    
                //Calculate the edges of the screen.
                float marginWidth = viewport.Width * ViewMargin;
                float marginLeft = cameraPosition + marginWidth;
                float marginRight = cameraPosition + viewport.Width - marginWidth;
    
                //Calculate how far to scroll when the player is near the edges of the screen
                float cameraMovement = 0.0f;
                if (Player.Position.X < marginLeft)
                    cameraMovement = Player.Position.X - marginLeft;
                else if (Player.Position.X > marginRight)
                    cameraMovement = Player.Position.X - marginRight;
    
                //Update the camera position, but prevent scrolling off the ends of the level
                float maxCameraPosition = Tile.Width * Width - viewport.Width;
                cameraPosition = MathHelper.Clamp(cameraPosition + cameraMovement, 0.0f, maxCameraPosition);
            }
    
    
            //Draws each tile in the level
            private void DrawTiles(SpriteBatch spriteBatch)
            {
                //Calculate the visible range of tiles
                int left = (int)Math.Floor(cameraPosition / Tile.Width);
                int right = 48 + left + spriteBatch.GraphicsDevice.Viewport.Width / Tile.Width;
                right = Math.Min(right, Width - 1);
    
                //For each tile position
                for (int y = 0; y < Height; ++y)
                {
                    for (int x = left; x <= right; ++x)
                    {
                        //If there is a visible tile in that position
                        Texture2D texture = tiles[x, y].Texture;
                        if (texture != null)
                        {
                            //Draw it in screen space
                            Vector2 position = new Vector2(x, y) * Tile.Size;
                            spriteBatch.Draw(texture, position, Color.White);
                        }
                    }
                }
            }
    
            #endregion
        }
    }
    

    Mittwoch, 22. Februar 2012 17:22
  • Kürzer wars, aber nicht hilfreich :-)

    Du hast im Konstruktor die erstellung des ContentManagers auskommentiert.


    http://patrickgetzmann.wordpress.com/

    Mittwoch, 22. Februar 2012 18:26
  • Früher wäre deine App durch den Prozess geflogen.

    Wie es heute ist, weiß ich nicht genau, aber du darfst nicht einfach so in deiner App Sounds/Musik abspielen.

    Du musst zuvor überprüfen, ob der MediaPlayer.GameHasControl hat oder nicht und dann ggf. den Benutzer nach seinem Einverständnis fragen...

    Donnerstag, 23. Februar 2012 08:04
  • hmm da hatte ich es mir wohl wirklich etwas leicht gemacht ;) denn da kommt die fehlermeldung einer unbehandelten ArgumentNullException auch nach abwandllung:

    if (content == null)
    {
        content = new ContentManager(serviceProvider, "Content");
    }

    und wenn ich wie in der GameScreen klasse

    content = new ContentManager(ScreenManager.Game.Services, "Content");

    benutze kommt wieder eine Null ReferenceException, wobei ich das ja auch gar nicht machen darf denn der Verweis in der Gamescreen Klasse erwartet ja einen IServiceProvider eintrag :S

    Donnerstag, 23. Februar 2012 11:19
  • Hallo Droggel,

    es fliegt eine Null Exception und du weißt nicht wo, korrekt?

    Debugge doch mal in dein Programm, dann siehst du welches Objekt null ist. Das hillft schonmal!

    Desweiteren könntest du doch auch den ContentManager einfach durchschleifen, d.h. du übergibst den Content einfach im Konstruktor

    Ansonsten einfach global verfügbar machen...

    Donnerstag, 23. Februar 2012 11:43
  • naja also ich weiss das content = null ist

    und das es das eigentlich nicht sein dürfte, da ich ja mit der methode


    public ContentManager Content
            {
                get { return content; }
            }
            ContentManager content;

    den content laden müsste, entsprechend vermute ich das das nicht klappt, da sich alle klassen vorher im "Hauptverzeichnis" des SPiels befunden haben und nun in einem Unterordner sind, das sich die get und set methoden "nicht mehr finden".

    Ist diese vermutung richtig oder bin ich da auf einem holzweg?

    Donnerstag, 23. Februar 2012 12:42
  • Holzweg.

    Für die Zukunft: Reindebuggen ^^

    Setz einen Breakpoint beim get vom Contentmanager. Du wirst sehen dass du da bereits null zurücklieferst.

    Wieso?

    Weil dein

    public ContentManager Content // kannst du auch private machen, wa?
            {
                get { return content; }
            }

    auf deine Variable

    ContentManager content;

    verweist, die aber wohl nie gesetzt wird.

    Ich denke in deiner Game.cs wird dein Levelobjekt initialisiert. Richtig?

    Dann änder den Konstruktor von Level ab

    public Level(ContentManager manager)
    {
    this.Content = manager;
    }

    und beim erstellen des Levels einfach

    Level level = new Level(Content);

    • Als Antwort markiert Droggel Freitag, 24. Februar 2012 11:55
    Donnerstag, 23. Februar 2012 17:02
  • Nein, das passt so nicht. Content ist Deine öffentliche Variable und content das private Gegenstück. Das hat nichts mit den Verzeichnissen zu tun. Auch wird dort nicht der Content geladen.

    Das geschieht mit dem Aufruf

    content = new ContentManager(serviceProvider, "Content");

    im Konstruktor, den Du ja auskommentiert hast. Da es damit aber auch nicht geklappt hat gehe ich davon aus, dass Du das Level zu einer Zeit initilisierst, zu der die Services noch nicht bereit sind. Wo erstellst Du denn den Level? Wenn Du es aus der LoadContent Methode herraus machst sollte es funktionieren.


    http://patrickgetzmann.wordpress.com/

    Donnerstag, 23. Februar 2012 20:56
  • Danke WP7_Beginner (du wirst deinem NAmen hier nicht mehr gerecht glaub ich ;) ) hat (mit etwas gefrickel) super funktioniert :D
    Freitag, 24. Februar 2012 11:56