Repository navigation
Expand file tree
/
Copy pathgame.html
More file actions
191 lines (177 loc) · 9.59 KB
/
Copy pathgame.html
File metadata and controls
191 lines (177 loc) · 9.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>SwingProject — 2Dキャラ歩行デモ(プレイ)</title>
<link rel="icon" type="image/png" href="assets/favicon.png">
<style>
:root{
--ember:#E8722A; /* dashi theme11 p31: 暖オレンジ */
--ember2:#FFA24D;
--inkbg:#0E0B09;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{width:100%;height:100%;overflow:hidden;background:var(--inkbg);
font-family:"Hiragino Kaku Gothic ProN","Yu Gothic",YuGothic,Meiryo,sans-serif;
-webkit-user-select:none;user-select:none}
/* ---- ember backdrop ---- */
#glow{position:fixed;inset:0;pointer-events:none;
background:radial-gradient(60% 55% at 72% 78%, rgba(232,114,42,.22), transparent 65%),
radial-gradient(40% 40% at 18% 12%, rgba(232,114,42,.08), transparent 70%)}
.bracket{position:fixed;width:26px;height:26px;pointer-events:none;opacity:.55}
.bracket.tl{top:12px;left:14px;border-top:2px solid var(--ember);border-left:2px solid var(--ember)}
.bracket.tr{top:12px;right:14px;border-top:2px solid var(--ember);border-right:2px solid var(--ember)}
.bracket.bl{bottom:12px;left:14px;border-bottom:2px solid var(--ember);border-left:2px solid var(--ember)}
.bracket.br{bottom:12px;right:14px;border-bottom:2px solid var(--ember);border-right:2px solid var(--ember)}
.dia{position:fixed;left:-70px;bottom:-70px;width:240px;height:240px;pointer-events:none;
border:1px solid rgba(232,114,42,.25);transform:rotate(45deg);opacity:.5}
#wrap{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;z-index:1}
#stage{position:relative;transform-origin:center center}
/* ---- Java Swing (Windows) window ---- */
#jframe{position:absolute;left:0;top:0;background:#F0F0F0;border:1px solid #6f6f6f;
box-shadow:0 0 0 1px rgba(255,255,255,.06), 0 22px 60px rgba(0,0,0,.6), 0 0 42px rgba(232,114,42,.12)}
#jtbar{height:30px;background:#fff;display:flex;align-items:center;gap:8px;padding:0 10px;
border-bottom:1px solid #d9d9d9;font-size:13px;color:#111}
#jtbar img{width:18px;height:18px;image-rendering:pixelated}
#jtbar .btns{margin-left:auto;display:flex;gap:2px;color:#444}
#jtbar .btns i{width:30px;text-align:center;font-style:normal;font-size:12px;font-family:Segoe UI,system-ui,sans-serif}
#jtbar .btns i.x:hover{background:#e81123;color:#fff}
#content{position:relative}
/* Metal L&F 風ボタン */
button.sw{position:absolute;background:linear-gradient(#fdfdfd,#e6e6e6 60%,#dcdcdc);
border:1px solid #8f8f8f;border-radius:2px;font-size:12px;font-family:inherit;color:#111;cursor:pointer;
white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
button.sw:hover{background:linear-gradient(#ffffff,#efefef 60%,#e5e5e5)}
button.sw:active{background:#d8d8d8}
#panel{position:absolute;left:12px;top:10px;width:328px;height:233px;background:#EFEFEF;
overflow:hidden;cursor:crosshair;border:1px solid #dcdcdc}
#panel1{position:absolute;left:351px;top:10px;width:77px;height:83px;background:#EFEFEF;
border:1px solid #dcdcdc;display:grid;place-items:center}
#panel1 canvas{image-rendering:pixelated}
/* スプライト:1枚もの画像から background-position で切り出し */
#chara{position:absolute;width:64px;height:96px;display:none;
background-image:url(assets/vx_chara02_a_transparent.png);
background-size:768px 768px; /* 384×384 を2倍 */
image-rendering:pixelated;pointer-events:none}
.jlabel{position:absolute;font-size:12px;color:#111;white-space:nowrap}
#ghlink{position:fixed;right:10px;bottom:8px;z-index:20;font-size:13px;font-weight:700;
color:var(--ember2);text-decoration:none;background:rgba(14,11,9,.75);
padding:4px 12px;border-radius:999px;border:1px solid rgba(232,114,42,.4)}
#ghlink:hover{background:rgba(232,114,42,.18)}
#hint{position:fixed;left:12px;bottom:8px;z-index:20;font-size:13px;color:#d8c9bd;
background:rgba(14,11,9,.75);padding:4px 12px;border-radius:999px;border:1px solid rgba(232,114,42,.25)}
</style>
</head>
<body>
<div id="glow" aria-hidden="true"></div>
<i class="bracket tl"></i><i class="bracket tr"></i><i class="bracket bl"></i><i class="bracket br"></i>
<div class="dia" aria-hidden="true"></div>
<a id="ghlink" href="https://github.com/tobisako/work_JavaSwing" target="_blank" rel="noopener">↗ GitHub</a>
<span id="hint">タップ/マウス移動=歩く・左クリック=向き・右クリック=キャラ変更</span>
<div id="wrap">
<div id="stage">
<div id="jframe">
<div id="jtbar"><img src="assets/favicon.png" alt="">SwingTest01
<span class="btns"><i>─</i><i>□</i><i class="x">✕</i></span></div>
<div id="content">
<div id="panel"><div id="chara"></div></div>
<div id="panel1"></div>
<button class="sw" id="btnKiri" style="left:352px;top:103px;width:76px;height:21px">切り出し</button>
<button class="sw" id="btnPut" style="left:12px;top:253px;width:129px;height:21px">PUT</button>
<button class="sw" id="btnDir" style="left:170px;top:253px;width:90px;height:21px">向き変更</button>
<button class="sw" id="btnKind" style="left:270px;top:253px;width:90px;height:21px">キャラ変更</button>
<span class="jlabel" style="left:12px;top:284px">PUTボタンを押して、マウスをWindow中心部に移動して下さい。</span>
<span class="jlabel" style="left:12px;top:305px">左クリックでキャラの向きを変えます。</span>
<span class="jlabel" style="left:12px;top:325px">右クリックで、キャラを変更します。</span>
</div>
</div>
</div>
</div>
<script>
"use strict";
/* ============ JCharUnitLabel 移植(原作 Java Swing 版の定数そのまま) ============ */
const ORG_W=32, ORG_H=48, X_NUM=4, MOTION_MAX=3, ZOOM=2; // JPersonUnitLabel(choice)
const DISP_W=ORG_W*ZOOM, DISP_H=ORG_H*ZOOM;
/* 向き: 0=下 1=左 2=右 3=上(シートの行順) */
const S={ dire:0, motion:1, motionV:1, chara:0, placed:false, timer:null };
const chara=document.getElementById('chara');
const panel=document.getElementById('panel');
/* 番号から座標(ChangeNoToPos 相当): x=(no%4)*3+motion, y=(no/4)*4+direction */
function spritePos(no,direction,motion){
const x=(no%X_NUM)*MOTION_MAX+motion;
const y=Math.floor(no/X_NUM)*4+direction;
return [x,y];
}
function updateSprite(){
const [x,y]=spritePos(S.chara,S.dire,S.motion);
chara.style.backgroundPosition=`-${x*DISP_W}px -${y*DISP_H}px`;
}
function setPosition(px,py){ chara.style.left=px+'px'; chara.style.top=py+'px'; }
function changeMotion(){ // 0→1→2→1→0…(ピンポン)
S.motion+=S.motionV;
if(S.motion>=MOTION_MAX-1) S.motionV=-1;
if(S.motion===0) S.motionV=1;
}
function changeDirection(rotate){ // ChangeCharaDirection 相当
if(rotate){ if(++S.dire>3) S.dire=0; }
else changeMotion();
updateSprite();
}
function changeKind(){ if(++S.chara>7) S.chara=0; updateSprite(); }
/* ============ SwingTest01 移植 ============ */
function put(){ // PUT: 配置して300msタイマー開始
S.placed=true;
chara.style.display='block';
setPosition(10,20);
updateSprite();
if(!S.timer) S.timer=setInterval(()=>changeDirection(false),300); // 300msで足踏み
}
panel.addEventListener('pointermove',e=>{
if(!S.placed) return;
const r=panel.getBoundingClientRect(), sc=r.width/panel.offsetWidth;
setPosition((e.clientX-r.left)/sc,(e.clientY-r.top)/sc); // マウスに追従
});
panel.addEventListener('pointerdown',e=>{
if(e.pointerType==='touch'){ // タッチ: その場へ歩かせる
if(!S.placed){ put(); }
const r=panel.getBoundingClientRect(), sc=r.width/panel.offsetWidth;
setPosition((e.clientX-r.left)/sc,(e.clientY-r.top)/sc);
return;
}
if(e.button===0) changeDirection(true); // 左クリック: 向き回転
});
panel.addEventListener('contextmenu',e=>{ // 右クリック: モーション+キャラ変更
e.preventDefault();
changeDirection(false); changeKind();
});
panel.addEventListener('auxclick',e=>{ if(e.button===1) changeKind(); }); // 中ボタン
document.getElementById('btnPut').addEventListener('click',put);
document.getElementById('btnDir').addEventListener('click',()=>{ if(S.placed) changeDirection(true); });
document.getElementById('btnKind').addEventListener('click',()=>{ if(S.placed){ changeDirection(false); changeKind(); } });
/* 「切り出し」: vx_chara02_a.png(非透過版)から (32*5, 48*5) の1コマを切り出して表示 */
document.getElementById('btnKiri').addEventListener('click',()=>{
const im=new Image();
im.onload=()=>{
const cv=document.createElement('canvas'); cv.width=32; cv.height=48;
cv.style.width='64px'; cv.style.height='96px';
cv.getContext('2d').drawImage(im, 32*5, 48*5, 32,48, 0,0, 32,48);
const p1=document.getElementById('panel1'); p1.innerHTML=''; p1.appendChild(cv);
};
im.src='assets/vx_chara02_a.png';
});
/* ============ レイアウト・スケーリング ============ */
const CONTENT_W=440, CONTENT_H=348; // 原作フレーム 456×407 の内寸相当
function layout(){
const c=document.getElementById('content');
c.style.width=CONTENT_W+'px'; c.style.height=CONTENT_H+'px';
const W=CONTENT_W+2, H=CONTENT_H+32;
const st=document.getElementById('stage');
st.style.width=W+'px'; st.style.height=H+'px';
const s=Math.min((innerWidth-16)/W,(innerHeight-56)/H,1.7);
st.style.transform=`scale(${s})`;
}
addEventListener('resize',layout); layout();
</script>
</body>
</html>