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

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

這次的目標是讓使用者開門!

因為你有很多個場景,假如你都是用btnBackToMain回到前一個場景,

就需要做一下修改了。

先看範例:

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

<!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>小遊戲教學4</title>
</head>
<style type="text/css">
#scene_main{
	background:url(ebg.gif);
}
#desk{
	background:url(table.gif) no-repeat;
	width: 135px;
	height: 69px;
	position:absolute;
	left: 50px;
	top: 150px;
	cursor: pointer;
}
#door{
	background:url(door.gif) no-repeat;
	width: 60px;
	height: 82px;
	position:absolute;
	left: 270px;
	top: 44px;
	cursor: pointer;
}
#scene_undertable{
	background:url(under.gif);
}
#scene_door{
	background:url(normalbg.gif);
}
#doorClose{
	background:url(door.gif) no-repeat;
	background-size: 100%;
	width: 151px;
	height: 204px;
	position:absolute;
	left: 191px;
	top: 17px;
	display: none;
}
.bg{
	background-repeat:no-repeat;
	width: 533px;
	height: 273px;
	position: absolute;
	left: 0px;
	top: 0px;
	cursor: default;
	z-index: -100;
}
.hide{
	display: none;
}
input[type=button]{
	border: none;
	outline: none;
	position: absolute;
	cursor: pointer;
}
#btnBack{
	background: #666666;
	opacity: 0.5;
	width: 533px;
	height: 35px;
	left: 0px;
	top: 238px;
	z-index: 100px;
	
}
#btnBack:hover{
	opacity: 0.8;
}
#btnBack:enabled:active{
	opacity: 0.1;
}
</style>
<script type="text/javascript">
	window.onload=function(){
		var scene={
			main: new Array("desk","door","scene_main"),
			undertable: new Array("btnBack","scene_undertable"),
			door: new Array("doorClose","btnBack","scene_door")
		};
		var now="main";
		
		getById("desk").onclick=function(){
			hide(scene.main);
			show(scene.undertable);
			now="undertable";
		}
		
		getById("door").onclick=function(){
			hide(scene.main);
			show(scene.door);
			now="door";
		}
		
		getById("btnBack").onclick=function(){
			if(now=="undertable"){
				show(scene.main);
				hide(scene.undertable);
				now="main";
			}else if(now=="door"){
				show(scene.main);
				hide(scene.door);
				now="main";
			}
		}
		
		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>
<body>
<input type="button" id="btnBack" class="hide" />
<div id="desk"></div>
<div id="door"></div>
<div class="bg" id="scene_main"></div>
<div class="bg hide" id="scene_undertable"></div>
<div id="doorClose"></div>
<div class="bg hide" id="scene_door"></div>
</body>
</html>

這次我們在css做了一些變動,

主要是讓使用者按下門後,畫面來到門的畫面。

在css管理上,讓場景與其上面的元件排在一起。html部分則是依照場景將元件放在場景前面。

#doorClose多了background-size: 100%;設定,讓你改變div大小後,背景圖能隨著延伸。

其實門的畫面就是修改場景圖以及將門放大,導致有靠近的效果。

javascript的部分,多了門的場景。

當你點擊門後,除了顯示門,原本的btnBackToMain又出現了!

為了讓這個返回按鈕依照不同的場景回到不同的畫面,我們新增一個叫做now的變數。

因此每當場景切換時,now也要依照顯示的場景做修改。

因此按鈕btnBackToMain改成了btnBack(也就是專門處理返回場景的按鈕):

getById("btnBack").onclick=function(){
			if(now=="undertable"){
				show(scene.main);
				hide(scene.undertable);
				now="main";
			}else if(now=="door"){
				show(scene.main);
				hide(scene.door);
				now="main";
			}
		}

這樣一來所有的場景都換湯不換藥,

你可以使用btnBack按鈕根據now變數回到不同的場景。

此範例下載:lesson4_3.zip

 

因此,我們追加桌子底下點擊小紙條顯示提示吧!

由於我們的小紙條不是單一圖片,而是圖片的某個區域,我們要自己做一個感應區給他,神奇的div又來了~

首先看一下這個效果:

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

也就是追加了一個新元件作為感應區:hint

#hint{
	background: #000000;
	opacity: 0.5;
	width: 20px;
	height: 16px;
	position:absolute;
	left: 283px;
	top: 114px;
	cursor: pointer;
	display: none;
}

這裡用背景顏色來讓你知道這個東西的用途。

也就是用div抓圖中小紙條大概的位置,而使用矩形作為感應區是最簡單的方法,你會發現很多遊戲也都是這樣用。

SV就很喜歡在玩FLASH遊戲時,用滑鼠測試元件看起來與我點起來的區域是矩形還是非矩形。

矩形的結果就是你人眼看到滑鼠沒有在物品上,仍然可以點擊,就是因為以矩形為作用範圍。

你可能覺得這樣好像很不細膩?然而現在很多遊戲還是這樣做,

否則就要用更難的技術:判斷透明像素來給圖片更精準的作用範圍了~

用矩形的話,使用碰撞偵測(兩個元件是否有重疊、碰在一起)也比較容易。

 

有了這個作用範圍,我們就能顯示提示囉(記得把hint的顏色拿掉呀):

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

這裡將提示隱藏的作法有兩種:

第一種:點擊提示將提示收起來

第二種:點擊btnBack將提示收起來

根據你的喜好來選擇哪一種,SV是用第二種。

顯示提示的部分跟scene陣列的處理不太一樣,

他不是將場景換成有提示的畫面,而是單純在提示上做顯示與隱藏,因此不能將code放在桌子場景的陣列中。

這邊還要注意,因為小紙條沒有另外變成圖片,因此我們顯示提示時(color那張提示)要蓋住小紙條才不會穿幫~

為了方便,我們又創建了一個方法:

function showHint(obj1,obj2){
			getById(obj1).style.display="none";
			getById(obj2).style.display="block";
		}

因為你的提示可能有很多個,作法大都是這樣,就用方法做處理。

到目前為止的程式碼如下:

<!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>小遊戲教學4</title>
</head>
<style type="text/css">
#scene_main{
	background:url(ebg.gif);
}
#desk{
	background:url(table.gif) no-repeat;
	width: 135px;
	height: 69px;
	position:absolute;
	left: 50px;
	top: 150px;
	cursor: pointer;
}
#door{
	background:url(door.gif) no-repeat;
	width: 60px;
	height: 82px;
	position:absolute;
	left: 270px;
	top: 44px;
	cursor: pointer;
}
#scene_undertable{
	background:url(under.gif);
}
#hint{
	width: 20px;
	height: 16px;
	position:absolute;
	left: 283px;
	top: 114px;
	cursor: pointer;
	display: none;
}
#code{
	background:url(code.gif) no-repeat;
	width: 328px;
	height: 140px;
	position:absolute;
	left: 102px;
	top: 50px;
	cursor: default;
	display: none;
}
#scene_door{
	background:url(normalbg.gif);
}
#doorClose{
	background:url(door.gif) no-repeat;
	background-size: 100%;
	width: 151px;
	height: 204px;
	position:absolute;
	left: 191px;
	top: 17px;
	cursor: default;
	display: none;
}
.bg{
	background-repeat:no-repeat;
	width: 533px;
	height: 273px;
	position: absolute;
	left: 0px;
	top: 0px;
	cursor: default;
	z-index: -100;
}
.hide{
	display: none;
}
input[type=button]{
	border: none;
	outline: none;
	position: absolute;
	cursor: pointer;
}
#btnBack{
	background: #666666;
	opacity: 0.5;
	width: 533px;
	height: 35px;
	left: 0px;
	top: 238px;
	z-index: 100px;
	
}
#btnBack:hover{
	opacity: 0.8;
}
#btnBack:enabled:active{
	opacity: 0.1;
}
</style>
<script type="text/javascript">
	window.onload=function(){
		var scene={
			main: new Array("desk","door","scene_main"),
			undertable: new Array("hint","btnBack","scene_undertable"),
			door: new Array("doorClose","btnBack","scene_door")
		};
		var now="main";
		
		getById("desk").onclick=function(){
			hide(scene.main);
			show(scene.undertable);
			now="undertable";
		}
		
		getById("door").onclick=function(){
			hide(scene.main);
			show(scene.door);
			now="door";
		}
		
		getById("btnBack").onclick=function(){
			if(now=="undertable"){
				show(scene.main);
				hide(scene.undertable);
				now="main";
			}else if(now=="door"){
				show(scene.main);
				hide(scene.door);
				now="main";
			}else if(now=="code"){
				showHint("code","hint")
				now="undertable";
			}
		}
		
		getById("hint").onclick=function(){
			showHint("hint","code")
			now="code";
		}
		
		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";
			}
		}
		
		function showHint(obj1,obj2){
			getById(obj1).style.display="none";
			getById(obj2).style.display="block";
		}
	}
</script>
<body>
<input type="button" id="btnBack" class="hide" />
<div id="desk"></div>
<div id="door"></div>
<div class="bg" id="scene_main"></div>
<div id="code"></div>
<div id="hint"></div>
<div class="bg hide" id="scene_undertable"></div>
<div id="doorClose"></div>
<div class="bg hide" id="scene_door"></div>
</body>
</html>

範例下載連結:lesson4_3_3.zip

最後就是在門旁邊加入密碼鎖,使用者輸入結果後判斷是否為正確答案,若正確就顯示成功脫出畫面!

不是的話密碼鎖顯示error:

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

密碼鎖的部分則是使用了table,如果覺得太制式化了(不美觀),你還是可以用你的圖片來做排版。

而我也在html部分演示如何在html之間加註解。

我還加入了判斷是否有看過提示的條件,也就是不讓使用者用暴力法解~

若希望使用者退出密碼鎖後,再回來要歸零(回復到顯示AAA)則是要再修改喔。

最後的脫出很弱掉,你可以用漂亮的圖片代替(才能讓人有成就感)

 

當然,謎題的好壞就要靠喜歡解謎遊戲的人好好摸索,

這也是為什麼密室解謎之類的遊戲總能讓人百玩不厭!

 

有空的話應該是教隨機謎題還有Game Over之場景變暗的效果。

 

目前完整範例下載:lesson4_3_4.zip

 

20150714新增:

其實改變背景還有一個方法,不過頭腦要很好否則可能會自己亂掉,

就是直接用一個div當背景,並且切換那個div的背景圖。

假設一開始的背景div長這樣:

<div id="scene_main" class="bg">

在javascript修改其背景就是修改他的background: url()裡面的圖檔名:

document.getElementById("scene_main").style.backgroundImage="url(normalbg.gif)";

只要場景需要切換,就用上述方法切換。