Member 14526996 Ответов: 2

Как я могу отображать изображения в моих сгенерированных кнопках?


Я работаю над игрой winform, чтобы просто ознакомиться с тем, как все работает. Мне удалось создать кнопки на основе пользовательского ввода ( которые будут отображаться как x количество строк и x количество столбцов). Я сохранил его в виде чисел (0 будет пустой кнопкой, 1 будет моим персонажем, а 2 - стеной)

Текстовые файлы выглядят следующим образом:
3,3 ---> количество строк и столбцов
2 -
2 - Эти три 2s будут изображениями стен для первой колонки
2 -
0 ->
1 -> 010 будет отображаться в среднем ряду в виде двух пустых кнопок с каждой стороны и
0 -> символ посередине
2
2
2

Итак, когда я загружаю это, я могу сгенерировать в общей сложности 9 плиток, но все они кажутся пустыми, как я могу заставить их загружаться с соответствующими изображениями?

Как я открываю и восстанавливаю текстовый файл и мой переключатель для моих изображений
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;
    }


Что я уже пробовал:

Теперь я попытался создать отдельный/другой метод, но я просто заблудился ( я новичок с c# и использую winforms, поэтому я просто очень запутался).

Метод, который я попытался создать, был:
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
}, 


Затем я попытался вызвать метод в своем цикле, используя
Tile.Image = GetTypeImage(Tile.Type); 


Извините за длину и беспорядочный код, я все еще пытаюсь привыкнуть к c# и нахожу его довольно неприятным, пытаясь понять, как это сделать ( хотя я чувствую, что слишком много думаю об этом, я не совсем уверен). Спасибо.

2 Ответов

Рейтинг:
2

RickZeeland

Взгляните на это: C# Tutorial – создайте простую платформенную игру в visual studio Moo ICT – Project Based Tutorials - - Страница 1[^]
Это выглядит забавно :)

А для более продвинутой разработки игр смотрите раздел: лучшие-2d-игровые движки[^]


Member 14526996

Я некоторое время искал учебник, но не смог его найти ( вероятно, из-за плохой формулировки), поэтому я ценю его.

RickZeeland

Удачи, и, возможно, когда вы закончите и захотите сделать более продвинутые вещи, вы можете попробовать игровой движок, например Unity :)

Рейтинг:
1

OriginalGriff

Поскольку у вас есть тип, который, по - видимому, является перечислением, используйте его вместо "магических чисел" в ваших операторах case:

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;
}
Это делает ваш код более надежным и удобным для чтения.
И когда вы передаете значение методу, это хорошая идея, чтобы использовать его:
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;
} 
Вероятно, Вам также следует передать плитку в метод вместо типа teh и использовать содержащееся в ней значение типа.

Это также очень хорошая идея, чтобы добавить default к каждому переключателю:
default: throw new ArgumentException($"Unknown Type: {tile.Type}");
Таким образом, если вы забудете один из вариантов в case список, вам говорят об этом - и если вы добавляете тип двери, он напоминает вам, если вы забыли добавить его в список. switch.

На несвязанной основе: делать целую карту с отдельными кнопками - это не очень хорошая идея-это может быть легко для вас, но количество кнопок, которые вам нужно создать, становится глупым, очень быстро - карта 10x10 имеет 100, но 50x50 имеет 2500 ... и большинство "интересных игр" имеют довольно большие карты. Больше кнопок равно большему количеству окон, равно худшей производительности / приложению или даже сбоям системы, потому что вы начинаете запускать оконные ручки. Гораздо, гораздо лучшая идея-нарисовать свою карту вручную на панели в событии рисования и сделать обнаружение щелчков для себя с помощью панели.Событие MouseClick и координаты, которые оно получает.


OriginalGriff

Я знаю, это звучит сложно, но ..... на самом деле это не так (просто нужно больше думать), и это дает лучший результат. Особенно если вы начинаете делать это и не слишком много вкладываете в неправильный подход!

Member 14526996

Эй, у меня есть несколько проблем с нижним корпусом переключателя, имена корпусов появляются как несуществующие (исключение для пустого, который непригоден для использования из-за уровня защиты, что странно) плитка появляется как нечитаемая и не существующая, и selectedTool теперь запрашивает ссылку на объект. Я добавил переключатель в свою основную форму, в которую пытаюсь его загрузить, должен ли я был добавить его в свой класс компонентов "плитка" вместо этого?

OriginalGriff

При объявлении метода как статического он не может получить доступ к переменным экземпляра класса. "tile" и "selectedTool", вероятно, являются переменными экземпляра.

Вероятно, вам нужно удалить статическое объявление из метода - но у меня нет доступа ко всему вашему коду, чтобы быть уверенным.

Member 14526996

Я включил его в другой файл для более удобного просмотра https://paste.ofcode.org/ce9uC77eU9jniBrjJnb2Ma

Member 14526996

Я действительно переименовал своего персонажа и стену в моем случае, я просто забыл включить изменение в этот пастебин, так как нашел некоторые другие изображения, которые я собираюсь использовать, спасибо за любую помощь.