javascript 小遊戲小技巧教學4(簡易密室遊戲part2)

摘要:javascript 小遊戲小技巧教學4(簡易密室遊戲part2)

本文接續上篇文章:

http://www.dotblogs.com.tw/shuinvy/archive/2015/07/10/151815.aspx

上面的文章提到:我有幾百個元件,不就要寫幾百行了嗎!

p.s.假如想要按照步驟簡單練習的可以拉到文章最下面有2015/07/14給初學者或網頁概念不熟的新手練習。

因此我們來簡化javascipt的部分:


<script type="text/javascript">
	window.onload=function(){
		var scene_main=new Array("desk","door","scene_main");
		var scene_undertable=new Array("btnBackToMain","scene_undertable");
		
		getById("desk").onclick=function(){
			hide(scene_main);
			show(scene_undertable);
		}
		
		getById("btnBackToMain").onclick=function(){
			show(scene_main);
			hide(scene_undertable);
		}
		
		function getById(id){
			return document.getElementById(id);
		}
		
		function hide(scene){
			for(var i in scene){
				getById(scene[i]).style.display="none";
			}
		}
		
		function show(scene){
			for(var i in scene){
				getById(scene[i]).style.display="block";
			}
		}
	}
</script>

首先,用陣列來儲存你的場景id名稱。

scene_main表示主要場景有哪些元件,就是門、桌子、以及主要場景本身。

scene_undertable也是一樣的道理,

因此如果你有上百個元件,只要將元件是哪個場景分配好,後面就輕鬆了!

(當然,你的場景也應該不至於有幾百個吧?要是那樣,玩家也可能玩不下去→太多了逛不完啦!)

我們將兩個感應區(桌子與場景後退按鈕)的寫法加以修改,

因為原本設定var desk是需要用到這個變數很多次,既然不需要,就直接用getById就可以了。

而原本的hide與show做了修改:


function hide(scene){
			for(var i in scene){
				getById(scene[i]).style.display="none";
			}
		}

這邊hide括弧裡的scene就不是id了,而是陣列。

也就是利用陣列來幫我們將所有這個場景的元件隱藏起來,

getById那邊是簡寫所以要思考一下:

原本應該是document.getElementById("desk").style.display="none";

用了getById後變成:getById("desk").style.display="block";

可是我們是用陣列來取得我們的元件id,

因此id則是array[index],

就變成getById(scene[i]).style.display="none";

所以之後你有任何追加的元件,就在陣列做修改即可。

我會把場景放在最後面當一個習慣,因此陣列長度-1的索引值一定是場景。(你也可以把場景放第一個,就變成索引值0一定是場景)

最後,我們的感應區就變得超簡單啦,

無論多少個場景,永遠是只有兩行在切換場景!(現在場景隱藏,顯示另一個場景)

 

此範例結果:

http://www.googledrive.com/host/0B7hg_8WvMyfJfkdOeVFBcUFBb2xYMkV4X3VuRXlFbUdEb0VKLWhVcDAzNFpEZ3hIRU9PVXM

結果當然是跟前一篇一樣的,但是我們在撰寫javascript部分簡潔不少!

此範例下載:lesson4_2_1.zip

 

假如你真的擔心你的場景很多導致場景的陣列要寫很多個,你可以改成這樣:


var scene={
			main: new Array("desk","door","scene_main"),
			undertable: new Array("btnBackToMain","scene_undertable")
		};
		
		getById("desk").onclick=function(){
			hide(scene.main);
			show(scene.undertable);
		}
		
		getById("btnBackToMain").onclick=function(){
			show(scene.main);
			hide(scene.undertable);
		}

也就是說有個叫做scene的陣列專門存放很多個場景,而使用方法就如同兩個感應區裡寫的那樣。

也許你覺得在感應區部分好像變得寫比較多字,但在陣列變數上就不用var很多個。

不同的場景陣列要用逗號,區隔,如果只有一個就不用逗號。

 

利用一個陣列管理場景的範例下載:lesson4_2_2.zip

 

part2就先到這!

'程式瘦身'其實是很重要的能力,它可以讓你更方便看懂你自己寫的程式法和管理程式碼。

如何瘦身也是需要靠經驗累積的,一定還有更簡潔的寫法,能學多少就學多少囉~

要知道有些時候你得n年後回頭看自己的程式碼還能不能看得懂?

而人都有劣根性,

拿了別人的程式碼、測試運作正常,就放著不管了,

也沒想到要用更簡潔的寫法(有時候別人只是提供觀念而寫出你想要的結果,但是卻很複雜)。

程式碼瘦身更是讓你真的了解你從別人那邊得到的程式碼的方法之一!

當然,這真的很難,(連我也常犯這樣的毛病)

先求有,再求好吧!

 

下一篇大同小異:給使用者開門的方法吧!

20150714 新增:
 
給初學者或者對於javascript與概念還不是很清楚的新手的小撇步(盡量無須動腦思考版):
 
1.將圖檔分成背景與物品(比方桌子椅子櫃子門窗杯子等等):
 
所謂的物品是你希望使用者用滑鼠點擊會有反應的東西,
 
假如桌子從頭到尾都不需要使用者點擊,
 
背景圖就包含桌子(可以利用Photoshop或小畫家等等軟體將他們存成同一個圖檔或者找一張直接有桌子的背景圖)
 
2.在記事本或其他文字/網頁編輯器(除了frontpage不要使用Microsoft Office系列)複製貼上這段:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>你設定的標題</title>
</head>

<body>
</body>
</html>

你設定的標題是可寫可不寫。檔案存成index.html,若你會改變編碼,請存成utf-8(否則中文可能有亂碼)。

3.在<body>與</body>之間放<div id="你設的id"></div>當背景圖片:
 
id部分用英文設定比較不會出錯喔!(怕有人直接將上述文字複製貼上XD)
 
假設id="bgToilet"(背景是在廁所裡)
 
所以你的<body>部分就會像這樣:

<body>
<div id="bgToilet"></div>
</body>
4.在</head>下面加入這行:<style type="text/css"></style>:
 
5.在<style type="text/css">下面加入以下這段

.bg{
	background-repeat:no-repeat;
	width: 533px;
	height: 273px;
	position: absolute;
	left: 0px;
	top: 0px;
	cursor: default;
	z-index: -100;
}
記得width: 後面的數值是你的背景圖的寬度(範例是533px)。
 
height: 後面的數值是你的背景圖的高度(範例是273px)。
 
假如你不知道你的圖檔大小,對著圖檔按右鍵後點選內容(R),在那邊找找看有沒有顯示多少數字X多少數字,
 
或者顯示寬、高資訊。
 
6.在剛剛的.bg上面加入這段:

#bgToilet{
	background:url(toilet.png);
}
#後面的字是你剛剛div設的id內容(剛剛div是長這樣:<div id="bgToilet"></div>)
 
url括弧中間是你的圖檔名,請記得把圖檔跟你的index.html放在同一個資料夾裡面(否則就需要設路徑了)。
 
7.回到剛剛的<div id="bgToilet"></div>,在雙引號後面加入空格與class="bg",
 
所以現在div部分會變成:
 
<div id="bgToilet" class="bg"></div>
 
以上是設定一張背景圖的教學,多練習這個步驟吧!
 
接著是很多張背景圖的教學:
 
接續上面的教學步驟,
 
1.在<div id="bgToilet" class="bg"></div>上方加入你的第二個背景(有幾個背景就加多少個div):
 
<div id="bgLobby"></div>
 
假設第二個背景叫做bgLobby,
 
所以兩個div就變成:
 
<div id="bgLobby"></div>
<div id="bgToilet" class="bg"></div>
 
2.在.bg那段下方加入以下這段:

.hide{
	display: none;
}

所以<style type="text/css">裡面就變成:


<style type="text/css">
#bgToilet{
	background:url(toilet.png);
}
.bg{
	background-repeat:no-repeat;
	width: 533px;
	height: 273px;
	position: absolute;
	left: 0px;
	top: 0px;
	cursor: default;
	z-index: -100;
}
.hide{
	display: none;
}
</style>

3.在#bgToilet上方加入這段:


#bgLobby{
	background:url(lobby.png);
}
#bgLobby就是我們剛剛設的第二個背景的id,url()中間是你的圖檔名稱(請依照你有的圖片設定)
 
4.回到剛剛的<div id="bgLobby"></div>,在雙引號後面空一格加入class="bg hide",
 
所以div就會變成
 
<div id="bgLobby" class="bg hide"></div>
<div id="bgToilet" class="bg"></div>
 
這表示一開始的畫面是在廁所,如果你想要將一開始的畫面是在大廳,就將div改成:
 
<div id="bgLobby" class="bg"></div>
<div id="bgToilet" class="bg hide"></div>
 
有多少個背景,除了一開始的畫面的div的class="bg",其他的都是class="bg hide"
 
因此到目前為止的檔案長相如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>你設定的標題</title>
</head>
<style type="text/css">
#bgToilet{
	background:url(toilet.png);
}
#bgLobby{
	background:url(lobby.png);
}
.bg{
	background-repeat:no-repeat;
	width: 533px;
	height: 273px;
	position: absolute;
	left: 0px;
	top: 0px;
	cursor: default;
	z-index: -100;
}
.hide{
	display: none;
}
</style>
<body>
<div id="bgLobby" class="bg"></div>
<div id="bgToilet" class="bg hide"></div>
</body>
</html>
請嘗試加入多個背景圖,並且利用class部分查看你的背景圖(將其他的class="bg hide"),
 
感受一下class的修改讓你要的背景圖顯示出來。
 
記得,無論有多少的背景圖,除了要顯示的(左鍵快點兩下index.html後網頁顯示)場景圖,
 
其他背景圖裡面的class="bg hide"
 
hide是隱藏的意思
 
再來是將你的物品放入場景的教學:
 
1.在你要放入的背景圖的div上加入新的<div>
 
<div id="tissue"></div>
 
假設是放在背景為廁所的物品(範例指的是衛生紙),則div就會變成:
 
<div id="tissue"></div>
<div id="bgToilet" class="bg"></div>
 
因此如果你的物品有很多個,則是依序放在剛剛的div上方,而最下面那個一定是背景圖。
 
例如廁所背景還有馬桶、馬桶刷、鏡子,而大廳裡有桌子、椅子、一幅畫,則div就變成:
 
<div id="picture"></div>
<div id="chair"></div>
<div id="desk"></div>
<div id="bgLobby"></div>
<div id="mirror"></div>
<div id="brush"></div>
<div id="toilet"></div>
<div id="bgToilet"></div>
 
 
2.以馬桶畫面有衛生紙為例,在#bgToilet那段下方加入這段:

#tissue{
	background:url(tissue.png) no-repeat;
	width: 135px;
	height: 69px;
	position:absolute;
	left: 50px;
	top: 150px;
	cursor: pointer;
}
#tissue就是你的物品的id(因為衛生紙的div是<div id="tissue"></div>)
 
修改你的width與height成為你的圖檔的寬與高,如同背景圖那樣。
 
修改left與top讓衛生紙或你的物品在畫面中最適合的位置,
 
若你覺得物品在畫面中偏左,則left的值就要變大(例如改成100px),反之則變小(例如改成20px)。
 
若你覺得物品在畫面中偏高,則top的值就要變大(例如改成200px),反之則變小(例如改成100px)。
 
不斷嘗試讓你的物品放在畫面最適合的位置吧!
 
因此以此類推假如你還有一個物品叫做mirror,也是一樣的做法:
 

#mirror{
	background:url(mirror.png) no-repeat;
	width: 50px;
	height: 69px;
	position:absolute;
	left: 150px;
	top: 250px;
	cursor: pointer;
}

所以<style type="text/css">那段就變成


<style type="text/css">
#bgToilet{
	background:url(toilet.png);
}
#tissue{
	background:url(tissue.png) no-repeat;
	width: 135px;
	height: 69px;
	position:absolute;
	left: 50px;
	top: 150px;
	cursor: pointer;
}
#mirror{
	background:url(mirror.png) no-repeat;
	width: 50px;
	height: 69px;
	position:absolute;
	left: 150px;
	top: 250px;
	cursor: pointer;
}
#bgLobby{
	background:url(lobby.png);
}
.bg{
	background-repeat:no-repeat;
	width: 533px;
	height: 273px;
	position: absolute;
	left: 0px;
	top: 0px;
	cursor: default;
	z-index: -100;
}
.hide{
	display: none;
}
</style>
3.當你把第一個場景的物品都配置好後,嘗試配置第二個場景的物品:
 
