我想用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
索引上。
问题:
您是否知道任何方法来改进此公式或简单地使其工作?
任何帮助表示赞赏;)
答案 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;
}
}
通过在表单上执行以下操作来控制位置:
右键单击:向右移动
左键单击:向左移动
向上滚动(使用鼠标滚轮):向上移动
向下滚动(使用鼠标滚轮):向下移动
双击:将按钮返回初始位置
答案 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坐标除以标题大小的情况
当然阵列可以是一个结构,所以你可以在每个位置都有元素来表示那个方格上的东西(物品,墙壁,门,陷阱等)。
希望有所帮助。