Last active
February 1, 2016 09:15
-
-
Save onfi/cdc00038dcdf6a157b5a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Resistance quest tool</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<!-- load MUI --> | |
<link href="https://cdn.muicss.com/mui-0.1.17/css/mui.min.css" rel="stylesheet" type="text/css" /> | |
<script src="https://cdn.muicss.com/mui-0.1.17/js/mui.min.js"></script> | |
<script src="https://cdn.jsdelivr.net/g/riot@2.2.1(riot.min.js+compiler.min.js)"></script> | |
<style type="text/css"> | |
html, body, #main {height:100%;} | |
.mui-btn-dekai { | |
width: 100%; | |
height:3.5em; | |
font-size:3em; | |
} | |
</style> | |
<style> | |
div.timer { | |
position: absolute; | |
top:0; | |
right:0; | |
bottom:0; | |
left:0; | |
background-color: #E6855E; | |
} | |
div.timer > span { | |
position: fixed; | |
font-size: 100pt; | |
top: 50%; | |
left: 50%; | |
color: #F2F5AA; | |
transform:translate(-50%, -50%); | |
z-index: 100; | |
} | |
div.timer > div { | |
background-color: #F6CA06; | |
position: absolute; | |
top:0; | |
right:0; | |
bottom:0; | |
left:0; | |
z-index: 10; | |
} | |
@keyframes anime-background { | |
0% { | |
top: 0; | |
} | |
100% { | |
top: 100%; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<div class="mui-container" style="height:100%; padding:10%"> | |
<div class="mui-row" id="main"> | |
</div> | |
</div> | |
<script type="riot/tag"> | |
<main> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<button class="mui-btn mui-btn-dekai mui-btn-danger mui-btn-raised" onclick={opts.controller.vote}>START</button> | |
</div> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<div class="mui-form-group"> | |
<input type="text" class="mui-form-control" value={opts.quest.obe} onkeyup={ oberon }> | |
<label class="mui-form-floating-label">OBERON STRIKES BACK</label> | |
</div> | |
</div> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<button class="mui-btn mui-btn-primary mui-btn-raised" onclick={timer1}>1 min.</button> | |
<button class="mui-btn mui-btn-primary mui-btn-raised" onclick={timer3}>3 min.</button> | |
<button class="mui-btn mui-btn-primary mui-btn-raised" onclick={timer5}>5 min.</button> | |
</div> | |
<div class="col mui-col-md-8 mui-col-md-offset-2" style="margin-top: 10%"> | |
<a href="https://www.youtube.com/watch?v=8SzpYqxjW10" target="r-a-nare">ナレーション オプションなし</a> | |
</div> | |
<div class="col mui-col-md-8 mui-col-md-offset-2" style="margin-top: 2%"> | |
<a href="https://www.youtube.com/watch?v=jeyCFC_G95Q" target="r-a-nare">ナレーション フル</a> | |
</div> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<button class="mui-btn mui-btn-primary mui-btn-raised" onclick={opts.controller.inputMember}>メンバー決め</button> | |
</div> | |
timer1(e){ | |
opts.controller.timer(1) | |
} | |
timer3(e){ | |
opts.controller.timer(3) | |
} | |
timer5(e){ | |
opts.controller.timer(5) | |
} | |
oberon(e){ | |
opts.quest.oberon(e.target.value) | |
} | |
</main> | |
<vote> | |
<vote-success if={ this.random } /> | |
<vote-failue if={ !this.random } /> | |
<div class="col mui-col-sm-8 mui-col-sm-offset-2 mui-hidden-md mui-hidden-lg"> </div> | |
<vote-failue if={ this.random } /> | |
<vote-success if={ !this.random } /> | |
this.random = (Math.floor( Math.random() * 2 ) == 1); | |
this.on('mount', function() { | |
this.clicked = false; | |
}); | |
success(e) { | |
vote('success'); | |
} | |
failure(e) { | |
vote('failure'); | |
} | |
function vote(result){ | |
if(!opts.controller.clicked) { | |
opts.controller.clicked = true; | |
opts.quest.vote(result); | |
opts.controller.voteResult(); | |
} | |
} | |
</vote> | |
<vote-success> | |
<div class="col mui-col-sm-8 mui-col-sm-offset-2 mui-col-md-5 mui-col-md-offset-1"> | |
<button class="mui-btn mui-btn-dekai mui-btn-primary mui-btn-raised" onclick={parent.success}>SUCCESS</button> | |
</div> | |
</vote-success> | |
<vote-failue> | |
<div class="col mui-col-sm-8 mui-col-sm-offset-2 mui-col-md-5 mui-col-md-offset-1"> | |
<button class="mui-btn mui-btn-dekai mui-btn-danger mui-btn-raised" onclick={parent.failure}>FAILURE</button> | |
</div> | |
</vote-failue> | |
<voteResult> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<div class="mui-panel"> | |
<h1>{unitName()}: {opts.quest.count()}</h1> | |
</div> | |
</div> | |
<div class="col mui-col-sm-8 mui-col-sm-offset-2 mui-col-md-5 mui-col-md-offset-1"> | |
<button class="mui-btn mui-btn-dekai mui-btn-default mui-btn-raised" onclick={opts.controller.vote}>CONTINUE</button> | |
</div> | |
<div class="col mui-col-sm-8 mui-col-sm-offset-2 mui-hidden-md mui-hidden-lg"> </div> | |
<div class="col mui-col-sm-8 mui-col-sm-offset-2 mui-col-md-5 mui-col-md-offset-1"> | |
<button class="mui-btn mui-btn-accent mui-btn-raised" onclick={open}>OPEN</button> | |
</div> | |
unitName(){ | |
if(opts.quest.count() == 1) { | |
return 'RESULT'; | |
} else { | |
return 'RESULTS' | |
} | |
} | |
open() { | |
if(confirm("Do you want to open?")) { | |
opts.controller.result(); | |
} | |
} | |
</voteResult> | |
<result> | |
<div class="col mui-col-md-8 mui-col-md-offset-2" if={!opts.quest.obe}> | |
<div class="mui-panel"> | |
<h1>SUCCESS: {opts.quest.result['success']}</h1> | |
<h1>FAILURE: {opts.quest.result['failure']}</h1> | |
</div> | |
</div> | |
<div class="col mui-col-md-8 mui-col-md-offset-2" if={opts.quest.obe}> | |
<h1 if={!opts.quest.result['failure'] || opts.quest.result['failure'] < opts.quest.obe}>SUCCESS</h1> | |
<h1 if={opts.quest.result['failure'] >= opts.quest.obe}>FAILURE</h1> | |
</div> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<button class="mui-btn mui-btn-dekai mui-btn-danger mui-btn-raised" onclick={ init }>GO TO TOP</button> | |
</div> | |
this.delay = false | |
this.controller = opts.controller | |
setTimeout(function(){ | |
this.delay = true | |
}, 3000) | |
init() { | |
if(this.delay) this.controller.init() | |
this.delay = true | |
} | |
</result> | |
<inputMember> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<div class="mui-form-group" each={ items }> | |
<input type="text" class="mui-form-control" value={members.names[index]} onkeyup={ parent.edit }> | |
<label class="mui-form-floating-label">参加者名</label> | |
</div> | |
</div> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<button class="mui-btn mui-btn-dekai mui-btn-danger mui-btn-raised" disabled={ count < 5 } onclick={ decision }>NEXT</button> | |
</div> | |
this.items = []; | |
this.members = opts.members; | |
this.count = this.members.names.length; | |
for(var i = 0; i < 10; i++){ | |
this.items[this.items.length] = {index : i}; | |
} | |
edit(e) { | |
this.members.names[e.item.index] = e.target.value; | |
this.count = 0; | |
for(var i = 0; i < this.members.names.length; i++){ | |
if(this.members.names[i]) { | |
this.count++; | |
} | |
} | |
} | |
decision(e) { | |
var names = []; | |
for(var i = 0; i < this.members.names.length; i++){ | |
if(this.members.names[i]) { | |
names[names.length] = this.members.names[i]; | |
} | |
} | |
this.members.names = names; | |
opts.controller.selectCharactor(); | |
} | |
</inputMember> | |
<selectCharactor> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<div onmousedown={ percival }> | |
<button class="mui-btn mui-btn-primary mui-btn-raised" disabled={ members.specials[0]['Percival'] == 0 }>パーシヴァル</button> | |
</div> | |
</div> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<div onmousedown={ mordred }> | |
<button class="mui-btn mui-btn-danger mui-btn-raised" disabled={ members.specials[1]['Mordred'] == 0 }>モードレッド</button> | |
</div> | |
<div onmousedown={ morgana }> | |
<button class="mui-btn mui-btn-danger mui-btn-raised" disabled={ members.specials[1]['Morgana'] == 0 }>モルガナ</button> | |
</div> | |
<div onmousedown={ oberon }> | |
<button class="mui-btn mui-btn-danger mui-btn-raised" disabled={ members.specials[1]['Oberon'] == 0 }>オベロン</button> | |
</div> | |
</div> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<button class="mui-btn mui-btn-dekai mui-btn-danger mui-btn-raised" onclick={ decision }>NEXT</button> | |
</div> | |
this.members = opts.members; | |
decision(e) { | |
this.members.init(); | |
opts.controller.member(0); | |
} | |
percival(e) { | |
if(this.members.specials[0]['Percival'] == 0) { | |
this.members.specials[0]['Percival'] = 1; | |
} else { | |
this.members.specials[0]['Percival'] = 0; | |
} | |
} | |
mordred(e) { | |
if(this.members.specials[1]['Mordred'] == 0) { | |
this.members.specials[1]['Mordred'] = 1; | |
} else { | |
this.members.specials[1]['Mordred'] = 0; | |
} | |
} | |
morgana(e) { | |
if(this.members.specials[1]['Morgana'] == 0) { | |
this.members.specials[1]['Morgana'] = 1; | |
} else { | |
this.members.specials[1]['Morgana'] = 0; | |
} | |
} | |
oberon(e) { | |
if(this.members.specials[1]['Oberon'] == 0) { | |
this.members.specials[1]['Oberon'] = 1; | |
} else { | |
this.members.specials[1]['Oberon'] = 0; | |
} | |
} | |
</selectCharactor> | |
<member> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<div class="mui-panel"> | |
<h1>{members.names[members.index]}さん</h1> | |
</div> | |
</div> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<button class="mui-btn mui-btn-primary mui-btn-raised" onclick={ open }>開く</button> | |
</div> | |
this.members = opts.members; | |
this.members.index = opts.idx; | |
open(e) { | |
if(confirm("Do you want to open?")) { | |
opts.controller.memberOpen(); | |
} | |
} | |
</member> | |
<memberOpen> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<div class="mui-panel"> | |
<h1>{members.names[members.index]}さん</h1> | |
<pre>{members.description(members.index)}</pre> | |
</div> | |
</div> | |
<div class="col mui-col-md-8 mui-col-md-offset-2"> | |
<button class="mui-btn mui-btn-primary mui-btn-raised" onclick={ next }>次へ</button> | |
</div> | |
this.members = opts.members; | |
next(e) { | |
if((this.members.index + 1) < this.members.names.length){ | |
opts.controller.member(this.members.index + 1); | |
} else { | |
opts.controller.init(0); | |
} | |
} | |
</memberOpen> | |
<timer> | |
<div class="timer"><div style="animation: anime-background { opts.minutes * 60 }s linear;"></div><span style="font-size: { screen.width * 0.3 }px" onclick="{opts.controller.init}">{ opts.minutes }</span></div> | |
</timer> | |
</script> | |
<script> | |
//model | |
var Quest = function(){ | |
var elements = ['success', 'failure']; | |
this.result = {}; | |
Quest.prototype.init = function(){ | |
for(var i = 0; i < elements.length; i++) { | |
this.result[elements[i]] = 0; | |
} | |
} | |
Quest.prototype.vote = function(result){ | |
this.result[result]++; | |
} | |
Quest.prototype.count = function(){ | |
var cnt = 0; | |
for(var i = 0; i < elements.length; i++) { | |
cnt += this.result[elements[i]]; | |
} | |
return cnt; | |
} | |
Quest.prototype.oberon = function(threshold){ | |
var intThreshold = parseInt(threshold) | |
if(intThreshold) { | |
this.obe = intThreshold | |
} else { | |
this.obe = null | |
} | |
} | |
} | |
var CHARACTER_MERLIN = 1; | |
var CHARACTER_PERCIVAL = 2; | |
var CHARACTER_LOYAL_SERVANTS_OF_ARTHUR = 3; | |
var CHARACTER_ASSASSIN = 4; | |
var CHARACTER_MORDRED = 5; | |
var CHARACTER_MORGANA = 6; | |
var CHARACTER_OBERON = 7; | |
var CHARACTER_MINION_OF_MORDRED = 8; | |
var Member = function(_name, _character){ | |
this.name = _name; | |
this.character = _character; | |
this.character_code = (function(_character){ | |
if(_character == 'Merlin') return CHARACTER_MERLIN; | |
if(_character == 'Percival') return CHARACTER_PERCIVAL; | |
if(_character == 'Loyal Servants of Arthur') return CHARACTER_LOYAL_SERVANTS_OF_ARTHUR; | |
if(_character == 'Assassin') return CHARACTER_ASSASSIN; | |
if(_character == 'Mordred') return CHARACTER_MORDRED; | |
if(_character == 'Morgana') return CHARACTER_MORGANA; | |
if(_character == 'Oberon') return CHARACTER_OBERON; | |
if(_character == 'Minion of Mordred') return CHARACTER_MINION_OF_MORDRED; | |
})(_character); | |
} | |
var Members = function(){ | |
var self = this; | |
var ARTHUR = 0; | |
var MORDRED = 1; | |
var TEAM_COUNT = { | |
2 : [1, 1], | |
3 : [2, 1], | |
4 : [3, 1], | |
5 : [3, 2], | |
6 : [4, 2], | |
7 : [4, 3], | |
8 : [5, 3], | |
9 : [6, 3], | |
10 : [7, 4], | |
} | |
self.specials = {} | |
self.specials[ARTHUR] = | |
{ | |
'Merlin' : 2, | |
'Percival' : 1 | |
}; | |
self.specials[MORDRED] = | |
{ | |
'Assassin' : 2, | |
'Mordred' : 1, | |
'Morgana' : 0, | |
'Oberon' : 0 | |
}; | |
self.index = 0; | |
self.names = []; | |
Members.prototype.add = function(){ | |
if(self.count < 10) self.count++; | |
} | |
Members.prototype.remove = function(){ | |
if(self.count > 5) self.count--; | |
} | |
Members.prototype.init = function(){ | |
self.index = 0 | |
var count = self.names.length; | |
var arthurCount = TEAM_COUNT[count][ARTHUR]; | |
var mordredCount = TEAM_COUNT[count][MORDRED]; | |
self.characters = []; | |
var arthurs = ['Merlin']; | |
if(self.specials[ARTHUR]['Percival']) arthurs[arthurs.length] = 'Percival'; | |
for(var i = arthurs.length; i < arthurCount; i++) { | |
arthurs[arthurs.length] = 'Loyal Servants of Arthur'; | |
} | |
var mordreds = ['Assassin']; | |
var fncs = | |
[ | |
function(){if(self.specials[MORDRED]['Mordred'] && mordreds.length < mordredCount) mordreds[mordreds.length] = 'Mordred'}, | |
function(){if(self.specials[MORDRED]['Morgana'] && mordreds.length < mordredCount) mordreds[mordreds.length] = 'Morgana'}, | |
function(){if(self.specials[MORDRED]['Oberon'] && mordreds.length < mordredCount) mordreds[mordreds.length] = 'Oberon'} | |
]; | |
self.randomSort(fncs); | |
for(var i = 0; i < fncs.length; i++) { | |
fncs[i](); | |
} | |
for(var i = mordreds.length; i < mordredCount; i++) { | |
mordreds[mordreds.length] = 'Minion of Mordred'; | |
} | |
var characters = arthurs.concat(mordreds); | |
self.randomSort(characters); | |
self.members = [1,2,3]; | |
for(var i = 0; i < self.names.length; i++) { | |
self.members[i] = new Member(self.names[i], characters[i]); | |
} | |
self.setCookie(); | |
return self.members; | |
} | |
Members.prototype.description = function(index){ | |
var member = self.members[index]; | |
var mordredFoundEvel = self.mordredFindEvel(); | |
var mordredFoundEvelText = "モードレッド陣営:"; | |
for(var i = 0; i < mordredFoundEvel.length; i++) { | |
mordredFoundEvelText = mordredFoundEvelText + "\n " + mordredFoundEvel[i].name + "さん"; | |
} | |
if(member.character_code == CHARACTER_MERLIN){ | |
var merlinFoundEvel = self.merlinFindEvel(); | |
var merlinFoundEvelText = "モードレッド陣営:"; | |
for(var i = 0; i < merlinFoundEvel.length; i++) { | |
merlinFoundEvelText = merlinFoundEvelText + "\n " + merlinFoundEvel[i].name + "さん"; | |
} | |
var text = "あなたはマーリンです。\n" + merlinFoundEvelText; | |
return text; | |
} | |
if(member.character_code == CHARACTER_PERCIVAL){ | |
var foundMerlin = self.findMerlin(); | |
var foundMerlinText = "マーリン:"; | |
for(var i = 0; i < foundMerlin.length; i++) { | |
foundMerlinText = foundMerlinText + "\n " + foundMerlin[i].name + "さん"; | |
} | |
var text = "あなたはパーシヴァルです。\n" + foundMerlinText; | |
return text; | |
} | |
if(member.character_code == CHARACTER_LOYAL_SERVANTS_OF_ARTHUR){ | |
var text = "あなたはアーサーの忠実なる家来です。"; | |
return text; | |
} | |
if(member.character_code == CHARACTER_ASSASSIN){ | |
var text = "あなたは暗殺者です。\n" + mordredFoundEvelText; | |
return text; | |
} | |
if(member.character_code == CHARACTER_MORDRED){ | |
var text = "あなたはモードレッドです。\n" + mordredFoundEvelText; | |
return text; | |
} | |
if(member.character_code == CHARACTER_MORGANA){ | |
var text = "あなたはモルガナです。\n" + mordredFoundEvelText; | |
return text; | |
} | |
if(member.character_code == CHARACTER_OBERON){ | |
var text = "あなたはオベロンです。"; | |
return text; | |
} | |
if(member.character_code == CHARACTER_MINION_OF_MORDRED){ | |
var text = "あなたはモードレッドのしもべです。\n" + mordredFoundEvelText; | |
return text; | |
} | |
} | |
Members.prototype.findMembers = function(_charcter_codes){ | |
var result = []; | |
for(var i = 0; i < self.members.length; i++) { | |
for(var j = 0; j < _charcter_codes.length; j++) { | |
if(self.members[i].character_code == _charcter_codes[j]) { | |
result[result.length] = self.members[i]; | |
break; | |
} | |
} | |
} | |
return result; | |
} | |
// モードレッド陣営で見える仲間(オベロンが見えない) | |
Members.prototype.mordredFindEvel = function(){ | |
return self.findMembers([CHARACTER_ASSASSIN, CHARACTER_MORDRED, CHARACTER_MORGANA, CHARACTER_MINION_OF_MORDRED]); | |
} | |
// マーリンから見えるモードレッド陣営(モードレッドが見えない) | |
Members.prototype.merlinFindEvel = function(){ | |
return self.findMembers([CHARACTER_ASSASSIN, CHARACTER_MORGANA, CHARACTER_OBERON, CHARACTER_MINION_OF_MORDRED]); | |
} | |
// マーリンを探す | |
Members.prototype.findMerlin = function(){ | |
return self.findMembers([CHARACTER_MERLIN, CHARACTER_MORGANA]); | |
} | |
Members.prototype.random = function(cnt){ | |
return Math.floor( Math.random() * cnt ); | |
} | |
Members.prototype.randomSort = function(ary){ | |
var algo = | |
function() { | |
return Math.random() - 0.5; | |
}; | |
return ary.sort(algo).sort(algo).sort(algo).sort(algo); | |
} | |
Members.prototype.serialize = function(){ | |
var obj = {}; | |
obj['names'] = self.names; | |
obj['specials'] = self.specials; | |
return JSON.stringify(obj); | |
} | |
Members.prototype.deserialize = function(serial){ | |
if(!serial) return; | |
if(serial == undefined) return; | |
if(serial == '') return; | |
if(typeof serial != "string") return; | |
if(!serial.startsWith('members=')) return; | |
var obj = JSON.parse(serial.replace('members=', '')); | |
if(!obj['names']) return; | |
if(!obj['specials']) return; | |
self.names = obj.names; | |
self.specials = obj.specials; | |
} | |
Members.prototype.setCookie = function() { | |
document.cookie = 'members=' + self.serialize() + '; expires=Tue, 31-Dec-2030 23:59:59'; | |
} | |
Members.prototype.readCookie = function() { | |
self.deserialize(document.cookie); | |
} | |
self.readCookie(); | |
} | |
var quest = new Quest(); | |
var members = new Members(); | |
// controller | |
var controller = { | |
init: function(wait){ | |
quest.init(); | |
controller.forward('main', {quest: quest}, wait); | |
}, | |
vote: function(){ | |
controller.clicked = false; | |
controller.forward('vote', {quest: quest}); | |
}, | |
voteResult: function(){ | |
controller.forward('voteResult', {quest: quest}); | |
}, | |
result: function(){ | |
controller.forward('result', {quest: quest}); | |
}, | |
inputMember: function(){ | |
controller.forward('inputMember', {members: members}); | |
}, | |
selectCharactor: function(){ | |
controller.forward('selectCharactor', {members: members}); | |
}, | |
member: function(idx){ | |
controller.forward('member', {members: members, idx: idx}, 0); | |
}, | |
memberOpen: function(){ | |
controller.forward('memberOpen', {members: members}); | |
}, | |
timer: function(minutes){ | |
controller.forward('timer', {minutes: minutes}); | |
}, | |
forward: function(tag, opts, wait) { | |
if(!opts) opts = {}; | |
opts.controller = controller; | |
// 少しアニメを見せる | |
if(wait === undefined) wait = 200; | |
setTimeout(function(){ | |
riot.mount('#main', tag, opts); | |
}, wait); | |
} | |
}; | |
controller.init(0); | |
window.onbeforeunload = function(event){ | |
event = event || window.event; | |
return event.returnValue = "Are you sure you want to exit this page?"; | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment