System.NullReferenceExeption (GC?) (XNA)

0

Piszę grę w XNA 4.0 pod Windows Phone 8.

Mam taki fragment kodu:

TouchCollection tc = TouchPanel.GetState();

            foreach (TouchLocation touchLocation in tc)
            {
                if (touchLocation.State == TouchLocationState.Pressed)
                {
                    int rodzajStatku = znajdzStatek((int)touchLocation.Position.X, (int)touchLocation.Position.Y);

                    Console.WriteLine(rodzajStatku);

                    if (rodzajStatku != -1 && iloscOkretowDoUstawienia[rodzajStatku - 2] > 0)
                    {
                        Texture2D nowaTekstura = Content.Load<Texture2D>("" + rodzajStatku);

                        okrety[iloscOkretowNaMapie].dodajTeksture(ref nowaTekstura, rodzajStatku);
                        zablokuj(iloscOkretowNaMapie);

                        iloscOkretowNaMapie++;
                        iloscOkretowDoUstawienia[rodzajStatku - 2]--;
                    }
                }

W linii:

okrety[iloscOkretowNaMapie].dodajTeksture(ref nowaTekstura, rodzajStatku);

występuje wyjątek podczas debugowania:

An exception of type 'System.NullReferenceException' occurred in WindowsPhoneGame1.DLL but was not handled in user code

If there is a handler for this exception, the program may be safely continued.

Co może powodować taki błąd? Słyszałem i przeczytałem, że być może Garbage Collector zwolnił teksturę i być może dlatego wywaliło ten wyjątek. Ale przecież referencja do niej jest przechowywana w tablicy obiektów 'okrety'.

Co to może być?

0

może Content.Load zwraca null dla którejś z wartości. proponuję zdebugować program z użyciem... debuggera. czyli wykonaj program pod debuggerem, w momencie kiedy poleci null reference program zostanie zatrzymany na tej linijce, będziesz mógł podejrzeć wszystkie potrzebne zmienne i określić, która jest nullem i na tej podstawie dowiesz się, który kawałek kodu zawiódł.

jeśli nie masz możliwości uruchomienia aplikacji pod debuggerem, to chociaż sprawdzaj, czy każdy obiekt na pewno został utworzony (!= null) zanim odwołasz się do jego pól/metod.

0

Odpalam program w debuggerze.

Dodałem dodatkową zmienną 'text':

string text = "" + rodzajStatku;
Texture2D nowaTekstura = Content.Load<Texture2D>(text);

okrety[iloscOkretowNaMapie].dodajTeksture(ref nowaTekstura, rodzajStatku);

Zmienna text = "3"
Zmienna nowaTelstura ma poprawną strukturę

Jak zmieniłem wywołanie funkcji na przypisanie tekstury do pola to wywala to samo w tej linii:

okrety[iloscOkretowNaMapie].tekstura = nowaTekstura;

Nie wiem co może być nie tak.

0

Pewnie nie istnieje obiekt

okrety[iloscOkretowNaMapie] 

Inaczej nie tworzysz nigdzie obiektu pod indeksem iloscOkretowNaMapie.

0

Istnieje.

user image

0

ale masz w niej same nulle przecież. utwórz najpierw te obiekty, a dopiero potem się do nich odwołuj :/

0

Tworzę je w LoadContent():

protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            mapa = Content.Load<Texture2D>("mapa1");

            statkiStatyczne = new Texture2D[4];

            for (int i = 2; i <= 5; i++)
                statkiStatyczne[i - 2] = Content.Load<Texture2D>("" + i);

            soundEffect = Content.Load<SoundEffect>("Windows Ding");

            pozycjaMapy.X = 0;
            pozycjaMapy.Y = 0;

            pozycjeOkretowStatycznych = new Vector2[4];

            for (int i = 0; i < 4; i++)
                pozycjeOkretowStatycznych[i] = new Vector2(500, 45 + (i + 1) * 90);

            iloscOkretowDoUstawienia = new int[4];

            for (int i = 0; i < 4; i++)
                iloscOkretowDoUstawienia[i] = 4 - i;

            zablokowanyStatek = -1;

            okrety = new Element[10];
            iloscOkretowNaMapie = 0;

            // TODO: use this.Content to load your game content here
        }

A wybrany kod klasy Element jest taki:

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

namespace WindowsPhoneGame1
{
    class Element
    {
        public static int[,]    polozenia       = new int[10,10];
        public static int       pierwszyWolny   = 1;
        
        private static int[]    pozycjeSiatkiX  = new int[10];
        private static int[]    pozycjeSiatkiY  = new int[10];
        private static int      bazaSiatkiX     = 8;
        private static int      bazaSiatkiY     = 10;
        private static int      rozmiarSiatki   = 45;

        private static bool     czyZainicjowano = false;

        public Texture2D        tekstura;
        public Vector2          pozycja;
        public Vector2          pozycjaNaMapie;
        public int              rotacja;        // wartość w stopniach

        public int              numer;
        public int              dlugosc;

        // METODY

        private void inicjuj()
        {
            if (!czyZainicjowano)
            {
                czyZainicjowano = !czyZainicjowano;

                for (int i = 0; i < 10; i++)
                {
                    pozycjeSiatkiX[i] = bazaSiatkiX + i * rozmiarSiatki;
                    pozycjeSiatkiY[i] = bazaSiatkiY + i * rozmiarSiatki;
                }
            }
        }

        public Element()
        {
            inicjuj();

            tekstura = null;
            rotacja = 0;
            pozycja = new Vector2(0, 0);
            pozycjaNaMapie = new Vector2(-1, -1);
            dlugosc = 0;

            Console.WriteLine(polozenia[0, 0]);
        }

        ~Element()
        {
        }

        public void dodajTeksture(ref Texture2D tex, int len)
        {
            tekstura = tex;
            dlugosc = len;
            numer = pierwszyWolny++;
        }
}
0

Wcale nie tworzysz obiektów, tylko tablicę referencji do tych obiektów. Typy referencyjne domyślnie ustawiane są na null, więc masz tablicę nulli.

0

Aaa, dzięki :)

0

zresztą miałeś to podane na tacy na screenshocie, który sam podałeś - tablica zawierała same nulle. sam nawet kliknąłeś na plusik przy tejże tablicy, żeby rozwinąć listę jej elementów.
czytaj ze zrozumieniem :-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1