计算自定义网格中的索引

时间:2015-11-30 15:43:25

标签: c# winforms

我想用WinForms创建一个老主题的RPG,我需要像 grid 这样的东西来完成墙和场检查。通过 grid 我的意思是这样的(在我放置图形的位置):

00 01 02 03 04 05 06  
07 08 09 10 11 12 13  
14 15 16 17 18 19 20  

我已经这样做了,效果很好。现在要检查墙碰撞,我需要找出玩家在这个网格中的位置。我以某种方式想出了这个公式:

int index = (p.Location.X / p.Width) + ((p.Location.Y / p.Height) * (width));

p是图片框,width是Y-Scale上的字段数量。所有图片框和图片的大小均为64x64。不幸的是,这个公式并没有给我正确的结果。如果我(在测试中)在13索引上,它会告诉我我在14索引上。

问题:
您是否知道任何方法来改进此公式或简单地使其工作? 任何帮助表示赞赏;)

2 个答案:

答案 0 :(得分:1)

您进行计算的方法有点偏。

计算网格上单元格索引的通用公式为:

index = (cell_row * columns_in_grid) + cell_column

考虑到单元格的位置和大小以及网格的大小,公式变为:

index = ((cell_Y / cell_Height) * (grid_Width / cell_Width)) + (cell_X / cell_Width)

现在,将它转换为您的场景,假设PictureBox p直接放在其父控件上,索引可以计算为:

index = ((p.Location.Y / p.Height) * (p.Parent.Width / p.Width)) + (p.Location.X / p.Width);

由于我手上有一些空闲时间,这是我为你写的一个小型演示:

代码

public partial class Form1 : Form
{
    private Button btn;

    public Form1()
    {
        InitializeComponent();
        btn = new Button()
        {
            Text = "0",
            TextAlign = ContentAlignment.MiddleCenter,
            Location = new Point(0, 0),
            Size = new Size(30, 30),
        };

        this.Controls.Add(btn);
        this.ClientSize = new Size(btn.Width * 7, btn.Height * 3);

        btn.Move += btn_Move;
        this.MouseClick += Form1_MouseEvent;
        this.MouseWheel += Form1_MouseEvent;
    }

    private void btn_Move(object sender, EventArgs e)
    {
        btn.Text = CalculateIndex().ToString();
    }

    private int CalculateIndex()
    {
        return ((btn.Location.Y / btn.Height) * (btn.Parent.Width / btn.Width)) + 
               (btn.Location.X / btn.Width);
    }

    void Form1_MouseDoubleClick(object sender, MouseEventArgs e)
    {
        btn.Location = new Point(0, 0);
    }

    private void Form1_MouseEvent(object sender, MouseEventArgs e)
    {
        // moving horizontally with left and right buttons
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
            btn.Left -= btn.Width;
        else if (e.Button == System.Windows.Forms.MouseButtons.Right)
            btn.Left += btn.Width;

        // moving vertically with mouse wheel
        else if (e.Delta > 0)
            btn.Top -= btn.Height;
        else if (e.Delta < 0)
            btn.Top += btn.Height;
    }
}

截图

Cell index demo

控制

通过在表单上执行以下操作来控制位置:
右键单击:向右移动
左键单击:向左移动
向上滚动(使用鼠标滚轮):向上移动
向下滚动(使用鼠标滚轮):向下移动
双击:将按钮返回初始位置

答案 1 :(得分:0)

我建议使用二维数组来保存地图数据。通过这种方式,您可以通过将坐标除以图块的大小来计算玩家所在的元素。您可以直接在数组中直接引用该位置。

int[,] map = new int[7, 3];  // Create an array of same size as you example grid

data = map[x, y]; // reference the value stored in co-ordinates represented by x and y

将像素位置转换为网格参考应该是将实际像素x&amp; y坐标除以标题大小的情况

当然阵列可以是一个结构,所以你可以在每个位置都有元素来表示那个方格上的东西(物品,墙壁,门,陷阱等)。

希望有所帮助。