只要是要隱藏的(也就是第一個場景與其上面的物品),在class裡面加入hide,
 
(有bg就變成class="bg hide",沒有class就變成class="hide",例如<div id="tissue" class="hide"></div>)
 
4.配置第二個背景的物品如同第一個的方法,若還有第三個背景,則一樣將第一和第二個背景與其物品的class加入hide
 
重複以上的部分,你就能感受不同場景的畫面的樣子與切換。
 
因為物品一多,每個都要手動加hide太麻煩了,
 
我們來練習用程式碼切換場景吧!
 
首先假設目前的檔案內容如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>你設定的標題</title>
</head>
<style type="text/css">
#bgToilet{
	background:url(toilet.png);
}
#tissue{
	background:url(tissue.png) no-repeat;
	width: 135px;
	height: 69px;
	position:absolute;
	left: 50px;
	top: 150px;
	cursor: pointer;
}
#toilet{
	background:url(toilet2.png) no-repeat;
	width: 56px;
	height: 69px;
	position:absolute;
	left: 250px;
	top: 180px;
	cursor: pointer;
}
#brush{
	background:url(brush.png) no-repeat;
	width: 28px;
	height: 197px;
	position:absolute;
	left: 300px;
	top: 460px;
	cursor: pointer;
}
#mirror{
	background:url(mirror.png) no-repeat;
	width: 40px;
	height: 72px;
	position:absolute;
	left: 250px;
	top: 40px;
	cursor: pointer;
}
#bgLobby{
	background:url(lobby.png);
}
#desk{
	background:url(desk.png) no-repeat;
	width: 216px;
	height: 85px;
	position:absolute;
	left: 250px;
	top: 468px;
	cursor: pointer;
}
#chair{
	background:url(chair.png) no-repeat;
	width: 64px;
	height: 49px;
	position:absolute;
	left: 40px;
	top: 480px;
	cursor: pointer;
}
#picture{
	background:url(picture.png) no-repeat;
	width: 122px;
	height: 63px;
	position:absolute;
	left: 32px;
	top: 42px;
	cursor: pointer;
}
.bg{
	background-repeat:no-repeat;
	width: 533px;
	height: 273px;
	position: absolute;
	left: 0px;
	top: 0px;
	cursor: default;
	z-index: -100;
}
.hide{
	display: none;
}
</style>
<body>
<div id="picture" class="hide"></div>
<div id="chair" class="hide"></div>
<div id="desk" class="hide"></div>
<div id="bgLobby" class="bg hide"></div>
<div id="mirror"></div>
<div id="brush"></div>
<div id="toilet"></div>
<div id="tissue"></div>
<div id="bgToilet" class="bg hide"></div>
</body>
</html>

1.在</style>下方加入這行:

<script type="text/javascript"></script>

2.將以下放在<script type="text/javascript">與</script>之間:


window.onload=function(){
	
}

