一.角色基礎之操作
只要是需要操作角色的遊戲,在最一開始都會提示玩家最基本的操作,就是上下左右移動。
透過加減X、Y軸形成向上移動的錯覺,這點跟Minecraft的tp指令很類似,不過就目前學習到的內容,在移動角色方面若圖片解析度高且仔細看的話還是會看到微幅的角色移動殘影,希望以後能有方法解決。
不過如果知道了有keyCode這個東西,也清楚了if,如果之後有教碰撞偵測的寫法的話,一個簡單的動作遊戲就寫的出來了呢。
進入正題。
透過加減X、Y軸形成向上移動的錯覺,這點跟Minecraft的tp指令很類似,不過就目前學習到的內容,在移動角色方面若圖片解析度高且仔細看的話還是會看到微幅的角色移動殘影,希望以後能有方法解決。
不過如果知道了有keyCode這個東西,也清楚了if,如果之後有教碰撞偵測的寫法的話,一個簡單的動作遊戲就寫的出來了呢。
進入正題。
1.宣告
PImage player,bg; //player是玩家圖片、bg則是背景圖片
int posX = 200,posY = 200; //posX、posY是玩家角色的初始位置
int running_if = 0,timing = 0,img_status = 0; //running_if →是否開始跑步
//timing →計時器
//img_status→圖片目前狀態
int posX = 200,posY = 200; //posX、posY是玩家角色的初始位置
int running_if = 0,timing = 0,img_status = 0; //running_if →是否開始跑步
//timing →計時器
//img_status→圖片目前狀態
2.設定
void setup()
{
size(800,720); //這次有背景圖片,所以我以背景圖片1比1的大小為主
player = loadImage("down.png"); //先讀取初始的角色圖片
bg = loadImage("background.png"); //先讀取背景要用的圖片
}
//順帶一提,這是背景圖片:
{
size(800,720); //這次有背景圖片,所以我以背景圖片1比1的大小為主
player = loadImage("down.png"); //先讀取初始的角色圖片
bg = loadImage("background.png"); //先讀取背景要用的圖片
}
//順帶一提,這是背景圖片:
3.描繪
先說明一下,我有將目前所教的部分再延伸,讓角色圖片有不同的方向跟跑步的動畫,這也是為甚麼我前面設定會宣告計時器,文長注意。
void draw()
{
image(bg,0,0,800,720); //背景圖片先放進去,也同時消除角色會有的移動殘影
image(player,posX,posY,40,40); //玩家角色圖片,為40x40
//接下來為上下左右移動的分解動作,邊看圖片邊看程式會更容易理解
//往上的動作為下圖 :
if (keyPressed && keyCode == UP) //如果按住往上鍵的話執行
{
if ((posY-3) >= 40) posY -= 3; //因為背景圖片有邊界,所以以物件單位為主,讓角色不會跑到視窗外,0 + 40(邊界) = 40
if (running_if == 0) //如果還沒開始跑的話執行,會特別去判斷是否跑步是為了在重複執行的draw中執行一次性的指令
{
player = loadImage("up.png"); //玩家角色圖片為朝上
running_if = 1; //判斷為正在跑步
}
timing++; //計時器開始計時
if (timing % 40 > 0 && timing % 40 < 11 ) //透過除以40後的餘數來判斷現在為什麼動作
{
player = loadImage("up_run_0.png"); //右腳先
img_status = 3; //紀錄目前圖片狀態
}
else if (timing % 40 < 21 )
{
player = loadImage("up.png"); //收腳
img_status = 0;
}
else if (timing % 40 < 31 )
{
player = loadImage("up_run_1.png"); //出左腳
img_status = 4;
}
else //沒有餘數的話代表動作已完成
{
player = loadImage("up.png"); //變回站立的圖片
img_status = 0;
}
}
//往上的動作為下圖 :
if (keyPressed && keyCode == DOWN) //如果按住往下鍵的話執行,基本上跟往上是一樣的
{
if ((posY+3) <= 640) posY += 3; //要注意圖片的大小,為了不讓圖片被視窗砍半,必須多計算圖片的大小,所以是720 - 40(邊界) - 40(角色) = 640
if (running_if == 0)
{
player = loadImage("down.png");
running_if = 1;
}
timing++;
if (timing % 40 > 0 && timing % 40 < 11 )
{
player = loadImage("down_run_0.png");
img_status = 5;
}
else if (timing % 40 < 21 )
{
player = loadImage("down.png");
img_status = 0;
}
else if (timing % 40 < 31 )
{
player = loadImage("down_run_1.png");
img_status = 6;
}
else
{
player = loadImage("down.png");
img_status = 0;
}
}
//往右的動作為下圖 :
if (keyPressed && keyCode == RIGHT) //如果按住往右鍵的話執行
{
if ((posX+3) <= 720) posX += 3; //一樣注意邊界,800 - 40(邊界) - 40(角色) = 720
if (running_if == 0)
{
player = loadImage("right.png");
running_if = 1;
}
timing++;
if (timing % 20 > 10) //分解動作為兩幀,所以用20就夠了
{
player = loadImage("right_run_0.png");
img_status = 1;
}
else
{
player = loadImage("right.png");
img_status = 0;
}
}
//往左的動作為下圖 :
if (keyPressed && keyCode == LEFT) //如果按住往左鍵的話執行,基本上跟往右鍵一樣
{
if ((posX-3) >= 40) posX -= 3; //0 + 40(邊界) = 40
if (running_if == 0)
{
player = loadImage("left.png");
running_if = 1;
}
timing++;
if (timing % 20 > 10)
{
player = loadImage("left_run_0.png");
img_status = 2;
}
else
{
player = loadImage("left.png");
img_status = 0;
}
}
if (!keyPressed) //如果沒有按壓按鍵時執行,這是為了避免角色圖片會卡在跑步中的動作,所以要加個重置的判斷
{
timing = 0; //計時器歸零
running_if = 0; //判斷為沒有跑步
//以下則為上下左右的狀態歸零,讓角色沒有動的時候圖片會重置為站立的圖片
if (img_status == 1) player = loadImage("right.png");
if (img_status == 2) player = loadImage("left.png");
if (img_status == 3 || img_status == 4) player = loadImage("up.png");
if (img_status == 5 || img_status == 6) player = loadImage("down.png");
}
}
{
image(bg,0,0,800,720); //背景圖片先放進去,也同時消除角色會有的移動殘影
image(player,posX,posY,40,40); //玩家角色圖片,為40x40
//接下來為上下左右移動的分解動作,邊看圖片邊看程式會更容易理解
//往上的動作為下圖 :
if (keyPressed && keyCode == UP) //如果按住往上鍵的話執行
{
if ((posY-3) >= 40) posY -= 3; //因為背景圖片有邊界,所以以物件單位為主,讓角色不會跑到視窗外,0 + 40(邊界) = 40
if (running_if == 0) //如果還沒開始跑的話執行,會特別去判斷是否跑步是為了在重複執行的draw中執行一次性的指令
{
player = loadImage("up.png"); //玩家角色圖片為朝上
running_if = 1; //判斷為正在跑步
}
timing++; //計時器開始計時
if (timing % 40 > 0 && timing % 40 < 11 ) //透過除以40後的餘數來判斷現在為什麼動作
{
player = loadImage("up_run_0.png"); //右腳先
img_status = 3; //紀錄目前圖片狀態
}
else if (timing % 40 < 21 )
{
player = loadImage("up.png"); //收腳
img_status = 0;
}
else if (timing % 40 < 31 )
{
player = loadImage("up_run_1.png"); //出左腳
img_status = 4;
}
else //沒有餘數的話代表動作已完成
{
player = loadImage("up.png"); //變回站立的圖片
img_status = 0;
}
}
//往上的動作為下圖 :
if (keyPressed && keyCode == DOWN) //如果按住往下鍵的話執行,基本上跟往上是一樣的
{
if ((posY+3) <= 640) posY += 3; //要注意圖片的大小,為了不讓圖片被視窗砍半,必須多計算圖片的大小,所以是720 - 40(邊界) - 40(角色) = 640
if (running_if == 0)
{
player = loadImage("down.png");
running_if = 1;
}
timing++;
if (timing % 40 > 0 && timing % 40 < 11 )
{
player = loadImage("down_run_0.png");
img_status = 5;
}
else if (timing % 40 < 21 )
{
player = loadImage("down.png");
img_status = 0;
}
else if (timing % 40 < 31 )
{
player = loadImage("down_run_1.png");
img_status = 6;
}
else
{
player = loadImage("down.png");
img_status = 0;
}
}
//往右的動作為下圖 :
if (keyPressed && keyCode == RIGHT) //如果按住往右鍵的話執行
{
if ((posX+3) <= 720) posX += 3; //一樣注意邊界,800 - 40(邊界) - 40(角色) = 720
if (running_if == 0)
{
player = loadImage("right.png");
running_if = 1;
}
timing++;
if (timing % 20 > 10) //分解動作為兩幀,所以用20就夠了
{
player = loadImage("right_run_0.png");
img_status = 1;
}
else
{
player = loadImage("right.png");
img_status = 0;
}
}
//往左的動作為下圖 :
if (keyPressed && keyCode == LEFT) //如果按住往左鍵的話執行,基本上跟往右鍵一樣
{
if ((posX-3) >= 40) posX -= 3; //0 + 40(邊界) = 40
if (running_if == 0)
{
player = loadImage("left.png");
running_if = 1;
}
timing++;
if (timing % 20 > 10)
{
player = loadImage("left_run_0.png");
img_status = 2;
}
else
{
player = loadImage("left.png");
img_status = 0;
}
}
if (!keyPressed) //如果沒有按壓按鍵時執行,這是為了避免角色圖片會卡在跑步中的動作,所以要加個重置的判斷
{
timing = 0; //計時器歸零
running_if = 0; //判斷為沒有跑步
//以下則為上下左右的狀態歸零,讓角色沒有動的時候圖片會重置為站立的圖片
if (img_status == 1) player = loadImage("right.png");
if (img_status == 2) player = loadImage("left.png");
if (img_status == 3 || img_status == 4) player = loadImage("up.png");
if (img_status == 5 || img_status == 6) player = loadImage("down.png");
}
}
5.最後成品
二.心得感想
這次做的是全地圖式的平面操作,但其實光這次教的內容是可以再延伸成左右操作的地圖卷軸式,譬如說玩家可以按空白鍵跳躍,會有重力往下墜落之類的,但基本同理就沒有再做一個了,題外話,圖片素材是我參考神奇寶貝(寶可夢)Game boy時期的紅/藍版裡的角色和背景並微調製作而成的,如果未來有教到碰撞偵測的內容的話,我也許可以將這次的成品加上npc跟房子也說不定。
而製作過程我也發現有疑問產生,那就是要如何在畫面上顯示程式中宣告的數值和文字呢?
而製作過程我也發現有疑問產生,那就是要如何在畫面上顯示程式中宣告的數值和文字呢?






沒有留言:
張貼留言