使用Xamarin开发移动应用示例——数独游戏(二)创建游戏界面

博客 动态
0 282
优雅殿下
优雅殿下 2022-01-24 13:30:18
悬赏:0 积分 收藏

使用Xamarin开发移动应用示例——数独游戏(二)创建游戏界面

使用Xamarin编制移动数独游戏

在本系列第一部分,我们创建了程序框架,现在我们创建游戏的界面,项目代码可以从Github下载:https://github.com/zhenl/ZL.Shudu 。代码随项目进度更新。

首先在Views目录下添加一个内容页面,名称为Game.xaml:

然后,在AppShell.xaml中增加这个页面导航:

    <TabBar>        <ShellContent Title="游戏" Icon="icon_about.png" Route="Game"  ContentTemplate="{DataTemplate local:Game}" />          <ShellContent Title="关于" Icon="icon_about.png" Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />        <ShellContent Title="Browse" Icon="icon_feed.png" ContentTemplate="{DataTemplate local:ItemsPage}" />    </TabBar>

如果这时运行程序,会发现页面底部增加了一个“游戏”分页,并且初始页面也改为这个页面。现在我们修改这个页面,改造为数独游戏界面。数独的界面是9X9的格子,这些格子组成九个九宫格,每个格子中是1-9的数字,玩家需要将所有的格子填满,并且行、列和九宫格中的数据不能重复。我们可以使用Grid进行布局,构造九行九列,每个格子中放置一个按钮(Button),用户按下按钮,弹出数字输入框,输入数字后,数字显示在按钮上,完成一个输入。
下面是页面的布局XAML:

<?xml version="1.0" encoding="utf-8" ?><ContentPage xmlns="http://xamarin.com/schemas/2014/forms"             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"             x:>    <ContentPage.Content>        <StackLayout x:Name="outerStack"  Orientation="Vertical">            <!-- Place new controls here -->            <Grid x:Name="myGrid" IsVisible="True" >                <Grid.ColumnDefinitions>                    <ColumnDefinition Width="*" />                    <ColumnDefinition Width="*" />                    <ColumnDefinition Width="*" />                    <ColumnDefinition Width="*" />                    <ColumnDefinition Width="*" />                    <ColumnDefinition Width="*" />                    <ColumnDefinition Width="*" />                    <ColumnDefinition Width="*" />                    <ColumnDefinition Width="*" />                </Grid.ColumnDefinitions>                <Grid.RowDefinitions>                    <RowDefinition Height="25"  />                    <RowDefinition Height="25" />                    <RowDefinition Height="25" />                    <RowDefinition Height="25" />                    <RowDefinition Height="25" />                    <RowDefinition Height="25" />                    <RowDefinition Height="25" />                    <RowDefinition Height="25" />                    <RowDefinition Height="25" />                    <RowDefinition Height="40" x:Name="rowButton" />                    <RowDefinition Height="40" x:Name="rowResult" />                </Grid.RowDefinitions>                <Label x:Name="lbFinish" Text="完成" IsVisible="false" Grid.Row="10" Grid.Column="0"  Grid.ColumnSpan="2" />                <Label x:Name="lbTime" Grid.Row="10" Grid.Column="3" Grid.ColumnSpan="2" Text="" IsVisible="False"></Label>                <Label x:Name="lbMessage" Grid.Row="10" Grid.Column="5" Grid.ColumnSpan="4" Text="" IsVisible="False"></Label>            </Grid>            <Grid x:Name="grdNumber" IsVisible="false">                <Grid.ColumnDefinitions>                    <ColumnDefinition Width="*" />                    <ColumnDefinition Width="*" />                    <ColumnDefinition Width="*" />                    <ColumnDefinition Width="*" />                    <ColumnDefinition Width="*" />                </Grid.ColumnDefinitions>                <Grid.RowDefinitions>                    <RowDefinition Height="*" />                    <RowDefinition Height="*" />                </Grid.RowDefinitions>            </Grid>        </StackLayout>    </ContentPage.Content></ContentPage>

