0

我遇到了问题,我的程序正在运行,但没有渲染图像,我对 C# 还是很陌生,而且我一直在研究这个单一的应用程序!我已经包含了我的完整代码,希望有人能帮助我,我认为主要问题在于最后两种方法。它应该是一个 Whack a Mole 类型的游戏。

谢谢!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.IO;
using TeiUtils;


namespace WhackaMole
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        Image[] ImageArray = new Image[50];
        string[] CmdArgs = Environment.GetCommandLineArgs();
        string Moleini;
        string scorevalue;
        static String ImgNameMole = "C:/Users/MonAmi/Documents/Visual Studio 2012/Projects/WhackaMole/Hammer/Mole-with-Shovel.jpg";
        static String ImgHole = "C:/Users/MonAmi/Documents/Visual Studio 2012/Projects/WhackaMole/WhackaMole/hole.jpg";
        int ImageSize;
        string Root = "";
        string times = "";


        public MainWindow()
        {

            Root = TUtils.GetIniString(Moleini, "Root", "Path", "");
            Moleini = CmdArgs[1];
            scorevalue = TUtils.GetIniFileString(Moleini, "HighScores", "player", "0");
            InitializeComponent();
            // string ImageName = "Image"; \\
            for (int i = 0; i <= 8; i++)
            {
                Image Image = new Image();
                Image.Width = 100;
                Image.Height = 100;
                ImageArray[i] = Image;
                Image.Name = "Image" + i.ToString();
            }

            // Dispacher for Mole to Appear \\
            System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
            dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
            dispatcherTimer.Interval = TimeSpan.FromSeconds(1);
            dispatcherTimer.Start();

            // Dispacher for Full Game Time \\
            System.Windows.Threading.DispatcherTimer endGame = new System.Windows.Threading.DispatcherTimer();
            endGame.Tick += new EventHandler(endGame_Tick);
            endGame.Interval = TimeSpan.FromSeconds(5);
            endGame.Start();
        }

        private void dispatcherTimer_Tick(object sender, EventArgs e)
        {

            // Random Number Generator \\
            Random rnd = new Random();
            int num = rnd.Next(1, 9);

            // If Random Number is "1" Then Image will display \\
            if (num == 1)
            {
                ImageSource MoleImage = new BitmapImage(new Uri(ImgNameMole));
                ImageArray[1].Source = MoleImage;
            }
            // If Random Number does not equal 1 \\
            else if (num != 1)
            {
                ImageSource hole = new BitmapImage(new Uri(ImgHole));
                ImageArray[1].Source = hole;
            }

            // If Random Number is "2" Then Image will display \\
            else if (num == 2)
            {
                ImageSource MoleImage = new BitmapImage(new Uri(ImgNameMole));
                ImageArray[2].Source = MoleImage;
            }

            // If random number does not equal 2 \\
            else if (num != 2)
            {
                ImageSource hole = new BitmapImage(new Uri(ImgHole));
                ImageArray[2].Source = hole;
            }

            // If Random Number is "3" Then Image will display \\
            else if (num == 3)
            {
                ImageSource MoleImage = new BitmapImage(new Uri(ImgNameMole));
                ImageArray[3].Source = MoleImage;
            }

            // If random number does not equal 3 \\
            else if (num != 3)
            {
                ImageSource hole = new BitmapImage(new Uri(ImgHole));
                ImageArray[3].Source = hole;
            }

            // If Random Number is "4" Then Image will display \\
            else if (num == 4)
            {
                ImageSource MoleImage = new BitmapImage(new Uri(ImgNameMole));
                ImageArray[4].Source = MoleImage;
            }

            // If random number does not equal 4 \\
            else if (num != 4)
            {
                ImageSource hole = new BitmapImage(new Uri(ImgHole));
                ImageArray[4].Source = hole;
            }

            // If Random Number is "5" Then Image will display \\
            else if (num == 5)
            {
                ImageSource MoleImage = new BitmapImage(new Uri(ImgNameMole));
                ImageArray[5].Source = MoleImage;
            }

            // If random number does not equal 5 \\
            else if (num != 5)
            {
                ImageSource hole = new BitmapImage(new Uri(ImgHole));
                ImageArray[5].Source = hole;

            }

            // If Random Number is "6" Then Image will display \\
            else if (num == 6)
            {
                ImageSource MoleImage = new BitmapImage(new Uri(ImgNameMole));
                ImageArray[6].Source = MoleImage;

            }

           // If random number dose not equal 6 \\ 
            else if (num != 6)
            {
                ImageSource hole = new BitmapImage(new Uri(ImgHole));
                ImageArray[6].Source = hole;

            }

           // If Random Number is "7" Then Image will display \\
            else if (num == 7)
            {
                ImageSource MoleImage = new BitmapImage(new Uri(ImgNameMole));
                ImageArray[7].Source = MoleImage;


            }

            // If random number does not equal 7 \\
            else if (num != 7)
            {
                ImageSource hole = new BitmapImage(new Uri(ImgHole));
                ImageArray[7].Source = hole;


            }

            // If Random Number is "8" Then Image will display \\
            else if (num == 8)
            {
                ImageSource MoleImage = new BitmapImage(new Uri(ImgNameMole));
                ImageArray[8].Source = MoleImage;


            }

            // If random number does not equal 8 \\
            if (num != 8)
            {
                ImageSource hole = new BitmapImage(new Uri(ImgHole));
                ImageArray[8].Source = hole;

            }

        }

        // New Game Button - If Selected Open Window \\
        private void NewGameBttn_Click(object sender, RoutedEventArgs e)
        {

            Window1 win1 = new Window1();
            win1.Show();

        }

        // Points Declaration \\
        int Points = 0;
        // Mole Image \\
        ImageSource MoleImage = new BitmapImage(new Uri(ImgNameMole));

        bool MatchMoleImage(String ImgSrc)
        {
            String m1, m2;
            m1 = System.IO.Path.GetFileName(ImgSrc);
            m2 = System.IO.Path.GetFileName(ImgNameMole);

            if (m1 == m2)
            {
                Points = Points + 1;
                return true;
            }
            return false;
        }

        // Total Game Time Timer \\
        private void endGame_Tick(object sender, EventArgs e)
        {
            this.Close();

            if (Points > 0)
                MessageBox.Show("Congratulations! You Got " + (Points.ToString() + " Moles!"));
            else
                MessageBox.Show("Sorry! Timed out - No Moles today! - Please try again!");
        }

        // Score Keeping \\
        private void HighScore()
        {
            TUtils.WriteIniFileString(Moleini, "HighScores", "Player", (Points.ToString()));
        }

        // Exit Caution - If Selected Open Exit Window \\
        private void CloseBttn_Click(object sender, RoutedEventArgs e)
        {
            Window2 win2 = new Window2();
            win2.Show();

        }

        //Count Point per Button
        private void Image1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            // If Image is Shown Add 1 \\
            MatchMoleImage(ImageArray[1].Source.ToString());
        }

        private void Image2_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            // If Image is Shown Add 1 \\
            MatchMoleImage(ImageArray[2].Source.ToString());
        }

        private void Image3_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            // If Image is Shown Add 1 \\
            MatchMoleImage(ImageArray[3].Source.ToString());
        }

        private void Image4_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            // If Image is Shown Add 1 \\
            MatchMoleImage(ImageArray[4].Source.ToString());
        }

        private void Image5_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            // If Image is Shown Add 1 \\
            MatchMoleImage(ImageArray[5].Source.ToString());
        }

        private void Image6_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // If Image is Shown Add 1 \\
            MatchMoleImage(ImageArray[6].Source.ToString());
        }

        private void Image7_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // If Image is Shown Add 1 \\
            MatchMoleImage(ImageArray[7].Source.ToString());
        }

        private void Image8_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // If Image is Shown Add 1 \\
            MatchMoleImage(ImageArray[8].Source.ToString());
        }

        private void HighScoreini()
        {
            TUtils.WriteIniFileString(Moleini, "HighScores", "Player", Points.ToString());
        }

        private void PopulateGrid()
        {
            double NumofImages = TUtils.GetIniInt(Moleini, "NumPictures", "pictures", 8);
            int ImageSize = TUtils.GetIniInt(Moleini, "ImageSize", "imageSize", 50);
            int ImageBorderSize = TUtils.GetIniInt(Moleini, "ImageBorder", "imageBorder", 2);
            double NumberOfColumns = TUtils.GetIniInt(Moleini, "NumRowsColumns", "columnNum", 4);

            // More Columns than Rows \\
            if (NumberOfColumns > NumofImages)
            {
                MessageBox.Show("There is something wrong with the .ini file.");
                Window1.Close();
            }

            // Math - Get Necessary Variables \\
            int ColumnSize = (ImageSize + (4 * ImageBorderSize));
            int RowSize = (ImageSize + (4 * ImageBorderSize));
            int NumberofRows = (int)Math.Ceiling(NumofImages / NumberOfColumns);
            int MainWindowWidth = (TUtils.ToInt(NumberOfColumns.ToString(), 4) * ColumnSize) + 15;
            int MainWindowHeight = (NumberofRows * RowSize) + 35;

            // Set Window Size \\
            Window1.Width = MainWindowWidth;
            Window1.Height = MainWindowHeight;

            // Create Grid \\
            Grid grid_Main = new Grid();
            Window1.Content = grid_Main;
            grid_Main.Height = MainWindowHeight;
            grid_Main.Width = MainWindowWidth;

            // Grid Properties \\
            for (int i = 0; i < NumberofRows; i++)
            {
                ColumnDefinition newColumn = new ColumnDefinition();
                newColumn.Width = new GridLength(ColumnSize, GridUnitType.Pixel);
                grid_Main.ColumnDefinitions.Add(newColumn);
            }

            for (int i = 0; i < NumberofRows; i++)
            {
                RowDefinition Row = new RowDefinition();
                Row.Height = new GridLength(RowSize, GridUnitType.Pixel);
                grid_Main.RowDefinitions.Add(Row);
            }

            // Fill Grid \\
            int RowCount = 0;
            int ColumnCount = 0;

            for (int i = 0; i < NumofImages; i++)
            {
                StackPanel newStack = CreateStackPanel(i);
                grid_Main.Children.Add(newStack);

                if (RowCount < NumberofRows)
                {
                    if (ColumnCount < NumberOfColumns)
                    {
                        Console.WriteLine("ColumnCount: " + ColumnCount.ToString());
                        Grid.SetRow(newStack, ColumnCount);
                        Grid.SetColumn(newStack, ColumnCount);
                        ColumnCount++;
                    }

                    else
                    {
                        RowCount++;
                        ColumnCount = 0;
                        Grid.SetRow(newStack, ColumnCount);
                        Grid.SetColumn(newStack, ColumnCount);
                        ColumnCount++;
                        Console.WriteLine("RowCount: " + RowCount.ToString());
                    }
                }

                else
                {
                    break;
                }
            }
        }

            private StackPanel CreateStackPanel(int ImageNum)
            {
            // Gets and Set Variables \\
            ImageSize = TUtils.GetIniInt(Moleini, "ImageSize", "imageSize", 50);

            // StackPanel Properties \\
            System.Windows.Controls.StackPanel newStackPanel = new StackPanel();
            newStackPanel.Height = ImageSize;
            newStackPanel.Width = ImageSize;
            newStackPanel.Margin = new Thickness(3.0);

            // Fill Panel \\
            newStackPanel.Children.Insert(1, CreateImage(ImageNum));

            return newStackPanel;
            }

            private Image CreateImage(int ImageNum)
            {
                // Gets/Sets Necessary Variables \\
                double ImageHeight = ImageSize * 0.7;

                // Initialize Image \\
                System.Windows.Controls.Image newImage = new Image();

                // Image Properties \\
                newImage.Width = ImageSize;
                newImage.Height = ImageHeight;

                // Define Name and Content \\
                newImage.Name = "Image_" + ImageNum;
                String ImageFunction = TUtils.GetIniString(Moleini, "Image" + ImageNum  , "PictureFile", Root + "mole2.png");
                if (File.Exists(ImageFunction))
                {
                    newImage.Source = new BitmapImage(new Uri(ImageFunction));
                }
                else
                {
                    MessageBox.Show("Cannot find " + ImageFunction + ".", "Please fix in ini file");
                }

                return newImage;
            }

    }


}

