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;
}
}
}