在页面初始化时,生成数字按钮、游戏界面中每个单元格按钮,并根据初始数据确定按钮的文本和使能。

        public Game()        {            try            {                InitializeComponent();                SetNumButtons();                SetLayout();                SetNewGame();            }            catch (Exception ex)            {                lbMessage.IsVisible = true;                rowResult.Height = 40;                lbMessage.Text = ex.Message;                //throw;            }        }

设置数字按钮的函数代码如下:

      private void SetNumButtons()        {            var num = 1;            for (var i = 0; i < 2; i++)            {                for (var j = 0; j < 5; j++)                {                    var btn = new Button();                    if (num == 10)                    {                        btn.Text = "清除";                        btn.Clicked += btn_Clear_Clicked;                        btn.FontSize = 15;                    }                    else                    {                        btn.Text = num.ToString();                        btn.Clicked += btn_Num_Clicked;                        btn.FontSize = 16;                    }                    btn.Padding = 0;                    grdNumber.Children.Add(btn, j, i);                    numbuttons[i, j] = btn;                    num++;                }            }        }

设置数独界面按钮的代码如下:

       private void SetLayout()        {            for (var i = 0; i < 9; i++)            {                for (var j = 0; j < 9; j++)                {                    int m = i / 3;                    int n = j / 3;                    var btn = new Button();                    var c = new Color(0.9, 0.9, 0.9);                    if ((m + n) % 2 == 0)                    {                        c = new Color(0.5,0.5, 0.5);                    }                    btn.BackgroundColor = c;                    btn.Padding = 0;                    btn.Margin = 0;                    btn.FontSize = 20;                    myGrid.Children.Add(btn, i, j);                    btn.Clicked += Btn_Clicked;                    buttons[i, j] = btn;                }            }        }

根据初始化数据,设置按钮状态的代码如下:

      private void SetGame(int[,] inp)        {            for (var i = 0; i < 9; i++)            {                for (var j = 0; j < 9; j++)                {                    chess[i, j] = inp[i, j];                }            }            for (var i = 0; i < 9; i++)            {                for (var j = 0; j < 9; j++)                {                    var btn = buttons[i, j];                    if (chess[i, j] > 0)                    {                        btn.Text = chess[i, j].ToString();                        btn.IsEnabled = false;                    }                    else                    {                        btn.Text = "";                        btn.IsEnabled = true;                    }                }            }            this.lbFinish.IsVisible = false;            this.lbTime.IsVisible = false;            this.lbMessage.IsVisible = false;            this.rowResult.Height = 1;            lbTime.Text = "";            lbMessage.Text = "";        }

按钮的响应事件如下:

     private void Btn_Clicked(object sender, EventArgs e)        {            currentButton = sender as Button;            rowResult.Height = 1;            rowButton.Height = 1;            grdNumber.IsVisible = true;        }        private void btn_Clear_Clicked(object sender, EventArgs e)        {            if (currentButton == null) return;            currentButton.Text = "";            grdNumber.IsVisible = false;            myGrid.IsVisible = true;            rowResult.Height = 40;            rowButton.Height = 40;        }        private void btn_Num_Clicked(object sender, EventArgs e)        {            currentNumBtn = sender as Button;                        int x = -1, y = -1;            for (var i = 0; i < 9; i++)            {                for (var j = 0; j < 9; j++)                {                    if (buttons[i, j] == currentButton)                    {                        x = i;                        y = j;                        break;                    }                }            }            var num = int.Parse(currentNumBtn.Text);            if (!checkval(x, y, num))            {                return;            }            currentButton.Text = currentNumBtn.Text;            myGrid.IsVisible = true;            grdNumber.IsVisible = false;            rowResult.Height = 40;            rowButton.Height = 40;            if (IsFinish())            {                lbFinish.IsVisible = true;                rowResult.Height = 40;            }        }

判断输入状态和游戏结束的函数如下:

        private bool checkval(int x, int y, int num)        {            for (var i = 0; i < 9; i++)            {                var buttonnum = string.IsNullOrEmpty(buttons[x, i].Text) ? 0 : int.Parse(buttons[x, i].Text);                if (i != y && buttonnum == num) return false;            }            for (var i = 0; i < 9; i++)            {                var buttonnum = string.IsNullOrEmpty(buttons[i, y].Text) ? 0 : int.Parse(buttons[i, y].Text);                if (i != x && buttonnum == num) return false;            }            int m = x / 3;            int n = y / 3;            for (int i = m * 3; i < (m + 1) * 3; i++)            {                for (int j = n * 3; j < (n + 1) * 3; j++)                {                    var buttonnum = string.IsNullOrEmpty(buttons[i, j].Text) ? 0 : int.Parse(buttons[i, j].Text);                    if (i != x && j != y && buttonnum == num) return false;                }            }            return true;        }        private bool IsFinish()        {            for (var i = 0; i < 9; i++)            {                for (var j = 0; j < 9; j++)                {                    if (string.IsNullOrEmpty(buttons[i, j].Text)) return false;                }            }            return true;        }    }

运行效果如下:

现在基本界面已经搭建完成,后续需要增加允许回退、历史记录、退出保存以及自动完成等功能。项目代码可以从Github下载:https://github.com/zhenl/ZL.Shudu 。代码随项目进度更新。

本文来自博客园,作者:寻找无名的特质,转载请注明原文链接:https://www.cnblogs.com/zhenl/p/15831901.html

posted @ 2022-01-24 10:55 寻找无名的特质 阅读(59) 评论(0) 编辑 收藏 举报
回帖
    优雅殿下

    优雅殿下 (王者 段位)

    2012 积分 (2)粉丝 (47)源码

    小小码农,大大世界

     

    温馨提示

    亦奇源码

    最新会员