Problem following Nick Gravelyn's tile engine tutorial.

  • (2 Pages)
  • +
  • 1
  • 2

20 Replies - 2796 Views - Last Post: 18 October 2012 - 07:45 AM

#1 ArchColossus  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 49
  • Joined: 22-February 12

Problem following Nick Gravelyn's tile engine tutorial.

Posted 21 September 2012 - 07:12 AM

I've gotten to part 4C 3/4, and I've finally been stumped. Everything builds correctly, and there are no errors anywhere, but the tile editor isn't working. In the video he shows how to make a red outline for the tile that the cursor is over once you select the layer. However in mine, after I set the path, open the layer, and select the layer, as soon as I move the mouse over the tileDisplay, the image changes to a white box with a flashing red "X". I can't find what's causing this, and it's put a halt on my progress. Any help would be greatly apprieciated.

Is This A Good Question/Topic? 0
  • +

Replies To: Problem following Nick Gravelyn's tile engine tutorial.

#2 Kilorn  Icon User is offline

  • XNArchitect
  • member icon



Reputation: 1355
  • View blog
  • Posts: 3,528
  • Joined: 03-May 10

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 21 September 2012 - 07:39 AM

Without code, it's not going to be possible to track down the cause of the issue.
Was This Post Helpful? 0
  • +
  • -

#3 ArchColossus  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 49
  • Joined: 22-February 12

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 24 September 2012 - 07:19 AM

Here's my project so far. I've followed him into the 4C or D part of the tutorial I believe. As far as I can tell, the problem is in the Form.cs file in the Logic or Render method. Which is here:
private void Logic()
        {
            camera.Position.X = hScrollBar1.Value * TileLayer.TileWidth;
            camera.Position.Y = vScrollBar1.Value * TileLayer.TileHeight;

            int mx = Mouse.GetState().X;
            int my = Mouse.GetState().Y;

            if (currentLayer != null)
            {

                if (mx > 0 && mx < tileDisplay1.Width && my > 0 && my < tileDisplay1.Height)
                {
                    cellX = mx / TileLayer.TileWidth;
                    cellY = my / TileLayer.TileHeight;

                    cellX = (int)MathHelper.Clamp(cellX, 0, currentLayer.Width);
                    cellY = (int)MathHelper.Clamp(cellY, 0, currentLayer.Height);

                    if (Mouse.GetState().LeftButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed)
                    {
                        if (drawRadioButton.Checked)
                        {
                            Texture2D texture = textureDict[textureListBox.SelectedItem as string];

                            int index = currentLayer.IsUsingTexture(texture);

                            if (index == -1)
                            {
                                currentLayer.AddTexture(texture);

                                index = currentLayer.IsUsingTexture(texture);

                                currentLayer.SetCellIndex(cellX, cellY, index);
                            }
                        }

                        else if (eraseRadioButton.Checked)
                        {
                            currentLayer.SetCellIndex(cellX, cellY, -1);
                        }
                    }
                }

                else
                {
                    cellX = cellY = -1;
                }
            }

        }

        private void Render()
        {
            GraphicsDevice.Clear(Color.Black);

            //tileMap.Draw(spriteBatch, camera);
            foreach (TileLayer layer in tileMap.Layers)
            {
                layer.Draw(spriteBatch, camera);

                spriteBatch.Begin();
                for (int y = 0; y < layer.Height; y++)
                {
                    for (int x = 0; x < layer.Width; x++)
                    {
                       if (layer.GetCellIndex(x, y) == -1)
                       {
                       spriteBatch.Draw(
                       tileTexture,
                       new Rectangle(
                           x * TileLayer.TileWidth - (int)camera.Position.X,
                           y * TileLayer.TileHeight - (int)camera.Position.Y,
                           TileLayer.TileWidth,
                           TileLayer.TileHeight),
                       Color.White);
                       }
                    }
                }
                spriteBatch.End();
            }

            

            if (currentLayer != null)
            {
                
                if (cellX != -1 && cellY != -1)
                {
                    spriteBatch.Begin();
                    spriteBatch.Draw(
                       tileTexture,
                       new Rectangle(
                           cellX * TileLayer.TileWidth - (int)camera.Position.X,
                           cellY * TileLayer.TileHeight - (int)camera.Position.Y,
                           TileLayer.TileWidth,
                           TileLayer.TileHeight),
                       Color.Red);
                    spriteBatch.End();

                }
            }

        }


But I have no clue as to why it isn't working. As soon as I select the layer to edit and move the mouse over the tileDisplay, it changes from the tile map to a white box with a flashing red X.

Attached File(s)


Was This Post Helpful? 0
  • +
  • -

#4 ArchColossus  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 49
  • Joined: 22-February 12

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 27 September 2012 - 07:31 AM

I'm still stuck on this. I can't find anything wrong with it. Can anyone else see if they can at least reproduce the problem?
Was This Post Helpful? 0
  • +
  • -

#5 Kilorn  Icon User is offline

  • XNArchitect
  • member icon



Reputation: 1355
  • View blog
  • Posts: 3,528
  • Joined: 03-May 10

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 27 September 2012 - 07:53 AM

I'll check your code against mine later when I get some free time. My code is considerably altered, but maybe something will jump out at me.
Was This Post Helpful? 0
  • +
  • -

#6 ArchColossus  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 49
  • Joined: 22-February 12

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 27 September 2012 - 08:10 AM

Thank you, my main problem is that there are no build errors, but it still fails.
Was This Post Helpful? 0
  • +
  • -

#7 Kilorn  Icon User is offline

  • XNArchitect
  • member icon



Reputation: 1355
  • View blog
  • Posts: 3,528
  • Joined: 03-May 10

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 27 September 2012 - 08:31 AM

The only thing I really see that's different, except from the logic and render code that I added for a complete tileSet functionality, seems to be:
Mouse.WindowHandle = tileDisplay1.Handle;



That line is in the Logic method as the first line of code inside:
if (mx > 0 && mx < tileDisplay1.Width && my > 0 && my < tileDisplay1.Height)



The line of code that I've posted basically just ensures that the Handle for the current window matches the Handle for the tileDisplay1 object. It's just a way to make sure that the system properly knows which area of the form your mouse is currently over.

