MAUI俄罗斯方块

MainPage.xaml

<ContentPage.Resources>
        <Style x:Key="btnSyle" TargetType="ImageButton">
            <Setter Property="Padding" Value="6"/>
            <Setter Property="BorderColor" Value="Silver"/>
            <Setter Property="BorderWidth" Value="3"/>
            <Setter Property="CornerRadius" Value="10"/>
        </Style>
    </ContentPage.Resources>
    <Grid RowDefinitions="*,160" Padding="10">
        <GraphicsView x:Name="gView"/>
        <Grid Grid.Row="1" RowDefinitions="*,*,*" ColumnDefinitions="*,*,*" Margin="20,10,20,0" ColumnSpacing="50">
            <ImageButton x:Name="btnPlay" Grid.Row="0" Grid.Column="1" Source="play.png" Style="{StaticResource btnSyle}" Clicked="btnPlay_Clicked"/>
            <ImageButton x:Name="btnLeft" Grid.Row="1" Grid.Column="0" Source="left.png" Style="{StaticResource btnSyle}" Clicked="btnLeft_Clicked"/>
            <ImageButton x:Name="btnRight" Grid.Row="1" Grid.Column="2" Source="right.png" Style="{StaticResource btnSyle}" Clicked="btnRight_Clicked"/>
            <ImageButton x:Name="btnDrop" Grid.Row="2" Grid.Column="1" Source="drop.png" Style="{StaticResource btnSyle}" Clicked="btnDrop_Clicked"/>
            <ImageButton x:Name="btnRotate" Grid.Row="1" Grid.Column="1" Source="rotate.png" Style="{StaticResource btnSyle}" Clicked="btnRotate_Clicked"/>
        </Grid>
    </Grid>

