嗨,大家好,今天是視窗程式設計第二十三天的影片教學,昨天的影片教學當中,我們已經了解如何透過二維矩陣(Array)來建立地圖,今天要來實作推箱子的功能。
地圖的建立如下:
int[,] map =
{
{0,0,0,0,0,0,0,0,0,0 },
{0,0,1,1,2,2,2,0,0,0 },
{0,0,1,1,1,0,0,0,0,0 },
{0,0,1,1,1,1,1,1,0,0 },
{0,0,0,3,1,1,1,1,0,0 },
{0,1,1,1,0,3,0,1,0,0 },
{0,1,3,1,0,1,1,1,0,0 },
{0,1,1,1,0,1,1,1,0,0 },
{0,1,1,1,0,0,0,0,0,0 },
{0,0,0,0,0,0,0,0,0,0 }
};
在此,我們新增兩個變數,用來儲存主角在地圖的所在位置(二維矩陣的索引值)
int pic_x = 2, pic_y = 1; // dog's initial location on map,水平,垂直位置
接著,透過 KeyDown 結合上下左右的按鍵來做出物體的移動。關於個方向的處理情形如下:
左邊的處理情形
分成是否碰到碗和不能走區域以及可走區域
if (e.KeyCode == Keys.Left)
{
if( map[pic_y , pic_x - 1] == 1 || map[pic_y , pic_x - 1] == 2) // 下一步沒有物體的路
{
pic_x -= 1; // 改變主角的位置(index)
pictureBox_dog.Left -= this.Width / 10; // 改變主角在視窗中的位置
}
else if(map[pic_y, pic_x - 1] == 3 && map[pic_y, pic_x - 2] == 1) // 碰到箱子且箱子下一步有路可走
{
map[pic_y, pic_x - 1] = 1; map[pic_y, pic_x - 2] = 3; // 更改 map array 中的值
pic_x -= 1; // 改變主角的位置(index)
pictureBox_dog.Left -= this.Width / 10; // 改變主角在視窗中的位置
// 改變箱子在視窗中的位置
foreach (Control x in this.Controls)
{
if (x.Tag == "bowl" && pictureBox_dog.Bounds.IntersectsWith(x.Bounds))
x.Location = new Point(pictureBox_dog.Left -(this.Width / 10 ), 0);
}
}
}
右邊的處理情形
分成是否碰到碗、不能走區域、可走區域,以及推到終點等
if (e.KeyCode == Keys.Right)
{
if (map[pic_y , pic_x + 1] == 1 || map[ pic_y , pic_x + 1] == 2) // 下一步沒有物體的路
{
pic_x += 1;
pictureBox_dog.Left += this.Width / 10;
}
else if (map[pic_y, pic_x + 1] == 3) // 碰到箱子
{
if (map[pic_y, pic_x + 2] == 1) // 碰到箱子且箱子下一步有路可走
{
map[pic_y, pic_x + 1] = 1; map[pic_y, pic_x + 2] = 3;
pic_x += 1;
pictureBox_dog.Left += this.Width / 10;
ChangeBowlLocation(+(this.Width / 10 ), 0);
}
else if (map[pic_y, pic_x + 2] == 2) // 碰到箱子且箱子下一步為終點
{
map[pic_y, pic_x + 1] = 1; map[pic_y, pic_x + 2] = 4;
pic_x +=1;
pictureBox_dog.Left += this.Width / 10 ;
ChangeBowlLocation(+(this.Width / 10), 0);
}
}
else if(map[pic_y, pic_x + 1] == 4 && map[pic_y, pic_x + 2] == 2) // 碰到箱子且箱子下一步有路可走,且又是終點
{
map[pic_y, pic_x + 1] = 2; map[pic_y, pic_x + 2] = 4;
pic_x += 1;
pictureBox_dog.Left += this.Width / 10;
ChangeBowlLocation(+(this.Width / 10 ), 0);
}
}
往上的處理情形
分成是否碰到碗、不能走區域、可走區域,以及推到終點等
if (e.KeyCode == Keys.Up)
{
if (map[pic_y - 1 , pic_x] == 1 || map[pic_y - 1 , pic_x] == 2)
{
pic_y -= 1;
pictureBox_dog.Top -= this.Height / 10 ;
}
else if (map[pic_y - 1, pic_x] == 3)
{
if (map[pic_y - 2, pic_x] == 1)
{
map[pic_y - 1, pic_x] = 1; map[pic_y - 2, pic_x] = 3;
pic_y -= 1;
pictureBox_dog.Top -= this.Height / 10;
ChangeBowlLocation(0, -(this.Height / 10 ));
}
else if (map[pic_y - 2, pic_x] == 2)
{
map[pic_y - 1, pic_x] = 1; map[pic_y - 2, pic_x] = 4;
pic_y -= 1;
pictureBox_dog.Top -= this.Height / 10;
ChangeBowlLocation(0, -(this.Width / 10 ));
}
}
}
往下的處理情形
分成是否碰到碗、不能走區域以及可走區域
if (e.KeyCode == Keys.Down)
{
if (map[pic_y + 1, pic_x] == 1)
{
pic_y += 1;
pictureBox_dog.Top += this.Height / 10;
}
else if (map[pic_y + 1, pic_x] == 3 && map[pic_y + 2, pic_x] == 1)
{
map[pic_y + 1, pic_x] = 1; map[pic_y + 2, pic_x] = 3;
pic_y += 1;
pictureBox_dog.Top += this.Height / 10;
ChangeBowlLocation(0, +(this.Width / 10 ));
}
}
判斷獲勝的方式
if (map[1, 4] == 4 && map[1, 5] == 4 && map[1, 6] == 4) { label_winGame.Visible = true; }
改變碗的位置的 function
void ChangeBowlLocation(int move_x , int move_y)
{
foreach (Control x in this.Controls)
{
if (x.Tag == "bowl" && pictureBox_dog.Bounds.IntersectsWith(x.Bounds))
x.Location = new Point(pictureBox_dog.Left + move_x, pictureBox_dog.Top + move_y);
}
}
以上是今天的教學,感謝大家的觀看。
icon素材:flaticon(https://www.flaticon.com/)