
ãã®èšäºã§ã¯ãããããªæŠè»ã¢ãã«ãã·ãŒã³ã«ã€ã³ããŒããã
websocket
ãš
asyncio
ã䜿çšããŠãã¬ã€ã€ãŒãšããããäºãã«åæãããéšå±éã§ãã©ã³ã¹ããšãããšããããã©ãŠã¶ãŒããŒã¹ã®
3D
ã·ã¥ãŒãã£ã³ã°ã²ãŒã ã®äœæã«ã€ããŠèª¬æããããšããŸããã
ã¯ããã«1.ã²ãŒã ã®æ§é 2.ã¢ãã«ãšãã¬ã³ããŒãã€ã³ããŒããã3. babylon.jsãšã¢ãã«èªäœã䜿çšããŠã²ãŒã ã«ã¢ãã«ãããŒããã4. babylon.jsã®åããããããããããã³ã²ãŒã ãµãŠã³ã5. Webãœã±ãããšã²ãŒã ã®åæ6.ãã¬ã€ã€ãŒãšãã®èª¿æŽ7.éšå±ãšãªããžã§ã¯ãã®Pythonã«ãããã¬ã€ã€ãŒã®ãã©ã³ã¹èª¿æŽ8. Asyncioããã³ãããã®åäœçæ9. Nginxããã³ãœã±ãããããã·10. memcacheãä»ããéåæãã£ãã·ã³ã°11.ããšãããšããŒããããPython3
ã
WebGL
ãããã³åãªãã²ãŒã ã®éåæã¢ããªã±ãŒã·ã§ã³ã®ãããã¯ã«èå³ã®ããæ¹ã¯ãç«ããé¡ãããŸãã
ã¯ããã«
ãã®èšäºèªäœã¯ã
aiohttpãš
asyncio
ã䜿çšããŠéåæã¢ããªã±ãŒã·ã§ã³ãäœæãããããã¯ã®ç¶ããšããŠèããããŠããŸããã
æåã®éšåã
aiohttp( asyncio )
äžã«
django
ãããªã¢ãžã¥ãŒã«æ§é ãäœæããæ¹æ³ã«å°å¿µããŠããå Žåã
2çªç®ã®éšåã§ã¯ãã£ãšåµé çãªããšããããããšæããŸããã
åœç¶ã®ããšãªããã
3D
ããã¡ããäœãããšã¯ç§ã«ãšã£ãŠã¯é¢çœããã§ãã²ãŒã 以å€ã§ã¯éåæããã°ã©ãã³ã°ãå¿
èŠãªå ŽåããããŸãã
ç»é²ããã«ããäºããããããéšå±ãç°¡åãªãã£ãããç°¡åãªé¢šæ¯ããããããšãã§ããããã¡ããçšæããŸãã ã²ãŒã ã¢ãã«ãšããŠãæãã·ã³ãã«ã§éŠŽæã¿ã®ããããã€ãã®æŠè»ãšãåæã«ææšãšãªãã²ãŒã ã¢ãã«ãåãäžããŸãã ããŠããã¬ãŒã ã¯ãŒã¯ã®äžéšãšããŠã
memcached
ãã£ãã·ã¥ãæãåºããŸãããã
ããããããããããã«ãäžéšã®ããã»ã¹ã¯ããªã¢ãŒãã§ã€ã³ãã©ã°ã©ãã£ãã¯ã飿³ãããåçã§è¡šãããŸããããã¯ããããã¯ãŒã¯ããã°ã©ãã³ã°ããéä¿¡ãããŠãããã®ãšåŒã³åºãããŠãããã®ãç¢å°ã§ç€ºããŠããå Žåãåžžã«ç°¡åã§äŸ¿å©ã«èŠãããšã¯éããªãããã§ãã
ã€ã³ãã©ã°ã©ãã£ãã¯ãšéåžžã®åœ¢åŒã®äž¡æ¹ã®ã³ãŒãäŸã¯ãäžè¬çãªäœæ¥ã¹ããŒã ã®çè§£ãæ·±ããããã«ãéåžžã«é »ç¹ã«ç°¡ç¥åãããŸãã ããã«ãææ°ã®ä¿®æ£ãå«ãå®å
šãªã³ãŒãã¯
githubã§è¡šç€ºã§ããŸãã
ããããããã¯å®å
šãªã²ãŒã ã§ã¯ãªãããšãçè§£ããå¿
èŠããããŸã-圌ã
git clone
ãæžããŠATMã«è¡ã£ããšããæå³ã§ã ããããã²ãŒã ãã¬ãŒã ã¯ãŒã¯ã1ã€ã®ããã«ã§ã®
asyncio
ããã³
webgl
ãã¢ãäœæãã詊ã¿ã§ãã ã·ã§ãŒã±ãŒã¹ãè©äŸ¡ã培åºçã«ãã¹ããããã»ãã¥ãªãã£ãªã©ã¯ãããŸããããäžæ¹ã§ã
open sourse
éçºããã
open sourse
ãããžã§ã¯ãã§ã¯ãæãªãšãã«ååã«æ©èœããããã§ãã
2ã¢ãã«ãšãã¬ã³ããŒã®ã€ã³ããŒã
åœç¶ãããã¡ãã«ã¯ãã£ã©ã¯ã¿ãŒã®
3D
ã¢ãã«ãå¿
èŠã§ããã颚æ¯ã建ç©ãªã©ãã·ãã¥ã¬ãŒãããã¢ãã«ãå¿
èŠã§ãã
ãã£ã©ã¯ã¿ãŒã¯ãäººãæŠè»ãé£è¡æ©ã§ãã 2ã€ã®ãªãã·ã§ã³ããããŸã-ã¢ãã«ãæç»ãã宿ãããã®ãã€ã³ããŒãããŸãã æãç°¡åãªæ¹æ³ã¯ãå°éãµã€ãã®1ã€ã§æ¢è£œã®ã¢ãã«ãèŠã€ããããšã§ãïŒããšãã°ã
hereãŸãã¯
hereïŒ ã æŠè»ãä»ã®ã¢ãã«ãæãããã»ã¹ã«èå³ããã人ãYouTubeã«ã¯ããããã®ãããªããããããã«ã¯ãã®
ãããã¯ã«é¢ããè³æããã
ãŸã ã
ã€ã³ããŒãããã»ã¹èªäœã«ã€ããŠè©³ãã説æããŸãã
blender
ã«ã€ã³ããŒãããã圢åŒã®äžã§ã
.die .obj .3ds
ãæãããèŠãããŸãã
ã€ã³ããŒã/ãšã¯ã¹ããŒãã«ã¯å€ãã®ãã¥ã¢ã³ã¹ããããŸãã ããšãã°ã
.3ds
ãã€ã³ããŒãããå ŽåãååãšããŠãã¢ãã«ã¯ãã¯ã¹ãã£ãªãã§ã€ã³ããŒããããŸããããããªã¢ã«ã¯æ¢ã«äœæãããŠããŸãã ãã®å Žåããã£ã¹ã¯ãã¯ã¹ãã£ããåãããªã¢ã«ãããŒãããã ãã§ãã
.obj
å ŽåãååãšããŠããã¯ã¹ãã£ã«å ããŠã
.mtl
ãã¡ã€ã«ãååšããå Žåããããååšããå Žåãéåžžã¯åé¡ã®å¯èœæ§ã¯äœããªããŸãã
ã¢ãã«ãã·ãŒã³ã«ãšã¯ã¹ããŒãããåŸã
webgl
衚瀺ã«åé¡ããããšããèŠåãšãšãã«ã
chrome
ã¯ã©ãã·ã¥ããããšããããŸãã ãã®å Žåãããšãã°ãè¡çªãã¢ãã¡ãŒã·ã§ã³ãªã©ãããå Žåããã¬ã³ããŒã§äœåãªãã®ããã¹ãŠåé€ããããã«ããŠãã ããã
ããã«ãæãéèŠãªãã€ã³ãã®1ã€ã§ãã ãããå
ãç§»åããã¢ãã«ã«ã€ããŠã¯ã
ã¢ãã«ãæ§æãããã¹ãŠã®ãªããžã§ã¯ããæ¥çããå¿
èŠããããŸãã ããããªããšãããããç§»åããããšã¯ã§ããŸãããèŠèŠçã«ã¯ãã¿ã³ã¯ã®ä»£ããã«ãã·ã³ã¬ã³ã®ã¿ãé§åããããã«èŠããŸãããŸããããªãŒã«å¿
èŠãªåº§æšãèšå®ããããšãããšããããäžã®äœçœ®ã¯æšã®åãæ ªã®ã¿ã倿Žããä»ã®ãã¹ãŠã¯ãããã®äžå€®ã«æ®ããŸãã
ãã®åé¡ã解決ããã«ã¯2ã€ã®æ¹æ³ããããŸãã
1ïŒã¢ãã«ã®ãã¹ãŠã®è©³çްãçµã¿åãããŠã1ã€ã®ãªããžã§ã¯ãã«ããŸãã ãã®æ¹æ³ã¯å°ãé«éã§ããã
UV
ã¹ãã£ã³ã®åœ¢åŒã§1ã€ã®ãã¯ã¹ãã£ãããå Žåã«ã®ã¿æ©èœããŸãã ãããè¡ãã«ã¯ãã·ããä»ãã®ã¢ãŠãã©ã€ãã䜿çšããŠãã¹ãŠã®ãªããžã§ã¯ããéžæããŸãããããã¯ç¹åŸŽçãªãªã¬ã³ãžè²ã§åŒ·èª¿è¡šç€ºããã
object
ã¡ãã¥ãŒã§
join
ã¢ã€ãã ãéžæããŸãã

