IT Knowledge Base

~ Without sacrifice, there can be no victory ~

發佈日期:

啤牌計算遊戲

今天收到前同事的一個查詢,說學校快要35週年。老闆構思了一個數字遊戲來娛賓。遊戲很簡單,出現3個啤牌數字,由參加者加上中間的運算子(Operators),令計算出來結果等於35。做法要求是用Microsoft Powerpoint先顯示問題,再在下一頁顯示答案。但對於最喜歡攪事的我來說,想到的是用程式直接在瀏覽器上顯示問題,再來是用拖放方式(Drag and Drop)把運算子(Operators)加到方程式中,再顯示答案。01. 先準備運算子(Operators)符號,就是常用的加、減、乘、除。

02. 再準備是52張的啤牌及1張啤牌背面,為何要有1張啤牌背面。因為老闆的構思,需要顯示啤牌時要帶有翻牌的效果。

03. 為了方便沒有上網時也可以運行到,所以今次程式放棄使用PHP,直接用Javascript在編寫。

04. 先為運算子(Operators)符號,加入draggable=”true”屬性及數值,而當使用者開始拖放(Drag and Drop)有關符號動作時,便執行有關Javascript程式。

<div id="s1"><img title="+" src="images/01.png" draggable="true" ondragstart="drag(event)" id="drag1"></div>
<div id="s2"><img title="-" src="images/02.png" draggable="true" ondragstart="drag(event)" id="drag2"></div>
<div id="s3"><img title="*" src="images/03.png" draggable="true" ondragstart="drag(event)" id="drag3"></div>
<div id="s4"><img title="/" src="images/04.png" draggable="true" ondragstart="drag(event)" id="drag4"></div>

05. 3個啤牌數字運算,第1、3、5個位置是顯示啤牌數字,第2、4個位置是放置使用者拖放(Drag and Drop)的運算子,固加入ondrop=”drop(event)”屬性及數值,而當使用者完成拖放(Drag and Drop)有關符號動作時,便執行有關Javascript程式。第6個位置是用來計算答案的『等於』符號。第7個位置就是計算出來答案。

<div id="p31" class="back"></div>
<div id="p32" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="p33" class="back"></div>
<div id="p34" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="p35" class="back"></div>
<div id="equal3"><img src="images/05.png"></div>
<div id="output3"></div>

06. Javascript程式方面,因為要保證問題一定是可以計算到35這個答案,首先在第1、3、5個位置建立能成功運算正確結果的數字。

var items3 = [[13, 13, 9], [12, 12, 11], [11, 11, 13]];

07. 為增加效果,當出現數字後,隨機在葵扇、紅心、梅花及階磚選擇一個。

var rnd3 = Math.floor((Math.random() * items3.length));
var type31 = Math.floor((Math.random() * 4) + 1);
var type32 = Math.floor((Math.random() * 4) + 1);
var type33 = Math.floor((Math.random() * 4) + 1);

08. 用document.getElementById().innerHTML函數將有關啤牌放到第1、3、5個位置。

document.getElementById("p31").innerHTML = '<img src="poker/'+ items3[rnd3][0] +'_'+ type31 +'.png" title="'+ items3[rnd3][0] +'">';
document.getElementById("p33").innerHTML = '<img src="poker/'+ items3[rnd3][1] +'_'+ type32 +'.png" title="'+ items3[rnd3][1] +'">';
document.getElementById("p35").innerHTML = '<img src="poker/'+ items3[rnd3][2] +'_'+ type33 +'.png" title="'+ items3[rnd3][2] +'">';

09. 這幾個Javascript程式是按照HTML5中的拖放功能(Drag and Drop)抄出來,有需要可自行參考有關手冊。

function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function removeNode(node) {
node.parentNode.removeChild(node);
}

10. 這是控制使用者拖放運算子到方程式後的動作。第一是如果方程式中己有之前的運算子,會用新拖放的運算子取代。而當有關動作完成後,便用ev.stopPropagation()阻止之後冒泡事件再發生。最後用return false,阻止所有事件的發生。

