摘要:javascript 小遊戲小技巧教學4(簡易密室遊戲part1)
遊戲教學真的好久沒新增了~
因為我在忙別的事情Orz
這次教的是用css排版,
一開始只學javascript的人對於css會很陌生,而且javascript可以做到css能做到的東西,那為什麼還是要用css呢?
原因就是分工呀!css專攻美觀的部分,javascript負責遊戲運作的部分,這樣的話javascript會看起來比較乾淨,而使用css排版也有其效率。
p.s.假如想要按照步驟簡單練習的可以到下一篇文章最下面有2015/07/14給初學者或網頁概念不熟的新手練習:
http://www.dotblogs.com.tw/shuinvy/archive/2015/07/10/151816.aspx
先用一個例子舉例:
這是一個有一張桌子和一扇門的場景,當你點擊桌子時,桌子就會放大,你會發現桌子底下有一個小字條(目前無作用),點擊下方灰色的區域可以回到一開始的一張桌子一扇門畫面。
然後你會發現門似乎可以點擊但是卻沒任何反應?因為那跟小字條一樣是之後教學才會用上的!
雖然這個動作很簡單,卻是密室、脫出遊戲的精髓呀!
先說之前用的img修改src的切換場景其實很不好,因為依據網頁下載速度,圖片的解析很耗時間,
因此最好是所有圖片都存在畫面上,接著再用javascript依照情況顯示或隱藏。
這也是為什麼先前的教學範例網頁圖片切換總是慢半拍,那半拍給人就是很不順暢的感受!
當然,也可能是因為我用google drive的關係才會導致網頁跑很慢......但是用隱藏與顯示的切換是比較正確的做法,
事實上以前的GB Game也是類似的道理(或者以前那種掌中遊戲)
不使用img還有另一個原因:不讓使用者直接下載圖片。要是使用img,用滑鼠點右鍵時可以點選另存圖片。
假如你不希望使用者使用你自己的圖片,最好不要用img來顯示圖片。
那麼你就會覺得奇怪啦!我不用img如何顯示圖片?
html有個叫做div的好東西,他是一個區塊,把你想要顯示的圖片當作div的背景,就可以顯示圖片囉!
先看這次的範例:
<!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);
}
#scene_undertable{
background:url(under.gif);
}
.bg{
background-repeat:no-repeat;
width: 533px;
height: 273px;
position: absolute;
left: 0px;
top: 0px;
cursor: default;
z-index: -100;
}
.hide{
display: none;
}
#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;
}
input[type=button]{
border: none;
outline: none;
position: absolute;
cursor: pointer;
}
#btnBackToMain{
background: #666666;
opacity: 0.5;
width: 533px;
height: 35px;
left: 0px;
top: 238px;
z-index: 100px;
}
#btnBackToMain:hover{
opacity: 0.8;
}
#btnBackToMain:enabled:active{
opacity: 0.1;
}
</style>
<script type="text/javascript">
window.onload=function(){
var desk=getById("desk");
var scene_main=getById("scene_main");
var scene_undertable=getById("scene_undertable");
var btnBackToMain=getById("btnBackToMain");
var door=getById("door");
desk.onclick=function(){
hide(desk);
hide(scene_main);
hide(door);
show(scene_undertable);
show(btnBackToMain);
}
btnBackToMain.onclick=function(){
show(desk);
show(scene_main);
show(door);
hide(scene_undertable);
hide(btnBackToMain);
}
function getById(id){
return document.getElementById(id);
}
function hide(id){
id.style.display="none";
}
function show(id){
id.style.display="block";
}
}
</script>
<body>
<input type="button" id="btnBackToMain" 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>
</body>
</html>
假如單看javascript的部分,其實沒有很多行。這是因為美工的部分放在javascript上面的style那邊。
先看body的部分:
<input type="button" id="btnBackToMain" 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,
後面的div是用來顯示背景的,為了做區隔,我在id的命名上皆以scene_來開頭,而div裡面還有叫做class的東西。
這class就是套用你所設定的美工模組(style)的意思。bg就是background而hide則是隱藏。
也就是說,一開始的場景是桌子、門、主要背景,而一個叫做btnBackToMain的按鈕與一個叫做scene_undertable(桌子底下)的場景則是隱藏的。
因此回到style的部分:
<style type="text/css">
#scene_main{
background:url(ebg.gif);
}
#scene_undertable{
background:url(under.gif);
}
.bg{
background-repeat:no-repeat;
width: 533px;
height: 273px;
position: absolute;
left: 0px;
top: 0px;
cursor: default;
z-index: -100;
}
.hide{
display: none;
}
#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;
}
input[type=button]{
border: none;
outline: none;
position: absolute;
cursor: pointer;
}
#btnBackToMain{
background: #666666;
opacity: 0.5;
width: 533px;
height: 35px;
left: 0px;
top: 238px;
z-index: 100px;
}
#btnBackToMain:hover{
opacity: 0.8;
}
#btnBackToMain:enabled:active{
opacity: 0.1;
}
</style>
你會看到scene_main前面有個井字號#,這表示,這個美工是設計給哪個id的,
而bg的前面是小數點.,這表示這個美工設計是只要用了這個的class都可以套上(沒有特定哪個id)
還有一個很奇怪的是input[type=button],這表示所有的按鈕都有這樣的美工設計。
也就是只要是符合其html標籤(tag)都適用,因此,想要img都設定寬度為100px,
則只需要這樣設定:
img{
width: 100px;
}
因此css比較麻煩的就是搞懂你設定的美工需不需要前面加井字號還是小數點,或者不用?
接著裡面美工的設定就要靠經驗的累積了......
你會發現有個常常出現的設定:
background:url(under.gif);
這表示這個div的背景圖片是url裡面的圖片。假如你的圖片不是在你的資料夾裡面,則要使用相對路徑或者網路上的網址。
既然是自己做的遊戲,那還是先學放在資料夾的寫法囉~
再來background-repeat: no-repeat是指背景圖需不需要循環排列?你可以想像成你的電腦桌面的背景圖,
如果循環,當你的div寬高比你的圖片大時,就會需要設定以x(橫向)重複還是y(縱向)重複圖片顯示。
接著width和height就是寬度與高度,設定的依據是我們的圖片大小。
至於cursor,你可以選擇拿掉,增加使用者玩的困難度,也或者將.bg的cursor改成cursor: pointer;
預設是讓使用者感覺到有"感應區",他們就會明白那邊是可以點擊的。
SV自己的FLAH遊戲也是傾向於有感應區,因此網頁也是這樣設定。
若沒有感應區,你的玩家可能會點滑鼠點到瘋掉XDDD
.hide部分則是將你要的東西隱藏起來,因此用display:none;
跟visibility:hidden不同的是,用display:none後不會佔你畫面的空間。總之你可以把那行改成visibility:hidden試看看效果。
至於position的部分,你會好奇:我怎麼知道我的桌子要放在畫面的哪個位置?
答案是:trial and error!
修改你的left與top,然後重新整理網頁,就可以看出效果,如果偏左,就將left改大一點。
假如你有dreamweaver或frontpage這種網頁編輯器,就不用這麼麻煩,直接拉到你想要的位置就可以啦!
最後跟之前教學比較不同的一些設定是input[text=button]裡的一些參數:
border:none;因為原本按鈕是有邊框的,我們想拿掉邊框。
outline: none;如果你點擊按鈕,通常會有點擊後的聚焦邊框,用這個就可以拿掉聚焦邊框。
opacity: 0.5;這代表透明度,注意!不是所有瀏覽器都可以正常反應,IE8和以下可能沒有變化。
看向#btnBackToMain的部分,
第一個後面沒有接東西的表示一開始這個按鈕長的樣子。
接著後面加了:hover表示當我們的滑鼠移到按鈕上面時的情況,
而加了enabled:active表示當我們點擊按鈕時的情況。
此例只用透明度做區隔,你也可以用背景顏色的改變來區隔,只要將各個opacity改成background:你想要的顏色就可以了。
回到body裡面,你會發現有的class不只一個,這表示他的美工設定不只套用一個。如果有很多個,就用空格隔開。
終於來到javascipt部份了!
首先,為了簡化程式碼,我設定了3個function(方法)。
function getById(id){
return document.getElementById(id);
}
就是因為我們每次都要寫那又臭又長一串才能找到我們要的id,於是我就把那部分移出來寫成一個方法。
function hide(id){
id.style.display="none";
}
這裡表示我們給指定的id做隱藏的動作。
而id其實就是document.getElementById("你的id")的部分。
function show(id){
id.style.display="block";
}
跟hide很像,其實就是顯示出來的意思。
前面說過div是一個區塊,因此要顯示出來就用block。
那麼var那些就是為了所有id取的變數。
var scene_main=getById("scene_main");就等同於var scene_main=document.getElementById("scene_main");
是不是少寫很多字呢~
然後我們要做的動作是點擊桌子,切換到桌子底下的場景,
按下下方的按鈕(通常是退出、回到前一個畫面)回到原本的主要畫面。
所以我們的onclick部分就是利用hide與show方法將需要的元件隱藏與顯示。
到這邊你一定會想:要是我的畫面有幾百個元件,不就要show和hide好多次,那樣的話有幾百個元件不就幾百行了嗎!!!
所以下一篇就是這一篇的延伸:如何簡化場景切換。
提供這次的範例網頁:lesson4_1.zip
如何使用範例檔案:
將你的圖檔放入與index.html同資料夾中,
將width與height部分改成你的圖片檔案寬度與高度。