2ïŒæ¬¡ã®ãªãã·ã§ã³ã¯ã芪åã®ååã«åŸã£ãŠãã¹ãŠã®è©³çްããªã³ã¯ããããšã§ãã ãã®å Žåãåãã£ããŒã«ã«ç¬èªã®ãã¯ã¹ãã£ããã£ããšããŠãããã¯ã¹ãã£ã«åé¡ã¯ãããŸããã ãããè¡ãã«ã¯ãå³ã¯ãªãã¯ããŠèŠªãªããžã§ã¯ããšåãé ã«éžæãã
ctrl+P
ãæŒããŠã¡ãã¥ãŒãã
object
ãéžæããŸãã ãã®çµæããªãã©ã€ã³ã¢ãŒãã§ã¯ãã¢ãã«ãæ§æãããã¹ãŠã®ãªããžã§ã¯ããåã芪ã«å±ããŠããããšãããããŸãã

ããã§ããç§ã¯ãã®ãããªçºèšãæ¿å
¥ããããšæããŸããå€ãã®å Žåãããã€ãã®ã¢ãã«ã¯ãäžæãªçç±ã«ããããã¬ã³ããŒã«ã€ã³ããŒããããªãããäœããã®ãžã£ã³ã¯ã®åœ¢ã§ã€ã³ããŒããããŸãã ãŸããéåžžã«å€ãã®å Žåãã¢ãã«ã«ä»å±ããŠããäžéšã®ãã¯ã¹ãã£ã¯é©çšããããªãå ŽåããããŸãã ãã®ãããªå Žåãäœãã§ããŸãããä»ã®ãªãã·ã§ã³ã«é²ãå¿
èŠããããŸãã
3. babylon.jsãšã¢ãã«èªäœã䜿çšããŠã²ãŒã ã«ã¢ãã«ãããŒããã
ã¢ãã«èªäœã®ããŒãã¯éåžžã«åçŽã«èŠãããã£ã¹ã¯äžã®ã¡ãã·ã¥ã®å Žæã瀺ããŸãã
loader = new BABYLON.AssetsManager(scene); mesh = loader.addMeshTask('enemy1', "", "/static/game/t3/", "t.babylon");
ãã®åŸãã¢ãã«ããã§ã«ããŒããããŠããããšãä»»æã®å Žæã§ç¢ºèªããå¿
èŠã«å¿ããŠãã®äœçœ®ãèšå®ããŠå€æããããšãã§ããŸãã
mesh.onSuccess = function (task) { task.loadedMeshes[0].position = new BABYLON.Vector3(10, 2, 20); };
ãã®å Žåã®æãäžè¬çãªæäœã®1ã€ã¯ããªããžã§ã¯ãã®ã¯ããŒã³äœæã§ããããšãã°ãããªãŒããããŸããåããªãŒãåå¥ã«ããŒãããªãããã«ãäžåºŠããŒãããŠãç°ãªã座æšã§ã·ãŒã³å
šäœã«ã¯ããŒã³ãäœæã§ããŸãã
var palm = loader.addMeshTask('palm', "", "/static/game/g6/", "untitled.babylon"); palm.onSuccess = function (task) { var p = task.loadedMeshes[0]; p.position = new BABYLON.Vector3(25, -2, 25); var p1 = p.clone('p1'); p1.position = new BABYLON.Vector3(10, -2, 20); var p2 = p.clone('p2'); p2.position = new BABYLON.Vector3(15, -2, 30); };
AssetsManager
ã®å Žåãã¯ããŒãã³ã°ãéèŠãªåœ¹å²ãæãããŸãã 圌ã¯ã·ãŒã³ã®äž»èŠéšåãããŒãããããŸã§åçŽãªã¹ãã©ãã·ã¥ç»é¢ãæç»ãã
loader.onFinish
ã«å
¥ãã
loader.onFinish
ããšã確èªããŸãã
var createScene = function () { . . . } var scene = createScene(); loader.onFinish = function (tasks) { engine.runRenderLoop(function () { scene.render(); }); };