function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
var isLeft = 'drag1' == data || "drag2" == data || "drag3" == data || "drag4" == data;
var nodeCopy = document.getElementById(data).cloneNode(true);
nodeCopy.id = "img" + ev.target.id;
if (isLeft) {
if (ev.target.nodeName == 'IMG') {
ev.target.parentNode.appendChild(nodeCopy);
removeNode(ev.target);
} else 
ev.target.appendChild(nodeCopy);
}
else {
if (ev.target.nodeName != 'IMG') {
removeNode(document.getElementById(data));
ev.target.appendChild(nodeCopy);
}
}
ev.stopPropagation();
return false;
}

11. 完成方程式後,當使用者按下『等於』符號,便用以下程式取得有關數字及運算子內容。

$("#equal3").click(function() {
var x = document.getElementById('p31').getElementsByTagName('img')[0].title;
var y = document.getElementById('p33').getElementsByTagName('img')[0].title;
var z = document.getElementById('p35').getElementsByTagName('img')[0].title;
var a = document.getElementById('p32').getElementsByTagName('img')[0];
var b = document.getElementById('p34').getElementsByTagName('img')[0];

12. 考慮到使用者沒有完成方程式便按下『等於』符號,所以加入以下考慮。成功取得數字及運算子,用eval()函數計算出答案。

if (a === undefined || b === undefined) {
alert("You haven't finished the question.");
return;
} else {
var c = a.title;
var d = b.title;
var result = parseInt(eval(x + c + y + d + z));
document.getElementById("output3").innerHTML = result;
var div = document.getElementById('output3');
if (result === 35) {
div.style.backgroundColor = 'green';
} else {
div.style.backgroundColor = 'red';
}
}
});

13. 還記得之前老闆題到的翻牌的效果(既然你想到,我就做出來比你),利用jQuery Flip程式,首先建立背面及正面的啤牌。所以第5點的內容會更改為以下內容。

<div id="card31"> 
<div id="back" class="front"><img src="poker/14.png"></div>
<div id="p31" class="back"></div>
</div>
<div id="p32" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="card32">
<div id="back" class="front"><img src="poker/14.png"></div>
<div id="p33" class="back"></div>
</div>
<div id="p34" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="card33">
<div id="back" class="front"><img src="poker/14.png"></div>
<div id="p35" class="back"></div>
</div>
<div id="equal3"><img src="images/05.png"></div>
<div id="output3"></div>

14. 而根據jQuery Flip程式要求,加入以下內容。

$("#card31, #card32, #card33").flip ({
trigger: 'click'
});

15. 既然是翻牌,沒有可能一次過去翻吧,那就逐張牌來,但原來jQuery Flip不支援用delay()的方式來做延遲時間,只能用setTimeout()函數。

setTimeout(function(){
$("#card31").flip(true);
}, 500);
setTimeout(function(){
$("#card32").flip(true);
}, 1000);
setTimeout(function(){
$("#card33").flip(true);
}, 1500);

16. 既然是35週年,有3張牌的遊戲,自然也要有5張牌的遊戲。做法也是一樣。先建立3張牌及5張牌的選單,再按以上方法建立5張牌的遊戲內容。

<header>
Calculate the result equal 35!
<div id="clear"></div>
<nav><a href="?game=3">3 cards game</a></nav>
<nav><a href="?game=5">5 cards game</a></nav>
</header>

17. 當第一次來到遊戲時,用以下程式先設定為3張牌的遊戲。如使用者選擇了其他選項,便執行相關遊戲。

var game = location.search.split('game=')[1];
if (game === undefined) {
game = "3";
}
switch(game) {
case "3":
break;
case "5":
break;
}

18. 最後,如真的要用Microsoft Powerpoint來表達,可以把題目及答案畫面撮取,再放入Powerpoint內。

19. 遊戲的瀏覽器版本可按『這裡』測試。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *