Merge pull request #40 from LoveEevee/scoresheet-new-screen
Scoresheet: Change results screen
This commit is contained in:
commit
57f1419e49
@ -19,7 +19,6 @@
|
|||||||
<link rel="stylesheet" href="/src/css/main.css"/>
|
<link rel="stylesheet" href="/src/css/main.css"/>
|
||||||
<link rel="stylesheet" href="/src/css/loader.css">
|
<link rel="stylesheet" href="/src/css/loader.css">
|
||||||
<link rel="stylesheet" href="/src/css/titlescreen.css">
|
<link rel="stylesheet" href="/src/css/titlescreen.css">
|
||||||
<link rel="stylesheet" href="/src/css/scoresheet.css">
|
|
||||||
<link rel="stylesheet" href="/src/css/loadsong.css">
|
<link rel="stylesheet" href="/src/css/loadsong.css">
|
||||||
<link rel="stylesheet" href="/src/css/game.css">
|
<link rel="stylesheet" href="/src/css/game.css">
|
||||||
|
|
||||||
@ -47,6 +46,7 @@
|
|||||||
<script src="/src/js/pageevents.js"></script>
|
<script src="/src/js/pageevents.js"></script>
|
||||||
<script src="/src/js/viewassets.js"></script>
|
<script src="/src/js/viewassets.js"></script>
|
||||||
<script src="/src/js/gamerules.js"></script>
|
<script src="/src/js/gamerules.js"></script>
|
||||||
|
<script src="/src/js/canvasdraw.js"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -1,207 +0,0 @@
|
|||||||
.scoresheet{
|
|
||||||
width:100%;
|
|
||||||
height:100%;
|
|
||||||
color:black;
|
|
||||||
font-family: TnT;
|
|
||||||
background: url("/assets/img/bg-pattern-2.png");
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet h2{
|
|
||||||
position:absolute;
|
|
||||||
top:1%;
|
|
||||||
left:1%;
|
|
||||||
font-size: 7vmin;
|
|
||||||
margin:0;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-window{
|
|
||||||
width:70%;
|
|
||||||
margin:auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet button{
|
|
||||||
height: 50%;
|
|
||||||
min-width:20%;
|
|
||||||
position: absolute;
|
|
||||||
display: inline-block;
|
|
||||||
cursor: pointer;
|
|
||||||
border:5px solid #ae7a26;
|
|
||||||
background: rgb(255, 255, 255);
|
|
||||||
color: black;
|
|
||||||
font-family: TnT;
|
|
||||||
font-size: 5vmin;
|
|
||||||
border-radius: 10px;
|
|
||||||
outline: none;
|
|
||||||
top:10%;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .replay{
|
|
||||||
left:1%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .song-select{
|
|
||||||
left:23%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet button:hover,
|
|
||||||
.scoresheet .bottom-part:not(:hover) button.selected{
|
|
||||||
border-color:#fa5d3a;
|
|
||||||
color:white;
|
|
||||||
background:#0c6577;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .result-bar{
|
|
||||||
max-width: 120vh;
|
|
||||||
height: 71vh;
|
|
||||||
min-height: 200px;
|
|
||||||
display:flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: flex-end;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .score-cont{
|
|
||||||
position:relative;
|
|
||||||
right:1%;
|
|
||||||
width:60%;
|
|
||||||
height:80%;
|
|
||||||
background:rgba(255,255,255,0.7);
|
|
||||||
border-radius:15px;
|
|
||||||
margin: 10px;
|
|
||||||
max-height: 33vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .score-hp-bar-bg{
|
|
||||||
position: relative;
|
|
||||||
margin-top:2%;
|
|
||||||
margin-left:5%;
|
|
||||||
background: url("/assets/img/hp-bar-bg.png");
|
|
||||||
background-size: contain;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .score-hp-bar-colour{
|
|
||||||
position:absolute;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .score-hp-bar-colour img{
|
|
||||||
position:absolute;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
margin:0;
|
|
||||||
padding:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .score-points{
|
|
||||||
min-width:30%;
|
|
||||||
height:18%;
|
|
||||||
background:black;
|
|
||||||
border:5px solid #ae7a26;
|
|
||||||
border-radius: 10px;
|
|
||||||
position:absolute;
|
|
||||||
bottom:5%;
|
|
||||||
left:5%;
|
|
||||||
color: white;
|
|
||||||
font-size: 5vmin;
|
|
||||||
text-align: right;
|
|
||||||
padding: .3% 1%;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .score-details{
|
|
||||||
position: absolute;
|
|
||||||
right:5%;
|
|
||||||
width:70%;
|
|
||||||
height:50%;
|
|
||||||
color:white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .score-details th,
|
|
||||||
.scoresheet .score-details td{
|
|
||||||
font-size: 3vmin;
|
|
||||||
font-weight: normal;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .score-details td{
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .value{
|
|
||||||
width: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .bottom-part{
|
|
||||||
position: fixed;
|
|
||||||
width:100%;
|
|
||||||
height:19vh;
|
|
||||||
bottom:0;
|
|
||||||
-webkit-box-shadow: inset 0px 10px 20px -5px #ee6d46;
|
|
||||||
-moz-box-shadow: inset 0px 10px 20px -5px #ee6d46;
|
|
||||||
box-shadow: inset 0px 10px 20px -5px #ee6d46;
|
|
||||||
border-top:10px outset #b6361d;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .score-mark{
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
right: 105%;
|
|
||||||
height: 40%;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .gradient-overlay{
|
|
||||||
position:absolute;
|
|
||||||
width:100%;
|
|
||||||
height:100%;
|
|
||||||
background: linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(255,165,100,0.64) 62%, rgba(255,165,100,0.65) 63%);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.scoresheet .top-part{
|
|
||||||
width:100%;
|
|
||||||
height:10vh;
|
|
||||||
background:#e84019;
|
|
||||||
border-bottom:5px solid #b23111;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-great,
|
|
||||||
.header-fail{
|
|
||||||
color: transparent;
|
|
||||||
}
|
|
||||||
.header-great::after,
|
|
||||||
.header-fail::after{
|
|
||||||
content: attr(alt);
|
|
||||||
color: transparent;
|
|
||||||
-webkit-background-clip: text;
|
|
||||||
background-clip: text;
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
.header-great::after{
|
|
||||||
background-image: linear-gradient(0deg, #f00 10%, #fe0 70%);
|
|
||||||
}
|
|
||||||
.header-fail::after{
|
|
||||||
background-image: linear-gradient(0deg, #00b3df 30%, #6a62f9 90%);
|
|
||||||
|
|
||||||
}
|
|
||||||
.scoresheet .stroke-sub{
|
|
||||||
position:relative;
|
|
||||||
z-index:1;
|
|
||||||
}
|
|
||||||
.scoresheet .stroke-sub::before{
|
|
||||||
left:auto;
|
|
||||||
}
|
|
@ -1,6 +1,5 @@
|
|||||||
var assets = {
|
var assets = {
|
||||||
"img": [
|
"img": [
|
||||||
"background.png",
|
|
||||||
"title-screen.png",
|
"title-screen.png",
|
||||||
"logo-big.png",
|
"logo-big.png",
|
||||||
"don-0.png",
|
"don-0.png",
|
||||||
@ -18,11 +17,7 @@ var assets = {
|
|||||||
"score-230.png",
|
"score-230.png",
|
||||||
"score-450.png",
|
"score-450.png",
|
||||||
"dancing-don.gif",
|
"dancing-don.gif",
|
||||||
"scoresheet.jpg",
|
|
||||||
"bg-pattern-1.png",
|
"bg-pattern-1.png",
|
||||||
"bg-pattern-2.png",
|
|
||||||
"ranking-S.png",
|
|
||||||
"ranking-X.png",
|
|
||||||
"muzu_easy.png",
|
"muzu_easy.png",
|
||||||
"muzu_normal.png",
|
"muzu_normal.png",
|
||||||
"muzu_hard.png",
|
"muzu_hard.png",
|
||||||
@ -41,7 +36,9 @@ var assets = {
|
|||||||
"bg_genre_4.png",
|
"bg_genre_4.png",
|
||||||
"bg_genre_5.png",
|
"bg_genre_5.png",
|
||||||
"bg_genre_6.png",
|
"bg_genre_6.png",
|
||||||
"bg_genre_7.png"
|
"bg_genre_7.png",
|
||||||
|
"bg_score_p1.png",
|
||||||
|
"bg_score_p2.png"
|
||||||
],
|
],
|
||||||
"audioSfx": [
|
"audioSfx": [
|
||||||
"start.wav",
|
"start.wav",
|
||||||
@ -86,7 +83,7 @@ var assets = {
|
|||||||
"title.ogg",
|
"title.ogg",
|
||||||
"pause.wav",
|
"pause.wav",
|
||||||
"cancel.wav",
|
"cancel.wav",
|
||||||
"results.wav",
|
"results.ogg",
|
||||||
"diffsel.wav",
|
"diffsel.wav",
|
||||||
|
|
||||||
"gamefullcombo.wav",
|
"gamefullcombo.wav",
|
||||||
@ -110,7 +107,6 @@ var assets = {
|
|||||||
"views": [
|
"views": [
|
||||||
"game.html",
|
"game.html",
|
||||||
"loadsong.html",
|
"loadsong.html",
|
||||||
"scoresheet.html",
|
|
||||||
"songselect.html",
|
"songselect.html",
|
||||||
"titlescreen.html",
|
"titlescreen.html",
|
||||||
"tutorial.html"
|
"tutorial.html"
|
||||||
|
762
public/src/js/canvasdraw.js
Normal file
762
public/src/js/canvasdraw.js
Normal file
@ -0,0 +1,762 @@
|
|||||||
|
class CanvasDraw{
|
||||||
|
constructor(){
|
||||||
|
this.diffStarPath = new Path2D("M3 17 5 11 0 6h6l3-6 3 6h6l-5 5 2 6-6-3")
|
||||||
|
this.longVowelMark = new Path2D("m1 5c2 3 1 17 .5 25 0 5 6 5 6.5 0C9 22 9 6 7 3 4-2-1 2 1 5")
|
||||||
|
|
||||||
|
this.diffIconPath = [[{w: 40, h: 33}, {
|
||||||
|
fill: "#ff2803",
|
||||||
|
d: new Path2D("m27 10c9-9 21 9 5 11 10 9-6 18-12 7C14 39-2 30 8 21-8 19 4 1 13 10 6-4 34-3 27 10Z")
|
||||||
|
}, {
|
||||||
|
fill: "#ffb910",
|
||||||
|
noStroke: true,
|
||||||
|
d: new Path2D("m12 15c5 1 7 0 8-4 1 4 3 5 8 4-4 3-4 5-2 8-4-4-8-4-12 0 2.2-3 2-5-2-8")
|
||||||
|
}], [{w: 48, h: 31}, {
|
||||||
|
fill: "#8daf51",
|
||||||
|
d: new Path2D("m24 0c-3 0-4 3-5 6-2 6-2 11 0 17 0 0 1 4 5 8 4-4 5-8 5-8C31 17 31 12 29 6 28 3 27 0 24 0M37 2c4 3 7 6 8 8 2 4 3 6 2 13C43 21 39 18 39 18 35 15 32 12 30 8 27 0 32-2 37 2M11 2C7 5 4 8 3 10 1 14 0 16 1 23 5 21 9 18 9 18 13 15 16 12 18 8 21 0 16-2 11 2")
|
||||||
|
}], [{w: 56, h: 37}, {
|
||||||
|
fill: "#784439",
|
||||||
|
d: new Path2D("m26 34v-2c-10 1-12 0-12-7 4-3 8-5 14-5 6 0 10 2 14 5 0 7-2 8-12 7V34Z")
|
||||||
|
}, {
|
||||||
|
fill: "#000",
|
||||||
|
noStroke: true,
|
||||||
|
d: new Path2D("m18 19v9h8v-9m4 9h8v-9h-8")
|
||||||
|
}, {
|
||||||
|
fill: "#414b2b",
|
||||||
|
d: new Path2D("M8 26C3 26-3 21 2 11 6 5 11 4 18 10c0-6 4-10 10-10 6 0 10 4 10 10 7-6 12-5 16 1 5 10-1 15-6 15-5 0-10-7-20-7-10 0-15 7-20 7")
|
||||||
|
}], [{w: 29, h: 27}, {
|
||||||
|
fill: "#db1885",
|
||||||
|
d: new Path2D("m18 9c1 3 4 4 7 3 0 4 1 11 4 16H0c3-5 4-12 4-16 3 1 6 0 7-3z")
|
||||||
|
}, {
|
||||||
|
fill: "#fff",
|
||||||
|
d: new Path2D("m6 0.5-2 11c4 1.5 6-0.5 6.5-3zm17 0-4.5 8C19 11 21 13 25 11.5ZM5.5 17.5C4.5 23.5 9 25 11 22Zm18 0L18 22c2 3 6.5 1.5 5.5-4.5z")
|
||||||
|
}]]
|
||||||
|
|
||||||
|
this.diffPath = {
|
||||||
|
good: new Path2D("m12 17c4 3 9 7 10 9 0 0 1 3-1 3C19 29 9 18 9 18m6 2c3 0 3-3 3-3 2-1 5 1 4 3-1 1-2 2-5 3m-1 0C13 26 4 29 1 29 0 29 0 26 0 26 0 24 2 24 2 24V13l5-1v4l8-1c1 0 1-3 1-3 0 0-9 1-14 1V8L7 7v4.5L15 11C16 11 16 8 16 8 16 7 2 9 2 9-1 10 0 5 1 5h10l6-1c3 0 4 2 4 6 0 3-1 7-1 7L7 19v4.5c4 0 7-2.5 7-2.5M9 6C8 4 8 1 8 1c0 0 4-1 6 0 0 0 0 3 1 5"),
|
||||||
|
ok: new Path2D("m4 10c0 0 3-1 7-1 4 0 3 8 2 11-1 2-3 1-3 1-1-1 1-7 0-8-1-1-4-1-6 0m8 6c-1 1.2-7 1-7 1v-3c0 0 6 0 7-1M2 10c1-2 3 0 3 0 0 0 0 4 1 9-2 3-4 2-4 0zM21 5v19c0 1-2 3-3 3-1 0-5-4-5-4 0-1 4-1 4-1V5M1 2C12 2 17.9 0 20 0 23 0 25 3 21 5 11.7 6 9 6 5 6 0 7-1 2 1 2Z"),
|
||||||
|
bad: new Path2D("m13 7c8 0 10 9 10 9 1 4-6 3-8 0 0-1 4 0 2.5-3 0 0-2.5-4-4.5 0M16 6 3 18c-2 2-4 1-4 0 0-1 8-8 9-12m6 0c1 8 0 18 0 18-0.1 1-2 3-3 3-1 0-5-4-5-4 0-1 4-1 4-1 0 0-1-8 0-16M2 7C1 7 1 2 2 2 10 2 21 0 22 1 22 1 24 2 24 4 24 7 2 7 2 7Z")
|
||||||
|
}
|
||||||
|
|
||||||
|
this.crownPath = new Path2D("m82 21c0-4 3-6 5.5-6 2.5 0 5.5 2 5.5 6 0 4-3 6-5.5 6C85 27 82 25 82 21ZM41.5 6c0-4 3-6 5.5-6 2.5 0 5.5 2 5.5 6 0 4-3 6-5.5 6-2.5 0-5.5-2-5.5-6zM1 21C1 17 4 15 6.5 15 9 15 12 17 12 21 12 25 9 27 6.5 27 4 27 1 25 1 21Zm12 46h68l2 11H11ZM13 62 5 18 29 34 47 6 65 34 89 18 81 62Z")
|
||||||
|
|
||||||
|
this.regex = {
|
||||||
|
comma: /[,.]/,
|
||||||
|
ideographicComma: /[、。]/,
|
||||||
|
apostrophe: /['']/,
|
||||||
|
brackets: /[\((\))「」『』]/,
|
||||||
|
tilde: /[\--~~]/,
|
||||||
|
tall: /[bbddffh-lh-ltt0-90-9♪]/,
|
||||||
|
uppercase: /[A-ZA-Z!!]/,
|
||||||
|
lowercase: /[a-za-z・]/,
|
||||||
|
latin: /[A-ZA-Z!!a-za-z・]/,
|
||||||
|
smallHiragana: /[ぁぃぅぇぉっゃゅょァィゥェォッャュョ]/,
|
||||||
|
hiragana: /[\u3040-\u30ff]/,
|
||||||
|
todo: /[トド]/,
|
||||||
|
en: /[ceghknsuxyzceghknsuxyz]/,
|
||||||
|
em: /[mwmw]/,
|
||||||
|
emCap: /[MWMW]/,
|
||||||
|
rWidth: /[abdfIjo-rtvabdfIjo-rtv]/,
|
||||||
|
lWidth: /[ilil!!]/,
|
||||||
|
uppercaseDigit: /[A-ZA-Z0-90-9]/
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tmpCanvas = document.createElement("canvas")
|
||||||
|
this.tmpCtx = this.tmpCanvas.getContext("2d")
|
||||||
|
}
|
||||||
|
|
||||||
|
roundedRect(config){
|
||||||
|
var ctx = config.ctx
|
||||||
|
var x = config.x
|
||||||
|
var y = config.y
|
||||||
|
var w = config.w
|
||||||
|
var h = config.h
|
||||||
|
var r = config.radius
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5)
|
||||||
|
ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, 0)
|
||||||
|
ctx.arc(x + w - r, y + h - r, r, 0, Math.PI / 2)
|
||||||
|
ctx.arc(x + r, y + h - r, r, Math.PI / 2, Math.PI)
|
||||||
|
ctx.lineTo(x, y + r)
|
||||||
|
}
|
||||||
|
|
||||||
|
songFrame(config){
|
||||||
|
var ctx = config.ctx
|
||||||
|
var x = config.x
|
||||||
|
var y = config.y
|
||||||
|
var w = config.width
|
||||||
|
var h = config.height
|
||||||
|
var border = config.border
|
||||||
|
var innerBorder = config.innerBorder
|
||||||
|
var allBorders = border + innerBorder
|
||||||
|
var innerX = x + allBorders
|
||||||
|
var innerY = y + allBorders
|
||||||
|
var innerW = w - allBorders * 2
|
||||||
|
var innerH = h - allBorders * 2
|
||||||
|
|
||||||
|
ctx.save()
|
||||||
|
|
||||||
|
ctx.shadowColor = "rgba(0, 0, 0, 0.5)"
|
||||||
|
ctx.shadowBlur = 10
|
||||||
|
ctx.shadowOffsetX = 5
|
||||||
|
ctx.shadowOffsetY = 5
|
||||||
|
ctx.fillStyle = "#000"
|
||||||
|
ctx.fillRect(x, y, w, h)
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
ctx.save()
|
||||||
|
|
||||||
|
{
|
||||||
|
let _x = x + border
|
||||||
|
let _y = y + border
|
||||||
|
let _w = w - border * 2
|
||||||
|
let _h = h - border * 2
|
||||||
|
ctx.fillStyle = config.borderStyle[1]
|
||||||
|
ctx.fillRect(_x, _y, _w, _h)
|
||||||
|
ctx.fillStyle = config.borderStyle[0]
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.moveTo(_x, _y)
|
||||||
|
ctx.lineTo(_x + _w, _y)
|
||||||
|
ctx.lineTo(_x + _w - innerBorder, _y + innerBorder)
|
||||||
|
ctx.lineTo(_x + innerBorder, _y + _h - innerBorder)
|
||||||
|
ctx.lineTo(_x, _y + _h)
|
||||||
|
ctx.fill()
|
||||||
|
}
|
||||||
|
ctx.fillStyle = config.background
|
||||||
|
ctx.fillRect(innerX, innerY, innerW, innerH)
|
||||||
|
|
||||||
|
ctx.save()
|
||||||
|
|
||||||
|
ctx.strokeStyle = "rgba(255, 255, 255, 0.3)"
|
||||||
|
ctx.lineWidth = 3
|
||||||
|
ctx.strokeRect(innerX, innerY, innerW, innerH)
|
||||||
|
if(!config.noCrop){
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.rect(innerX, innerY, innerW, innerH)
|
||||||
|
ctx.clip()
|
||||||
|
}
|
||||||
|
|
||||||
|
config.innerContent(innerX, innerY, innerW, innerH)
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
|
||||||
|
if(config.highlight){
|
||||||
|
this.highlight({
|
||||||
|
ctx: ctx,
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
w: w,
|
||||||
|
h: h,
|
||||||
|
animate: config.highlight === 2,
|
||||||
|
animateMS: config.animateMS,
|
||||||
|
opacity: config.highlight === 1 ? 0.8 : 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
highlight(config){
|
||||||
|
var ctx = config.ctx
|
||||||
|
ctx.save()
|
||||||
|
var _x = config.x + 3.5
|
||||||
|
var _y = config.y + 3.5
|
||||||
|
var _w = config.w - 7
|
||||||
|
var _h = config.h - 7
|
||||||
|
var rect = () => {
|
||||||
|
if(config.radius){
|
||||||
|
this.roundedRect({
|
||||||
|
ctx: ctx,
|
||||||
|
x: _x,
|
||||||
|
y: _y,
|
||||||
|
w: _w,
|
||||||
|
h: _h,
|
||||||
|
radius: config.radius
|
||||||
|
})
|
||||||
|
ctx.stroke()
|
||||||
|
}else{
|
||||||
|
ctx.strokeRect(_x, _y, _w, _h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(config.animate){
|
||||||
|
ctx.globalAlpha = this.fade((this.getMS() - config.animateMS) % 2000 / 2000)
|
||||||
|
}else if(config.opacity){
|
||||||
|
ctx.globalAlpha = config.opacity
|
||||||
|
}
|
||||||
|
ctx.strokeStyle = "rgba(255, 249, 1, 0.45)"
|
||||||
|
ctx.lineWidth = 14
|
||||||
|
rect()
|
||||||
|
ctx.strokeStyle = "rgba(255, 249, 1, .8)"
|
||||||
|
ctx.lineWidth = 8
|
||||||
|
rect()
|
||||||
|
ctx.strokeStyle = "#fff"
|
||||||
|
ctx.lineWidth = 6
|
||||||
|
rect()
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
fade(pos){
|
||||||
|
if(pos < 0.5){
|
||||||
|
pos = 1 - pos
|
||||||
|
}
|
||||||
|
return (1 - Math.cos(Math.PI * pos * 2)) / 2
|
||||||
|
}
|
||||||
|
easeIn(pos){
|
||||||
|
return 1 - Math.cos(Math.PI / 2 * pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
verticalText(config){
|
||||||
|
var ctx = config.ctx
|
||||||
|
var inputText = config.text
|
||||||
|
var mul = config.fontSize / 40
|
||||||
|
var ura = false
|
||||||
|
|
||||||
|
if(inputText.endsWith(" (裏)")){
|
||||||
|
inputText = inputText.slice(0, -4)
|
||||||
|
ura = true
|
||||||
|
}else if(inputText.endsWith("(裏)")){
|
||||||
|
inputText = inputText.slice(0, -3)
|
||||||
|
ura = true
|
||||||
|
}
|
||||||
|
var string = inputText.split("")
|
||||||
|
var drawn = []
|
||||||
|
|
||||||
|
var r = this.regex
|
||||||
|
for(let symbol of string){
|
||||||
|
if(symbol === " "){
|
||||||
|
// Space
|
||||||
|
drawn.push({text: symbol, x: 0, y: 0, h: 18})
|
||||||
|
}else if(symbol === "ー"){
|
||||||
|
// Long-vowel mark
|
||||||
|
drawn.push({svg: this.longVowelMark, x: -4, y: 5, h: 33, scale: [mul, mul]})
|
||||||
|
}else if(r.comma.test(symbol)){
|
||||||
|
// Comma, full stop
|
||||||
|
drawn.push({text: symbol, x: 16, y: -7, h: 0, scale: [1.2, 0.7]})
|
||||||
|
}else if(r.ideographicComma.test(symbol)){
|
||||||
|
// Ideographic comma, full stop
|
||||||
|
drawn.push({text: symbol, x: 16, y: -16, h: 18})
|
||||||
|
}else if(r.apostrophe.test(symbol)){
|
||||||
|
// Apostrophe
|
||||||
|
drawn.push({text: ",", x: 20, y: -39, h: 0, scale: [1.2, 0.7]})
|
||||||
|
}else if(r.brackets.test(symbol)){
|
||||||
|
// Rotated brackets
|
||||||
|
drawn.push({text: symbol, x: 0, y: -5, h: 25, rotate: true})
|
||||||
|
}else if(r.tilde.test(symbol)){
|
||||||
|
// Rotated hyphen, tilde
|
||||||
|
if(symbol === "~"){
|
||||||
|
symbol = "~"
|
||||||
|
}
|
||||||
|
drawn.push({text: symbol, x: 0, y: 2, h: 35, rotate: true})
|
||||||
|
}else if(r.tall.test(symbol)){
|
||||||
|
// Tall latin script lowercase, numbers
|
||||||
|
drawn.push({text: symbol, x: 0, y: 4, h: 34, scale: [1.05, 0.9]})
|
||||||
|
}else if(r.uppercase.test(symbol)){
|
||||||
|
// Latin script upper case
|
||||||
|
drawn.push({text: symbol, x: 0, y: 8, h: 37})
|
||||||
|
}else if(r.lowercase.test(symbol)){
|
||||||
|
// Latin script lower case
|
||||||
|
drawn.push({text: symbol, x: 0, y: -1, h: 28, scale: [1.05, 0.9]})
|
||||||
|
}else if(r.smallHiragana.test(symbol)){
|
||||||
|
// Small hiragana, small katakana
|
||||||
|
drawn.push({text: symbol, x: 0, y: -8, h: 25, right: true})
|
||||||
|
}else if(r.hiragana.test(symbol)){
|
||||||
|
// Hiragana, katakana
|
||||||
|
drawn.push({text: symbol, x: 0, y: 5, h: 38, right: r.todo.test(symbol)})
|
||||||
|
}else{
|
||||||
|
// Kanji, other
|
||||||
|
drawn.push({text: symbol, x: 0, y: 3, h: 39, right: true})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var drawnHeight = 0
|
||||||
|
for(let symbol of drawn){
|
||||||
|
if(config.letterSpacing){
|
||||||
|
symbol.h += config.letterSpacing
|
||||||
|
}
|
||||||
|
drawnHeight += symbol.h * mul
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.save()
|
||||||
|
ctx.translate(config.x, config.y)
|
||||||
|
|
||||||
|
var scale = 1
|
||||||
|
if(config.height){
|
||||||
|
var height = config.height - (ura ? 52 * mul : 0)
|
||||||
|
if(drawnHeight > height){
|
||||||
|
scale = height / drawnHeight
|
||||||
|
ctx.scale(1, scale)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ura){
|
||||||
|
// Circled ura
|
||||||
|
drawn.push({text: "裏", x: 0, y: 18, h: 52, ura: true, scale: [1, 1 / scale]})
|
||||||
|
}
|
||||||
|
|
||||||
|
var actions = []
|
||||||
|
if(config.outline){
|
||||||
|
actions.push("stroke")
|
||||||
|
}
|
||||||
|
if(config.fill){
|
||||||
|
actions.push("fill")
|
||||||
|
}
|
||||||
|
for(let action of actions){
|
||||||
|
ctx.font = config.fontSize + "px " + config.fontFamily
|
||||||
|
ctx.textBaseline = "top"
|
||||||
|
if(action === "stroke"){
|
||||||
|
ctx.strokeStyle = config.outline
|
||||||
|
ctx.lineWidth = config.outlineSize * mul
|
||||||
|
ctx.lineJoin = "round"
|
||||||
|
ctx.miterLimit = 1
|
||||||
|
}else if(action === "fill"){
|
||||||
|
ctx.fillStyle = config.fill
|
||||||
|
}
|
||||||
|
var offsetY = 0
|
||||||
|
|
||||||
|
for(let symbol of drawn){
|
||||||
|
var saved = false
|
||||||
|
var currentX = symbol.x
|
||||||
|
if(symbol.right){
|
||||||
|
currentX += 20 * mul
|
||||||
|
}
|
||||||
|
var currentY = offsetY + symbol.y * mul
|
||||||
|
if(symbol.rotate || symbol.scale || symbol.svg || symbol.ura){
|
||||||
|
saved = true
|
||||||
|
ctx.save()
|
||||||
|
|
||||||
|
if(symbol.rotate){
|
||||||
|
ctx.translate(currentX + 20 * mul, currentY + 20 * mul)
|
||||||
|
ctx.rotate(Math.PI / 2)
|
||||||
|
}else{
|
||||||
|
ctx.translate(currentX, currentY)
|
||||||
|
}
|
||||||
|
if(symbol.scale){
|
||||||
|
ctx.scale(symbol.scale[0], symbol.scale[1])
|
||||||
|
ctx.lineWidth = ctx.lineWidth / symbol.scale[0]
|
||||||
|
}
|
||||||
|
currentX = 0
|
||||||
|
currentY = 0
|
||||||
|
}
|
||||||
|
if(symbol.svg){
|
||||||
|
ctx[action](symbol.svg)
|
||||||
|
}else{
|
||||||
|
if(symbol.right){
|
||||||
|
ctx.textAlign = "right"
|
||||||
|
}else{
|
||||||
|
ctx.textAlign = "center"
|
||||||
|
}
|
||||||
|
if(symbol.ura){
|
||||||
|
ctx.font = (30 * mul) + "px Meiryo"
|
||||||
|
ctx.textBaseline = "center"
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.arc(currentX, currentY + (21.5 * mul), (18 * mul), 0, Math.PI * 2)
|
||||||
|
if(action === "stroke"){
|
||||||
|
ctx.fillStyle = config.outline
|
||||||
|
ctx.fill()
|
||||||
|
}else if(action === "fill"){
|
||||||
|
ctx.strokeStyle = config.fill
|
||||||
|
ctx.lineWidth = 2.5 * mul
|
||||||
|
ctx.fillText(symbol.text, currentX, currentY)
|
||||||
|
}
|
||||||
|
ctx.stroke()
|
||||||
|
}else{
|
||||||
|
ctx[action + "Text"](symbol.text, currentX, currentY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offsetY += symbol.h * mul
|
||||||
|
if(saved){
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
layeredText(config, layers){
|
||||||
|
var ctx = config.ctx
|
||||||
|
var mul = config.fontSize / 40
|
||||||
|
ctx.save()
|
||||||
|
|
||||||
|
var string = config.text.split("")
|
||||||
|
if(config.align === "right"){
|
||||||
|
string.reverse()
|
||||||
|
}
|
||||||
|
var drawn = []
|
||||||
|
|
||||||
|
var r = this.regex
|
||||||
|
for(let symbol of string){
|
||||||
|
if(symbol === "-"){
|
||||||
|
drawn.push({text: symbol, x: -4, y: 0, w: 28, scale: [0.8, 1]})
|
||||||
|
}else if(symbol === "™"){
|
||||||
|
drawn.push({text: symbol, x: -2, y: 0, w: 20, scale: [0.6, 0.5]})
|
||||||
|
}else if(symbol === " "){
|
||||||
|
drawn.push({text: symbol, x: 0, y: 0, w: 10})
|
||||||
|
}else if(r.en.test(symbol)){
|
||||||
|
// n-width
|
||||||
|
drawn.push({text: symbol, x: 0, y: 0, w: 28, scale: [1, 0.95]})
|
||||||
|
}else if(r.em.test(symbol)){
|
||||||
|
// m-width
|
||||||
|
drawn.push({text: symbol, x: 0, y: 0, w: 38, scale: [1, 0.95]})
|
||||||
|
}else if(r.rWidth.test(symbol)){
|
||||||
|
// r-width
|
||||||
|
drawn.push({text: symbol, x: 0, y: 0, w: 24, scale: [1, 0.95]})
|
||||||
|
}else if(r.lWidth.test(symbol)){
|
||||||
|
// l-width
|
||||||
|
drawn.push({text: symbol, x: 0, y: -1, w: 12, scale: [1, 0.95]})
|
||||||
|
}else if(r.emCap.test(symbol)){
|
||||||
|
// m-width uppercase
|
||||||
|
drawn.push({text: symbol, x: 0, y: -2, w: 38})
|
||||||
|
}else if(r.uppercaseDigit.test(symbol)){
|
||||||
|
// Latin script uppercase, digits
|
||||||
|
drawn.push({text: symbol, x: 0, y: -2, w: 32})
|
||||||
|
}else if(r.smallHiragana.test(symbol)){
|
||||||
|
// Small hiragana, small katakana
|
||||||
|
drawn.push({text: symbol, x: 0, y: 0, w: 30})
|
||||||
|
}else if(r.hiragana.test(symbol)){
|
||||||
|
// Hiragana, katakana
|
||||||
|
drawn.push({text: symbol, x: 0, y: 0, w: 35})
|
||||||
|
}else{
|
||||||
|
drawn.push({text: symbol, x: 0, y: 0, w: 39})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var drawnWidth = 0
|
||||||
|
for(let symbol of drawn){
|
||||||
|
if(config.letterSpacing){
|
||||||
|
symbol.w += config.letterSpacing
|
||||||
|
}
|
||||||
|
drawnWidth += symbol.w
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.translate(config.x, config.y)
|
||||||
|
var scale = 1
|
||||||
|
if(config.width && drawnWidth > config.width){
|
||||||
|
scale = config.width / drawnWidth
|
||||||
|
ctx.scale(scale, 1)
|
||||||
|
}
|
||||||
|
ctx.font = config.fontSize + "px " + config.fontFamily
|
||||||
|
ctx.textBaseline = "top"
|
||||||
|
ctx.textAlign = "center"
|
||||||
|
|
||||||
|
for(let layer of layers){
|
||||||
|
var action = "strokeText"
|
||||||
|
if(layer.outline){
|
||||||
|
ctx.strokeStyle = layer.outline
|
||||||
|
ctx.lineJoin = "round"
|
||||||
|
ctx.miterLimit = 1
|
||||||
|
}
|
||||||
|
if(layer.letterBorder){
|
||||||
|
ctx.lineWidth = layer.letterBorder
|
||||||
|
}
|
||||||
|
if(layer.fill){
|
||||||
|
ctx.fillStyle = layer.fill
|
||||||
|
action = "fillText"
|
||||||
|
}
|
||||||
|
if(layer.shadow){
|
||||||
|
ctx.save()
|
||||||
|
ctx.shadowOffsetX = layer.shadow[0]
|
||||||
|
ctx.shadowOffsetY = layer.shadow[1]
|
||||||
|
ctx.shadowBlur = layer.shadow[2]
|
||||||
|
ctx.shadowColor = "rgba(0, 0, 0, " + (1 / (layer.shadow[3] || 2)) + ")"
|
||||||
|
}
|
||||||
|
var offsetX = 0
|
||||||
|
for(let symbol of drawn){
|
||||||
|
var saved = false
|
||||||
|
var currentX = offsetX + symbol.x + (layer.x || 0) + symbol.w / 2
|
||||||
|
var currentY = symbol.y + (layer.y || 0)
|
||||||
|
var isLatin = r.latin.test(symbol.text)
|
||||||
|
|
||||||
|
if(config.align === "center"){
|
||||||
|
currentX -= drawnWidth / 2
|
||||||
|
}else if(config.align === "right"){
|
||||||
|
currentX = -offsetX + symbol.x + (layer.x || 0) - symbol.w / 2
|
||||||
|
}
|
||||||
|
if(symbol.scale || isLatin){
|
||||||
|
saved = true
|
||||||
|
ctx.save()
|
||||||
|
ctx.translate(currentX, currentY)
|
||||||
|
if(symbol.scale){
|
||||||
|
ctx.scale(symbol.scale[0], symbol.scale[1])
|
||||||
|
ctx.lineWidth /= symbol.scale[0]
|
||||||
|
}
|
||||||
|
currentX = 0
|
||||||
|
currentY = 0
|
||||||
|
}
|
||||||
|
if(isLatin){
|
||||||
|
if(action === "strokeText"){
|
||||||
|
ctx.lineWidth *= 1.05
|
||||||
|
ctx.strokeText(symbol.text, currentX, currentY)
|
||||||
|
}else{
|
||||||
|
ctx.lineWidth *= 0.05
|
||||||
|
ctx.strokeStyle = ctx.fillStyle
|
||||||
|
ctx.strokeText(symbol.text, currentX, currentY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx[action](symbol.text, currentX, currentY)
|
||||||
|
if(saved){
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
offsetX += symbol.w * mul
|
||||||
|
}
|
||||||
|
if(layer.shadow){
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
diffIcon(config){
|
||||||
|
var ctx = config.ctx
|
||||||
|
var scale = config.scale
|
||||||
|
ctx.save()
|
||||||
|
ctx.lineWidth = config.border
|
||||||
|
ctx.strokeStyle = "#000"
|
||||||
|
var icon = this.diffIconPath[config.diff]
|
||||||
|
ctx.translate(config.x - icon[0].w * scale / 2, config.y - icon[0].h * scale / 2)
|
||||||
|
ctx.scale(scale, scale)
|
||||||
|
for(var i = 1; i < icon.length; i++){
|
||||||
|
if(!icon[i].noStroke){
|
||||||
|
ctx.stroke(icon[i].d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!config.noFill){
|
||||||
|
for(var i = 1; i < icon.length; i++){
|
||||||
|
ctx.fillStyle = icon[i].fill
|
||||||
|
ctx.fill(icon[i].d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
diffOptionsIcon(config){
|
||||||
|
var ctx = config.ctx
|
||||||
|
ctx.save()
|
||||||
|
ctx.translate(config.x - 21, config.y - 21)
|
||||||
|
|
||||||
|
var drawLine = y => {
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.moveTo(12, y)
|
||||||
|
ctx.arc(20.5, 25, 8.5, Math.PI, Math.PI * 2, true)
|
||||||
|
ctx.lineTo(29, 18)
|
||||||
|
ctx.stroke()
|
||||||
|
}
|
||||||
|
var drawTriangle = noFill => {
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.moveTo(29, 5)
|
||||||
|
ctx.lineTo(21, 19)
|
||||||
|
ctx.lineTo(37, 19)
|
||||||
|
ctx.closePath()
|
||||||
|
if(!noFill){
|
||||||
|
ctx.fill()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.strokeStyle = "#000"
|
||||||
|
ctx.lineWidth = 12
|
||||||
|
drawLine(9)
|
||||||
|
ctx.lineWidth = 5
|
||||||
|
drawTriangle(true)
|
||||||
|
ctx.stroke()
|
||||||
|
ctx.lineWidth = 7
|
||||||
|
ctx.fillStyle = "#fff"
|
||||||
|
ctx.strokeStyle = "#fff"
|
||||||
|
drawLine(11)
|
||||||
|
drawTriangle()
|
||||||
|
ctx.translate(-1.5, -0.5)
|
||||||
|
ctx.fillStyle = "#23a6e1"
|
||||||
|
ctx.strokeStyle = "#23a6e1"
|
||||||
|
ctx.globalCompositeOperation = "darken"
|
||||||
|
drawLine(11)
|
||||||
|
drawTriangle()
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
diffCursor(config){
|
||||||
|
var ctx = config.ctx
|
||||||
|
ctx.save()
|
||||||
|
if(config.scale){
|
||||||
|
ctx.translate(config.x, config.y)
|
||||||
|
ctx.scale(config.scale, config.scale)
|
||||||
|
ctx.translate(-48, -64)
|
||||||
|
}else{
|
||||||
|
ctx.translate(config.x - 48, config.y - 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.fillStyle = config.two ? "#65cdcd" : "#ff411c"
|
||||||
|
ctx.strokeStyle = "#000"
|
||||||
|
ctx.lineWidth = 6
|
||||||
|
ctx.beginPath()
|
||||||
|
if(!config.side){
|
||||||
|
var textX = config.two ? 20 : 17
|
||||||
|
ctx.moveTo(48, 120)
|
||||||
|
ctx.arc(48, 48.5, 45, Math.PI * 0.58, Math.PI * 0.42)
|
||||||
|
}else if(config.two){
|
||||||
|
var textX = 70
|
||||||
|
ctx.moveTo(56, 115)
|
||||||
|
ctx.arc(98, 48.5, 45, Math.PI * 0.75, Math.PI * 0.59)
|
||||||
|
}else{
|
||||||
|
var textX = -33
|
||||||
|
ctx.moveTo(39, 115)
|
||||||
|
ctx.arc(-2, 48.5, 45, Math.PI * 0.41, Math.PI * 0.25)
|
||||||
|
}
|
||||||
|
ctx.closePath()
|
||||||
|
ctx.fill()
|
||||||
|
ctx.stroke()
|
||||||
|
this.layeredText({
|
||||||
|
ctx: ctx,
|
||||||
|
text: config.two ? "2P" : "1P",
|
||||||
|
fontSize: 43,
|
||||||
|
fontFamily: config.font,
|
||||||
|
x: textX,
|
||||||
|
y: 26,
|
||||||
|
width: 54,
|
||||||
|
letterSpacing: -4
|
||||||
|
}, [
|
||||||
|
{outline: "#fff", letterBorder: 11},
|
||||||
|
{fill: "#000"}
|
||||||
|
])
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
diffStar(config){
|
||||||
|
var ctx = config.ctx
|
||||||
|
ctx.save()
|
||||||
|
ctx.fillStyle = config.songSel ? "#fff" : "#f72568"
|
||||||
|
if(config.songSel){
|
||||||
|
ctx.shadowColor = "#fff"
|
||||||
|
ctx.shadowBlur = 10
|
||||||
|
ctx.translate(config.x - 9, config.y - 9)
|
||||||
|
}else{
|
||||||
|
ctx.translate(config.x - 10.5, config.y - 9.5)
|
||||||
|
ctx.scale(1.1, 1.1)
|
||||||
|
}
|
||||||
|
ctx.fill(this.diffStarPath)
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern(config){
|
||||||
|
var ctx = config.ctx
|
||||||
|
ctx.save()
|
||||||
|
var mul = config.scale || 1
|
||||||
|
|
||||||
|
if(mul !== 1){
|
||||||
|
ctx.scale(1 / mul, 1 / mul)
|
||||||
|
}
|
||||||
|
ctx.fillStyle = ctx.createPattern(config.img, "repeat")
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.rect(config.x * mul, config.y * mul, config.w * mul, config.h * mul)
|
||||||
|
ctx.translate(config.dx, config.dy)
|
||||||
|
ctx.fill()
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
score(config){
|
||||||
|
var ctx = config.ctx
|
||||||
|
ctx.save()
|
||||||
|
|
||||||
|
ctx.translate(config.x, config.y)
|
||||||
|
if(config.scale){
|
||||||
|
ctx.scale(config.scale, config.scale)
|
||||||
|
}
|
||||||
|
ctx.strokeStyle = "#000"
|
||||||
|
ctx.lineWidth = 7
|
||||||
|
if(config.score === "good"){
|
||||||
|
var grd = ctx.createLinearGradient(0, 0, 0, 29)
|
||||||
|
grd.addColorStop(0.3, "#f7fb00")
|
||||||
|
grd.addColorStop(0.9, "#ff4900")
|
||||||
|
ctx.fillStyle = grd
|
||||||
|
ctx.stroke(this.diffPath.good)
|
||||||
|
ctx.fill(this.diffPath.good)
|
||||||
|
}else if(config.score === "ok"){
|
||||||
|
ctx.fillStyle = "#fff"
|
||||||
|
ctx.stroke(this.diffPath.ok)
|
||||||
|
ctx.fill(this.diffPath.ok)
|
||||||
|
}else if(config.score === "bad"){
|
||||||
|
var grd = ctx.createLinearGradient(0, 0, 0, 27)
|
||||||
|
grd.addColorStop(0.1, "#6B5DFF")
|
||||||
|
grd.addColorStop(0.7, "#00AEDE")
|
||||||
|
ctx.fillStyle = grd
|
||||||
|
ctx.stroke(this.diffPath.bad)
|
||||||
|
ctx.fill(this.diffPath.bad)
|
||||||
|
ctx.translate(26, 0)
|
||||||
|
ctx.stroke(this.diffPath.ok)
|
||||||
|
ctx.fill(this.diffPath.ok)
|
||||||
|
}
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
crown(config){
|
||||||
|
var ctx = config.ctx
|
||||||
|
ctx.save()
|
||||||
|
|
||||||
|
ctx.translate(config.x, config.y)
|
||||||
|
if(config.scale){
|
||||||
|
ctx.scale(config.scale, config.scale)
|
||||||
|
}
|
||||||
|
ctx.translate(-47, -39)
|
||||||
|
ctx.miterLimit = 1.7
|
||||||
|
|
||||||
|
ctx.save()
|
||||||
|
ctx.strokeStyle = "#fff"
|
||||||
|
ctx.lineWidth = 35
|
||||||
|
ctx.filter = "blur(1.5px)"
|
||||||
|
ctx.stroke(this.crownPath)
|
||||||
|
ctx.restore()
|
||||||
|
|
||||||
|
if(config.shine){
|
||||||
|
ctx.strokeStyle = "#fff"
|
||||||
|
ctx.lineWidth = 18
|
||||||
|
ctx.stroke(this.crownPath)
|
||||||
|
ctx.globalAlpha = 1 - config.shine
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.strokeStyle = "#000"
|
||||||
|
ctx.lineWidth = 18
|
||||||
|
ctx.stroke(this.crownPath)
|
||||||
|
|
||||||
|
if(config.shine){
|
||||||
|
ctx.globalAlpha = 1
|
||||||
|
ctx.fillStyle = "#fff"
|
||||||
|
ctx.fill(this.crownPath)
|
||||||
|
ctx.globalAlpha = 1 - config.shine
|
||||||
|
}
|
||||||
|
|
||||||
|
var grd = ctx.createLinearGradient(0, 0, 94, 0)
|
||||||
|
if(config.type === "gold"){
|
||||||
|
grd.addColorStop(0, "#ffffc5")
|
||||||
|
grd.addColorStop(0.23, "#ffff44")
|
||||||
|
grd.addColorStop(0.53, "#efbd12")
|
||||||
|
grd.addColorStop(0.83, "#ffff44")
|
||||||
|
grd.addColorStop(1, "#efbd12")
|
||||||
|
}else if(config.type === "silver"){
|
||||||
|
grd.addColorStop(0, "#d6efef")
|
||||||
|
grd.addColorStop(0.23, "#bddfde")
|
||||||
|
grd.addColorStop(0.53, "#97c1c0")
|
||||||
|
grd.addColorStop(0.83, "#bddfde")
|
||||||
|
grd.addColorStop(1, "#97c1c0")
|
||||||
|
}
|
||||||
|
ctx.fillStyle = grd
|
||||||
|
ctx.fill(this.crownPath)
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
alpha(amount, ctx, callback){
|
||||||
|
if(amount >= 1){
|
||||||
|
return callback(ctx)
|
||||||
|
}else if(amount >= 0){
|
||||||
|
this.tmpCanvas.width = ctx.canvas.width
|
||||||
|
this.tmpCanvas.height = ctx.canvas.height
|
||||||
|
callback(this.tmpCtx)
|
||||||
|
ctx.save()
|
||||||
|
ctx.globalAlpha = amount
|
||||||
|
ctx.drawImage(this.tmpCanvas, 0, 0)
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getMS(){
|
||||||
|
return +new Date
|
||||||
|
}
|
||||||
|
}
|
@ -100,6 +100,10 @@ class Controller{
|
|||||||
this.view.refresh()
|
this.view.refresh()
|
||||||
}
|
}
|
||||||
this.keyboard.checkMenuKeys()
|
this.keyboard.checkMenuKeys()
|
||||||
|
|
||||||
|
if(this.scoresheet){
|
||||||
|
this.scoresheet.redraw()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
togglePauseMenu(){
|
togglePauseMenu(){
|
||||||
@ -109,10 +113,10 @@ class Controller{
|
|||||||
gameEnded(){
|
gameEnded(){
|
||||||
var score = this.getGlobalScore()
|
var score = this.getGlobalScore()
|
||||||
var vp
|
var vp
|
||||||
if(score.fail === 0){
|
if(score.bad === 0){
|
||||||
vp = "fullcombo"
|
vp = "fullcombo"
|
||||||
this.playSoundMeka("fullcombo", 1.350)
|
this.playSoundMeka("fullcombo", 1.350)
|
||||||
}else if(score.hp >= 50){
|
}else if(score.gauge >= 50){
|
||||||
vp = "clear"
|
vp = "clear"
|
||||||
}else{
|
}else{
|
||||||
vp = "fail"
|
vp = "fail"
|
||||||
@ -120,17 +124,18 @@ class Controller{
|
|||||||
assets.sounds["game" + vp].play()
|
assets.sounds["game" + vp].play()
|
||||||
}
|
}
|
||||||
displayResults(){
|
displayResults(){
|
||||||
this.clean()
|
|
||||||
if(this.multiplayer !== 2){
|
if(this.multiplayer !== 2){
|
||||||
new Scoresheet(this, this.getGlobalScore(), this.multiplayer)
|
this.scoresheet = new Scoresheet(this, this.getGlobalScore(), this.multiplayer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
displayScore(score, notPlayed){
|
displayScore(score, notPlayed){
|
||||||
this.view.displayScore(score, notPlayed)
|
this.view.displayScore(score, notPlayed)
|
||||||
}
|
}
|
||||||
songSelection(){
|
songSelection(fadeIn){
|
||||||
|
if(!fadeIn){
|
||||||
this.clean()
|
this.clean()
|
||||||
new SongSelect()
|
}
|
||||||
|
new SongSelect(false, fadeIn)
|
||||||
}
|
}
|
||||||
restartSong(){
|
restartSong(){
|
||||||
this.clean()
|
this.clean()
|
||||||
|
@ -6,15 +6,17 @@ class Game{
|
|||||||
this.elapsedTime = {}
|
this.elapsedTime = {}
|
||||||
this.currentCircle = 0
|
this.currentCircle = 0
|
||||||
this.combo = 0
|
this.combo = 0
|
||||||
|
this.rules = new GameRules(this)
|
||||||
this.globalScore = {
|
this.globalScore = {
|
||||||
points: 0,
|
points: 0,
|
||||||
great: 0,
|
|
||||||
good: 0,
|
good: 0,
|
||||||
fail: 0,
|
ok: 0,
|
||||||
|
bad: 0,
|
||||||
maxCombo: 0,
|
maxCombo: 0,
|
||||||
drumroll: 0,
|
drumroll: 0,
|
||||||
hp: 0,
|
gauge: 0,
|
||||||
song: selectedSong.title
|
title: selectedSong.title,
|
||||||
|
difficulty: this.rules.difficulty
|
||||||
}
|
}
|
||||||
this.HPGain = 100 / this.songData.circles.filter(circle => {
|
this.HPGain = 100 / this.songData.circles.filter(circle => {
|
||||||
var type = circle.getType()
|
var type = circle.getType()
|
||||||
@ -28,7 +30,6 @@ class Game{
|
|||||||
this.fadeOutStarted = false
|
this.fadeOutStarted = false
|
||||||
this.currentTimingPoint = 0
|
this.currentTimingPoint = 0
|
||||||
this.offsetTime = 0
|
this.offsetTime = 0
|
||||||
this.rules = new GameRules(this)
|
|
||||||
|
|
||||||
assets.songs.forEach(song => {
|
assets.songs.forEach(song => {
|
||||||
if(song.id == selectedSong.folder){
|
if(song.id == selectedSong.folder){
|
||||||
@ -291,6 +292,11 @@ class Game{
|
|||||||
}else if(this.musicFadeOut === 2 && (ms >= started + 8600 && ms >= this.controller.mainAsset.duration * 1000 + 250)){
|
}else if(this.musicFadeOut === 2 && (ms >= started + 8600 && ms >= this.controller.mainAsset.duration * 1000 + 250)){
|
||||||
this.controller.displayResults()
|
this.controller.displayResults()
|
||||||
this.musicFadeOut++
|
this.musicFadeOut++
|
||||||
|
}else if(this.musicFadeOut === 3 && (ms >= started + 9600 && ms >= this.controller.mainAsset.duration * 1000 + 1250)){
|
||||||
|
if(this.controller.scoresheet){
|
||||||
|
this.controller.scoresheet.startRedraw()
|
||||||
|
}
|
||||||
|
this.controller.clean()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -394,22 +400,22 @@ class Game{
|
|||||||
// Circle score
|
// Circle score
|
||||||
switch(score){
|
switch(score){
|
||||||
case 450:
|
case 450:
|
||||||
this.globalScore.great++
|
|
||||||
break
|
|
||||||
case 230:
|
|
||||||
this.globalScore.good++
|
this.globalScore.good++
|
||||||
break
|
break
|
||||||
|
case 230:
|
||||||
|
this.globalScore.ok++
|
||||||
|
break
|
||||||
case 0:
|
case 0:
|
||||||
this.globalScore.fail++
|
this.globalScore.bad++
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// HP Update
|
// Gauge update
|
||||||
if(score !== 0){
|
if(score !== 0){
|
||||||
this.globalScore.hp += this.HPGain
|
this.globalScore.gauge += this.HPGain
|
||||||
}else if(this.globalScore.hp - this.HPGain > 0){
|
}else if(this.globalScore.gauge - this.HPGain > 0){
|
||||||
this.globalScore.hp -= this.HPGain
|
this.globalScore.gauge -= this.HPGain
|
||||||
}else{
|
}else{
|
||||||
this.globalScore.hp = 0
|
this.globalScore.gauge = 0
|
||||||
}
|
}
|
||||||
// Points update
|
// Points update
|
||||||
score += Math.max(0, Math.floor((Math.min(this.combo, 100) - 1) / 10) * 100)
|
score += Math.max(0, Math.floor((Math.min(this.combo, 100) - 1) / 10) * 100)
|
||||||
|
@ -1,139 +1,530 @@
|
|||||||
class Scoresheet{
|
class Scoresheet{
|
||||||
constructor(controller, score, multiplayer){
|
constructor(controller, results, multiplayer){
|
||||||
this.controller = controller
|
this.controller = controller
|
||||||
this.score = score
|
this.results = results
|
||||||
this.multiplayer = multiplayer
|
this.multiplayer = multiplayer
|
||||||
loader.changePage("scoresheet")
|
|
||||||
this.run()
|
this.canvas = document.getElementById("canvas")
|
||||||
|
this.ctx = this.canvas.getContext("2d")
|
||||||
|
|
||||||
|
this.font = "TnT"
|
||||||
|
this.state = {
|
||||||
|
screen: "fadeIn",
|
||||||
|
screenMS: this.getMS(),
|
||||||
|
startDelay: 3300,
|
||||||
|
hasPointer: 0
|
||||||
}
|
}
|
||||||
setResults(score, scoreCont){
|
this.draw = new CanvasDraw()
|
||||||
this.positionning(scoreCont)
|
|
||||||
var scoreMark = this.elem("score-mark", scoreCont)
|
|
||||||
var scoreHpBarColour = this.elem("score-hp-bar-colour", scoreCont)
|
|
||||||
|
|
||||||
if(score.fail == 0){
|
|
||||||
var mark = "gold"
|
|
||||||
}else if (score.hp >= 50){
|
|
||||||
var mark = "silver"
|
|
||||||
}
|
|
||||||
scoreHpBarColour.dataset.hp = score.hp
|
|
||||||
var imgW = score.hp * scoreHpBarColour.offsetWidth / 100
|
|
||||||
var imgH = scoreHpBarColour.offsetHeight
|
|
||||||
scoreHpBarColour.getElementsByTagName("img")[0].style.clip = "rect(0, " + imgW + "px, " + imgH + "px, 0)"
|
|
||||||
|
|
||||||
if(mark == "gold"){
|
|
||||||
scoreMark.src = "/assets/img/ranking-X.png"
|
|
||||||
}else if(mark == "silver"){
|
|
||||||
scoreMark.src = "/assets/img/ranking-S.png"
|
|
||||||
}else{
|
|
||||||
scoreMark.parentNode.removeChild(scoreMark)
|
|
||||||
}
|
|
||||||
this.altText(this.elem("score-points", scoreCont), score.points + "点")
|
|
||||||
this.altText(this.elem("nb-great", scoreCont), score.great)
|
|
||||||
this.altText(this.elem("nb-good", scoreCont), score.good)
|
|
||||||
this.altText(this.elem("nb-fail", scoreCont), score.fail)
|
|
||||||
this.altText(this.elem("max-combo", scoreCont), score.maxCombo)
|
|
||||||
this.altText(this.elem("nb-drumroll", scoreCont), score.drumroll)
|
|
||||||
|
|
||||||
pageEvents.add(window, "resize", () => {
|
|
||||||
this.positionning(scoreCont)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
elem(className, parent){
|
|
||||||
return parent.getElementsByClassName(className)[0]
|
|
||||||
}
|
|
||||||
text(string){
|
|
||||||
return document.createTextNode(string)
|
|
||||||
}
|
|
||||||
altText(element, string){
|
|
||||||
element.appendChild(this.text(string))
|
|
||||||
element.setAttribute("alt", string)
|
|
||||||
}
|
|
||||||
positionning(scoreCont){
|
|
||||||
var scoreHpBarBg = this.elem("score-hp-bar-bg", scoreCont)
|
|
||||||
var scoreHpBarColour = this.elem("score-hp-bar-colour", scoreCont)
|
|
||||||
|
|
||||||
var scoreBarW = scoreCont.offsetWidth * 0.9
|
|
||||||
var bgW = scoreBarW
|
|
||||||
var bgH = 51 / 703 * scoreBarW
|
|
||||||
|
|
||||||
scoreHpBarBg.style.width = bgW + "px"
|
|
||||||
scoreHpBarBg.style.height = bgH + "px"
|
|
||||||
var bgX = scoreHpBarBg.offsetLeft
|
|
||||||
var bgY = scoreHpBarBg.offsetTop
|
|
||||||
|
|
||||||
scoreHpBarColour.style.left = (bgW * 0.008) + "px"
|
|
||||||
scoreHpBarColour.style.top = (bgH * 0.15) + "px"
|
|
||||||
scoreHpBarColour.style.width = (bgW - bgW * 0.08) + "px"
|
|
||||||
scoreHpBarColour.style.height = (bgH - bgH * 0.25) + "px"
|
|
||||||
|
|
||||||
var imgW = scoreHpBarColour.dataset.hp * scoreHpBarColour.offsetWidth / 100
|
|
||||||
var imgH = scoreHpBarColour.offsetHeight
|
|
||||||
scoreHpBarColour.getElementsByTagName("img")[0].style.clip = "rect(0, " + imgW + "px, " + imgH + "px, 0)"
|
|
||||||
}
|
|
||||||
run(){
|
|
||||||
this.scoresheet = document.getElementsByClassName("scoresheet")[0]
|
|
||||||
var scoreCont = this.elem("score-cont", this.scoresheet)
|
|
||||||
var scoreContHtml = scoreCont.innerHTML
|
|
||||||
assets.sounds["results"].play()
|
|
||||||
assets.sounds["bgm_result"].playLoop(0.1, false, 0, 0.847, 17.689)
|
|
||||||
|
|
||||||
this.setResults(this.score, scoreCont)
|
|
||||||
this.altText(this.elem("result-song", this.scoresheet), this.score.song)
|
|
||||||
|
|
||||||
this.songSelect = this.elem("song-select", this.scoresheet)
|
|
||||||
this.replay = this.elem("replay", this.scoresheet)
|
|
||||||
pageEvents.once(this.songSelect, "click").then(() => {
|
|
||||||
this.clean()
|
|
||||||
assets.sounds["don"].play()
|
|
||||||
this.controller.songSelection()
|
|
||||||
})
|
|
||||||
pageEvents.once(this.elem("replay", this.scoresheet), "click").then(() => {
|
|
||||||
this.clean()
|
|
||||||
assets.sounds["don"].play()
|
|
||||||
this.controller.restartSong()
|
|
||||||
})
|
|
||||||
pageEvents.keyAdd(this, "all", "down", this.keyDown.bind(this))
|
|
||||||
this.gamepad = new Gamepad({
|
this.gamepad = new Gamepad({
|
||||||
"13": ["b", "start"],
|
"13": ["a", "b", "start"]
|
||||||
"37": ["l", "r", "lb", "lt", "rb", "rt"]
|
|
||||||
}, (pressed, key) => {
|
|
||||||
if(pressed){
|
|
||||||
this.keyDown(false, key)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if(this.multiplayer && p2.results){
|
this.redrawRunning = true
|
||||||
var scoreCont2 = document.createElement("div")
|
this.redrawBind = this.redraw.bind(this)
|
||||||
scoreCont2.classList.add("score-cont")
|
this.redraw()
|
||||||
scoreCont2.innerHTML = scoreContHtml
|
pageEvents.keyAdd(this, "all", "down", this.keyDown.bind(this))
|
||||||
scoreCont.parentNode.appendChild(scoreCont2)
|
pageEvents.add(this.canvas, "mousedown", this.mouseDown.bind(this))
|
||||||
this.setResults(p2.results, scoreCont2)
|
|
||||||
}
|
assets.sounds["results"].play()
|
||||||
|
assets.sounds["bgm_result"].playLoop(3, false, 0, 0.847, 17.689)
|
||||||
}
|
}
|
||||||
keyDown(event, code){
|
keyDown(event, code){
|
||||||
if(!code){
|
if(!code){
|
||||||
|
if(event.repeat){
|
||||||
|
return
|
||||||
|
}
|
||||||
code = event.keyCode
|
code = event.keyCode
|
||||||
}
|
}
|
||||||
var selected = this.elem("selected", this.scoresheet)
|
var key = {
|
||||||
if(code == 13 || code == 32 || code == 86 || code == 66){
|
confirm: code == 13 || code == 32 || code == 86 || code == 66,
|
||||||
// Enter, Space, V, B
|
// Enter, Space, V, B
|
||||||
selected.click()
|
cancel: code == 27 || code == 8
|
||||||
}else if(code == 37 || code == 39 || code == 67 || code == 78){
|
// Esc, Backspace
|
||||||
// Left, Right, C, N
|
|
||||||
assets.sounds["ka"].play()
|
|
||||||
selected.classList.remove("selected")
|
|
||||||
var next = selected.nextElementSibling
|
|
||||||
if(!next){
|
|
||||||
next = selected.previousElementSibling
|
|
||||||
}
|
}
|
||||||
next.classList.add("selected")
|
if(key.cancel && event){
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
if(key.confirm || key.cancel){
|
||||||
|
this.toNext()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mouseDown(event){
|
||||||
|
if(event.which !== 1){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.toNext()
|
||||||
|
}
|
||||||
|
toNext(){
|
||||||
|
var ms = this.getMS()
|
||||||
|
var elapsed = ms - this.state.screenMS - this.state.startDelay
|
||||||
|
if(this.state.screen === "fadeIn"){
|
||||||
|
if(elapsed >= 3400){
|
||||||
|
snd.musicGain.fadeOut(0.5)
|
||||||
|
this.state.screen = "fadeOut"
|
||||||
|
this.state.screenMS = ms
|
||||||
|
assets.sounds["don"].play()
|
||||||
|
}else if(elapsed >= 0 && elapsed <= 2400){
|
||||||
|
this.state.screenMS = ms - 2400 - this.state.startDelay
|
||||||
|
assets.sounds["don"].play()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startRedraw(){
|
||||||
|
this.redrawing = true
|
||||||
|
requestAnimationFrame(this.redrawBind)
|
||||||
|
this.winW = null
|
||||||
|
this.winH = null
|
||||||
|
}
|
||||||
|
|
||||||
|
redraw(){
|
||||||
|
if(!this.redrawRunning){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(this.redrawing){
|
||||||
|
requestAnimationFrame(this.redrawBind)
|
||||||
|
}
|
||||||
|
var ms = this.getMS()
|
||||||
|
|
||||||
|
this.gamepad.play((pressed, keyCode) => {
|
||||||
|
if(pressed){
|
||||||
|
this.keyDown(false, keyCode)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if(!this.redrawRunning){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctx = this.ctx
|
||||||
|
ctx.save()
|
||||||
|
|
||||||
|
var winW = innerWidth
|
||||||
|
var winH = innerHeight
|
||||||
|
this.pixelRatio = window.devicePixelRatio || 1
|
||||||
|
winW *= this.pixelRatio
|
||||||
|
winH *= this.pixelRatio
|
||||||
|
var ratioX = winW / 1280
|
||||||
|
var ratioY = winH / 720
|
||||||
|
var ratio = (ratioX < ratioY ? ratioX : ratioY)
|
||||||
|
|
||||||
|
if(this.redrawing){
|
||||||
|
if(this.winW !== winW || this.winH !== winH){
|
||||||
|
this.canvas.width = winW
|
||||||
|
this.canvas.height = winH
|
||||||
|
ctx.scale(ratio, ratio)
|
||||||
|
this.canvas.style.width = (winW / this.pixelRatio) + "px"
|
||||||
|
this.canvas.style.height = (winH / this.pixelRatio) + "px"
|
||||||
|
}else if(!document.hasFocus() && ms - this.state.screenMS - this.state.startDelay > 2400){
|
||||||
|
return
|
||||||
|
}else{
|
||||||
|
ctx.clearRect(0, 0, winW / ratio, winH / ratio)
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
ctx.scale(ratio, ratio)
|
||||||
|
}
|
||||||
|
this.winW = winW
|
||||||
|
this.winH = winH
|
||||||
|
this.ratio = ratio
|
||||||
|
winW /= ratio
|
||||||
|
winH /= ratio
|
||||||
|
|
||||||
|
var frameTop = winH / 2 - 720 / 2
|
||||||
|
var frameLeft = winW / 2 - 1280 / 2
|
||||||
|
|
||||||
|
var players = this.multiplayer && p2.results ? 2 : 1
|
||||||
|
var p2Offset = 298
|
||||||
|
|
||||||
|
var bgOffset = 0
|
||||||
|
var elapsed = ms - this.state.screenMS
|
||||||
|
if(this.state.screen === "fadeIn" && elapsed < 1000){
|
||||||
|
bgOffset = Math.min(1, this.draw.easeIn(1 - elapsed / 1000)) * (winH / 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bgOffset){
|
||||||
|
ctx.save()
|
||||||
|
ctx.translate(0, -bgOffset)
|
||||||
|
}
|
||||||
|
this.draw.pattern({
|
||||||
|
ctx: ctx,
|
||||||
|
img: assets.image["bg_score_p1"],
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
w: winW,
|
||||||
|
h: winH / 2,
|
||||||
|
dx: frameLeft - 35,
|
||||||
|
dy: frameTop + 17
|
||||||
|
})
|
||||||
|
ctx.fillStyle = "rgba(127, 28, 12, 0.5)"
|
||||||
|
ctx.fillRect(0, winH / 2 - 12, winW, 12)
|
||||||
|
ctx.fillStyle = "#000"
|
||||||
|
ctx.fillRect(0, winH / 2 - 2, winW, 3)
|
||||||
|
ctx.fillStyle = "#fa4529"
|
||||||
|
ctx.fillRect(0, 0, winW, frameTop + 64)
|
||||||
|
ctx.fillStyle = "#bf2900"
|
||||||
|
ctx.fillRect(0, frameTop + 64, winW, 8)
|
||||||
|
|
||||||
|
if(bgOffset){
|
||||||
|
ctx.restore()
|
||||||
|
ctx.save()
|
||||||
|
ctx.translate(0, bgOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.draw.pattern({
|
||||||
|
ctx: ctx,
|
||||||
|
img: assets.image[this.multiplayer ? "bg_score_p2" : "bg_score_p1"],
|
||||||
|
x: 0,
|
||||||
|
y: winH / 2,
|
||||||
|
w: winW,
|
||||||
|
h: winH / 2,
|
||||||
|
dx: frameLeft - 35,
|
||||||
|
dy: frameTop - 17
|
||||||
|
})
|
||||||
|
ctx.fillStyle = this.multiplayer ? "rgba(138, 245, 247, 0.5)" : "rgba(249, 163, 149, 0.5)"
|
||||||
|
ctx.fillRect(0, winH / 2, winW, 12)
|
||||||
|
ctx.fillStyle = "#000"
|
||||||
|
ctx.fillRect(0, winH / 2 - 1, winW, 3)
|
||||||
|
ctx.fillStyle = this.multiplayer ? "#6bbec0" : "#fa4529"
|
||||||
|
ctx.fillRect(0, winH - frameTop - 64, winW, frameTop + 64)
|
||||||
|
ctx.fillStyle = this.multiplayer ? "rgba(160, 228, 229, 0.8)" : "rgba(255, 144, 116, 0.8)"
|
||||||
|
ctx.fillRect(0, winH - frameTop - 72, winW, 7)
|
||||||
|
ctx.fillStyle = this.multiplayer ? "#a8e0e0" : "#ff9b7a"
|
||||||
|
ctx.fillRect(0, winH - frameTop - 66, winW, 2)
|
||||||
|
|
||||||
|
if(bgOffset){
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.state.screen === "fadeOut"){
|
||||||
|
var elapsed = 2400
|
||||||
|
}else{
|
||||||
|
var elapsed = ms - this.state.screenMS - this.state.startDelay
|
||||||
|
}
|
||||||
|
|
||||||
|
if(elapsed >= 0){
|
||||||
|
if(this.state.hasPointer === 0){
|
||||||
|
this.state.hasPointer = 1
|
||||||
|
this.canvas.style.cursor = "pointer"
|
||||||
|
}
|
||||||
|
ctx.save()
|
||||||
|
ctx.setTransform(1, 0, 0, 1, 0, 0)
|
||||||
|
this.draw.alpha(Math.min(1, elapsed / 400), ctx, ctx => {
|
||||||
|
ctx.scale(ratio, ratio)
|
||||||
|
ctx.translate(frameLeft, frameTop)
|
||||||
|
|
||||||
|
this.draw.layeredText({
|
||||||
|
ctx: ctx,
|
||||||
|
text: "成績発表",
|
||||||
|
fontSize: 48,
|
||||||
|
fontFamily: this.font,
|
||||||
|
x: 23,
|
||||||
|
y: 15,
|
||||||
|
letterSpacing: 3
|
||||||
|
}, [
|
||||||
|
{x: -2, y: -2, outline: "#000", letterBorder: 22},
|
||||||
|
{},
|
||||||
|
{x: 2, y: 2, shadow: [2, 2, 7]},
|
||||||
|
{x: 2, y: 2, outline: "#ad1516", letterBorder: 10},
|
||||||
|
{x: -2, y: -2, outline: "#ff797b"},
|
||||||
|
{outline: "#f70808"},
|
||||||
|
{fill: "#fff", shadow: [-1, 1, 3, 1.5]}
|
||||||
|
])
|
||||||
|
|
||||||
|
this.draw.layeredText({
|
||||||
|
ctx: ctx,
|
||||||
|
text: this.results.title,
|
||||||
|
fontSize: 40,
|
||||||
|
fontFamily: this.font,
|
||||||
|
x: 1257,
|
||||||
|
y: 20,
|
||||||
|
align: "right"
|
||||||
|
}, [
|
||||||
|
{outline: "#000", letterBorder: 10, shadow: [1, 1, 3]},
|
||||||
|
{fill: "#fff"}
|
||||||
|
])
|
||||||
|
|
||||||
|
ctx.save()
|
||||||
|
for(var p = 0; p < players; p++){
|
||||||
|
var results = this.results
|
||||||
|
if(p === 1){
|
||||||
|
results = p2.results
|
||||||
|
ctx.translate(0, p2Offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
var imgScale = 1.35
|
||||||
|
ctx.drawImage(assets.image["muzu_" + results.difficulty],
|
||||||
|
276, 150, imgScale * 176, imgScale * 120
|
||||||
|
)
|
||||||
|
|
||||||
|
this.draw.roundedRect({
|
||||||
|
ctx: ctx,
|
||||||
|
x: 532,
|
||||||
|
y: 98,
|
||||||
|
w: 728,
|
||||||
|
h: 232,
|
||||||
|
radius: 30,
|
||||||
|
})
|
||||||
|
ctx.fillStyle = p === 1 ? "rgba(195, 228, 229, 0.8)" : "rgba(255, 224, 216, 0.8)"
|
||||||
|
ctx.fill()
|
||||||
|
this.draw.roundedRect({
|
||||||
|
ctx: ctx,
|
||||||
|
x: 556,
|
||||||
|
y: 237,
|
||||||
|
w: 254,
|
||||||
|
h: 70,
|
||||||
|
radius: 15,
|
||||||
|
})
|
||||||
|
ctx.fillStyle = "#000"
|
||||||
|
ctx.fill()
|
||||||
|
this.draw.roundedRect({
|
||||||
|
ctx: ctx,
|
||||||
|
x: 559,
|
||||||
|
y: 240,
|
||||||
|
w: 248,
|
||||||
|
h: 64,
|
||||||
|
radius: 14,
|
||||||
|
})
|
||||||
|
ctx.fillStyle = "#eec954"
|
||||||
|
ctx.fill()
|
||||||
|
this.draw.roundedRect({
|
||||||
|
ctx: ctx,
|
||||||
|
x: 567,
|
||||||
|
y: 248,
|
||||||
|
w: 232,
|
||||||
|
h: 48,
|
||||||
|
radius: 6,
|
||||||
|
})
|
||||||
|
ctx.fillStyle = "#000"
|
||||||
|
ctx.fill()
|
||||||
|
ctx.font = "36px " + this.font
|
||||||
|
ctx.textAlign = "right"
|
||||||
|
ctx.fillStyle = "#fff"
|
||||||
|
ctx.strokeStyle = "#000"
|
||||||
|
ctx.lineWidth = 0.5
|
||||||
|
ctx.fillText("点", 788, 284)
|
||||||
|
ctx.strokeText("点", 788, 284)
|
||||||
|
|
||||||
|
this.draw.score({
|
||||||
|
ctx: ctx,
|
||||||
|
score: "good",
|
||||||
|
x: 823,
|
||||||
|
y: 192
|
||||||
|
})
|
||||||
|
this.draw.score({
|
||||||
|
ctx: ctx,
|
||||||
|
score: "ok",
|
||||||
|
x: 823,
|
||||||
|
y: 233
|
||||||
|
})
|
||||||
|
this.draw.score({
|
||||||
|
ctx: ctx,
|
||||||
|
score: "bad",
|
||||||
|
x: 823,
|
||||||
|
y: 273
|
||||||
|
})
|
||||||
|
|
||||||
|
ctx.textAlign = "right"
|
||||||
|
var grd = ctx.createLinearGradient(0, 0, 0, 30)
|
||||||
|
grd.addColorStop(0.2, "#ff4900")
|
||||||
|
grd.addColorStop(0.9, "#f7fb00")
|
||||||
|
this.draw.layeredText({
|
||||||
|
ctx: ctx,
|
||||||
|
text: "最大コンボ数",
|
||||||
|
x: 1150,
|
||||||
|
y: 193,
|
||||||
|
fontSize: 29,
|
||||||
|
fontFamily: this.font,
|
||||||
|
align: "right",
|
||||||
|
width: 216,
|
||||||
|
letterSpacing: 1
|
||||||
|
}, [
|
||||||
|
{outline: "#000", letterBorder: 8},
|
||||||
|
{fill: grd}
|
||||||
|
])
|
||||||
|
this.draw.layeredText({
|
||||||
|
ctx: ctx,
|
||||||
|
text: "連打数",
|
||||||
|
x: 1150,
|
||||||
|
y: 233,
|
||||||
|
fontSize: 29,
|
||||||
|
fontFamily: this.font,
|
||||||
|
letterSpacing: 4,
|
||||||
|
align: "right"
|
||||||
|
}, [
|
||||||
|
{outline: "#000", letterBorder: 8},
|
||||||
|
{fill: "#ffc700"}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
ctx.restore()
|
||||||
|
})
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
if(elapsed >= 800){
|
||||||
|
ctx.save()
|
||||||
|
ctx.translate(frameLeft, frameTop)
|
||||||
|
|
||||||
|
ctx.globalAlpha = Math.min(1, (elapsed - 800) / 500)
|
||||||
|
|
||||||
|
for(var p = 0; p < players; p++){
|
||||||
|
var results = this.results
|
||||||
|
if(p === 1){
|
||||||
|
results = p2.results
|
||||||
|
ctx.translate(0, p2Offset)
|
||||||
|
}
|
||||||
|
ctx.drawImage(assets.image["hp-bar-bg"],
|
||||||
|
552, 120, 688, 48
|
||||||
|
)
|
||||||
|
var gauge = results.gauge / 100
|
||||||
|
if(gauge > 0){
|
||||||
|
ctx.drawImage(assets.image["hp-bar-colour"],
|
||||||
|
0, 0, 650 * gauge, 40,
|
||||||
|
557, 127, 635 * gauge, 37,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
if(elapsed >= 1200){
|
||||||
|
ctx.save()
|
||||||
|
ctx.setTransform(1, 0, 0, 1, 0, 0)
|
||||||
|
|
||||||
|
for(var p = 0; p < players; p++){
|
||||||
|
var results = this.results
|
||||||
|
if(p === 1){
|
||||||
|
results = p2.results
|
||||||
|
}
|
||||||
|
var crownType = null
|
||||||
|
if(results.bad === 0){
|
||||||
|
crownType = "gold"
|
||||||
|
}else if(results.gauge >= 50){
|
||||||
|
crownType = "silver"
|
||||||
|
}
|
||||||
|
if(crownType !== null){
|
||||||
|
var amount = Math.min(1, (elapsed - 1200) / 450)
|
||||||
|
this.draw.alpha(this.draw.easeIn(amount), ctx, ctx => {
|
||||||
|
ctx.save()
|
||||||
|
ctx.scale(ratio, ratio)
|
||||||
|
ctx.translate(frameLeft, frameTop)
|
||||||
|
if(p === 1){
|
||||||
|
ctx.translate(0, p2Offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
var crownScale = 1
|
||||||
|
var shine = 0
|
||||||
|
if(amount < 1){
|
||||||
|
crownScale = 2.8 * (1 - amount) + 0.9
|
||||||
|
}else if(elapsed < 1850){
|
||||||
|
crownScale = 0.9 + (elapsed - 1650) / 2000
|
||||||
|
}else if(elapsed < 2200){
|
||||||
|
shine = (elapsed - 1850) / 175
|
||||||
|
if(shine > 1){
|
||||||
|
shine = 2 - shine
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.draw.crown({
|
||||||
|
ctx: ctx,
|
||||||
|
type: crownType,
|
||||||
|
x: 395,
|
||||||
|
y: 218,
|
||||||
|
scale: crownScale,
|
||||||
|
shine: shine
|
||||||
|
})
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
if(elapsed >= 2400){
|
||||||
|
ctx.save()
|
||||||
|
ctx.translate(frameLeft, frameTop)
|
||||||
|
|
||||||
|
for(var p = 0; p < players; p++){
|
||||||
|
var results = this.results
|
||||||
|
if(p === 1){
|
||||||
|
results = p2.results
|
||||||
|
ctx.translate(0, p2Offset)
|
||||||
|
}
|
||||||
|
ctx.save()
|
||||||
|
var points = results.points.toString()
|
||||||
|
var scale = 1.3
|
||||||
|
ctx.font = "36px " + this.font
|
||||||
|
ctx.translate(760, 286)
|
||||||
|
ctx.scale(1 / scale, 1 * 1.1)
|
||||||
|
ctx.textAlign = "center"
|
||||||
|
ctx.fillStyle = "#fff"
|
||||||
|
ctx.strokeStyle = "#fff"
|
||||||
|
ctx.lineWidth = 0.5
|
||||||
|
for(var i = 0; i < points.length; i++){
|
||||||
|
ctx.translate(-23 * scale, 0)
|
||||||
|
ctx.fillText(points[points.length - i - 1], 0, 0)
|
||||||
|
ctx.strokeText(points[points.length - i - 1], 0, 0)
|
||||||
|
}
|
||||||
|
ctx.restore()
|
||||||
|
|
||||||
|
var printNumbers = ["good", "ok", "bad", "maxCombo", "drumroll"]
|
||||||
|
for(var i in printNumbers){
|
||||||
|
this.draw.layeredText({
|
||||||
|
ctx: ctx,
|
||||||
|
text: results[printNumbers[i]].toString(),
|
||||||
|
x: 971 + 270 * Math.floor(i / 3),
|
||||||
|
y: 194 + (40 * (i % 3)),
|
||||||
|
fontSize: 27,
|
||||||
|
fontFamily: this.font,
|
||||||
|
letterSpacing: 4,
|
||||||
|
align: "right"
|
||||||
|
}, [
|
||||||
|
{outline: "#000", letterBorder: 9},
|
||||||
|
{fill: "#fff"}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.state.screen === "fadeOut"){
|
||||||
|
ctx.save()
|
||||||
|
if(this.state.hasPointer === 1){
|
||||||
|
this.state.hasPointer = 2
|
||||||
|
this.canvas.style.cursor = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var elapsed = ms - this.state.screenMS
|
||||||
|
ctx.globalAlpha = Math.max(0, Math.min(1, elapsed / 1000))
|
||||||
|
ctx.fillStyle = "#000"
|
||||||
|
ctx.fillRect(0, 0, winW, winH)
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
|
||||||
|
if(elapsed >= 1000){
|
||||||
|
this.clean()
|
||||||
|
this.controller.songSelection(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
mod(length, index){
|
||||||
|
return ((index % length) + length) % length
|
||||||
|
}
|
||||||
|
|
||||||
|
getMS(){
|
||||||
|
return +new Date
|
||||||
|
}
|
||||||
|
|
||||||
clean(){
|
clean(){
|
||||||
this.gamepad.clean()
|
|
||||||
assets.sounds["bgm_result"].stop()
|
assets.sounds["bgm_result"].stop()
|
||||||
|
snd.musicGain.fadeIn()
|
||||||
|
this.redrawRunning = false
|
||||||
pageEvents.keyRemove(this, "all")
|
pageEvents.keyRemove(this, "all")
|
||||||
pageEvents.remove(window, "resize")
|
pageEvents.remove(this.canvas, "mousedown")
|
||||||
|
delete this.ctx
|
||||||
|
delete this.canvas
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -90,13 +90,13 @@ class View{
|
|||||||
var docW = document.body.offsetWidth
|
var docW = document.body.offsetWidth
|
||||||
var docH = document.body.offsetHeight
|
var docH = document.body.offsetHeight
|
||||||
this.canvas.rescale()
|
this.canvas.rescale()
|
||||||
if(this.controller.multiplayer == 2){
|
if(this.controller.multiplayer === 2){
|
||||||
docH = docH / 3 * 2
|
docH = docH / 3 * 2
|
||||||
}
|
}
|
||||||
this.canvas.resize(docW, docH)
|
this.canvas.resize(docW, docH)
|
||||||
this.winW = this.canvas.scaledWidth
|
this.winW = this.canvas.scaledWidth
|
||||||
this.winH = this.canvas.scaledHeight
|
this.winH = this.canvas.scaledHeight
|
||||||
if(this.controller.multiplayer == 2){
|
if(this.controller.multiplayer === 2){
|
||||||
this.winH = this.winH / 2 * 3
|
this.winH = this.winH / 2 * 3
|
||||||
}
|
}
|
||||||
this.barY = 0.25 * this.winH
|
this.barY = 0.25 * this.winH
|
||||||
@ -227,8 +227,8 @@ class View{
|
|||||||
getHP(){
|
getHP(){
|
||||||
var circles = this.controller.getCircles()
|
var circles = this.controller.getCircles()
|
||||||
var currentCircle = this.controller.getCurrentCircle()
|
var currentCircle = this.controller.getCurrentCircle()
|
||||||
var hp = this.controller.getGlobalScore().hp
|
var gauge = this.controller.getGlobalScore().gauge
|
||||||
var width = Math.floor(hp * 650 / 1000) * 10
|
var width = Math.floor(gauge * 650 / 1000) * 10
|
||||||
return {
|
return {
|
||||||
imgW: width,
|
imgW: width,
|
||||||
canvasW: width / 650 * this.HPBarColMaxW
|
canvasW: width / 650 * this.HPBarColMaxW
|
||||||
@ -769,7 +769,7 @@ class View{
|
|||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
var animation = this.assets.don.getAnimation()
|
var animation = this.assets.don.getAnimation()
|
||||||
if(animation === "gogo" || this.controller.getGlobalScore().hp >= 50 && animation === "normal"){
|
if(animation === "gogo" || this.controller.getGlobalScore().gauge >= 50 && animation === "normal"){
|
||||||
this.assets.don.normalAnimation()
|
this.assets.don.normalAnimation()
|
||||||
}
|
}
|
||||||
if(ms >= this.gogoTimeStarted + 100){
|
if(ms >= this.gogoTimeStarted + 100){
|
||||||
@ -817,6 +817,10 @@ class View{
|
|||||||
}
|
}
|
||||||
clean(){
|
clean(){
|
||||||
pageEvents.mouseRemove(this)
|
pageEvents.mouseRemove(this)
|
||||||
|
if(this.controller.multiplayer === 2){
|
||||||
|
this.canvas.canvas.parentNode.removeChild(this.canvas.canvas)
|
||||||
|
}
|
||||||
|
this.cursor.parentNode.removeChild(this.cursor)
|
||||||
delete this.pauseMenu
|
delete this.pauseMenu
|
||||||
delete this.cursor
|
delete this.cursor
|
||||||
delete this.canvas
|
delete this.canvas
|
||||||
|
@ -42,7 +42,7 @@ class ViewAssets{
|
|||||||
var length = this.don.getAnimationLength("gogo")
|
var length = this.don.getAnimationLength("gogo")
|
||||||
this.don.setUpdateSpeed(this.beatInterval / (length / 4))
|
this.don.setUpdateSpeed(this.beatInterval / (length / 4))
|
||||||
this.don.setAnimation("gogo")
|
this.don.setAnimation("gogo")
|
||||||
}else if(this.controller.getGlobalScore().hp >= 50){
|
}else if(this.controller.getGlobalScore().gauge >= 50){
|
||||||
this.don.setAnimationStart(0)
|
this.don.setAnimationStart(0)
|
||||||
var length = this.don.getAnimationLength("clear")
|
var length = this.don.getAnimationLength("clear")
|
||||||
this.don.setUpdateSpeed(this.beatInterval / (length / 2))
|
this.don.setUpdateSpeed(this.beatInterval / (length / 2))
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
<div class="scoresheet">
|
|
||||||
<div class="top-part">
|
|
||||||
<h2 alt="成績発表" class="stroke-main result-title">成績発表</h2>
|
|
||||||
<h3 alt="" class="stroke-sub result-song"></h3>
|
|
||||||
</div>
|
|
||||||
<div class="result-bar">
|
|
||||||
<div class="score-cont">
|
|
||||||
<img class="score-mark" />
|
|
||||||
<div class="score-hp-bar-bg">
|
|
||||||
<div class="score-hp-bar-colour">
|
|
||||||
<img src="/assets/img/hp-bar-colour.png" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="score-points"></div>
|
|
||||||
<table class="score-details">
|
|
||||||
<tr>
|
|
||||||
<th class="header-great stroke-sub" alt="良">良</th>
|
|
||||||
<td class="value nb-great stroke-sub"></td>
|
|
||||||
<td class="stroke-sub" alt="最大コンボ数">最大コンボ数</td><td class="value max-combo stroke-sub"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th class="header-good stroke-sub" alt="可">可</th>
|
|
||||||
<td class="value nb-good stroke-sub"></td>
|
|
||||||
<td class="stroke-sub" alt="連打数">連打数</td><td class="value nb-drumroll stroke-sub"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th class="header-fail stroke-sub" alt="不可">不可</th>
|
|
||||||
<td class="value nb-fail stroke-sub"></td>
|
|
||||||
<td></td><td></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="bottom-part">
|
|
||||||
<div class="gradient-overlay"></div>
|
|
||||||
<button type="button" class="replay">Replay</button>
|
|
||||||
<button type="button" class="song-select selected">Song select</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
Loading…
Reference in New Issue
Block a user