ã²ãŒã ã®ãžã£ã³ã«ããããããã¹ã¿ã€ã«ã®éžæã¯éåžžã«èå³æ·±ãã¿ã¹ã¯ã§ãããã²ãŒã ã®æåã¯ãããã®åé¡ã®è§£æ±ºã«äŸåããå¯èœæ§ããããŸããããã«ã補åã®äœæã«åºã¥ããŠæè¡ãéžæããããšã§ãç¬èªã®ãã¥ã¢ã³ã¹ãããããããŸããç§ã®ç®æšã¯ããã®æ¥œããããã»ã¹ã®åºæ¬ã瀺ãããšãªã®ã§ãã·ã³ãã«ãªãã¶ã€ã³ã§3次å ã®è¿·è·¯ãäœããŸããããã«ãå¿ èŠã«å¿ããŠãšã³ãžã³ãäœæããæ¹æ³ã瀺ãããã«ãthree.jsãªã©ã®ã©ã€ãã©ãªããšã³ãžã³ã䜿çšããã«çŽç²ãªã³ãŒãã§å®è¡ããŸãïŒãã ãã倧èŠæš¡ãªãããžã§ã¯ããå®è¡ããããšããå§ãããŸãïŒãå®å šã«èªäœã®ã²ãŒã ã¯ãªãªãžãã«ã§ãããããèå³æ·±ããã®ã«ãªãå¯èœæ§ããããŸããäžè¬ã«ãã©ã¡ãã®ã¢ãããŒãã«ãé·æãšçæããããŸãã
ãã®èšäºãèªãã§ãããªããGoogle Chromeçšã®ã²ãŒã ãäœæãããããã¯ã«èå³ããããšæããŸããã€ãŸããhtml-css-javaScriptãã³ãã«ãã©ã®ããã«æ©èœããããç解ããŠããã®ã§ãåºæ¬ã«ã€ããŠã¯è©³ãã説æããŸããããããã«éçºãéå§ããŸããææ°ã®ãã¹ãŠã®ãã©ãŠã¶ãŒã§ãµããŒããããŠããhtml5ããã³css3ïŒExplorerã¯ã«ãŠã³ããããŸããïŒã§ã¯ããããã¯ã3次å 空éã«é 眮ããããšãã§ããŸããç·ãã°ã©ãã£ãã¯ããªããã£ããæç»ã§ããèŠçŽ ããããŸããã»ãšãã©ã®ãã©ãŠã¶ãšã³ãžã³ã¯<canvas>ã䜿çšããŸããããã¯ãããå€ãã®ããšãå®è¡ã§ããããã©ãŒãã³ã¹ãåäžããããã§ããããããåçŽãªããšã«ã€ããŠã¯ãããå°ãªãã³ãŒãã§å€æ3dã¡ãœããã䜿çšããããšã¯å®å šã«å¯èœã§ãã
1.éçºããŒã«
ãµã€ããšã²ãŒã ã®ãã§ãã¯ã«ã¯ãChromeãšMozillaã®2ã€ã®ãã©ãŠã¶ãã䜿çšããŠããŸãããä»ã®ãã¹ãŠã®ãã©ãŠã¶ïŒExplorerèªäœãé€ãïŒã¯æåã®ãšã³ãžã³ã§æ§ç¯ãããŠãããããçµæã¯ChromeãšãŸã£ããåãã§ããããããããã䜿çšããæå³ãããããŸãããã³ãŒããæžãã«ã¯ã¡ã¢åž³++ã§ååã§ãã
2. 3Dã¹ããŒã¹ã¯htmlã§ã©ã®ããã«å®è£ ãããŠããŸããïŒ
ãããã¯åº§æšç³»ãèŠãŠã¿ãŸãããã
ããã©ã«ãã§ã¯ãåãããã¯ã®åº§æšïŒå·ŠãšäžïŒã¯xã§0ãã¯ã»ã«ãyã§0ãã¯ã»ã«ã§ãããªãã»ããïŒå€æïŒã3軞ãã¹ãŠã§0ãã¯ã»ã«ããããäŸã§ç€ºããŸãããããã®ããã«ãæ°ãããã©ã«ããŒãäœæããŸãããã®äžã§ãindex.htmlãstyle.cssãscript.jsãã¡ã€ã«ãäœæããŸããindex.htmlãéããŠãããã«æ¬¡ã®ããã«èšè¿°ããŸãããã
<!DOCTYPE HTML>
<HTML>
<HEAD>
<TITLE></TITLE>
<LINK rel="stylesheet" href="style.css">
<meta charset="utf-8">
</HEAD>
<BODY>
<div id="container">
<div id="world">
</div>
</div>
</BODY>
</HTML>
<script src="script.js"></script>
style.cssãã¡ã€ã«ã§ããcontainerãèŠçŽ ãšãworldãèŠçŽ ã®ã¹ã¿ã€ã«ãèšå®ããŸãããã
#container{
position:absolute;
width:1200px;
height:800px;
border:2px solid #000000;
}
#world{
width:300px;
height:300px;
background-color:#C0FFFF;
}
ä¿åããŸããããChromeã§index.htmlãéããšã次ã®ããã«ãªããŸããtranslate3dã
èŠçŽ ãworldãã«é©çšããŠã¿ãŸãããã
#world{
width:300px;
height:300px;
background-color:#C0FFFF;
transform:translate3d(200px,100px,0px);
}
ãåç¥ã®ããã«ãç§ã¯ãã«ã¹ã¯ãªãŒã³ã¢ãŒãã«åãæ¿ããŸããã次ã«ãZãªãã»ãããèšå®ããŸããã
ãtransformïŒtranslate3dïŒ200pxã100pxã-1000pxïŒ;
ãã©ãŠã¶ãŒã§htmlãã¡ã€ã«ãå床éããšãå€æŽã¯è¡šç€ºãããŸãããå€æŽã確èªããã«ã¯ããã³ã³ããããªããžã§ã¯ãã®ããŒã¹ãã¯ãã£ããèšå®ããå¿ èŠããããŸãã
#container{
position:absolute;
width:1200px;
height:800px;
border:2px solid #000000;
perspective:600px;
}
ãã®çµæã
åºå Žã¯ç§ãã¡ããé ããããŸãããããŒã¹ãã¯ãã£ãã¯htmlã§ã©ã®ããã«æ©èœããŸããïŒåçãèŠãŠã¿ãŸããã
ãdã¯ãŠãŒã¶ãŒãããªããžã§ã¯ããŸã§ã®è·é¢ãzã¯ãã®åº§æšã§ããè² ã®zïŒhtmlã§ã¯ããã¯translateZïŒã¯ããªããžã§ã¯ãã移åããããšãæå³ããæ£ã®zã¯ãã®éã§ããããŒã¹ãã¯ãã£ãå€ã¯dã®å€ã決å®ããŸããããŒã¹ãã¯ãã£ãããããã£ãèšå®ãããŠããªãå Žåãdå€ã¯ç¡é倧ã§ãããšèŠãªãããŸãããã®å Žåããªããžã§ã¯ãã¯zã®å€åã«ãã£ãŠãŠãŒã¶ãŒã«å¯ŸããŠèŠèŠçã«å€åããŸããããã®å Žåãd = 600pxã«èšå®ããŸããããã©ã«ãã§ã¯ãããŒã¹ãã¯ãã£ããã¥ãŒãã€ã³ãã¯èŠçŽ ã®äžå€®ã«ãããŸãããperspective-originïŒããããã£ãèšå®ããããšã§å€æŽã§ããŸãã
ããã§ã¯ããã軞ãäžå¿ã«ãäžçããå転ãããŸãããã cssã§å転ããæ¹æ³ã¯2ã€ãããŸãã 1ã€ç®ã¯ãxãyãz軞ãäžå¿ãšããå転ã§ãããããè¡ãã«ã¯ãå€æããããã£rotateXïŒïŒãrotateYïŒïŒãããã³rotateZïŒïŒã䜿çšããŸãã 2ã€ç®ã¯ãrotate3dïŒïŒããããã£ã䜿çšããç¹å®ã®è»žãäžå¿ãšããå転ã§ããæåã®æ¹æ³ã䜿çšããŸããããã¯ãã¿ã¹ã¯ã«ããé©ããŠããããã§ããå転軞ã¯é·æ¹åœ¢ã®äžå¿ããå€ããããšã«æ³šæããŠãã ããïŒ
å€æãçºçãããã€ã³ãã¯ãtranslate-originïŒããããã£ãèšå®ããããšã§å€æŽã§ããŸããããã§ã¯ãx軞ã«æ²¿ã£ããäžçãã®å転ãèšå®ããŸãããã
#world{
width:300px;
height:300px;
background-color:#C0FFFF;
transform:translate3d(200px,100px,0px) rotateX(45deg);
}
åæèšåãã«é¡èãªãªãã»ããã åŸãããŸããrotateYïŒïŒãè¿œå ãããšãY軞ã«æ²¿ã£ãå€äœãåŸãããŸãããããã¯ãå転ããããšãå転軞ãå転ããããšã«æ³šæããŠãã ãããããŸããŸãªå転å€ãè©Šãããšãã§ããŸãã
ããã§ããworldããããã¯å ã«å¥ã®ãããã¯ãäœæããŸãããã®ããã«ãhtmlãã¡ã€ã«ã«ã¿ã°ãè¿œå ããŸãã
<!DOCTYPE HTML>
<HTML>
<HEAD>
<TITLE></TITLE>
<LINK rel="stylesheet" href="style.css">
<meta charset="utf-8">
</HEAD>
<BODY>
<div id="container">
<div id="world">
<div id="square1"></div>
</div>
</div>
</BODY>
</HTML>
<script src="script.js"></script>
style.cssã®ãã®ãããã¯ã«ã¹ã¿ã€ã«ãè¿œå ããŸãã
#square1{
position:absolute;
width:200px;
height:200px;
background-color:#FF0000;
}
æã ãåŸãïŒ
ã€ãŸãããäžçããããã¯å ã®èŠçŽ ã¯ããã®ãããã¯ã®äžéšãšããŠå€æãããŸããå転ã¹ã¿ã€ã«ãè¿œå ããŠãy軞ã«æ²¿ã£ãŠãsquare1ããå転ãããŠã¿ãŸããããtransform
ïŒrotateYïŒ30degïŒ;
æåŸã«ïŒ
ãããŒããŒã·ã§ã³ã¯ã©ãã«ãããŸããïŒã - ããªããå°ããïŒå®éãããã¯ãworldãèŠçŽ ã«ãã£ãŠåœ¢æãããå¹³é¢äžã®ãsquare1ããããã¯ã®æ圱ãã©ã®ããã«èŠãããã§ããããããæ圱ã¯å¿ èŠãããŸããããå®éã®å転ã¯å¿ èŠã§ãã ãã¯ãŒã«ããå ã®ãã¹ãŠã®èŠçŽ ã3次å ã«ããã«ã¯ãtransform-styleïŒpreserve-3dããããã£ãé©çšããå¿ èŠããããŸãã ãã¯ãŒã«ããã¹ã¿ã€ã«ã®ãªã¹ãå ã®ããããã£ã眮ãæããåŸãå€æŽã確èªããŸãã
åªããïŒãæ£æ¹åœ¢ãã®ãããã¯ã®ååã¯ãéããããã¯ã®åŸãã«é ããŠããŸããå®å šã«è¡šç€ºããã«ã¯ããã¯ãŒã«ãããããã¯ã®è²ãåé€ããŸããã€ãŸããèæ¯è²ã®ç·ãåé€ããŸããïŒC0FFFF; ãworldããããã¯å ã«ããã«é·æ¹åœ¢ãè¿œå ãããšã3Dã¯ãŒã«ããäœæã§ããŸãã次ã«ããã®èŠçŽ ã®ã¹ã¿ã€ã«ã®å€æããããã£è¡ãåé€ããŠããã¯ãŒã«ãããªãã»ãããåé€ããŸãããã
3.3次å ã®äžçã§ã¢ãŒã·ã§ã³ãäœæããŸã
ãŠãŒã¶ãŒããã®äžçã移åã§ããããã«ããã«ã¯ãããŒã¹ãããŒã¯ãšããŠã¹ã®åãã®ãã³ãã©ãŒãå®çŸ©ããå¿ èŠããããŸããã³ã³ãããŒã«ã¯æšæºã§ãã»ãšãã©ã®3Dã·ã¥ãŒã¿ãŒã«ãããŸããWãSãAãDããŒã䜿çšããŠãååŸå·Šå³ã«ç§»åããã¹ããŒã¹ããŒã䜿çšããŠãžã£ã³ãïŒã€ãŸããäžã«ç§»åïŒããããŠã¹ã䜿çšããŠèŠç·ã®æ¹åãå€æŽããŸãããããè¡ãã«ã¯ããŸã 空ã®script.jsãã¡ã€ã«ãéããŸãããŸããããã«æ¬¡ã®å€æ°ãè¿œå ããŸãããã
// ?
var PressBack = 0;
var PressForward = 0;
var PressLeft = 0;
var PressRight = 0;
var PressUp = 0;
æåã¯ããŒãæŒãããŠããŸãããããŒãæŒããšãç¹å®ã®å€æ°ã®å€ã1ã«å€ãããŸããé¢ããšã0ã«ãªããŸããããŒãæŒãããé¢ãããããããã®ãã³ãã©ãŒãè¿œå ããŠããããå®è£ ããŸãã
//
document.addEventListener("keydown", (event) =>{
if (event.key == "a"){
PressLeft = 1;
}
if (event.key == "w"){
PressForward = 1;
}
if (event.key == "d"){
PressRight = 1;
}
if (event.key == "s"){
PressBack = 1;
}
if (event.keyCode == 32 && onGround){
PressUp = 1;
}
});
//
document.addEventListener("keyup", (event) =>{
if (event.key == "a"){
PressLeft = 0;
}
if (event.key == "w"){
PressForward = 0;
}
if (event.key == "d"){
PressRight = 0;
}
if (event.key == "s"){
PressBack = 0;
}
if (event.keyCode == 32){
PressUp = 0;
}
});
32çªã¯ã¹ããŒã¹ã³ãŒãã§ããã芧ã®ãšãããå°äžã«ãããã©ããã瀺ãå€æ°onGroundããããŸããä»ã®ãšããã...å€æ°ãæŒããåŸã«onGroundå€æ°ãè¿œå ããŠãäžæ¹åãžã®ç§»åãèš±å¯ããŸãããã
// ?
var onGround = true;
ããã§ãããã·ã¥ã¢ã³ããã«ã¢ã«ãŽãªãºã ãè¿œå ããŸããã次ã«ãã ãŒãã¡ã³ãèªäœãè¿œå ããå¿ èŠããããŸããå®éãç§ãã¡ã¯äœãåãããŠããŸããã移åããŠãããªããžã§ã¯ãããããšæ³åããŠã¿ãŸããããããããããŒã³ããšåŒã³ãŸããããéåžžã®éçºè ã«ãšã£ãŠã¯æ £äŸã§ããããã«ãå¥ã®ãPlayerãã¯ã©ã¹ãäœæããŸããjavaScriptã®ã¯ã©ã¹ã¯ãå¥åŠãªããšã«ã次ã®é¢æ°ã䜿çšããŠäœæãããŸãã
function player(x,y,z,rx,ry) {
this.x = x;
this.y = y;
this.z = z;
this.rx = rx;
this.ry = ry;
}
ãã®ã³ãŒãããã¡ã€ã«ã®æåã®script.jsã«è²Œãä»ããŸãããããã¡ã€ã«ã®æåŸã«ããã®ã¿ã€ãã®ãªããžã§ã¯ããäœæããŸãããã
//
var pawn = new player(0,0,0,0,0);
ãããã®å€æ°ã®æå³ãæžãçããŸããããxãyãzã¯ãã¬ãŒã€ãŒã®åæ座æšãrxãryã¯x軞ãšy軞ã«å¯Ÿããå転è§åºŠïŒåºŠåäœïŒã§ããæžãããæåŸã®è¡ã¯ãéå§åº§æšããŒãã®ãplayerãã¿ã€ãã®ãpawnããªããžã§ã¯ããäœæããããšãæå³ããŸãïŒjavascriptã®ã¯ã©ã¹ã¯ä»ã®ããã€ãã®ããšãæå³ãããããã¯ã©ã¹ã§ã¯ãªããå ·äœçã«ã¿ã€ããæžããŠããŸãïŒããªããžã§ã¯ãã移åããŠããã¯ãŒã«ã座æšã¯å€æŽãããŸãããããããŒã³ã座æšã¯å€æŽãããŸããããã¯å€æ°ã®èŠ³ç¹ããã§ãããããŠããŠãŒã¶ãŒã®èŠ³ç¹ããã¯ããã¬ãŒã€ãŒã¯1ã€ã®å Žæã«ããŸãããäžçã¯åããŠããŸãããããã£ãŠãããã°ã©ã ã«ãã¬ãŒã€ãŒã®åº§æšãå€æŽããããããã®å€æŽãåŠçããæçµçã«ã¯äžçãåããå¿ èŠããããŸããå®éãããã¯æã£ãããç°¡åã§ãã
ãããã£ãŠãããã¥ã¡ã³ãããã©ãŠã¶ã«ããŒãããåŸãã¯ãŒã«ããåæç»ããé¢æ°ãå®è¡ããŸããåæç»é¢æ°ãæžããŠã¿ãŸãããïŒ
function update(){
//
let dx = (PressRight - PressLeft);
let dz = - (PressForward - PressBack);
let dy = PressUp;
//
pawn.x = pawn.x + dx;
pawn.y = pawn.y + dy;
pawn.z = pawn.z + dz;
// ( )
world.style.transform =
"rotateX(" + (-pawn.rx) + "deg)" +
"rotateY(" + (-pawn.ry) + "deg)" +
"translate3d(" + (-pawn.x) + "px," + (-pawn.y) + "px," + (-pawn.z) + "px)";
};
æ°ãããã©ãŠã¶ã§ã¯ãworldã¯id = "world"ã®èŠçŽ ãšäžèŽããŸããã次ã®æ§æã䜿çšããŠupdateïŒïŒé¢æ°ã®åã«å²ãåœãŠãæ¹ãå®å šã§ãã
var world = document.getElementById("world");
ã¯ãŒã«ãã®äœçœ®ã10ããªç§ããšã«å€æŽãïŒ1ç§ããã100åã®æŽæ°ïŒãç¡éã«ãŒããéå§ããŸãã
TimerGame = setInterval(update,10);
ã²ãŒã ãå§ããŸãããããã£ããŒãä»ãç§ãã¡ã¯åãããšãã§ããŸãïŒãã ããäžçã¯ã³ã³ããèŠçŽ ã®å¢çãè¶ ããŠã¯ããŒã«ããŸãããããé²ãããã«ãstyle.cssã§cssããããã£ãèšå®ããŸããããè¡ãªãŒããŒãããŒãè¿œå ããŸãïŒhidden; å€æŽã確èªããŸããäžçã¯ä»ãã³ã³ããã®äžã«ãšã©ãŸã£ãŠããŸãã
ç¹å®ã®ã³ãŒãè¡ãã©ãã«æžãå¿ èŠãããããåžžã«ç解ããŠãããšã¯éããªãå¯èœæ§ããããããããã§ãååŸããå¿ èŠã®ãããã¡ã€ã«ã玹ä»ããŸã
ãindex.htmlïŒ
<!DOCTYPE HTML>
<HTML>
<HEAD>
<TITLE></TITLE>
<LINK rel="stylesheet" href="style.css">
<meta charset="utf-8">
</HEAD>
<BODY>
<div id="container">
<div id="world">
<div id="square1"></div>
</div>
</div>
</BODY>
</HTML>
<script src="script.js"></script>
style.cssïŒ
#container{
position:absolute;
width:1200px;
height:800px;
border:2px solid #000000;
perspective:600px;
overflow:hidden;
}
#world{
position:absolute;
width:300px;
height:300px;
transform-style:preserve-3d;
}
#square1{
position:absolute;
width:200px;
height:200px;
background-color:#FF0000;
transform:rotateY(30deg);
}
script.jsïŒ
// Pawn
function player(x,y,z,rx,ry) {
this.x = x;
this.y = y;
this.z = z;
this.rx = rx;
this.ry = ry;
}
// ?
var PressBack = 0;
var PressForward = 0;
var PressLeft = 0;
var PressRight = 0;
var PressUp = 0;
// ?
var onGround = true;
//
document.addEventListener("keydown", (event) =>{
if (event.key == "a"){
PressLeft = 1;
}
if (event.key == "w"){
PressForward = 1;
}
if (event.key == "d"){
PressRight = 1;
}
if (event.key == "s"){
PressBack = 1;
}
if (event.keyCode == 32 && onGround){
PressUp = 1;
}
});
//
document.addEventListener("keyup", (event) =>{
if (event.key == "a"){
PressLeft = 0;
}
if (event.key == "w"){
PressForward = 0;
}
if (event.key == "d"){
PressRight = 0;
}
if (event.key == "s"){
PressBack = 0;
}
if (event.keyCode == 32){
PressUp = 0;
}
});
//
var pawn = new player(0,0,0,0,0);
// world
var world = document.getElementById("world");
function update(){
//
let dx = (PressRight - PressLeft);
let dz = - (PressForward - PressBack);
let dy = - PressUp;
//
pawn.x = pawn.x + dx;
pawn.y = pawn.y + dy;
pawn.z = pawn.z + dz;
// ( )
world.style.transform =
"rotateX(" + (-pawn.rx) + "deg)" +
"rotateY(" + (-pawn.ry) + "deg)" +
"translate3d(" + (-pawn.x) + "px," + (-pawn.y) + "px," + (-pawn.z) + "px)";
};
TimerGame = setInterval(update,10);
äœãéããã®ãããå Žåã¯ãå¿ ãä¿®æ£ããŠãã ããã
ãã£ã©ã¯ã¿ãŒã®åããæ¹ãåŠã³ãŸããããå転ã®ä»æ¹ãããããŸããïŒãã¡ããããã£ã©ã¯ã¿ãŒã®å転ã¯ããŠã¹ã§è¡ããŸããããŠã¹ã®å ŽåãæŒã...ããŒã®ç¶æ å€æ°ã«ããŠã¹ã®åãã®ç¶æ å€æ°ãè¿œå ããŸãã
// ?
var PressBack = 0;
var PressForward = 0;
var PressLeft = 0;
var PressRight = 0;
var PressUp = 0;
var MouseX = 0;
var MouseY = 0;
ãããŠãããã·ã¥ãªãªãŒã¹ãã³ãã©ãŒã®åŸã«ãã¢ãŒã·ã§ã³ãã³ãã©ãŒãæ¿å ¥ããŸãã
//
document.addEventListener("mousemove", (event)=>{
MouseX = event.movementX;
MouseY = event.movementY;
});
æŽæ°æ©èœã«ããŒããŒã·ã§ã³ãè¿œå ããŸãã
//
let dx = (PressRight - PressLeft);
let dz = - (PressForward - PressBack);
let dy = - PressUp;
let drx = MouseY;
let dry = - MouseX;
//
pawn.x = pawn.x + dx;
pawn.y = pawn.y + dy;
pawn.z = pawn.z + dz;
pawn.rx = pawn.rx + drx;
pawn.ry = pawn.ry + dry;
ããŠã¹ãy軞ã«æ²¿ã£ãŠåãããšãããŒã³ãx軞ã«æ²¿ã£ãŠå転ãããã®éãåæ§ã§ããããšã«æ³šæããŠãã ãããçµæãèŠããšãèŠããã®ã«ãã£ãšããŸããéèŠãªã®ã¯ããªãã»ããããªãå ŽåãMouseXãšMouseYã¯åããŸãŸã§ããããŒãã«çãããªããšããããšã§ããããã¯ãæŽæ°ãç¹°ãè¿ããã³ã«ãmishaã®ãªãã»ããããŒãã«ãªã»ããããå¿ èŠãããããšãæå³ããŸãã
//
let dx = (PressRight - PressLeft);
let dz = - (PressForward - PressBack);
let dy = - PressUp;
let drx = MouseY;
let dry = - MouseX;
// :
MouseX = MouseY = 0;
//
pawn.x = pawn.x + dx;
pawn.y = pawn.y + dy;
pawn.z = pawn.z + dz;
pawn.rx = pawn.rx + drx;
pawn.ry = pawn.ry + dry;
ããã«è¯ãããšã«ãåè»¢æ £æ§ãåãé€ããŸããããå転ã¯ãŸã å¥åŠã§ãïŒäœãèµ·ãã£ãŠããã®ããç解ããããã«ããã³ã³ãããå ã«ãããŒã³ãdivãè¿œå ããŸãããã
<div id="container">
<div id="world">
<div id="square1"></div>
</div>
<div id="pawn"></div>
</div>
style.cssã§ã¹ã¿ã€ã«ãèšå®ããŸãããïŒ
#pawn{
position:absolute;
width:100px;
height:100px;
top:400px;
left:600px;
transform:translate(-50%,-50%);
background-color:#0000FF;
}
çµæã確èªããŠã¿ãŸããããããã§ãã¹ãŠãã¹ã ãŒãºã«ãªããŸããïŒå¯äžã®ããšã¯éãæ£æ¹åœ¢ãæ£é¢ã«æ®ã£ãŠãããšããããšã§ãããããä»ã®ãšãããããæ®ããŸããããäžäººç§°ã§ã¯ãªãäžäººç§°ã§ã²ãŒã ãäœãã«ã¯ãèŠç¹ã®äŸ¡å€ã§äžçãç§ãã¡ã«è¿ã¥ããå¿ èŠããããŸããupdateïŒïŒé¢æ°ã®script.jsã§ãããå®è¡ããŸãããïŒ
world.style.transform =
"translateZ(600px)" +
"rotateX(" + (-pawn.rx) + "deg)" +
"rotateY(" + (-pawn.ry) + "deg)" +
"translate3d(" + (-pawn.x) + "px," + (-pawn.y) + "px," + (-pawn.z) + "px)";
ããã§ãäžäººç§°ããã²ãŒã ãäœãããšãã§ããŸããstyle.cssã«è¡ãè¿œå ããŠãããŒã³ãé衚瀺ã«ããŸãã
#pawn{
display:none;
position:absolute;
top:400px;
left:600px;
width:100px;
height:100px;
transform:translate(-50%,-50%);
background-color:#0000FF;
}
åªããã1ã€ã®æ£æ¹åœ¢ã®äžçãããã²ãŒãããã®ã¯éåžžã«é£ããã®ã§ããµã€ããäœæããŸãããsquare2ããããã¯ããworldãã«è¿œå ããŸãããã
<div id="world">
<div id="square1"></div>
<div id="square2"></div>
</div>
ãããŠãstyle.cssã«ããã®ã¹ã¿ã€ã«ãè¿œå ããŸãã
#square2{
position:absolute;
width:1000px;
height:1000px;
top:400px;
left:600px;
background-color:#00FF00;
transform:translate(-50%,-50%) rotateX(90deg) translateZ(-100px);
}
ããã§ãã¹ãŠãæ確ã«ãªããŸããããŸããå®å šã§ã¯ãããŸãããããŒãæŒããšãX軞ãšZ軞ã«æ²¿ã£ãŠå³å¯ã«ç§»åãããã¥ãŒã®æ¹åã«ç§»åããŸãã次ã®ããšãå®è¡ããŸããããscript.jsãã¡ã€ã«ã®æåã«ã2ã€ã®å€æ°ãè¿œå ããŸãã
//
var pi = 3.141592;
var deg = pi/180;
床ã¯pi /ã©ãžã¢ã³ã®180ã§ããã©ãžã¢ã³ããèšç®ããããµã€ã³ãšã³ãµã€ã³ãé©çšããå¿ èŠããããŸããäœããã¹ãã§ããïŒåçãèŠãŠ
ãã ãããèŠç·ãæãã«åããŠåé²ãããå ŽåãXãšZã®äž¡æ¹ã®åº§æšãå€åããŸãã暪ã«ç§»åãããšãäžè§é¢æ°ã¯åã«å Žæãå€æŽããçµæã®æ£åŒŠã®åã®ç¬Šå·ãå€åããŸããupdateïŒïŒã§ãªãã»ããæ¹çšåŒãå€æŽããŸãããïŒ
//
let dx = (PressRight - PressLeft)*Math.cos(pawn.ry*deg) - (PressForward - PressBack)*Math.sin(pawn.ry*deg);
let dz = - (PressForward - PressBack)*Math.cos(pawn.ry*deg) - (PressRight - PressLeft)*Math.sin(pawn.ry*deg);
let dy = -PressUp;
let drx = MouseY;
let dry = - MouseX;
ãã¹ãŠã®ãã¡ã€ã«ã泚ææ·±ã確èªããŠãã ãããäœããããªãã«ãšã£ãŠééã£ãŠããããšãå€æããå Žåãããªãã®é ãå£ãééããééããªããããŸãïŒ
index.htmlïŒ
<!DOCTYPE HTML>
<HTML>
<HEAD>
<TITLE></TITLE>
<LINK rel="stylesheet" href="style.css">
<meta charset="utf-8">
</HEAD>
<BODY>
<div id="container">
<div id="world">
<div id="square1"></div>
<div id="square2"></div>
</div>
<div id="pawn"></div>
</div>
</BODY>
</HTML>
<script src="script.js"></script>
style.cssïŒ
#container{
position:absolute;
width:1200px;
height:800px;
border:2px solid #000000;
perspective:600px;
overflow:hidden;
}
#world{
position:absolute;
width:inherit;
height:inherit;
transform-style:preserve-3d;
}
#square1{
position:absolute;
width:200px;
height:200px;
top:400px;
left:600px;
background-color:#FF0000;
transform:translate(-50%,-50%) rotateY(30deg);
}
#square2{
position:absolute;
width:1000px;
height:1000px;
top:400px;
left:600px;
background-color:#00FF00;
transform:translate(-50%,-50%) rotateX(90deg) translateZ(-100px);
}
#pawn{
display:none;
position:absolute;
top:400px;
left:600px;
transform:translate(-50%,-50%);
width:100px;
height:100px;
background-color:#0000FF;
}
script.jsïŒ
//
var pi = 3.141592;
var deg = pi/180;
// Pawn
function player(x,y,z,rx,ry) {
this.x = x;
this.y = y;
this.z = z;
this.rx = rx;
this.ry = ry;
}
// ?
var PressBack = 0;
var PressForward = 0;
var PressLeft = 0;
var PressRight = 0;
var PressUp = 0;
var MouseX = 0;
var MouseY = 0;
// ?
var onGround = true;
//
document.addEventListener("keydown", (event) =>{
if (event.key == "a"){
PressLeft = 1;
}
if (event.key == "w"){
PressForward = 1;
}
if (event.key == "d"){
PressRight = 1;
}
if (event.key == "s"){
PressBack = 1;
}
if (event.keyCode == 32 && onGround){
PressUp = 1;
}
});
//
document.addEventListener("keyup", (event) =>{
if (event.key == "a"){
PressLeft = 0;
}
if (event.key == "w"){
PressForward = 0;
}
if (event.key == "d"){
PressRight = 0;
}
if (event.key == "s"){
PressBack = 0;
}
if (event.keyCode == 32){
PressUp = 0;
}
});
//
document.addEventListener("mousemove", (event)=>{
MouseX = event.movementX;
MouseY = event.movementY;
});
// player
var pawn = new player(0,0,0,0,0);
// world
var world = document.getElementById("world");
function update(){
//
let dx = (PressRight - PressLeft)*Math.cos(pawn.ry*deg) - (PressForward - PressBack)*Math.sin(pawn.ry*deg);
let dz = - (PressForward - PressBack)*Math.cos(pawn.ry*deg) - (PressRight - PressLeft)*Math.sin(pawn.ry*deg);
let dy = - PressUp;
let drx = MouseY;
let dry = - MouseX;
// :
MouseX = MouseY = 0;
//
pawn.x = pawn.x + dx;
pawn.y = pawn.y + dy;
pawn.z = pawn.z + dz;
pawn.rx = pawn.rx + drx;
pawn.ry = pawn.ry + dry;
// ( )
world.style.transform =
"translateZ(600px)" +
"rotateX(" + (-pawn.rx) + "deg)" +
"rotateY(" + (-pawn.ry) + "deg)" +
"translate3d(" + (-pawn.x) + "px," + (-pawn.y) + "px," + (-pawn.z) + "px)";
};
TimerGame = setInterval(update,10);
ç§ãã¡ã¯ã»ãšãã©åããç解ããŸãããããããäžäŸ¿ããããŸãããããŠã¹ã«ãŒãœã«ã¯ç»é¢å ã§ãã移åã§ããŸãããäžæ¬¡å ã·ã¥ãŒã¿ãŒã§ã¯ãããŠã¹ã奜ããªã ãå転ãããããšãã§ããŸãããŸããã²ãŒã ç»é¢ïŒãã³ã³ãããäžïŒãã¯ãªãã¯ãããšãã«ãŒãœã«ãæ¶ããç»é¢ãµã€ãºã«å¶éãªãããŠã¹ãå転ãããããšãã§ããŸããç»é¢ãã¯ãªãã¯ãããšãããŠã¹ã®ãã£ããã£ãã¢ã¯ãã£ãã«ãªããŸãããã®ãããããŒæŒäžãã³ãã©ãŒã®åã«ãããã³ã³ãããŒãã«ããŠã¹ãã¯ãªãã¯ããããã®ãã³ãã©ãŒãé 眮ããŸãã
// container
var container = document.getElementById("container");
//
container.onclick = function(){
container.requestPointerLock();
};
ä»ã§ã¯ãŸã£ããå¥ã®åé¡ã§ãããã ããäžè¬çã«ã¯ãã«ãŒãœã«ããã£ããã£ããããšãã«ã®ã¿å転ãçºçããããã«ããã®ãæåã§ãããã¬ã¹åŸã«æ°ããå€æ°ãå°å ¥ããŸããã...
// ?
var lock = false;
ã«ãŒãœã«ãã£ããã£ãã³ãã©ã®åã«ãã«ãŒãœã«ãã£ããã£ã®ç¶æ ïŒãã£ããã£ãããŠãããã©ããïŒãå€æŽããããã®ãã³ãã©ãè¿œå ããŸãïŒããŒãããžãŒã«ã€ããŠã¯ç³ãèš³ãããŸããïŒã
//
document.addEventListener("pointerlockchange", (event)=>{
lock = !lock;
});
ãããŠãupdateïŒïŒã§ãããŒã³ãå転æ¡ä»¶ãè¿œå ããŸãã
// ,
if (lock){
pawn.rx = pawn.rx + drx;
pawn.ry = pawn.ry + dry;
};
ãŸããã³ã³ãããã¯ãªãã¯ãããšãã®ããŠã¹èªäœã®ãã£ããã£ã¯ãã«ãŒãœã«ããŸã ãã£ããã£ãããŠããªãå Žåã«ã®ã¿èš±å¯ãããŸãã
//
container.onclick = function(){
if (!lock) container.requestPointerLock();
};
ç§ãã¡ã¯ãã®åãã«å®å šã«å¯ŸåŠããŸãããäžçã®çæã«ç§»ããŸããã
4.ããããããŒããã
ç§ãã¡ã®å Žåã®äžçã¯ãããŸããŸãªå Žæãå転ããµã€ãºãè²ã®é·æ¹åœ¢ã®ã»ãããšããŠæã䟿å©ã«è¡šãããŸããè²ã®ä»£ããã«ãã¯ã¹ãã£ã䜿çšããããšãã§ããŸããå®éãã²ãŒã å ã®ãã¹ãŠã®ææ°ã®3Dã¯ãŒã«ãã¯ãããªãŽã³ãšåŒã°ããäžè§åœ¢ãšé·æ¹åœ¢ã®ã³ã¬ã¯ã·ã§ã³ã§ããã¯ãŒã«ãªã²ãŒã ã§ã¯ããã®æ°ã¯1ã€ã®ãã¬ãŒã ã§æ°äžã«éããå¯èœæ§ããããŸãããã©ãŠã¶èªäœã®ã°ã©ãã£ãã¯ããã©ãŒãã³ã¹ãäœããããçŽ100åãããŸããåã®æ®µèœã§ã¯ããworldãå ã«ãdivããããã¯ãæ¿å ¥ããŸããããããããã®ãããªãããã¯ãå€æ°ïŒæ°çŸïŒããå Žåããããã®ãããããã³ã³ãããŒã«æ¿å ¥ããã®ã¯éåžžã«é¢åã§ãããããŠãå€ãã®ã¬ãã«ããããŸãããããã£ãŠãjavaScriptã«ãç§ãã¡ã§ã¯ãªãããããã®é·æ¹åœ¢ãæ¿å ¥ãããŸãããã®ããã®ç¹å¥ãªé åãäœæããŸãã
index.htmlãéããŠããworldããããã¯ãããã¹ãŠã®å éšãããã¯ãåé€ããŸãããã
<BODY>
<div id="container">
<div id="world"></div>
<div id="pawn"></div>
</div>
</BODY>
ã芧ã®ãšãããçŸåšãäžçãã«ã¯äœããããŸãããstyle.cssã§ãïŒsquare1ãšïŒsquare2ã®ã¹ã¿ã€ã«ãåé€ãïŒãã®ãã¡ã€ã«ããïŒsquare1ãšïŒsquare2ãå®å šã«åé€ããŸãïŒã代ããã«ããã¹ãŠã®é·æ¹åœ¢ã«å ±éãã.squareã¯ã©ã¹ã®ã¹ã¿ã€ã«ãäœæããŸãããããŠããã®ããããã£ã1ã€ã ãèšå®ããŸãã
.square{
position:absolute;
}
次ã«ãé·æ¹åœ¢ã®é åãäœæããŸãããïŒããšãã°ãscript.jsã®ãã¬ãŒã€ãŒã³ã³ã¹ãã©ã¯ã¿ãŒãšãã¬ã¹å€æ°ã®éã«ããã·ã¥ããŸãïŒã
//
var map = [
[0,0,1000,0,180,0,2000,200,"#F0C0FF"],
[0,0,-1000,0,0,0,2000,200,"#F0C0FF"],
[1000,0,0,0,-90,0,2000,200,"#F0C0FF"],
[-1000,0,0,0,90,0,2000,200,"#F0C0FF"],
[0,100,0,90,0,0,2000,2000,"#666666"]
]
ãããã³ã³ã¹ãã©ã¯ã¿ãŒã®åœ¢åŒã§è¡ãããšã¯å¯èœã§ããããã³ã³ã¹ãã©ã¯ã¿ãŒã§ã¯ãªãé åãä»ããŠé·æ¹åœ¢ãé 眮ãããµã€ã¯ã«ãéå§ããæ¹ãç°¡åãªã®ã§ãä»ã®ãšããã¯çŽç²ãªé åã§ç®¡çããŸãããã®äžã®æ°åã®æå³ã説æããŸãããããé åã«ã¯ã[ããããããããã]ã®9ã€ã®å€æ°ã®1次å é åãå«ãŸããŠããŸããæåã®3ã€ã®æ°åã¯é·æ¹åœ¢ã®äžå¿ã®åº§æšã次ã®3ã€ã®æ°åã¯åºŠåäœã®å転è§åºŠïŒåãäžå¿ã«å¯ŸããïŒã2ã€ã®æ°åã¯ãã®å¯žæ³ãæåŸã®æ°åã¯èæ¯ã§ããããšãç解ããŠãããšæããŸããããã«ãèæ¯ã¯åè²ãã°ã©ããŒã·ã§ã³ããŸãã¯åçã«ããããšãã§ããŸããåŸè ã¯ãã¯ã¹ãã£ãšããŠäœ¿çšããã®ã«éåžžã«äŸ¿å©ã§ãã
é åãäœæããŸããã次ã«ããã®é åãé·æ¹åœ¢ã«å€æããé¢æ°ãäœæããŸãã
function CreateNewWorld(){
for (let i = 0; i < map.length; i++){
//
let newElement = document.createElement("div");
newElement.className = "square";
newElement.id = "square" + i;
newElement.style.width = map[i][6] + "px";
newElement.style.height = map[i][7] + "px";
newElement.style.background = map[i][8];
newElement.style.transform = "translate3d(" +
(600 - map[i][6]/2 + map[i][0]) + "px," +
(400 - map[i][7]/2 + map[i][1]) + "px," +
(map[i][2]) + "px)" +
"rotateX(" + map[i][3] + "deg)" +
"rotateY(" + map[i][4] + "deg)" +
"rotateZ(" + map[i][5] + "deg)";
// world
world.append(newElement);
}
}
äœãèµ·ãã£ãŠããã®ãã説æããŸããããäœæããã°ããã®èŠçŽ ãæãæ°ããå€æ°ãäœæããŠããŸããIDãšcssã¯ã©ã¹ïŒããã¯javaScriptã®ã¯ã©ã¹ãšããåèªã®æå³ã§ãïŒãå²ãåœãŠãå¹ ãé«ããèæ¯ãå€æã§èšå®ããŸããå€æã§ã¯ãé·æ¹åœ¢ã®äžå¿ã®åº§æšã«å ããŠã600ãš400ã®ãªãã»ãããšãé·æ¹åœ¢ã®äžå¿ãç®çã®åº§æšãšæ£ç¢ºã«äžèŽããããã«å¯žæ³ã®ååãæå®ããããšã«æ³šæããŠãã ãããã¿ã€ããŒã®åã§ã¯ãŒã«ããžã§ãã¬ãŒã¿ãŒãèµ·åããŸãããã
CreateNewWorld();
TimerGame = setInterval(update,10);
ãã³ã¯ã®å£ãšç°è²ã®åºã®ãããšãªã¢ã衚瀺ãããŸããã芧ã®ãšããããããã®äœæã¯æè¡çã«å®è£ ãé£ãããããŸããããã®çµæã3ã€ã®ãã¡ã€ã«ã®ã³ãŒãã¯æ¬¡ã®ããã«ãªããŸã
ãindex.htmlïŒ
<!DOCTYPE HTML>
<HTML>
<HEAD>
<TITLE></TITLE>
<LINK rel="stylesheet" href="style.css">
<meta charset="utf-8">
</HEAD>
<BODY>
<div id="container">
<div id="world"></div>
<div id="pawn"></div>
</div>
</BODY>
</HTML>
<script src="script.js"></script>
style.css
#container{
position:absolute;
width:1200px;
height:800px;
border:2px solid #000000;
perspective:600px;
overflow:hidden;
}
#world{
position:absolute;
width:inherit;
height:inherit;
transform-style:preserve-3d;
}
.square{
position:absolute;
}
#pawn{
display:none;
position:absolute;
top:400px;
left:600px;
transform:translate(-50%,-50%);
width:100px;
height:100px;
}
script.jsïŒ
//
var pi = 3.141592;
var deg = pi/180;
// player
function player(x,y,z,rx,ry) {
this.x = x;
this.y = y;
this.z = z;
this.rx = rx;
this.ry = ry;
}
//
var map = [
[0,0,1000,0,180,0,2000,200,"#F0C0FF"],
[0,0,-1000,0,0,0,2000,200,"#F0C0FF"],
[1000,0,0,0,-90,0,2000,200,"#F0C0FF"],
[-1000,0,0,0,90,0,2000,200,"#F0C0FF"],
[0,100,0,90,0,0,2000,2000,"#666666"]
]
// ?
var PressBack = 0;
var PressForward = 0;
var PressLeft = 0;
var PressRight = 0;
var PressUp = 0;
var MouseX = 0;
var MouseY = 0;
// ?
var lock = false;
// ?
var onGround = true;
// container
var container = document.getElementById("container");
//
document.addEventListener("pointerlockchange", (event)=>{
lock = !lock;
});
//
container.onclick = function(){
if (!lock) container.requestPointerLock();
};
//
document.addEventListener("keydown", (event) =>{
if (event.key == "a"){
PressLeft = 1;
}
if (event.key == "w"){
PressForward = 1;
}
if (event.key == "d"){
PressRight = 1;
}
if (event.key == "s"){
PressBack = 1;
}
if (event.keyCode == 32 && onGround){
PressUp = 1;
}
});
//
document.addEventListener("keyup", (event) =>{
if (event.key == "a"){
PressLeft = 0;
}
if (event.key == "w"){
PressForward = 0;
}
if (event.key == "d"){
PressRight = 0;
}
if (event.key == "s"){
PressBack = 0;
}
if (event.keyCode == 32){
PressUp = 0;
}
});
//
document.addEventListener("mousemove", (event)=>{
MouseX = event.movementX;
MouseY = event.movementY;
});
//
var pawn = new player(0,0,0,0,0);
// world
var world = document.getElementById("world");
function update(){
//
let dx = (PressRight - PressLeft)*Math.cos(pawn.ry*deg) - (PressForward - PressBack)*Math.sin(pawn.ry*deg);
let dz = - (PressForward - PressBack)*Math.cos(pawn.ry*deg) - (PressRight - PressLeft)*Math.sin(pawn.ry*deg);
let dy = - PressUp;
let drx = MouseY;
let dry = - MouseX;
// :
MouseX = MouseY = 0;
//
pawn.x = pawn.x + dx;
pawn.y = pawn.y + dy;
pawn.z = pawn.z + dz;
// ,
if (lock){
pawn.rx = pawn.rx + drx;
pawn.ry = pawn.ry + dry;
};
// ( )
world.style.transform =
"translateZ(" + (600 - 0) + "px)" +
"rotateX(" + (-pawn.rx) + "deg)" +
"rotateY(" + (-pawn.ry) + "deg)" +
"translate3d(" + (-pawn.x) + "px," + (-pawn.y) + "px," + (-pawn.z) + "px)";
};
function CreateNewWorld(){
for (let i = 0; i < map.length; i++){
//
let newElement = document.createElement("div");
newElement.className = "square";
newElement.id = "square" + i;
newElement.style.width = map[i][6] + "px";
newElement.style.height = map[i][7] + "px";
newElement.style.background = map[i][8];
newElement.style.transform = "translate3d(" +
(600 - map[i][6]/2 + map[i][0]) + "px," +
(400 - map[i][7]/2 + map[i][1]) + "px," +
(map[i][2]) + "px)" +
"rotateX(" + map[i][3] + "deg)" +
"rotateY(" + map[i][4] + "deg)" +
"rotateZ(" + map[i][5] + "deg)";
// world
world.append(newElement);
}
}
CreateNewWorld();
TimerGame = setInterval(update,10);
åé¡ããªããã°ã次ã®é ç®ã«é²ã¿ãŸãã
5.ãã¬ã€ã€ãŒãã¯ãŒã«ããªããžã§ã¯ããšè¡çªãã
ã¢ã¬ã€ããäžçãçã¿åºãã¢ãŒã·ã§ã³ãã¯ããã¯ãäœæããŸãããç§ãã¡ã¯çŸããäžçãåãåãããšãã§ããŸãããã ãããã¬ãŒã€ãŒã¯ãŸã 圌ãšå¯Ÿè©±ããŠããŸããããã®çžäºäœçšãçºçããããã«ã¯ããã¬ãŒã€ãŒãé·æ¹åœ¢ãšè¡çªãããã©ããã確èªããå¿ èŠããããŸããïŒã€ãŸããè¡çªããã§ãã¯ããŸãããŸãã空ã®é¢æ°ãæ¿å ¥ããŸãããã
function collision(){
}
ãããŠãupdateïŒïŒã§ãããåŒã³åºããŸãïŒ
// :
MouseX = MouseY = 0;
//
collision();
ããã¯ã©ã®ããã«èµ·ãããŸããïŒãã¬ãŒã€ãŒãååŸrã®ããŒã«ã§ãããšæ³åããŠã¿ãŸãããããããŠãããã¯é·æ¹åœ¢ã«åãã£ãŠç§»åããŸãã
æããã«ãããŒã«ããé·æ¹åœ¢ã®å¹³é¢ãŸã§ã®è·é¢ãrãã倧ããå Žåãè¡çªã¯ç¢ºå®ã«çºçããŸããããã®è·é¢ãèŠã€ããããã«ããã¬ãŒã€ãŒã®åº§æšãé·æ¹åœ¢ã®åº§æšç³»ã«å€æããããšãã§ããŸããã¯ãŒã«ãã·ã¹ãã ããé·æ¹åœ¢ã·ã¹ãã ã«è»¢éããé¢æ°ãæžããŠã¿ãŸãããã
function coorTransform(x0,y0,z0,rxc,ryc,rzc){
let x1 = x0;
let y1 = y0*Math.cos(rxc*deg) + z0*Math.sin(rxc*deg);
let z1 = -y0*Math.sin(rxc*deg) + z0*Math.cos(rxc*deg);
let x2 = x1*Math.cos(ryc*deg) - z1*Math.sin(ryc*deg);
let y2 = y1;
let z2 = x1*Math.sin(ryc*deg) + z1*Math.cos(ryc*deg);
let x3 = x2*Math.cos(rzc*deg) + y2*Math.sin(rzc*deg);
let y3 = -x2*Math.sin(rzc*deg) + y2*Math.cos(rzc*deg);
let z3 = z2;
return [x3,y3,z3];
}
ãããŠéé¢æ°ïŒ
function coorReTransform (x3,y3,z3,rxc,ryc,rzc){
let x2 = x3*Math.cos(rzc*deg) - y3*Math.sin(rzc*deg);
let y2 = x3*Math.sin(rzc*deg) + y3*Math.cos(rzc*deg);
let z2 = z3
let x1 = x2*Math.cos(ryc*deg) + z2*Math.sin(ryc*deg);
let y1 = y2;
let z1 = -x2*Math.sin(ryc*deg) + z2*Math.cos(ryc*deg);
let x0 = x1;
let y0 = y1*Math.cos(rxc*deg) - z1*Math.sin(rxc*deg);
let z0 = y1*Math.sin(rxc*deg) + z1*Math.cos(rxc*deg);
return [x0,y0,z0];
}
updateïŒïŒé¢æ°ã®åŸã«ãããã®é¢æ°ãæ¿å ¥ããŸããããåæãžãªã¡ããªã®ã³ãŒã¹ãæäŸããæ°ããªãã®ã§ããããã©ã®ããã«æ©èœãããã«ã€ããŠã¯èª¬æããŸãããå転äžã®åº§æšã®å€æã«ã¯ãã®ãããªåŒãããããããã䜿çšããã ãã§ããé·æ¹åœ¢ã®èŠ³ç¹ããããã¬ãŒã€ãŒã¯æ¬¡ã®ããã«é 眮ãããŸãã
ãã®å Žåãè¡çªæ¡ä»¶ã¯æ¬¡ã®ããã«ãªããŸããããŒã«ãå€vïŒvã¯ãã¯ãã«ïŒã§ç§»åããåŸãz座æšãârãšrã®éã«ãããx座æšãšy座æšãé·æ¹åœ¢å ã«ããããr以äžã®éã ãé¢ããŠããå Žåãè¡çªã宣èšãããŸãããã®å Žåããªãã»ããåŸã®ãã¬ãŒã€ãŒã®z座æšã¯rãŸãã¯-rã«ãªããŸãïŒãã¬ãŒã€ãŒãã©ã¡ãã®åŽããæ¥ãŠãããã«ãã£ãŠç°ãªããŸãïŒãããã«å¿ããŠããã¬ã€ã€ãŒã®ãªãã»ãããå€æŽãããŸãããã¬ãŒã€ãŒã®åº§æšãæŽæ°ããåã«ïŒïŒè¡çªãå ·äœçã«åŒã³åºããŠãæéã®ãªãã»ãããå€æŽããŸãããããã£ãŠãä»ã®è¡çªã¢ã«ãŽãªãºã ã§çºçããããã«ãããŒã«ãé·æ¹åœ¢ãšäº€å·®ããããšã¯ãããŸãããç©ççã«ã¯ãã¬ã€ã€ãŒã¯ç«æ¹äœã®ããã«ãªããŸãããããã«ã¯æ³šæãæããŸãããããã§ã¯ããããjavaScriptã§å®è£ ããŸãããã
function collision(){
for(let i = 0; i < map.length; i++){
//
let x0 = (pawn.x - map[i][0]);
let y0 = (pawn.y - map[i][1]);
let z0 = (pawn.z - map[i][2]);
let x1 = x0 + dx;
let y1 = y0 + dy;
let z1 = z0 + dz;
let point0 = coorTransform(x0,y0,z0,map[i][3],map[i][4],map[i][5]);
let point1 = coorTransform(x1,y1,z1,map[i][3],map[i][4],map[i][5]);
let point2 = new Array();
//
if (Math.abs(point1[0])<(map[i][6]+98)/2 && Math.abs(point1[1])<(map[i][7]+98)/2 && Math.abs(point1[2]) < 50){
point1[2] = Math.sign(point0[2])*50;
point2 = coorReTransform(point1[0],point1[1],point1[2],map[i][3],map[i][4],map[i][5]);
dx = point2[0] - x0;
dy = point2[1] - y0;
dz = point2[2] - z0;
}
};
}
x0ãy0ãz0ã¯ãé·æ¹åœ¢åº§æšç³»ã§ã®ãã¬ãŒã€ãŒã®åæ座æšã§ãïŒå転ãªããx1ãy1ãz1ã¯ãè¡çªãªãã®å€äœåŸã®ãã¬ãŒã€ãŒã®åº§æšã§ããpoint0ãpoint0ãpoint1ãpoint2ã¯ãåæååŸãã¯ãã«ãå€äœãªãã®ååŸãã¯ãã«ã§ããè¡çªãšè¡çªã䌎ãååŸãã¯ãã«ãããããmap[i] [3]ãªã©ãèŠããŠããã°ããããã¯é·æ¹åœ¢ã®å転è§åºŠã§ããæ¡ä»¶ã§ã¯ãé·æ¹åœ¢ã®å¯žæ³ã«100ã§ã¯ãªã98ãè¿œå ããããšã«æ³šæããŠãã ãããããã¯ã¯ã©ããã§ãããªãã ãšæããŸãããã²ãŒã ãéå§ãããšãããªãé«å質ã®è¡çªãçºçããã¯ãã§ãã
ã芧ã®ãšããããããã®ã¢ã¯ã·ã§ã³ã¯ãã¹ãŠããã¹ãŠã®é·æ¹åœ¢ã®forã«ãŒãã§å®è¡ãããŸãããããã®æ°ãå€ããšã座æšå€æé¢æ°ãžã®åŒã³åºãããã§ã«3ã€ãããå€ãã®æ°åŠçæäœãå®è¡ããããããã®ãããªæäœã¯éåžžã«ã³ã¹ããããããŸããæããã«ãé·æ¹åœ¢ããã¬ãŒã€ãŒããéåžžã«é¢ããŠããå Žåãè¡çªãæ°ããããšã¯æå³ããããŸããããã®æ¡ä»¶ãè¿œå ããŸãããïŒ
if ((x0**2 + y0**2 + z0**2 + dx**2 + dy**2 + dz**2) < (map[i][1]**2 + map[i][2]**2)){
let x1 = x0 + dx;
let y1 = y0 + dy;
let z1 = z0 + dz;
let point0 = coorTransform(x0,y0,z0,map[i][3],map[i][4],map[i][5]);
let point1 = coorTransform(x1,y1,z1,map[i][3],map[i][4],map[i][5]);
let point2 = new Array();
//
if (Math.abs(point1[0])<(map[i][6]+98)/2 && Math.abs(point1[1])<(map[i][7]+98)/2 && Math.abs(point1[2]) < 50){
point1[2] = Math.sign(point0[2])*50;
point2 = coorReTransform(point1[0],point1[1],point1[2],map[i][3],map[i][4],map[i][5]);
dx = point2[0] - x0;
dy = point2[1] - y0;
dz = point2[2] - z0;
}
}
ã ãããç§ãã¡ã¯è¡çªã«å¯ŸåŠããŸãããåŸæé¢ã«ç°¡åã«ç»ãããšãã§ãããã¡ããå¯èœã§ããã°ããã°ã®çºçã¯é ãã·ã¹ãã ã§ã®ã¿å¯èœã§ããå®éãäž»èŠãªæè¡éšåå šäœã¯ããã§çµãããŸãããéåãç©ãã¡ãã¥ãŒãé³ãçŸããã°ã©ãã£ãã¯ãªã©ã®ãã©ã€ããŒããªãã®ãè¿œå ããã ãã§ããããããããã¯ç°¡åã«å®è¡ã§ããå ã»ã©äœæãããšã³ãžã³ãšã¯é¢ä¿ãããŸããããããã£ãŠãããã«ã€ããŠã¯æ¬¡ã®ããŒãã§èª¬æããŸããä»ãç§ã®ã³ãŒãã§åŸããã®ã確èªããŠãã ããïŒ
index.htmlïŒ
<!DOCTYPE HTML>
<HTML>
<HEAD>
<TITLE></TITLE>
<LINK rel="stylesheet" href="style.css">
<meta charset="utf-8">
</HEAD>
<BODY>
<div id="container">
<div id="world"></div>
<div id="pawn"></div>
</div>
</BODY>
</HTML>
<script src="script.js"></script>
style.css
#container{
position:absolute;
width:1200px;
height:800px;
border:2px solid #000000;
perspective:600px;
overflow:hidden;
}
#world{
position:absolute;
width:inherit;
height:inherit;
transform-style:preserve-3d;
}
.square{
position:absolute;
}
#pawn{
display:none;
position:absolute;
top:400px;
left:600px;
transform:translate(-50%,-50%);
width:100px;
height:100px;
}
script.jsïŒ
//
var pi = 3.141592;
var deg = pi/180;
// player
function player(x,y,z,rx,ry) {
this.x = x;
this.y = y;
this.z = z;
this.rx = rx;
this.ry = ry;
}
//
var map = [
[0,0,1000,0,180,0,2000,200,"#F0C0FF"],
[0,0,-1000,0,0,0,2000,200,"#F0C0FF"],
[1000,0,0,0,-90,0,2000,200,"#F0C0FF"],
[-1000,0,0,0,90,0,2000,200,"#F0C0FF"],
[0,100,0,90,0,0,2000,2000,"#666666"]
];
// ?
var PressBack = 0;
var PressForward = 0;
var PressLeft = 0;
var PressRight = 0;
var PressUp = 0;
var MouseX = 0;
var MouseY = 0;
// ?
var lock = false;
// ?
var onGround = true;
// container
var container = document.getElementById("container");
//
document.addEventListener("pointerlockchange", (event)=>{
lock = !lock;
});
//
container.onclick = function(){
if (!lock) container.requestPointerLock();
};
//
document.addEventListener("keydown", (event) =>{
if (event.key == "a"){
PressLeft = 1;
}
if (event.key == "w"){
PressForward = 1;
}
if (event.key == "d"){
PressRight = 1;
}
if (event.key == "s"){
PressBack = 1;
}
if (event.keyCode == 32 && onGround){
PressUp = 1;
}
});
//
document.addEventListener("keyup", (event) =>{
if (event.key == "a"){
PressLeft = 0;
}
if (event.key == "w"){
PressForward = 0;
}
if (event.key == "d"){
PressRight = 0;
}
if (event.key == "s"){
PressBack = 0;
}
if (event.keyCode == 32){
PressUp = 0;
}
});
//
document.addEventListener("mousemove", (event)=>{
MouseX = event.movementX;
MouseY = event.movementY;
});
//
var pawn = new player(-900,0,-900,0,0);
// world
var world = document.getElementById("world");
function update(){
//
dx = (PressRight - PressLeft)*Math.cos(pawn.ry*deg) - (PressForward - PressBack)*Math.sin(pawn.ry*deg);
dz = - (PressForward - PressBack)*Math.cos(pawn.ry*deg) - (PressRight - PressLeft)*Math.sin(pawn.ry*deg);
dy = - PressUp;
drx = MouseY;
dry = - MouseX;
// :
MouseX = MouseY = 0;
//
collision();
//
pawn.x = pawn.x + dx;
pawn.y = pawn.y + dy;
pawn.z = pawn.z + dz;
console.log(pawn.x + ":" + pawn.y + ":" + pawn.z);
// ,
if (lock){
pawn.rx = pawn.rx + drx;
pawn.ry = pawn.ry + dry;
};
// ( )
world.style.transform =
"translateZ(" + (600 - 0) + "px)" +
"rotateX(" + (-pawn.rx) + "deg)" +
"rotateY(" + (-pawn.ry) + "deg)" +
"translate3d(" + (-pawn.x) + "px," + (-pawn.y) + "px," + (-pawn.z) + "px)";
};
function CreateNewWorld(){
for (let i = 0; i < map.length; i++){
//
let newElement = document.createElement("div");
newElement.className = "square";
newElement.id = "square" + i;
newElement.style.width = map[i][6] + "px";
newElement.style.height = map[i][7] + "px";
newElement.style.background = map[i][8];
newElement.style.transform = "translate3d(" +
(600 - map[i][6]/2 + map[i][0]) + "px," +
(400 - map[i][7]/2 + map[i][1]) + "px," +
(map[i][2]) + "px)" +
"rotateX(" + map[i][3] + "deg)" +
"rotateY(" + map[i][4] + "deg)" +
"rotateZ(" + map[i][5] + "deg)";
// world
world.append(newElement);
}
}
function collision(){
for(let i = 0; i < map.length; i++){
//
let x0 = (pawn.x - map[i][0]);
let y0 = (pawn.y - map[i][1]);
let z0 = (pawn.z - map[i][2]);
if ((x0**2 + y0**2 + z0**2 + dx**2 + dy**2 + dz**2) < (map[i][6]**2 + map[i][7]**2)){
let x1 = x0 + dx;
let y1 = y0 + dy;
let z1 = z0 + dz;
let point0 = coorTransform(x0,y0,z0,map[i][3],map[i][4],map[i][5]);
let point1 = coorTransform(x1,y1,z1,map[i][3],map[i][4],map[i][5]);
let point2 = new Array();
//
if (Math.abs(point1[0])<(map[i][6]+98)/2 && Math.abs(point1[1])<(map[i][7]+98)/2 && Math.abs(point1[2]) < 50){
point1[2] = Math.sign(point0[2])*50;
point2 = coorReTransform(point1[0],point1[1],point1[2],map[i][3],map[i][4],map[i][5]);
dx = point2[0] - x0;
dy = point2[1] - y0;
dz = point2[2] - z0;
}
}
};
}
function coorTransform(x0,y0,z0,rxc,ryc,rzc){
let x1 = x0;
let y1 = y0*Math.cos(rxc*deg) + z0*Math.sin(rxc*deg);
let z1 = -y0*Math.sin(rxc*deg) + z0*Math.cos(rxc*deg);
let x2 = x1*Math.cos(ryc*deg) - z1*Math.sin(ryc*deg);
let y2 = y1;
let z2 = x1*Math.sin(ryc*deg) + z1*Math.cos(ryc*deg);
let x3 = x2*Math.cos(rzc*deg) + y2*Math.sin(rzc*deg);
let y3 = -x2*Math.sin(rzc*deg) + y2*Math.cos(rzc*deg);
let z3 = z2;
return [x3,y3,z3];
}
function coorReTransform(x3,y3,z3,rxc,ryc,rzc){
let x2 = x3*Math.cos(rzc*deg) - y3*Math.sin(rzc*deg);
let y2 = x3*Math.sin(rzc*deg) + y3*Math.cos(rzc*deg);
let z2 = z3
let x1 = x2*Math.cos(ryc*deg) + z2*Math.sin(ryc*deg);
let y1 = y2;
let z1 = -x2*Math.sin(ryc*deg) + z2*Math.cos(ryc*deg);
let x0 = x1;
let y0 = y1*Math.cos(rxc*deg) - z1*Math.sin(rxc*deg);
let z0 = y1*Math.sin(rxc*deg) + z1*Math.cos(rxc*deg);
return [x0,y0,z0];
}
CreateNewWorld();
TimerGame = setInterval(update,10);