GraphicsDrawable.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Game
{
    internal class GraphicsDrawable : IDrawable
    {
        
        
        private int hCout;
        private int vCout;
        Color[,] bgArr;
        BlockFactory factory=new BlockFactory();
        Block activeBlock;
        Point pos;
        bool isOver=false;

        public GraphicsDrawable(int hCout, int vCout)
        { 
            this.hCout = hCout;
            this.vCout = vCout;
            bgArr=new Color[vCout,hCout];
           // pos = new Point(-activeBlock.Styles[0].X,(hCout-4)/2);   
        }
        public void Start()
        {
            Array.Clear(bgArr);
            CrateNewBlock();
            isOver = false;

        }
        public void MoveLeft()
        {
            if (!IsOutBound(activeBlock, new Point(pos.X, pos.Y - 1))) {
                pos.Y -= 1;
            }
           
        }
        public void MoveRight()
        {
            if (!IsOutBound(activeBlock, new Point(pos.X, pos.Y +1)))
            {
                pos.Y += 1;
            }

        }
        public bool MoveDown()
        {
            if (!IsOutBound(activeBlock, new Point(pos.X + 1, pos.Y)))
            {
                pos.X += 1;
                return true;
            }
            else
            {
                for (int i = 0; i < activeBlock.Styles.Length; i++)
                {
                    int x = (int)(pos.X + activeBlock.Styles[i].X);
                    int y = (int)(pos.Y + activeBlock.Styles[i].Y);
                    bgArr[x, y] = activeBlock.BlockColor;
                }
                EraseFullRow();
                
                return false;
            }
        }
        public bool CrateNewBlock()
        {
            activeBlock = factory.GetANowBlock();
            pos = new Point(-activeBlock.Styles[0].X, (hCout - 4) / 2);
            if (!IsOutBound(activeBlock, pos))
            { 
            return true;
            }
            isOver = true;
            return false;
        }

        public void Drop()
        { 
            while (MoveDown()) ;
        }
      
        public void Rotate()
        {
            Block block=factory.GetNextRotateBlock();
            if (!IsOutBound(block, pos))
            {
                factory.Rotate();
                activeBlock= block;
            }
        }
        public bool IsOutBound(Block block,Point p) {
            for (int i = 0; i < block.Styles.Length; i++)
            { 
                int x =(int)(block.Styles[i].X+p.X);
                int y = (int)(block.Styles[i].Y+p.Y);
                if(x < 0 || x > vCout - 1 || y < 0 || y > hCout - 1 || bgArr[x,y]!=null)
                {
                    return true;
                }
            }
            return false;
        }
        private void EraseFullRow()
        {
            int fullCount = 0;
            for (int row = vCout - 1; row >= 0; row--)
            {
                bool isFullRow = true;
                for (int col = 0; col < hCout; col++)
                {
                    if (bgArr[row, col] == null)
                    {
                        isFullRow = false;
                    }
                    if (fullCount> 0)
                    {
                        bgArr[row+fullCount, col] = bgArr[row,col];
                        bgArr[row, col] = null;
                    }
                }
                if (isFullRow)
                {
                    fullCount++;
                }
            }
        }
        public void Draw(ICanvas canvas, RectF dirtyRect)
            
        {
            //canvas.ResetState();
            float width=dirtyRect.Width;
            float height=dirtyRect.Height;
            float ratio=(float)vCout / hCout;
            if (height / width > ratio)
            {
                height = width * ratio;
            }
            else
            {
                width = height / ratio;
            }
            float oranginX = (dirtyRect.Width - width) / 2;
            float oranginY = (dirtyRect.Height - height) / 2;
            canvas.FillColor=Colors.Black;
            //canvas.FillRectangle(oranginX, oranginY, width, height);
            //canvas.Translate(oranginX, oranginY);
            //float scale = width / 200;
            //canvas.Scale(scale, scale);
            //绘制背景
            canvas.FillColor=Colors.Black;
            Rect bgRect = new Rect(0,0,width,height );
            canvas.FillRectangle(bgRect);


            //绘制背景数组所对应的每一个小方块
            float size = Math.Min(width/hCout,height/vCout);
            for (int x = 0; x < bgArr.GetLength(0); x++)
            {
                for (int y = 0; y < bgArr.GetLength(1); y++) 
                {
                    Rect rect=new Rect(y*size,x*size,size-1, size - 1);
                    if (bgArr[x,y] != null)
                   
                    {
                        canvas.FillColor = bgArr[x, y];
                        canvas.FillRectangle(rect);
                    }
                    //绘制坐标值
                    //canvas.FillRectangle(rect);
                    //canvas.DrawString(x.ToString()+","+y.ToString(),
                    //    rect,
                    //    HorizontalAlignment.Center,
                    //    VerticalAlignment.Center);
                }
            }
            //将活动方块颜色加入背景
            if (activeBlock != null)
            {
                for (int i = 0; i < activeBlock.Styles.Length; i++)
                {
                    int x = (int)(pos.X + activeBlock.Styles[i].X);
                    int y = (int)(pos.Y + activeBlock.Styles[i].Y);
                    canvas.FillColor = activeBlock.BlockColor;

                    canvas.FillRectangle(y*size,x* size, size-1,size-1);
                }
            }
            //绘制游戏结束
            if (isOver)
            {
                canvas.Font = Microsoft.Maui.Graphics.Font.DefaultBold;
                canvas.FontSize = 50;
                canvas.FontColor = Colors.White;
                canvas.DrawString("GAME OVER",bgRect,HorizontalAlignment.Center,VerticalAlignment.Center);
            }
        }
    }
}

BlockFactory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Game
{  
   internal class BlockFactory
    {
        int styleNum = 0;
        int rotateNum = 0;
        int[][] items =
       {
        new int[] {17504,1856,1570,736},
        new int[] {8800,1136,1604,3616},
        new int[] {9760,624,17984,1824},
        new int[] {8738,240},
        new int[] {1632},
        new int[] {17952,864},
        new int[] {9792,1584}
    };
        Color[] colors =
         {
            Colors.Red,
            Colors.Orange,
            Colors.Yellow,
            Colors.Green,
            Colors.Cyan,
            Colors.Blue,
            Colors.Purple

        };

        //随机生成一个方块
        public Block  GetANowBlock()
        {
            rotateNum = 0;
            Random rm = new Random();
            styleNum = rm.Next(colors.Length);   
            return new Block(items[styleNum][0], colors[styleNum]);
        }
        public Block GetNextRotateBlock()
        {
            int[] style = items[styleNum];
            int num=(rotateNum+1)%style.Length;
            return new Block(items[styleNum][num], colors[styleNum]);
        }
        public void Rotate()
        {
            int[] style = items[styleNum];
            rotateNum = (rotateNum + 1) % style.Length;
        }
    }
}

Block.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Game
{
    internal class Block
    {
       public Point[] Styles { get; }
        public Color BlockColor { get; }

        public Block(int style,Color blockColor)
        {
            List< Point > coords= new List< Point >();
            for(int i = 0; i < 16; i++)
            {
                if((style&(1<<i)) != 0)
                {
                    coords.Add(new Point(i/4, i%4));
                }
            }
            Styles = coords.ToArray();
            BlockColor=blockColor;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/hb_ljj/article/details/129374070