3.在window.onload=function(){底下加入這一段:


var scene={
	toilet: new Array("mirror","brush","toilet","tissue","bgToilet"),
	lobby: new Array("picture","chair","desk","bgLobby")
};

在new Array()裡面,你有多少個屬於物品的div就將其id加入,

因為廁所的背景有tissue、toilet、brush、mirror等物品,就將這些物品的id加入(用雙引號包住,並用逗號區隔)

在每個new Array最後放入背景本身(toilet: 的new Array最後面就是放"bgToilet"),

若有不同的場景就用逗號隔開上一個,並且加入場景名稱與冒號、new Array(),

一樣將場景與物品的id放入new Array中。

4.在剛剛的var scene的括弧分號下面加入這段:


function hide(scene){
	for(var i in scene){
		getById(scene[i]).style.display="none";
	}
}
	
function show(scene){
	for(var i in scene){
		getById(scene[i]).style.display="block";
	}
}

function getById(id){
	return document.getElementById(id);
}

因此現在<script type="text/javascript">與</script>就變成:


<script type="text/javascript">
window.onload=function(){
	var scene={
		toilet: new Array("mirror","brush","toilet","tissue","bgToilet"),
		lobby: new Array("picture","chair","desk","bgLobby")
	};
	
	function hide(scene){
		for(var i in scene){
			getById(scene[i]).style.display="none";
		}
	}
	
	function show(scene){
		for(var i in scene){
			getById(scene[i]).style.display="block";
		}
	}
	
	function getById(id){
		return document.getElementById(id);
	}
}
</script>

5.在function hide(scene){那行上方加入這段:


hide(scene.toilet);
show(scene.lobby);

記得重新整理你打開的index.html網頁,你會發現原本一開始是顯示廁所場景,

現在場景變成大廳裡了!

hide是隱藏場景,show是顯示場景。

括弧裡面放的格式就是var scene裡的scene+小數點+你設定的背景名稱(像是toilet與lobby,後面都帶有new Array)

因此<script type="text/javascript"></script>就變成:


<script type="text/javascript">
window.onload=function(){
	var scene={
		toilet: new Array("mirror","brush","toilet","tissue","bgToilet"),
		lobby: new Array("picture","chair","desk","bgLobby")
	};
	
	hide(scene.toilet);
	show(scene.lobby);
	
	function hide(scene){
		for(var i in scene){
			getById(scene[i]).style.display="none";
		}
	}
	
	function show(scene){
		for(var i in scene){
			getById(scene[i]).style.display="block";
		}
	}
	
	function getById(id){
		return document.getElementById(id);
	}
}
</script>

嘗試使用同樣的方法(在hide與show括弧中間改成你要隱藏與顯示的場景名稱),來切換不同的場景吧!

進階練習:利用點擊物品來切換場景

雖然通常是用門來做場景的切換(點擊門後場景改變),因為是練習,利用現有的物品做設計吧。

假設點擊廁所的衛生紙,會來到大廳畫面,點擊大廳的畫,會來到廁所的畫面。

首先讓剛剛的hide與show拿掉,因此<script type="text/javascript"></script>就會是這樣:


<script type="text/javascript">
window.onload=function(){
	var scene={
		toilet: new Array("mirror","brush","toilet","tissue","bgToilet"),
		lobby: new Array("picture","chair","desk","bgLobby")
	};
	
	function hide(scene){
		for(var i in scene){
			getById(scene[i]).style.display="none";
		}
	}
	
	function show(scene){
		for(var i in scene){
			getById(scene[i]).style.display="block";
		}
	}
	
	function getById(id){
		return document.getElementById(id);
	}
}
</script>

1.將function hide(scene){那段上方加入這段:


getById("tissue").onclick=function(){
	hide(scene.toilet);
	show(scene.lobby);
}
	
getById("picutre").onclick=function(){
	hide(scene.lobby);
	show(scene.toilet);
}

onclick就是指滑鼠點擊以後要做的事情,因為是點擊衛生紙,所以getById()裡面是放衛生紙div的id

(<div id="tissue"></div>)

畫的部分也是同樣的道理(畫的id是picture)

這樣,就可以利用物品切換場景了。

<script type="text/script"></script>就會變成:


<script type="text/javascript">
window.onload=function(){
	var scene={
		toilet: new Array("mirror","brush","toilet","tissue","bgToilet"),
		lobby: new Array("picture","chair","desk","bgLobby")
	};
	
	getById("tissue").onclick=function(){
		hide(scene.toilet);
		show(scene.lobby);
	}
	
	getById("picutre").onclick=function(){
		hide(scene.lobby);
		show(scene.toilet);
	}
	
	function hide(scene){
		for(var i in scene){
			getById(scene[i]).style.display="none";
		}
	}
	
	function show(scene){
		for(var i in scene){
			getById(scene[i]).style.display="block";
		}
	}
	
	function getById(id){
		return document.getElementById(id);
	}
}
</script>

以上就是給新手的教學,

若真的還是不懂,可以來信詢問:yokunanduAThotmailDOMcom