So the code should look like:
if (mx > 0 && mx < tileDisplay1.Width && my > 0 && my < tileDisplay1.Height)
{
    Mouse.WindowHandle = tileDisplay1.Handle;

    cellX = mx / TileLayer.TileWidth;
    cellY = my / TileLayer.TileHeight;

    // ... Rest of your code below here.



If that doesn't work, I'll have to dig a little deeper into your code, as it is really the only thing I can see that isn't in your code.

This post has been edited by Kilorn: 27 September 2012 - 08:32 AM

Was This Post Helpful? 0
  • +
  • -

#8 r233967  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 3
  • Joined: 30-September 12

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 30 September 2012 - 01:37 AM

Are the tile textures displayed in the tileDisplay (grass, road, etc)?

If not, then the red X you're describing means that you don't have textures to display.

Use the debugger. In the openToolStripMenuItem_Click method check that your textures are getting read in correctly.

The Texture2D.FromFile method that Nick used in XNA 3 is depricated in XNA 4 so Visual Studio will generate errors and won't build your solution. You can use Texture2D.FromStream but you have to have the full path.

In the openToolStripMenuItem_Click method, you have the full path because you're building it with the contentPathTextBox and texturename.

But in the tileDisplay1_OnInitialize method, you don't have the full path to the tile.png that Nick uses for the cursor image.

Get the textures loaded and displaying in openToolStripMenuItem_Click first to make sure you're using the Texture2D.FromStream method correctly. That's the easy one since you have the full path.

Then tackle building the full path in tileDisplay1_OnInitialize.
Was This Post Helpful? 0
  • +
  • -

#9 ArchColossus  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 49
  • Joined: 22-February 12

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 02 October 2012 - 06:31 AM

I'm not quite understanding. I see the different paths, and I see how the openToolStripMenuItem_Click has the full path. But what I'm not seeing is how the tileDisplay1_OnInitialize doesn't. Can some one explain this just a bit more please?

Also thank you Kilorn, I was in fact missing that line. :P
Was This Post Helpful? 0
  • +
  • -

#10 r233967  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 3
  • Joined: 30-September 12

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 02 October 2012 - 07:38 PM

Okay, I'll try to elaborate and hopefully guide you along a bit to help you solve your problem...

In openToolStripMenuItem_Click, you're building the fullPath because you browsed to the TileGameContent directory and the code appends a "/" and the filenames in your Layer1.layer file.

In openToolStripMenuItem_Click, set a breakpoint at:

Image image = Image.FromFile(fullPath);


and run your program. Browse to your TileGameContent directory and Open your Layer1.layer file. You should hit your breakpoint now.

In the debugger, open the "Locals" window using the Debug->Windows->Locals menu item if the window isn't already open.

You should see the local variable "fullPath" set to the first texture path in Layer1.layer. It should look something like "C:\\Users\\r233967\\Documents\\Visual Studio 2010\\Projects\\TileGame\\TileGame\\TileGameContent/Tiles/se_free_dirt_texture.jpg". The path of course will depend on where you TileGameContent directory is. Also, don't worry about the mixed forward and back slashs in the path.

You should also see the local variable "tex" set to [Microsoft.Xna.Framework.Graphics.Texture2D].

This is what these variables should look like. If your debugging session shows that your local variables look like this, then you are reading in the textures correctly using Texture2D.FromStream. If the tex variable is null, then your Texture2D.FromStream failed to read your texture. You would also probably get an exception here.

Next, look for the instance variable tileTexture. You'll have to scroll to the top of the "Locals" window and click on the + (plus sign) next to "this". Scroll down the list until you find tileTexture. It should be set to [Microsoft.Xna.Framework.Graphics.Texture2D], just like the tex variable. If it's null, then your Texture2D.FromStream failed to read your tile.png (or tilecursor.png in your case).

If both texture variables looked okay, remove your breakpoint and hit continue. You should see your tileDisplay with the dirt, grass and road textures. If you see a flashing red X here, there is probably something wrong with the way you are handling your dirt, grass or road textures.

Click on "Layer1.layer" in your layerListBox and move your cursor into the tileDisplay. You should see your tilecursor whereever your mouse cursor is. If you see a flashing red X here, there is probably something wrong with the way you are handling your tilecursor texture or possibly the texture file itself.

Can you try the above and see if the variables look correct and where the flashing red X appears.
Was This Post Helpful? 0
  • +
  • -

#11 ArchColossus  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 49
  • Joined: 22-February 12

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 03 October 2012 - 06:20 AM

The problem is the tilecursor. I tried adding the tilecursor to the map itself, and it worked. But I don't know how to get it to work in the On_Initialize. I've been messing with the file path to the image. But no luck so far.
Was This Post Helpful? 0
  • +
  • -

#12 r233967  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 3
  • Joined: 30-September 12

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 03 October 2012 - 06:56 PM

Great! You've isolated the problem to the tilecursor.

Try specifying a full path to your tilecursor.png image in tileDisplay1_OnInitialize, something like:

tileTexture = Texture2D.FromStream(GraphicsDevice, new StreamReader("C:/Users/r233967/Documents/Visual Studio 2010/Projects/TileGame/TileEditor/Content/tilecursor.png").BaseStream);


If that doesn't work, comment out the above line in tileDisplay1_OnInitialize and add something like the following to openToolStripMenuItem_Click after your foreach loop that reads in the other textures:

tileTexture = Texture2D.FromStream(GraphicsDevice, new StreamReader(contentPathTextBox.Text + "/Tiles/tilecursor.png").BaseStream);


Since this path is looking in the TileGame's TileGameContent directory, you'll have to copy your tilecursor.png image to that directory (the same directory as your dirt, grass, road textures). This isn't really a solution since the tilecursor belongs in the TileEditor's Content directory, but it may help you figure out why you can't read the tilecursor.png image in tileDisplay1_OnInitialize.
Was This Post Helpful? 1
  • +
  • -

#13 ArchColossus  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 49
  • Joined: 22-February 12

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 04 October 2012 - 06:19 AM

Thank you. I've been stuck there for awhile and now everything works again. I shall now continue through the tutorials. That feels like it shouldn't have been that hard to figure out. But thank you. Now I know. Wherever you are employed, I hope they give you a raise.
Was This Post Helpful? 0
  • +
  • -

#14 ArchColossus  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 49
  • Joined: 22-February 12

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 04 October 2012 - 07:31 AM

Er, I seem to have run into another, luckily simpler problem.
private void addTextureButton_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "JPG Image|*.jpg|PNG Image|*.png|TGA Image|*.tga";
            openFileDialog1.InitialDirectory = contentPathTextBox.Text;

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string filename = openFileDialog1.FileName;

                Texture2D texture = Texture2D.FromFile(GraphicsDevice, filename);
                Image image = Image.FromFile(filename);

                filename = filename.Remove(contentPathTextBox.Text);
            }
        }

My problem here is the depreciated Texture2D.FromFile. I know there's a workaround for it, but I don't quite understand it yet.

I'm also getting another two errors for "filename = filename.Remove(contentPathTextBox.Text);". "The best overloaded method match for 'string.Remove(int)' has some invalid arguments." and "Argument 1: cannot convert from 'string' to 'int'". I'm confused as to why it's referring to (contentPathTextBox.Text) as an int. If someone could explain these to me I'd be even more grateful than I already am. Thank you in advance.

Edit: I think I may have fixed the FromFile problem, but if someone could still explain it to me I'd appreciate it.

This post has been edited by ArchColossus: 04 October 2012 - 07:44 AM

Was This Post Helpful? 0
  • +
  • -

#15 ArchColossus  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 49
  • Joined: 22-February 12

Re: Problem following Nick Gravelyn's tile engine tutorial.

Posted 04 October 2012 - 08:02 AM

And I fixed the second error. Flew into full debug mode before watching the part where he finds the error and fixes it... whoops. If someone can explain Texture2D.FromStream to me, (Which I think is how you fix the FromFile) I still don't quite understand it. Apologies for the slight debug panic spam. :whistling:
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2