ããŸããŸãªçç±ã«ãããã²ãŒã äžã«ãã以äžããŒãããããšã¯é¿ããªããã°ãªããŸããã ãããã£ãŠããã¹ãŠã®ãã£ã©ã¯ã¿ãŒã¯åæåäžã«ããŒãããããã§ã«ãœã±ããã®åŠçãããã¬ãŒã€ãŒã®å€èгãšåäœãæ
åœããã¯ã©ã¹ã§ãå¿
èŠãªæ©åšãªã©ã®ã¯ããŒã³ãäœæããŸãã ã¹ããŒã ã¯æ¬¡ã®ããã«ãªããŸãã

ããã«ãã¢ãã«èªäœã«ã€ããŠå°ã説æããããšæããŸãããã®ããŒãžã§ã³ã®ã«ãŒãã¯æ¢æã®ãœãªã¥ãŒã·ã§ã³ãšãããããå®éšçãªãã®ã§ãããå
šäœåãçè§£ããã®ã«å®³ã¯ãããŸããã
ãã®å Žåããã£ã©ã¯ã¿ãŒã¯2çš®é¡ã®æŠè»ãT-90ãšãšã€ãã©ã ã¹ã«ãã£ãŠè¡šãããŸãã åå©ãšæåã®ã²ãŒã ããžãã¯ã¯ãªãããããã¬ãŒã ã¯ãŒã¯ã®å Žåã¯ãåã
ã®ã±ãŒã¹ããšã«ããããã¹ãŠãçºæããå¿
èŠãããããšãæç€ºãããŠããŸãã ã ããä»ã¯éžæè¢ããªããæåã®äººã¯åžžã«ãšã€ãã©ã ã¹ããã¬ã€ããããããšä»ã®ãã¹ãŠã®ãã¬ã€ã€ãŒã¯T-90ãšããŠè¡šç€ºãããŸãã
ãããèªäœã«ã¯ãç¹å®ã®ã¬ãªãŒãããããŸã
ãheightMapãšåŒã°ãã
babylon.js
ã䜿çšããŠéåžžã«ç°¡åã«äœæãããŸãããã®ãããåå£ãã¯ã¹ãã£ã«é»ãšçœã®ç»åãé©çšããå¿
èŠããããŸããäžã§ã¯ãç¹æ§ã®äžéšããã©ã¡ãŒã¿ã§æå®ã§ããŸããæãéšåãšçœãéšåã®éã®é·ç§»ããŒãããŠããã»ã©ãåŸé
ã¯ç·©ããã«ãªããŸãã
var ground = BABYLON.Mesh.CreateGroundFromHeightMap("ground", "/static/HMap.png", 200, 200, 70, 0, 10, scene, false); var groundMaterial = new BABYLON.StandardMaterial("ground", scene); groundMaterial.diffuseTexture = new BABYLON.Texture("/static/ground.jpg", scene); ground.material = groundMaterial;

ããã«ãå®¶ã®åœ¢ã®å°ããªåŽè¿ããã®è¿ãã®çµŠæ°Žå¡ãããã€ãã®æšãšããã€ãã®èããããŸãã
èçã¯ãæå€§ã®äœããªã§ããã¯ã¹ãã£ããã®äžã«ãããã¬ãŒã³ã§åºãŠããŸããã ãããŠããã®é£è¡æ©ã¯ããŸããŸãªå Žæã§åŸããŠããŸãã äžè¬çã«ãããªãŽã³ã¢ãã«ãäœããã°äœãã»ã©ãããã©ãŒãã³ã¹ã¯åäžããŸãããæãããªçç±ã«ããããšã³ã¿ãŒãã€ã¡ã³ããæãªãããŸãã
ãã¡ãããèšå®ãã°ã©ãã£ãã¯å質ãã§éžæãè¡ãããšã¯ã§ããŸãããç§ãã¡ã®å Žåã¯ã§ããŸããã
èãšã¯ç°ãªãããããã®ã€ã·ã«ã¯ããªãã®æ°ã®ããŒã¯ãããããããããäžã«æ°åã®ããŒã¹ââã®ã¿ãæ®ãããšã«ããŸããã
ãããäžã®é ç¹ãå€ãã»ã©ã
FPS
ã¯äœããªããŸãã

å®¶ã¯å°ãé¢ããŠãããè¡çªã®ããéæãªç«æ¹äœã§èŠãããšã決å®ãããŸããã
ãããŠæåŸã«æ®ãããã®ã¯3ã€ã®ã«ã©ãã«ãªãã¥ãŒãã§ãããããã¯ãã¹ãŠã®ãŠãŒã¶ãŒã«å¯ŸããŠåæãããŠããããåçŽãªã¿ãŒã²ããã衚ããŠããŸãã ããããã«ããããããšãç¹ç¯ããŠæ¶ããŸãã

