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
#game-area{ | |
position: relative; | |
} | |
#play-area{ | |
padding: 15px 0; | |
position: relative; | |
user-select: none; | |
} | |
#play-area,#controller{ | |
background-color: #43A047; | |
} | |
#controller{ | |
padding: 10px; | |
text-align: right; | |
} | |
#joker-area{ | |
width: 100%; | |
position: absolute; | |
top: 10px; | |
right: 10px; | |
text-align: right; | |
pointer-events: none; | |
} | |
.joker{ | |
pointer-events: auto; | |
} | |
.pyramid-row{ | |
line-height: 0; | |
text-align: center; | |
font-size: 0; | |
letter-spacing: 0; | |
} | |
.pyramid-row+.pyramid-row{ | |
margin-top: -9%; | |
} | |
#hand-area{ | |
display: flex; | |
justify-content: space-evenly; | |
margin: 10px 0; | |
} | |
#reload-meter{ | |
padding-right: 10px; | |
text-align: right; | |
color: white; | |
} | |
.card{ | |
width: 12%; | |
max-height: calc((95vh - 130px) / 4.4); | |
margin: 0 2px; | |
cursor: pointer; | |
} | |
.selected{ | |
box-shadow: 0 0 0 4px #A1436A; | |
} | |
.hidden{ | |
visibility: hidden; | |
} | |
#before-init,#cleared{ | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
width: 100%; | |
height: 100%; | |
position: absolute; | |
top: 0; | |
left: 0; | |
background-color: rgba(0,0,0,.7); | |
color: white; | |
font-size: 2.5rem; | |
line-height: 1.5em; | |
text-align: center; | |
} | |
#cleared.hide{ | |
display: none; | |
} | |
@media screen and (min-width:481px) { | |
.pyramid-row+.pyramid-row{ | |
margin-top: calc((130px - 95vh) * 0.6 / 4.4); | |
} | |
.card{ | |
width: auto; | |
height: calc((95vh - 130px) / 4.4); | |
margin: 0 4px; | |
} | |
#before-init,#cleared{ | |
font-size: 5rem; | |
} | |
.selected{ | |
box-shadow: 0 0 0 7px #A1436A; | |
} | |
} |
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
<div id="game-area"> | |
<div id="controller"> | |
<button id="new-game">New Game</button> | |
<button id="re-start">Re Start</button> | |
</div> | |
<div id="play-area"> | |
<div id="joker-area"> | |
<canvas class="card joker" width="100px" height="162px"></canvas> | |
<canvas class="card joker" width="100px" height="162px"></canvas> | |
</div> | |
<div id="pyramid"> | |
<div class="pyramid-row"> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
</div> | |
<div class="pyramid-row"> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
</div> | |
<div class="pyramid-row"> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
</div> | |
<div class="pyramid-row"> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
</div> | |
<div class="pyramid-row"> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
</div> | |
<div class="pyramid-row"> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
</div> | |
<div class="pyramid-row"> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
<canvas class="card mt-card" width="100px" height="162px"></canvas> | |
</div> | |
</div> | |
<div id="hand-area"> | |
<canvas id="discard" class="card" width="100px" height="162px"></canvas> | |
<canvas id="using" class="card" width="100px" height="162px"></canvas> | |
<canvas id="deck" class="card" width="100px" height="162px"></canvas> | |
</div> | |
<div id="reload-meter"></div> | |
<div id="cleared">Game Clear!!</div> | |
</div> | |
<div id="before-init">準備中...</div> | |
</div> |
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
const unit_w = 100; | |
const unit_h = 162; | |
const limit = 2; | |
let mt_ctx = []; | |
let mt_map=[]; | |
let mtc = 0; | |
[...document.getElementsByClassName('pyramid-row')].forEach(row=>{ | |
let ar = []; | |
[...row.getElementsByClassName('mt-card')].forEach(el=>{ | |
ar.push([el,mtc]) | |
mtc++; | |
}); | |
mt_map.push(ar); | |
}); | |
const mt_cards = document.getElementsByClassName('mt-card'); | |
[...mt_cards].forEach((mt_card,i)=>{ | |
mt_ctx.push(mt_card.getContext('2d')); | |
mt_card.addEventListener('click',(e)=>{ | |
e.stopPropagation(); | |
click_mt(e,i,row_num(i)); | |
}); | |
}); | |
const selecteds = document.getElementsByClassName('selected'); | |
const discard = document.getElementById('discard'); | |
const using = document.getElementById('using'); | |
const deck = document.getElementById('deck'); | |
const hand_ctx ={ | |
'discard': discard.getContext('2d'), | |
'using': using.getContext('2d'), | |
'deck': deck.getContext('2d') | |
} | |
deck.addEventListener('click',(e)=>{e.stopPropagation();click_deck();}); | |
using.addEventListener('click',(e)=>{e.stopPropagation();click_using();}); | |
discard.addEventListener('click',(e)=>{e.stopPropagation();click_discard();}); | |
const jokers = document.getElementsByClassName('joker'); | |
[...jokers].forEach(joker=>{ | |
joker.addEventListener('click',(e)=>{ | |
e.stopPropagation(); | |
click_joker(e.target); | |
}); | |
}); | |
const joker_ctx = [jokers[0].getContext('2d'),jokers[1].getContext('2d')]; | |
document.getElementById('new-game').addEventListener('click',reset); | |
document.getElementById('re-start').addEventListener('click',init); | |
const reload_meter = document.getElementById('reload-meter'); | |
const cleared = document.getElementById('cleared'); | |
document.getElementById('play-area').addEventListener('click',cansel); | |
let card_set; | |
let mt_set; | |
let deck_set; | |
let using_set; | |
let discard_set; | |
let imgset; | |
let imgback; | |
let imgreload; | |
let imgnocard; | |
let imglimit; | |
let selected_num = false; | |
let mt_selected = false; | |
let chance; | |
Promise.all([ | |
load_img('../img/pcard/p-card.png'), | |
load_img('../img/pcard/p-card-back.png'), | |
load_img('../img/pcard/p-card-reload.png'), | |
load_img('../img/pcard/p-card-nocard.png'), | |
load_img('../img/pcard/p-card-limit.png') | |
]).then(val=>{ | |
imgset = val[0]; | |
imgback = val[1]; | |
imgreload = val[2]; | |
imgnocard = val[3]; | |
imglimit= val[4]; | |
reset(); | |
document.getElementById('before-init').style.display = 'none'; | |
}); | |
function reset(){ | |
card_set = []; | |
for(let i=1;i<=4;i++){ | |
for(let j=1;j<=13;j++){ | |
card_set.push([i,j]); | |
} | |
} | |
for(let i=card_set.length-1;i>=1;i--){ | |
const j = randomMN(0,i); | |
[card_set[j],card_set[i]] = [card_set[i],card_set[j]]; | |
} | |
mt_set = card_set.slice(0,28); | |
init(); | |
} | |
function init(){ | |
cleared.classList.add('hide'); | |
//init draw | |
[...mt_cards].forEach((mt_card,i)=>{ | |
if(i<=20){ | |
mt_card.classList.remove('active'); | |
draw(mt_ctx[i],imgback,false); | |
}else{ | |
mt_card.classList.add('active'); | |
draw(mt_ctx[i],imgset,true,mt_set[i][1],mt_set[i][0]); | |
} | |
mt_card.classList.remove('hidden'); | |
}); | |
discard.classList.remove('active'); | |
using.classList.remove('active'); | |
deck.classList.add('active'); | |
hand_ctx.discard.clearRect(0,0,unit_w,unit_h); | |
hand_ctx.using.clearRect(0,0,unit_w,unit_h); | |
draw(hand_ctx.deck,imgback,false); | |
[...jokers].forEach((joker,i)=>{ | |
joker.classList.add('active'); | |
joker.classList.remove('hidden'); | |
draw(joker_ctx[i],imgset,true,1,5); | |
}); | |
cansel(); | |
//set hand-area | |
deck_set = card_set.slice(28); | |
using_set = []; | |
discard_set = []; | |
chance = limit; | |
reload_meter.textContent = `山札再使用:残り${chance}回`; | |
} | |
function load_img(src){ | |
return new Promise(resolve=>{ | |
const img = new Image(); | |
img.onload = () => resolve(img); | |
img.src = src; | |
}); | |
} | |
function draw(ctx,img,isOpen,suit,num){ | |
ctx.clearRect(0,0,unit_w,unit_h); | |
if(isOpen){ | |
ctx.drawImage(img,(suit-1)*unit_w,(num-1)*unit_h,unit_w,unit_h,0,0,unit_w,unit_h); | |
}else{ | |
ctx.drawImage(img,0,0); | |
} | |
} | |
function row_num(x){ | |
for(let i=0;i<=6;i++){ | |
const n = ((i+1)*(i+2)/2)-1; | |
if(x<=n) return i; | |
} | |
} | |
function click_mt(e,id,row){ | |
const card = e.target; | |
if(!card.classList.contains('active')) return; | |
if(selected_num){ | |
//second select | |
if(!card.classList.contains('selected')){ | |
//another select | |
if(selected_num+mt_set[id][1]==13||selected_num=='joker'){ | |
if(mt_set[id][1]==13){ | |
//joker → K | |
del_cards([mt_cards[id]]); | |
}else{ | |
//else | |
del_cards([selecteds[0],mt_cards[id]]); | |
} | |
} | |
} | |
selecteds[0].classList.remove('selected'); | |
selected_num = false; | |
}else{ | |
//first select | |
if(mt_set[id][1]==13){ | |
//first K | |
del_cards([mt_cards[id]]); | |
}else{ | |
selected_num = mt_set[id][1]; | |
card.classList.add('selected'); | |
} | |
} | |
} | |
function click_using(){ | |
if(!using.classList.contains('active')) return; | |
if(selected_num){ | |
//second select | |
if(selected_num+using_set[0][1]==13&&selecteds[0].classList.contains('mt-card')){ | |
del_cards([selecteds[0],using]); | |
} | |
selecteds[0].classList.remove('selected'); | |
selected_num = false; | |
}else{ | |
//first select | |
if(using_set[0][1]==13){ | |
del_cards([using]); | |
}else{ | |
using.classList.add('selected'); | |
selected_num = using_set[0][1]; | |
} | |
} | |
} | |
function click_discard(){ | |
if(!discard.classList.contains('active')) return; | |
if(selected_num){ | |
//second select | |
if(selected_num+discard_set[discard_set.length-1][1]==13&&selecteds[0].classList.contains('mt-card')){ | |
del_cards([selecteds[0],discard]); | |
} | |
selecteds[0].classList.remove('selected'); | |
selected_num = false; | |
}else{ | |
//first select | |
if(discard_set[discard_set.length-1][1]==13){ | |
del_cards([discard]); | |
}else{ | |
discard.classList.add('selected'); | |
selected_num = discard_set[discard_set.length-1][1]; | |
} | |
} | |
} | |
function click_joker(joker){ | |
if(!joker.classList.contains('active')) return; | |
if(selected_num){ | |
//second_select | |
if(selecteds[0].classList.contains('mt-card')){ | |
del_cards([selecteds[0],joker]); | |
} | |
selecteds[0].classList.remove('selected'); | |
selected_num = false; | |
}else{ | |
//first select | |
joker.classList.add('selected'); | |
selected_num = 'joker'; | |
} | |
} | |
function click_deck(){ | |
if(!deck.classList.contains('active')) return; | |
if(selecteds.length>0) selecteds[0].classList.remove('selected'); | |
selected_num = false; | |
if(deck_set.length==0){ | |
//reload | |
if(using_set.length>0){ | |
discard_set.push(using_set[0]); | |
using_set.shift(); | |
} | |
if(discard_set.length>0){ | |
deck_set = discard_set.slice(0); | |
discard_set = []; | |
} | |
hand_ctx.discard.clearRect(0,0,unit_w,unit_h); | |
discard.classList.remove('active'); | |
hand_ctx.using.clearRect(0,0,unit_w,unit_h); | |
using.classList.remove('active'); | |
if(deck_set.length==0){ | |
//no card | |
deck.classList.remove('active'); | |
draw(hand_ctx.deck,imgnocard,false); | |
}else{ | |
draw(hand_ctx.deck,imgback,false); | |
chance--; | |
reload_meter.textContent = `山札再使用:残り${chance}回`; | |
} | |
}else{ | |
//use | |
if(using_set.length>0){ | |
discard_set.push(using_set[0]); | |
draw(hand_ctx.discard,imgset,true,discard_set[discard_set.length-1][1],discard_set[discard_set.length-1][0]); | |
discard.classList.add('active'); | |
using_set.shift(); | |
} | |
using_set.unshift(deck_set[0]); | |
draw(hand_ctx.using,imgset,true,deck_set[0][1],deck_set[0][0]); | |
using.classList.add('active'); | |
deck_set.shift(); | |
if(deck_set.length==0){ | |
if(chance==0){ | |
deck.classList.remove('active'); | |
draw(hand_ctx.deck,imglimit,false); | |
}else{ | |
draw(hand_ctx.deck,imgreload,false); | |
} | |
} | |
} | |
} | |
function cansel(){ | |
[...selecteds].forEach(v=>v.classList.remove('selected')); | |
selected_num = false; | |
} | |
function del_cards(arr){ | |
arr.forEach(card=>{ | |
if(card.classList.contains('mt-card')){ | |
card.classList.add('hidden'); | |
card.classList.remove('active'); | |
}else if(card.classList.contains('joker')){ | |
card.classList.add('hidden'); | |
card.classList.remove('active'); | |
}else if(card.id=='using'){ | |
using_set.shift(); | |
hand_ctx.using.clearRect(0,0,unit_w,unit_h); | |
using.classList.remove('active'); | |
}else if(card.id=='discard'){ | |
discard_set.pop(); | |
if(discard_set.length>0){ | |
draw(hand_ctx.discard,imgset,true,discard_set[discard_set.length-1][1],discard_set[discard_set.length-1][0]); | |
}else{ | |
hand_ctx.discard.clearRect(0,0,unit_w,unit_h); | |
discard.classList.remove('active'); | |
} | |
} | |
}); | |
if(arr.indexOf(mt_cards[0])!=-1){ | |
game_clear(); | |
return; | |
} | |
mt_open(); | |
} | |
function mt_open(){ | |
mt_map.forEach((row,r)=>{ | |
row.forEach((card,c)=>{ | |
if(card[0].classList.contains('hidden')||card[0].classList.contains('active')) return; | |
if(mt_map[r+1][c][0].classList.contains('hidden')&&mt_map[r+1][c+1][0].classList.contains('hidden')){ | |
card[0].classList.add('active'); | |
const id = mt_map[r][c][1]; | |
draw(mt_ctx[id],imgset,true,mt_set[id][1],mt_set[id][0]); | |
} | |
}); | |
}); | |
} | |
function game_clear(){ | |
cleared.classList.remove('hide'); | |
} | |
function randomMN(m,n){ | |
const d = Math.max(m,n)-Math.min(m,n); | |
return Math.floor(Math.random()*(d+1)+Math.min(m,n)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment