65.9K
CodeProject 正在变化。 阅读更多。
Home

动态滑动拼图生成器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (3投票s)

2011 年 3 月 25 日

CC (Attr 3U)

2分钟阅读

viewsIcon

42967

downloadIcon

2385

一个动态滑动拼图生成器,涉及 LINQ 和图片缩放功能。

引言

根据维基百科的定义,滑动拼图、滑动方块拼图或滑动瓷砖拼图挑战玩家沿着某些路线(通常在棋盘上)滑动通常是平面的碎片,以建立某种最终配置。但在这里,我将创建一个简单的(程序上复杂的)滑动拼图原型,玩家可以灵活地从他们选择的图像生成拼图。

背景

最近,我一直在研究各种实现滑动拼图的方法(事实上,有很多种方法)。这里的游戏版本非常简单,并且具有很强的**动态**性。这里的每一行代码都编写成允许用户完全灵活地设置图片中每个块的大小以及每行单元格的数量。

实现游戏的关键特性是

  1. 在行数和每个单元格的大小方面具有极强的动态性。
  2. 动态加载图像块。
  3. 将图像缩放到拼图的长度。
  4. 使用事件来实现逻辑。

使用代码

这里的逻辑是动态地构建并将图像添加到 Windows 窗体中。函数 AssignEventsToButtons() 执行此核心功能。

private void AssignEventsToButtons()
{
    PictureBox temp = null;
    int x = -1;
    for (int i = 0; i <= MaxSeed; i++)
    {
         temp = new PictureBox
                {
                   TabIndex = ++x,
                   SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage,
                   Size = new System.Drawing.Size(SideLength, SideLength),
                   Name = string.Concat("pictureBox", x.ToString()),
                   AllowDrop = true,
                   Location = new Point(0, 0)
                };
        
        temp.MouseDown += new MouseEventHandler(button_MouseDown);
        temp.DragDrop += new DragEventHandler(button_DragDrop);
        temp.DragEnter += new DragEventHandler(button_DragEnter);
        temp.CreateControl();
        flowLayoutPanel1.Controls.Add(temp);
    }
    
    flowLayoutPanel1.Controls.Add(this.groupBox1);
    flowLayoutPanel1.PerformLayout();
}

处理鼠标事件至关重要。每个方块都需要处理所有三个事件,即 MouseDownDragDropDragEnter。最初,考虑将一个块移动到空白处,处理当前块的鼠标按下事件,以将图片发送到前方。

private void button_MouseDown(object sender, MouseEventArgs e)
{
    Cursor = Cursors.Hand;
    _dragSource = (PictureBox)sender;
    _dragSource.DoDragDrop(_dragSource.Image, 
                DragDropEffects.Copy | DragDropEffects.Move);
}

事件 DragEnter 基本上是为了处理移动图片的预期效果。

private void button_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = e.Data.GetDataPresent(DataFormats.Bitmap) ? 
                         DragDropEffects.Move : DragDropEffects.None;
}

游戏的逻辑部分是检查是否为有效移动。拖动块的信息被存储并与目标块进行比较,具体步骤如下

  1. 目标位置应该是有效的移动位置(不允许交叉移动)。
  2. 不应允许图像在其自身上进行拖放。
  3. 完成检查后,图像将被交换。
private void button_DragDrop(object sender , DragEventArgs e)
{
    var dest = (PictureBox) sender;

    if(dest.Image.Equals(_dragSource.Image))
        return;

    if( !new List<int>
             {
                 _dragSource.TabIndex + 1,
                 _dragSource.TabIndex - 1,
                 _dragSource.TabIndex + RowCount,
                 _dragSource.TabIndex - RowCount
             }.Contains(dest.TabIndex))
    {
        MessageBox.Show(Resources.DynPuzzleform_button_DragDrop_Invalid_move);
        return;
    }
    
    if (!ImageCompareArray(dest.Image as Bitmap,Resources._17))
    {
        MessageBox.Show(Resources.DynPuzzleform_button_DragDrop_Invalid_move);
        return;
    }

    _dragSource.Image = dest.Image;
    dest.Image = e.Data.GetData(DataFormats.Bitmap) as Image;

    //checks state
    CheckState(_dragSource.TabIndex, dest.TabIndex);
}

在这里,函数 CheckState 在每一步检查游戏的状态,并与 _successState 进行检查,以确认游戏是否完成。当您按下 F3 时,可以看到此游戏中另一个有趣的特性。是的,您可以加载您选择的图像。图像将被缩放到玩家配置的大小,而不会失真。函数 ResizeImage 会为您完成此操作。

注意:检查 DynSlidingPuzzle.exe.config 中的设置 SideLengthRowCount。请为它们分配有效值。

结论

这完成了制作一个简单但动态的游戏应用程序的过程,它展示了使用 .NET 的便利性。请阅读代码并告诉我您的意见。提前感谢。

© . All rights reserved.