Click here to Skip to main content
15,921,454 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm working on a winform game to just familiarize myself with how things work. I have managed to generate buttons based on user input ( which would display as x amount of rows and x amount of columns). I have saved it as numbers (0 would be an empty button, 1 would be my character, and 2 would be a wall)

The textfiles appear as:
3,3 ---> the amount of rows and columns
2 -
2 - These three 2s would be pictures of walls for the first column
2 -
0 ->
1 -> The 010 would display in the middle row as two empty buttons on each side and the
0 -> character in the middle
2
2
2

So when I am loading this, I am able to generate 9 tiles in total, but all of them appear blank, how do I make them load up with their respective images?

How I am opening and regenerating from the textfile and my switch for my images
C#
private void openButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofg = new OpenFileDialog();
            ofg.Filter = "Game File(*.game)|*.game";
            if (ofg.ShowDialog() == DialogResult.OK)
            {
                using (StreamReader sr = new StreamReader(ofg.FileName))
                {
                    var intLines = File.ReadAllLines(ofg.FileName);

                    var rowsCols = intLines[0].Split(',');
                    int.TryParse(rowsCols[0], out rows);
                    int.TryParse(rowsCols[1], out cols);
    
                    var line = 1;

                    for (int row = 0; row < rows; row++)
                    {
                        for (int col = 0; col < cols; col++)
                        {  
                            var tileMap = Tile.Parse(intLines[line++], row, col);
                            
                            tileMap.Width = tileWidth;
                            tileMap.Height = tileHeight;
                            tileMap.Left = col * tileWidth;
                            tileMap.Top = row * tileHeight;
                       
                            pnlBoard.Controls.Add(tileMap);
                        }
                    }

                }
            }
        }   

private void tile_Click(object sender, EventArgs e) 
    {
        Tile tile = (Tile)sender;
        tile.Type = (TileType)selectedTool;

        switch (selectedTool) 
        {
            case 0:
                tile.Image = null;  
                tile.Tag = 0;
                break;
            case 1:
                tile.Image = Properties.Resources.Char; 
                tile.Tag = 1;
                break;
            case 2:
                tile.Image = Properties.Resources.Wall;
                tile.Tag = 2;
                break;        
        }
        selectedTool = (int)tile.Tag;
    }


What I have tried:

Now I have tried creating a separate/different method but I just got lost ( I am a beginner with c# and using winforms so I ended up just getting very confused).

The method I tried creating was:
C#
public static Image GetTypeImage(Type imageType) 
{ 
     switch (selectedTool) 
        {
            case 0:
                tile.Image = null;  
                tile.Tag = 0;
                break;
            case 1:
                tile.Image = Properties.Resources.Char; 
                tile.Tag = 1;
                break;
            case 2:
                tile.Image = Properties.Resources.Wall;
                tile.Tag = 2;
                break;        
        }
        selectedTool = (int)tile.Tag;
    //I was unsure how to proceed from here
}, 


I then tried to call the method in my loop using
C#
Tile.Image = GetTypeImage(Tile.Type); 


Sorry for the length and messy code, I am still trying to get accustomed with c# and have been finding it pretty frustrating trying to figure out how to do this ( Although I feel I am overthinking it, I am not quite sure.). Thanks.
Posted
Updated 2-Nov-19 4:27am

Since you have a Type - which presumably is an enum - use that instead of "magic numbers" in your case statements:
tile.Type = (TileType)selectedTool;

switch (tile.Type)
{
    case Empty:
        tile.Image = null;
        tile.Tag = 0;
        break;
    case Character:
        tile.Image = Properties.Resources.Char;
        tile.Tag = 1;
        break;
    case Wall:
        tile.Image = Properties.Resources.Wall;
        tile.Tag = 2;
        break;
}
That makes your code both more reliable, and easier to read.
And when you pass a value to a method, it's a good idea to use it:
public static Image GetTypeImage(Type imageType) 
{ 
     switch (imageType) 
        {
            case Empty:
                tile.Image = null;  
                tile.Tag = 0;
                break;
            case Character:
                tile.Image = Properties.Resources.Char; 
                tile.Tag = 1;
                break;
            case Wall:
                tile.Image = Properties.Resources.Wall;
                tile.Tag = 2;
                break;        
        }
    selectedTool = (int)tile.Tag;
    return tile.Image;
} 
You should probably also pass the Tile through to the method instead of teh Type, and use the Type value that contains.

It's also a very good idea to add a default to every switch:
C#
default: throw new ArgumentException($"Unknown Type: {tile.Type}");
That way, if you forget an option in the case list, you get told about it - and if you add a Door type, it reminds you if you forget to add it to a switch.

On an unrelated basis: Doing a whole map with individual buttons is not a good idea - it may be easy for you, but the number of buttons you need to create gets silly, very quickly - a 10x10 map has 100, but a 50x50 has 2500 ... and most "interesting games" have pretty big maps. More Buttons equals more windows, equals worse performance / app or even system crashes because you start to run out of window handles. A much, much better idea is to draw your map manually onto a Panel in it's Paint event and do the click detection for yourself using the Panel.MouseClick event and the coordinates it gets passed.
 
Share this answer
 
Comments
OriginalGriff 2-Nov-19 13:15pm    
I know it sounds complicated, but ... it isn't really (it just takes more thinking about) and it does produce a better result. Especially if you start off doing it and don't have too much invested in the wrong approach!
Member 14526996 2-Nov-19 13:36pm    
Hey, I am having a few issues with the bottom switch case, the case names are appearing as they not existing (excrept for empty which is unusable due to the protection level which is strange) tile appears as unreacable and not existing, and selectedTool is asking for an object reference now. I added the switch onto my main form I am trying to load it into, should I have added it into my component class "Tile" instead?
OriginalGriff 2-Nov-19 14:42pm    
When you declare a method as static, it cannot access any class instance variables. "tile" and "selectedTool" are probably instance variables.

Probably, you need to remove the static declaration from the method - but I don't have access to your whole code to be sure.
Member 14526996 2-Nov-19 17:20pm    
I've included it in another file for easier viewing https://paste.ofcode.org/ce9uC77eU9jniBrjJnb2Ma
Member 14526996 2-Nov-19 15:30pm    
I did rename my character and wall in my case I just forgot to include the change in that pastebin as I found some other images I am going to use, thanks for any help.
Take a look at: C# Tutorial – Create a simple platform game in visual studio Moo ICT – Project Based Tutorials - - Page 1[^]
It looks like fun :)

And for more advanced game development see: best-2d-game-engines[^]
 
Share this answer
 
v2
Comments
Member 14526996 2-Nov-19 13:10pm    
I was looking for a tutorial for a while but I couldn't find one ( probably because of poor wording) so I appreciate it.
RickZeeland 2-Nov-19 13:40pm    
Good luck, and maybe when you are done and want to do more advanced things you could try a game engine like Unity for instance :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900