如何在GDI+实现的迷宫游戏中实现玩家遇墙禁止移动功能?

- 蓝色图片框 = PlayerPictureBox
- 新游戏按钮 = btnCreate
首先,已使用GDI+实现迷宫的形状。
我已实现玩家移动功能,但如何实现玩家遇到墙壁时禁止移动的功能?
以下是我的代码:
private void btnCreate_Click(object sender, EventArgs e) { int wid = 15; int hgt = 15; CellWidth = picMaze.ClientSize.Width / (wid+2); CellHeight = picMaze.ClientSize.Height / (hgt+2); Xmin = (picMaze.ClientSize.Width - wid * CellWidth) / 2; Ymin = (picMaze.ClientSize.Height - hgt * CellHeight) / 2; MazeNode[,] nodes = MakeNodes(wid, hgt); MakeRandomMaze(nodes[0, 0]); DisplayMaze(nodes); PlayerPictureBox.Visible = true; arrivePicturBox.Visible = true; PlayerPictureBox.Location = new Point(70,51); } protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { switch (keyData) { case Keys.Left: PlayerPictureBox.Left -= 5; break; case Keys.Right: PlayerPictureBox.Left += 5; break; case Keys.Up: PlayerPictureBox.Top -= 5; break; case Keys.Down: PlayerPictureBox.Top += 5; break; default: return base.ProcessCmdKey(ref msg, keyData); } return true; }
解决方案
核心思路是先判断移动方向是否存在墙壁,再执行移动,结合你的迷宫数据结构,按以下步骤修改:
提升关键变量为类成员
把nodes、wid、hgt、CellWidth、CellHeight、Xmin、Ymin这些变量从btnCreate_Click方法里移到类的成员区域,让ProcessCmdKey能访问到。修改移动逻辑,加入碰撞检测
假设你的MazeNode类包含HasLeftWall、HasRightWall、HasTopWall、HasBottomWall四个布尔属性记录墙壁状态,修改后的ProcessCmdKey如下:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { bool canMove = true; int playerCol = (PlayerPictureBox.Left - Xmin) / CellWidth; int playerRow = (PlayerPictureBox.Top - Ymin) / CellHeight; // 先检查玩家是否在迷宫范围内 if (playerCol < 0 || playerCol >= wid || playerRow < 0 || playerRow >= hgt) { canMove = false; } else { MazeNode currentNode = nodes[playerRow, playerCol]; switch (keyData) { case Keys.Left: canMove = playerCol > 0 && !currentNode.HasLeftWall; break; case Keys.Right: canMove = playerCol < wid - 1 && !currentNode.HasRightWall; break; case Keys.Up: canMove = playerRow > 0 && !currentNode.HasTopWall; break; case Keys.Down: canMove = playerRow < hgt - 1 && !currentNode.HasBottomWall; break; default: return base.ProcessCmdKey(ref msg, keyData); } } // 允许移动才执行位置变更 if (canMove) { switch (keyData) { case Keys.Left: PlayerPictureBox.Left -= 5; break; case Keys.Right: PlayerPictureBox.Left += 5; break; case Keys.Up: PlayerPictureBox.Top -= 5; break; case Keys.Down: PlayerPictureBox.Top += 5; break; } } return true; }
- 补充说明
如果你的移动步长(5像素)不等于单元格尺寸,或者需要更精确的像素级碰撞检测,可以直接获取墙壁的像素坐标,用PlayerPictureBox.Bounds.IntersectsWith(墙壁矩形)来判断是否会碰撞。
内容的提问来源于stack exchange,提问作者toe ko
相关产品推荐
相关产品推荐

