iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0
影片教學

視窗程式設計系列 第 23

【Day23】視窗程式設計-推箱子的判斷流程

  • 分享至 

  • xImage
  •  

嗨,大家好,今天是視窗程式設計第二十三天的影片教學,昨天的影片教學當中,我們已經了解如何透過二維矩陣(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/)

Yes


上一篇
【Day22】用二維 Array 建立推箱子地圖
下一篇
【Day24】Functions, call fun! Function 的介紹
系列文
視窗程式設計30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言