4. babylon.jsã®åããããããããããã³ã²ãŒã ãµãŠã³ã
åãã«ã€ããŠèšãã°ãããã¯äž»ã«æåã®äººã«é¢ãããã®ã§ããä»ã®ãã¬ã€ã€ãŒããããã®åãã¯åžžã«äœçœ®ã®å€åã§ãããã»ãšãã©ã®å ŽåããµãŒããŒããã®ãœã±ããã䜿çšããŠãããŒããã£ã¹ããããŸãã
ããèªäœã§ã¯ãåãã¯åã«ã«ã¡ã©ãšãã¬ãŒã€ãŒã®ç®ã«èŠããéšåãå¶åŸ¡ããã ãã§ãã ããšãã°ããã¬ãŒã€ãŒãå³ã«æ²ããã®ã§ãã«ã¡ã©ãç§ãã¡ãèŠãŠããå Žæã«å¯ŸããŠå³ã«åãããã·ãŒã³ãç®çã®çšåºŠã«å転ãããå¿
èŠããããŸãã ãŸããããšãã°ãæµãåãããã®ããã€ãã®ææ®µãæããã¢ãã«ãæå¹ã«ããå¿
èŠããããŸãã
åºæ¬çã«äžäººç§°ã®åãã®ããã«
babylon.js
ã§äœãããã²ãŒã ã§ã¯ã2ã€ã®ã«ã¡ã©ããããŸãïŒ
FreeCamera
ååãšããŠããã£ã©ã¯ã¿ãŒã®èŠªã§ããããã£ã©ã¯ã¿ãŒã¯åçŽã«ããã«åŸããŸããé«åºŠãªæè¡ã人ãé£è¡ãããã¹ãŠã®ãã®ã«äœ¿çšããã®ã«éåžžã«äŸ¿å©ã§ãFreeCamera
ã¯æ
£æ§ãšé床ã調æŽããæ©èœãããããããéåžžã«éèŠã§ããFollowCamera
å察ã«ãããã¯ããçš®ã®ãªããžã§ã¯ããFollowCamera
ããã«ã¡ã©ã§ããããŠã¹ãšããŒããŒãããã®ã³ã³ãããŒã«ãç°ãªãå Žåã«äœ¿çšãããšäŸ¿å©ã§ãã ã€ãŸããã¬ãã¥ãŒã¯ç§»åã®æ¹åã«äŸåããŸããã
äŸïŒ
ç§»åäžããããäžãã·ã§ããäžãç§»åäžãªã©ã«ããã€ãã®é³ãããã¯ãã§ãã
babylon.js
ã«ã¯åªãããµãŠã³ã管ç
APIããããŸã ã ãµãŠã³ãã³ã³ãããŒã«ã®ãããã¯ã¯éåžžã«åºç¯å²ã§ãããããããã€ãã®å°ããªäŸãæ€èšããŸãã
åæåã®äŸïŒ
var music = new BABYLON.Sound("Music", "music.wav", scene, null, { playbackRate:0.5,
ã·ã§ããã®é³ã®äŸ-ã¯ãªãã¯ãããšãã€ã³ã¿ãŒããã¯ãè§£é€ãããŠããããšã確èªããã·ã³ã°ã«ã·ã§ããã®é³ãåçããŸãã
var gunS = new BABYLON.Sound("gunshot", "static/gun.wav", scene); window.addEventListener("mousedown", function (e) { if (!lock && e.button === 0) gunS.play(); });
ç¢å°ãååŸã«æŒããŠãããã«å¿ããŠåçãéå§ããå Žåã«ãæ©åšã®åãã®é³ã忢ããŸãã ããŒãªãªãŒã¹ã€ãã³ãã§ãåçã忢ããŸãã
var ms = new BABYLON.Sound("mss", "static/move.mp3", scene, null, { loop: true, autoplay: false }); document.addEventListener("keydown", function(e){ switch (e.keyCode) { case 38: case 40: case 83: case 87: if (!ms.isPlaying) ms.play(); break; } }); document.addEventListener("keyup", function(e){ switch (e.keyCode) { case 38: case 40: case 83: case 87: if (ms.isPlaying) ms.pause(); break; } });
ããããã
ã·ã¥ãŒãã£ã³ã°ã²ãŒã ã«ã¯ããã¬ã€ã€ãŒã ããèŠãããšãã§ãããããããããŸãã¯äžåºŠã«ãã¹ãŠãèŠãããšãã§ããããããããå¿
èŠã§ãããã®å ŽåãããèŠããšãã·ã§ã«ãèŠãããšãã§ããŸãã
babylon.js
ãããå®è£
ããæ¹æ³ã¯ããã€ããããŸãã ããããæãç°¡åãªæ¹æ³ã¯ãå¥ã®ã«ã¡ã©ãäœæãããããã®äžã«é
眮ãããã®ã«ã¡ã©ããã®ãã¥ãŒãå¿
èŠãªã³ãŒããŒã«é
眮ããããšã§ãã

ç§ãã¡ã®å Žåã
freeCamera
ã䜿çšããŠã
freeCamera
ãäžçªäžã«é
眮ããããã«äŒããŸãã
camera2 = new BABYLON.FreeCamera("minimap", new BABYLON.Vector3(0,170,0), scene);
Y
座æšã倧ããã»ã©ããã¥ãŒã¯å®å
šã«ãªããŸããããããã®è©³çްã¯çްãããªããŸãã
次ã«ãã«ã¡ã©ã«ç»åãã¹ã¯ãªãŒã³ã«é
眮ããæ¹æ³ãã«ã¡ã©ã«äŒããŸãã
camera2.viewport = new BABYLON.Viewport(x, y, width, height);
æåŸã«ãäž¡æ¹ã®ã«ã¡ã©ãã·ãŒã³ã«è¿œå ããå¿
èŠããããŸãïŒã«ã¡ã©ã1å°ã®å Žåããããè¡ãå¿
èŠã¯ãããŸããïŒã
scene.activeCameras.push(camera); scene.activeCameras.push(camera2);
5. Webãœã±ãããšã²ãŒã ã®åæ
ã²ãŒã ã®åºæ¬æ§é å
šäœã
websoket
æ§ç¯ããããã¬ã€ã€ãŒã¯äœããã®ã¢ã¯ã·ã§ã³ãããŠã¹ã®å転ããŸãã¯ããŒã¹ãããŒã¯ãå®è¡ãããã¬ã€ã€ãŒã®äœçœ®åº§æšããµãŒããŒã«éä¿¡ãããã€ãã³ãããã®åãã§ãã³ã°ã¢ããããŸããéšå±ã
æåã¯ã
FreeCamera
ã䜿çšããããã芪ãªããžã§ã¯ãã§ããããããã®åº§æšã䜿çšããŸãã äŸïŒ
camera.cameraRotation
è»žã«æ²¿ã£ãå転ã®X
ããã³Y
座æšãå«ãŸããŸããcamera.position
ãããäžã®ã¡ãã·ã¥ã®äœçœ®ã®X
ã Y
ã Z
座æšãå«ãŸããŸãã
次ã®å³ã§ã¯ããµãŒããŒãžã®æ¥ç¶ãéããŠæ°ãããã¬ãŒã€ãŒãäœæããŠããããŠãŒã¶ãŒã®ã¢ã¯ã·ã§ã³ã«å¿çãããšãã«ã¡ãã»ãŒãžã亀æãããŸã§ã®ããã»ã¹äŸã瀺ããŠããŸãã

6.ãµãŒããŒåŽã®ããã€ã¹
äžèšã§ã¯ãéåžžã«ç°¡æœãªç°¡åãªå³ãèŠãŸããããä»åºŠã¯ãµãŒããŒåŽã®åäœã«ã€ããŠè©³ãã説æããŸãã ãœã±ãããã³ãã©ãŒã®é¢æ°ã§ã¯ã次ã®ã¡ãã»ãŒãžãåä¿¡ããåŸããã®
action
ã確èªããæ¬¡ã«ãã¬ãŒã€ãŒãå®è¡ãã
action
ã確èªããããã«åŸã£ãŠç®çã®é¢æ°ãã€ãã³ããã³ãã©ãŒãåŒã³åºããŸãã
async def game_handler(request): . . . async for msg in ws: if msg.tp == MsgType.text: if msg.data == 'close': await ws.close() else: e = json.loads( msg.data ) action = e['e'] if action in handlers: handler = handlers[action] handler(ws, e) . . .
ããšãã°ã
move
ãæ¥ãå Žåãããã¯ãã¬ã€ã€ãŒãããã€ãã®åº§æšã«ç§»åããããšãæå³ããŸãã ãã®ã¢ã¯ã·ã§ã³ã®é¢æ°ãã³ãã©ãŒã§ã¯ããããã®åº§æšã
Player
ã¯ã©ã¹ã«å²ãåœãŠãã ãã§ããããã®åº§æšãåŠçãããŠæ»ãããããã«çŸåšã®éšå±ã®ä»ã®ãã¹ãŠã®ãã¬ãŒã€ãŒã«éä¿¡ãããŸãã
def h_move(me, e): me.player.set_pos(e['x'], e['y'], e['z']) mess = dict(e="move", id=me.player.id, **me.player.pos_as_dict) me.player.room.send_all(mess, except_=(me.player,))
ãã¡ãããçŸåš
Player
ã¯ã©ã¹ã座æšã§è¡ãããšã¯ãã¹ãŠãåçŽã«ãããããããã«æž¡ããŠãçŠç¹ãåãããŸãã ãããŠçæ³çã«ã¯ã座æšã§ãããå
šäœããã§ãã¯ããå¿
èŠããããŸãããã¬ãŒã€ãŒãé害ã«ééããå Žåãããšãã°äžæ£è¡çºãé¿ããããã«ãã¯ã©ã€ã¢ã³ãã§ã¹ã¯ãªããã倿Žãããå Žåãå£ããæŒããªãããã«ããå¿
èŠããããŸãã
class Player(list): . . . def __init__(self, client, room, x=0, y=0, z=0, a=0, b=0): list.__init__(self, (x, y, z, a, b)) self._client = client self._room = room Player.last_id += 1 self._id = Player.last_id room.add_player(self) . . . def set_rot(self, a, b): self[3:5] = a, b def getX(self): return self[0] . . . def setX(self, newX): self[0] = newX . . . x = property(getX, setX) . . . @property def pos_as_dict(self): return dict(zip(('x', 'y', 'z'), self.pos))
Player
ã¯ã©ã¹ã§ã¯ã
property
ã䜿çšããŠã座æšããã䟿å©ã«åŠçããŸãã è峿·±ãã®ã¯ãããã©ã§ãã®ããŒãã«é¢ããè¯ã
è³æããã£ãããšã§ãã
7.éšå±ããšã®ãã¬ã€ã€ãŒã®ãã©ã³ã¹
ã²ãŒã ã®ããªãéèŠãªéšåã¯ãç°ãªãæ°æãéšå±ãææãåœãªã©ã§ãã¬ã€ã€ãŒãè²ãŠãããšã§ãã ãã以å€ã®å Žåããã¹ãŠã1æã®ã«ãŒãã«åãŸããªãããã§ãã ç§ãã¡ã®å Žåãã·ã¹ãã ã¯ãŸã éåžžã«ã·ã³ãã«ã§ã-1ã€ã®éšå±ã«èšå®ã§èšå®ãããŠãããããå€ãã®ãã¬ã€ã€ãŒãããå ŽåïŒããã©ã«ãã§ã¯ãããã§4ïŒãæ°ããéšå±ãäœæããæ®ãã®ãã¬ã€ã€ãŒãããã«åã§éä¿¡ããŸãã
çŸæç¹ã§ã¯ãã·ã§ãŒã±ãŒã¹ãšã¬ãŒãã£ã³ã°ããªããããäœããã®ããŒã¹ã䜿çšããæå³ããªããããã©ã®éšå±ã®ã©ã®ãã¬ãŒã€ãŒãªã©ã«é¢ãããã¹ãŠã®æ
å ±ãã¡ã¢ãªã«ä¿åãããŸãã
ã«ãŒã çªå·ã¯ããã¬ã€ã€ãŒãã«ãŒã
/pregame
ããã¹ã¿ãŒãããŒãžããã²ãŒã ã«å
¥ããšãã«å²ãåœãŠãããŸãã ãã¿ã³ãæŒããããšã
ajax
ããªã¬ãŒãããŸããçµæãæåããå Žåã¯ããã¬ãŒã€ãŒãç®çã®éšå±ã«ãªãã€ã¬ã¯ããããŸãã
if (data.result == 'ok') { window.location = '/game#'+data.room;
ãµãŒããŒåŽã§ã¯ããã¹ãŠã®éšå±ãšãã®äžã®ãã¬ã€ã€ãŒã®ãªã¹ããå«ã
rooms
ãã£ã¯ã·ã§ããª
id
ãŸãããã¬ã€ã€ãŒã®æ°ãæå®ãããå€ãè¶
ããŠããªãå Žåã¯ãéšå±
id
ã¯ã©ã€ã¢ã³ãã«è¿ããŸãã ãã¬ã€ã€ãŒã®æ°ãå€ãå Žåã¯ãæ°ããéšå±ãäœæããŸãã
def check_room(request): found = None for _id, room in rooms.items(): if len(room.players) < 3: found = _id break else: while not found: _id = uuid4().hex[:3] if _id not in rooms: found = _id
Room
ã«ã€ããŠã¯ã
Room
ã¯ã©ã¹ãæ
åœããŸãã 圌ã®äžè¬çãªäœæ¥ã¹ããŒã ã¯æ¬¡ã®ããã«ãªããŸãã

Player
ã¯ã©ã¹ãšçžäºäœçšããããšãããããŸãããããããã¹ããŒã å
šäœã¯å®å
šã«ç·åœ¢ã«èŠããŸããããæçµçã«ã¯ããã®ãããªãã§ãŒã³ãéåžžã«äŸ¿å©ã«æžãããšãã§ããŸãã
ç§ã¯ãç§ã®ååã«ã€ããŠããã®æèµ·ããã質åã«ã€ããŠå°ã話ãããããšæããŸãã
me
ã¯ãã€ãã³ããæäŸãã颿°ã®ãã©ã¡ãŒã¿ãŒãšããŠæž¡ããããœã±ããã§ãã
def h_new(me, e): me.player = Player(me, Room.get( room_id ), x, z)
ããã§ãå®éã«ã¯ã翻蚳è
ãèšãããã«ããããã Pythonã®ãã¹ãŠããªããžã§ã¯ãã§ããããšãç¥ã£ãŠããã®ã§ã
ããã¯ããæç¢ºã«èµ·ããããšã§ãïŒ
player = Player( Room.get(room_id), x, z) player.me = me me.player = player
player
ã¢ãžã¥ãŒã«ãš
me
ãªããžã§ã¯ãã®
.player
ãšãã2ã€ã®ãªã³ã¯ãååŸããŸããäž¡æ¹ãšãçãããå°ãªããšã1ã€ã®ãªã³ã¯ãååšããéãååšããã¡ã¢ãªå
ã®åããªããžã§ã¯ããåç
§ããŸãã
ããã¯ããã«ç°¡åãªäŸã§èŠãããšãã§ããŸãïŒ
>>> a = {1} >>> b = a >>> b.add(2) >>> b {1, 2} >>> a {1, 2}
ãã®äŸã§ã¯ã
b
ãš
a
ã¯1ã€ã®å
±éå€ãžã®åãªãåç
§ã§ãã
>>> a.add(3) >>> a {1, 2, 3} >>> b {1, 2, 3}
ããã«èª¿æ»ããŸãã
>>> class A(object): ... pass ... >>> a = A() >>> a.player = b >>> a.player {1, 2, 3} >>> b {1, 2, 3} >>> a.__dict__ {'player': {1, 2, 3}}
ãªããžã§ã¯ãã®ããããã£ã¯åãªãæ§æç³ã§ãã ãã®å Žåããããã¯åã«
__dict__
èŸæžã«æ ŒçŽãããŸã
ãã®çµæããªã³ã¯
a
1ã€ã匷å¶çµäºããŸã
a
ããã®ä»£ããã«ãæ°ããäœæãããªããžã§ã¯ãã«å±ããå¥ã®ãªã³ã¯ãäœæããå®éã«ãã®ãªããžã§ã¯ãã®èŸæž
__dict__
ãŸãã
>>> a <__main__.A object at 0x7f3040db91d0>
8. Asyncioããã³ãããã®åäœçæ
éåžžã®ã²ãŒã ã§ã¯ãå°ãªããšã1ã€ã®ããããå¿
èŠã§ãããã®ã²ãŒã ãäŸå€ã§ã¯ãããŸããã ãã¡ãããããããã§ããã®ã¯åå¿åãæãããšã ãã§ããã¬ã€ã€ãŒããã座æšã«åŸã
ã«è¿ã¥ããŠãããŸãã æ°ãããã¬ãŒã€ãŒãå
¥ããšããããã¯ããã«æ³šæãåããŸãã
ããããç§»åãã座æšã«é¢ããéšå±å
ã®ãã¹ãŠã®ãã¬ã€ã€ãŒã«ã¡ãã»ãŒãžãéä¿¡ããè¡ã
mess = dict(e="move", bot=1, id=self.id, **self.pos_as_dict) self.room.send_all(mess, except_=(self,))
次ã®ããã«ã¯ã©ã€ã¢ã³ãéšåãšããããšã®çžäºäœçšã®äžè¬çãªã¹ããŒã ã¯æ¬¡ã®ãšããã§ãã
ã¯ã©ã¹ã§ã¯Room
ãç§ãã¡ã¯ã__init__
ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãBot
ããããŠããã§ã«def __init__
ã¯ã©ã¹ã§Bot
ãç§ãã¡ã¯asyncio.async(self.update())
åãã¹äžã§å®è¡ãããªããã°ãªããªãã¿ã¹ã¯ãperedaomããå«ã颿°ãåŒã³åºããŠãawait
ã颿°èªäœã¯éå§ãããŸãããããžã§ãã¬ãŒã¿ãŒãªããžã§ã¯ããäœæãããŸããclass
ãã®é¢æ°ã¯éå§ããªãããã宣èšããã颿°ãåŒã³åºãã ãã§ãªãããã®ã¯ã©ã¹ãæäŸãããªããžã§ã¯ããäœæããŸããawait
ãžã§ãã¬ãŒã¿ãŒã§ã¡ãœãããåŒã³åºããããšãå«ã颿°ã®åŒã³åºããçºçããŸã.__next__()
ããã®å Žå- next
ãã³ã¬ãŒã¿ã«ããasync
-ã³ã«ãŒãã³ãåæåããŸããç°¡åã«èšãã°ã100ããªç§ããšã«ãããã®æ°ãã座æšã䜿çšããŠã¯ã©ã€ã¢ã³ãã«ã¡ãã»ãŒãžãéä¿¡ãã0.5ç§ããšã«ãããã®åº§æšãæŽæ°ããŸããç¡éã«ãŒãã§ã¿ã¹ã¯ãæäœããç°¡åãªäŸïŒ import asyncio async def test( name ): ctr = 0 while True: await asyncio.sleep(2) ctr += 1 print("Task {}: test({})".format( ctr, name )) asyncio.ensure_future( test("A") ) asyncio.ensure_future( test("B") ) asyncio.ensure_future( test("C") ) loop = asyncio.get_event_loop() loop.run_forever( )
å
¥ãããã¹ãŠã®é¢æ°ã¯ã2ç§ã§asyncio.ensure_future
æå®ãasyncio.sleep(2)
ããé
å»¶ã§åã§å®è¡ãããŸãïŒãããã®å®çšçãªçšéã¯éåžžã«åºç¯å²ã§ãããã²ãŒã çšã®ãããã«å ããŠãããšãã°ãã¬ãŒãã£ã³ã°ã·ã¹ãã çšã®ãããã ããæžãããšãã§ããŸããç§ã®äž»èгçãªæèŠã§ã¯ãããã¯å Žæã§ã®éçºãç°¡çŽ åããéåžžã«äŸ¡å€ããããåç©åãåé¿ããŸãã9. Nginxããã³ãœã±ãããããã·
ãããŠã²ãŒã ã«é¢ããŠèšåããæåŸã®ããšã¯ãNginx
ç§ãã¡ã®ãããžã§ã¯ãã確å®ã«åäœããwebsocket
ãšç¢ºä¿¡ããŠããå Žåã®æ£ããèšå®ã§ãhttp
ãæåã«æãæµ®ãã¶ã®ã¯ããã®æ§æã®ãããªãã®ã§ãïŒ server { server_name aio.dev; location / { proxy_pass http://127.0.0.1:8080; } }
ãŸããããŒã«ã«ã§æ£åžžã«åäœããŸããã1ã€ã®æ ¹æ¬çãªæ¬ ç¹ããããŸãããœã±ããã¯ããã®èšå®ã§ã¯å€éšãµãŒããŒã§åäœã5.5.5.10
ãªããªãloalhost
ãŸãããããã£ãŠã次ã®ã¢ã€ãã¢ã¯æžãããšã§ãã server { server_name aio.dev; location / { proxy_pass http://5.5.0.10:8080; } }
ãããã圌女ã¯Pythonã®ããã©ãŒãã³ã¹æ§èœã®äœãã®ã§ãããŸãã«ããæ¬ é¥ãããnginx
æ¡éãã«ãããšããããã®å Žåã«proxy_pass
ããªããã°ãªããªãhttp://127.0.0.1:8080
ã®ã§ãæ©äŒãåãNginx
ãœã±ããããããã·ãæ°å¹Žåã«ç»å Žã-aããïŒ server { server_name aio.dev; location / { proxy_pass http://127.0.0.1:8080; } location /ws { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
ãœã±ãããåæåãããšãã®ã¢ãã¬ã¹ã«ã¯ãããŒã80ãæå®ããŸããããã¯ãæç€ºçã«æå®ããªãéããããã©ã«ãã§ããŒã80ã§ãªãã¹ã³ããããã«æ§æãããŠããvar uri = "ws://aio.dev:80/ws"
ããNginx
ã§ãlisten
ããã®æ§æã§ã¯ããããããã«åãã ããNginx
çªç®ããããŠäŸ¿å©ã«ã¢ã¯ã»ã¹å¯èœãšãªãwebsoket
ãSãããã³http
ã10.éåæãã£ãã·ã¥ã
ãã®ã²ãŒã ã¯ãã¬ãŒã ã¯ãŒã¯ã®ãã©ã°ã€ã³ã³ã³ããŒãã³ãã®1ã€ãšããŠèšè¿°ãããŠãããããå°ããªã€ãããŒã·ã§ã³ã«ã€ããŠå°ã説æããããšæããŸãããã®memcached
ãããã§é¢æ°ã䜿çšããããŒãžãã£ãã·ã³ã°ã®äŸãèããŠã¿ãŸãããasync def
ãå€ããå°ãªãã蚪åããã¯ã©ã·ãã¯ãµã€ãã§ã¯ãã¡ã€ã³ããŒãžããã¥ãŒã¹ããŒãžãªã©ã®èšªåããããŒãžããã£ãã·ã¥ã§ããã»ããããŒãžã倿Žããããšãã«ãã£ãã·ã¥æéãåããåã«ãã£ãã·ã¥ããªã»ããã§ããããã«ããå¿
èŠããããŸãã幞ããªããšã«ãmemcached ã®éåæãã©ã€ããŒã¯æ¢ã«svetlovã«ãã£ãŠäœæãããŠããããã³ã¬ãŒã¿ãŒãäœæããããã€ãã®å°ããªåé¡ã解決ããããã«æ®ã£ãŠããŸããããèªäœã§ã¯ãããšãã°ã次ã®ããã«ãä»»æã®é¢æ°ã«å¯ŸããŠãã³ã¬ãŒã¿ã®åœ¢ã§ããªã銎æã¿ã®ããæ¹æ³ã§ãã£ãã·ã³ã°ãè¡ãããšã決å®ãããŸãããããŒã«ãŒããã³ã¬ãŒã¿ã§ã¯ããã£ãã·ã¥æéãèšå®ããç¹ã«memcachedã®ããŒãšãªãååãèšå®ããå¿
èŠããããŸããããŒã¿memcached
ã¯ã·ãªã¢ã«åãããŠäœ¿çšããpickle
ãŸãããããŠãã1ã€ã®ãã¥ã¢ã³ã¹-ãã¬ãŒã ã¯ãŒã¯ã¯æäžéšaiohttp
ã«èšè¿°ãCIMultiDict
ããŠãããããã·ãªã¢ã«åãããŠããŸãããåãããŒãæã€æ©èœãåããèŸæžã®å®è£
ã§ãããäœæCython
è
ã«ããé«éã«èšè¿°ãããŠããŸãaiohttp
ã dct = CIMultiDict() print( dct ) <CIMultiDict {}> dct = MultiDict({'1':['www', 333]}) print( dct ) <MultiDict {'1': ['www', 333]}> dct = MultiDict([('a', 'b'), ('a', 'c')]) print( dct ) <MultiDict {'a': 'b', 'a': 'c'}> dct = dict([('a', 'b'), ('a', 'c')]) print( dct ) {'a': 'c'}
ãããã£ãŠãããã«æ ŒçŽãããå€ã¯ã§ã·ãªã¢ã«åã§ããŸããã§ããpickle
ããããã£ãŠãããããååŸããŠå梱å
ããå¿
èŠããããŸããããæéãçµã€ã«ã€ããŠCIMultiDict
ã·ãªã¢ã«åå¯èœã«ãªãããšãé¡ã£ãŠãpickle
ãŸãã d = MultiDict([('a', 'b'), ('a', 'c')]) prepared = [(k, v) for k, v in d.items()] saved = pickle.dumps(prepared) restored = pickle.loads(saved) refined = MultiDict( restored )
å®å
šãªãã£ãã·ã³ã°ã³ãŒã def cache(name, expire=0): def decorator(func): async def wrapper(request=None, **kwargs): args = [r for r in [request] if isinstance(r, aiohttp.web_reqrep.Request)] key = cache_key(name, kwargs) mc = request.app.mc value = await mc.get(key) if value is None: value = await func(*args, **kwargs) v_h = {} if isinstance(value, web.Response): v_h = value._headers value._headers = [(k, v) for k, v in value._headers.items()] await mc.set(key, pickle.dumps(value, protocol=pickle.HIGHEST_PROTOCOL), exptime=expire) if isinstance(value, web.Response): value._headers = v_h else: value = pickle.loads(value) if isinstance(value, web.Response): value._headers = CIMultiDict(value._headers) return value return wrapper return decorator
ãã£ãã·ã³ã°ã¯ããã³ã¬ãŒã¿ãäžçªäžã«èšè¿°ãããã£ãã·ã¥ã®æå¹æéãšååãæå®ããã ãã§é©çšã§ããŸãã from core.union import cache @cache('list_cached', expire=10 ) async def list_tags(request): return templ('list_tags', request, {})
ããšãã
ãã®æ®µéã§ã¯ãããã¯ããããå¯èœæ§ãå®èšŒããããã«ãå¯èœæ§ã®é«ãã²ãŒã ã®åæã®å®æœæ®µéã§ãããšWebGL
ããasyncio
補åçããããããããã¬ãŒã ã¯ãŒã¯ã®å°æ¥ã®ããŒãžã§ã³ã§ã¯ããã¹ãŠãçæ³ã«ã¯ããã«è¿ã¥ãããšãé¡ã£ãŠããŸãã空äžãå°äžããããŠåã«åã
ã®ãã¬ã€ã€ãŒãšããŠããã¬ã€ã€ãŒãæŠéã®ãã£ã©ã¯ã¿ãŒãéžæãããåçã«å€æŽãããã§ããã¹ããŒã¹ãµã¬ã®åœ¢ã§ã²ãŒã ãäœããããšæããŸããç§ã¯åžžã«ã¹ã¿ãŒãŠã©ãŒãºã®ãã£ã©ã¯ã¿ãŒã奜ãã ã£ãã®ã§ãæŽå²çãªãã®ãããæªæ¥çãªæ¹æ³ã§ãã¹ãŠãããããã§ããèšå®ã§ã²ãŒã ã®ä»»æã®ã¬ãã«ãããŒã«ã©ã€ãºãããããã¡ã€ã³ã®ã¬ãã«ã«ããå¯èœãªéãã²ãŒã ã®ã«ãŒããšãã£ã©ã¯ã¿ãŒãåçã«å€æŽããæ©èœãåããŠããŸãã以äžã¯ãäž»ã«ãããçšåºŠèšããçšåºŠã«çŸåšååšããæãå¯èœæ§ã®é«ãããããªãäœæ¥ãè¡ãããäž»ãªæ¬ ç¹ã§ããping
ãµãŒããŒã¯åãã¬ãŒã€ãŒããã®pingãç£èŠããããããç§»åãªã©ã®é床ãåæããããšããå¿
èŠããããŸããå°ãªããšãããããæ°ãããã¬ã€ã€ãŒãåå ãããšãã圌ã¯å¯ŸæŠçžæãã»ãŒåãpingãæã£ãŠããéšå±ã«å
¥ãå¿
èŠããããŸãã忥çšã§ãããããŸããŸãªãªãã·ã§ã³ãæãæµ®ãã³ãŸããäžæ£è¡çº
åœç¶ãã¯ã©ã€ã¢ã³ããæ±ºããŠä¿¡é Œããã¹ãã§ã¯ãããŸãããéåžžã®ãµãŒããŒã§ã¯ããããå
šäœãå®å
šã«çè§£ãããã¬ãŒã€ãŒã®ãã¹ãŠã®åãã匟䞞ã®è»éããã§ãã¯ããå¿
èŠããããŸããããã§ãªããã°ãã²ãŒã ã®æå°ã®äººæ°ã§ã倿§ãªäžæ£è¡çºã®ç¹æ ã¯é¿ããããªãã§ããããããŒãããã-ã²ãŒã
ã¯ã©ã€ã¢ã³ãïŒ- ãããå°æãããå€ãã®æŠåšã
- ã¿ã³ã¯å¶åŸ¡-ã¿ã¯ãŒã®ã¿ãããŠã¹ã§å転ããã¿ã³ã¯èªäœã¯ç¢å°ã§å転ããŸã
- ããŸããŸãªè§åºŠããã®åã
- å®å®/空æŠçšã®ããããšã³ã³ãããŒã«ã®è¿œå
- ã¢ãŒãã³ãã©ãŒã®ãããªãã£ãŒã«ãã«æ©å
µæŠäºããããšãã£ã©ã¯ã¿ãŒã远å ãã
ãµãŒããŒïŒ- ãã¹ãŠã®åãã確èªãã
- ã·ã§ããã®æ¹åã確èªãã
- ãããã®æ©èœãæ¡åŒµããïŒããšãã°ããããã®æ°ãå¢ãããåçã«æžãããªã©ïŒ
- ãããã®ããŒã¹AI
ããŒãããã-ãã¬ãŒã ã¯ãŒã¯å
šäœ
- å°ããCMS
- å庫äŒèšã®ã³ã³ã¹ãã©ã¯ã¿ãŒïŒããERPïŒ
- ã¬ããŒããã¶ã€ããŒ
- MongoDBã®Webã¯ã©ã€ã¢ã³ã
- ãã¢ãããœãŒã·ã£ã«ãããã¯ãŒã¯
äœããæžãã®ãå¿ããŠãã©ããã§åœŒã¯çšèªãšééãããããããããŸããããããã£ãŠããã¹ãŠã®ææ³çããã³ãã®ä»ã®ãšã©ãŒãPMã«æžã蟌ããããé¡ãããŸããåç·šbabylon.jsã«é¢ããèšäºã確èªãã githubã®three.jsã©ã€ãã©ãªãšæ¯èŒããããã¥ã¡ã³ããèªãç¡æã®å€§èŠæš¡ãªéžæãäž»èŠãªãµã€ãã®äžã€ãšã¯ã3Dã¢ãã«ãæ¯æã£ããã¬ã³ããŒã®ããã®ç¡æã®3Dã¢ãã«ãšãŠã§ããµã€ããå転babylon.jsã®äžã®é³ãšäœæ¥é³ã®å¯èŠåäŸasynioã«ããã®äžçã¹ãªãŒãã¿ã¹ã¯ãšäœæ¥ã¹ãããé話PEP-0492ã®ããã° Svetlovã® aiohttpèè
memcachedã®éåæãã©ã€ãbabylon.jsã®ããã®æŽæ°ãããããã¥ã¡ã³ãgithubã®äžã®ææžaiohttpaiohttpããã¥ã¡ã³ãreadthedocsã®ããã®æ©çãŸãæããããã¥ã¡ã³ãã©ã€ãã©ãªã®ãªã¹ã- AIO-LIBSã®å¥ã®ããå
æ¬çãªãªã¹ãïŒçºé»æ©ã®è©³çްhttp://www.dabeaz.com/generators/Generatorsã pdfhttp://www.dabeaz.com/coroutines/Coroutines.pdfhttp://www.dabeaz.com/finalgenerator/FinalGenerator.pdf