它应该看起来像这样,鼹鼠从一个地方到另一个地方

它应该看起来像这样,鼹鼠从一个地方到另一个地方

4

1 回答 1

2

好的。删除所有代码并重新开始。

WPF 的默认方法(无论应用程序类型如何,在这种情况下是游戏)是一种称为MVVM的东西,我会说你必须先学习,然后才能在 WPF 中编写一行代码或 XAML。

这是我对您描述的内容的看法:

<Window x:Class="MiscSamples.WhackAMole"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WhackAMole" Height="300" Width="300">
    <ItemsControl ItemsSource="{Binding Moles}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Rows="3" Columns="3" IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Image x:Name="Mole" Height="0" Width="100" 
                       Source="/Images/Mole.Png"
                       Stretch="Fill"
                       VerticalAlignment="Bottom"/>
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding IsUp}" Value="True">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard TargetName="Mole">
                                    <DoubleAnimation Storyboard.TargetProperty="Height" 
                                                     From="0" To="77"
                                                     Duration="00:00:00.3"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                        <DataTrigger.ExitActions>
                            <BeginStoryboard>
                                <Storyboard TargetName="Mole">
                                    <DoubleAnimation Storyboard.TargetProperty="Height"
                                                     From="77" To="0"
                                                     Duration="00:00:00.3"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.ExitActions>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

代码背后:

public partial class WhackAMole : Window
{
    public WhackAMole()
    {
        InitializeComponent();

        DataContext = new WhackAMoleViewModel();
    }
}

视图模型:

public class WhackAMoleViewModel: PropertyChangedBase
{
    private List<Mole> _moles;
    public List<Mole> Moles
    {
        get { return _moles; }
    }

    private System.Threading.Timer timer;
    private System.Random random = new Random();

    public WhackAMoleViewModel()
    {
        _moles = Enumerable.Range(1, 9).Select(x => new Mole()).ToList();
        timer = new Timer(x => RaiseRandomMole(), null, 0, 300);
    }

    private void RaiseRandomMole()
    {
        //If random number is less than 5 skip this iteration
        if (random.Next(1, 10) > 5)
            return;

        //Choose a random mole
        var mole = Moles[random.Next(0, 8)];

        //If it's already raised, do nothing
        if (mole.IsUp)
            return;

        //Raise it
        mole.IsUp = true;

        //Then Get it down somewhere between 1 and 2 seconds after
        Task.Factory.StartNew(() => Thread.Sleep(random.Next(1000, 2000)))
                    .ContinueWith(x => mole.IsUp = false);
    }
}

数据项:

public class Mole: PropertyChangedBase
{
    private bool _isUp;
    public bool IsUp
    {
        get { return _isUp; }
        set
        {
            _isUp = value;
            OnPropertyChanged("IsUp");
        }
    }
}

PropertyChangedBase 类(MVVM 助手):

public class PropertyChangedBase:INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        Application.Current.Dispatcher.BeginInvoke((Action) (() =>
                                                                 {
                                                                     PropertyChangedEventHandler handler = PropertyChanged;
                                                                     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
                                                                 }));
    }
}

结果:

在此处输入图像描述

  • 请注意,我正在使用 WPF 的动画能力来显示/隐藏痣。
  • 另请注意,在我的示例中没有一行代码引用或操作任何 UI 元素。UI 是在 XAML 中完成的,它通过DataBinding对模型/ViewModel 中的更改做出反应
  • 我做了一个基本的例子,它不支持点击痣,你必须使用 a DelegateCommand
  • 以我的示例为基础并遵循我的逻辑(这是正确的)。不要在代码中操纵 UI 元素。
于 2013-05-16T19:18:59.273 回答