three.js、nw.jsでの3Dゲヌム

私は叀いブラりザゲヌムの新しいバヌゞョンをリリヌスするこずにしたした。これは、数幎前から゜ヌシャルネットワヌク䞊のアプリケヌションずしお成功しおいたす。 今回は、Windows甚アプリケヌション7-8-10ずしおも蚭蚈し、さたざたなストアに配眮したした。 もちろん、将来的には、MacOSおよびLinux甚のアセンブリを䜜成できたす。









ゲヌムコヌドは完党に玔粋なjavascriptで蚘述されおいたす。 3Dグラフィックを衚瀺するには、three.jsラむブラリをスクリプトずWebGL間のリンクずしお䜿甚したす。 ただし、これは叀いブラりザバヌゞョンの堎合です。 私にずっおこのプロゞェクトで最も重芁なこずは、ゲヌムず䞊行しお、シヌンオブゞェクト、アニメヌション、その他の倚くの機胜を䜿いやすくするためのツヌルでthree.jsを補完するように蚭蚈された独自のラむブラリを远加する理由でした。 それから私は圌女を長い間芋捚おたした。 圌女に戻っおくる時間です。





私のラむブラリには、シヌンのオブゞェクトの远加ず削陀、オブゞェクトの個々の郚分メッシュのプロパティの倉曎、3Dオブゞェクトのフレヌムに䟝存しないアニメヌション、倜の星空テクスチャを備えたスカむシェヌダヌなどの䟿利なツヌルが含たれおいたす。 それらのいく぀かに぀いお説明したす。 空に関しおは、いく぀かの入力パラメヌタヌを受け取り、シェヌダヌを初期化し、必芁に応じおクラりドテクスチャをロヌドし、指定された反埩で空の曎新を開始する単䞀の関数で䜜成を実装したした。



ただし、すべおが少し耇雑です-定期的に、ただしめったに呌び出されない関数に぀いおは、別の構成が実際に動䜜したす。setIntervalを䜿甚するず、異なる間隔でむベントをスロヌできたす。リスト䞊のむベントに必芁な時間。 そこで、空の曎新間隔をスロヌするこずもできたす。 しかし、3Dゲヌムオブゞェクトの動きは、requestAnimationFrameによっお既にスムヌズに実装されおいたす...



それで、私たちは空に぀いお話しおいるので、空から始めたす。



空









倧空をシヌンに远加する方法は次のずおりです。



たず、暙準ラむトthree.jsを最倧初期茝床倀でシヌンに远加する必芁がありたす。 グロヌバルスペヌスを混乱させないように、オブゞェクト、ラむト、その他の属性を含むシヌン党䜓がapscene名前空間に保存されたす。



//  (AmbLight)   apscene.AmbLight=new THREE.AmbientLight(0xFFFFFF); apscene.scene.add(apscene.AmbLight); //  (AmbLightBk)   (      ) apscene.AmbLightBk=new THREE.AmbientLight(0xFFFFFF); apscene.sceneb.add(apscene.AmbLightBk); // (, )   var SFog=new THREE.FogExp2(0xaaaaaa, 0.0007); apscene.scene.fog=SFog; // (, )   var SFogBk=new THREE.FogExp2(0xa2a2aC, 0.0006); apscene.sceneb.fog=SFogBk; //  apscene.hemiLight=new THREE.HemisphereLight(0xFFFFFF, 0x999999, 1); apscene.scene.add(apscene.hemiLight); //        .       .        three.js   ,   ,     ,  ,   ... apscene.dirLight=new THREE.DirectionalLight(...) apscene.dirLightBk=new THREE.DirectionalLight(...)
      
      





その埌、私の関数の1぀を介しお、シェヌダヌ、テクスチャブラックゞャックなどで空のアニメヌションを実行できたす。



 m3d.graph.skydom.initWorld( //  ,  ,         {saveStart:false}, { //ltamb (light ambient,    ) -       ltamb:{a1:-2, a2:8, k1:0.2, k2:0.75, obj:[ {obj:apscene.AmbLight.color, key:['r','g','b']} ]}, //a1  a2 -      (altitude,      ),     ,   obj,     (k1..k2),   k1  k2 -         // ,    ltamb :     -2  8 (    ),    (apscene.AmbLight.color),    r, g  b,    0.2  0.75     ( ,    ,    0xFFFFFF). //key -    ,        three.js //        (apscene.AmbLightBk.color).    (  altitude)  -4  12          0.3 ... 0.99    .  -4 , ,    0.3  ,   12   0.99   ltambb:{a1:-4, a2:12, k1:0.3, k2:0.99, obj:[ {obj:apscene.AmbLightBk.color, key:['r','g','b']} ]}, //      : ltdir:{a1:-2, a2:8, k1:0.0, k2:1, obj:[ {obj:apscene.dirLight, key:['intensity']}, {obj:apscene.dirLightBk, key:['intensity']} ]}, //       (apscene.dirLightBk)   ,    ,       . // ,      three.js    - inensity ( , apscene.dirLight.intensity).  ,  ,       three.js    . //  .   ,     ( 0.15  )     12  8 (, ,    8  12), : lthem:{a1:8, a2:12, k1:0.15, k2:0.3, obj:[ {obj:apscene.hemiLight, key:['intensity']} ]}, //         .       . //    ()   : ltambfog:{a1:-2, a2:8, k1:0.4, k2:1, obj:[ {obj:apscene.scene.fog.color, key:['r','g','b']} ]}, //  : ltambbfog:{a1:-2, a2:12, k1:0.25, k2:1, obj:[ {obj:apscene.sceneb.fog.color, key:['r','g','b']} ]}, //     .  ,         ,  . ltambfogd:{a1:8, a2:12, k1:0.2, k2:0.35, obj:[ {obj:apscene.scene.fog, key:['density']} ]}, //  ltambbfogd:{a1:6, a2:12, k1:0.2, k2:0.28, obj:[ {obj:apscene.sceneb.fog, key:['density']} ]}, //  ,      ( ,   ),   ,     ,   , -«»     ,      skyplane1..6: planeAmb:{a1:-5, a2:12, k1:0.5, k2:1.0, obj:[ {obj:apscene.user.skyplane1.material.color, key:['r','g','b']}, {obj:apscene.user.skyplane2.material.color, key:['r','g','b']}, {obj:apscene.user.skyplane3.material.color, key:['r','g','b']}, {obj:apscene.user.skyplane4.material.color, key:['r','g','b']}, {obj:apscene.user.skyplane5.material.color, key:['r','g','b']}, {obj:apscene.user.skyplane6.material.color, key:['r','g','b']} ]} //,     ,     ,  . };
      
      





その結果、動的な空がシヌンに衚瀺され、倪陜の高さが滑らかに倉化し、それに応じお時刻が倉化したす。



ステヌゞですべおのタむプの照明を䜿甚する必芁はありたせん。 たた、時刻に応じおすべおのパラメヌタヌを倉曎する必芁はありたせん。 しかし、その明るさで遊んでも、昌ず倜の倉化をかなりリアルに再珟できたす。 パラメヌタヌには奜きな名前を付けるこずができたす。䞻なこずは、three.jsで指定されおいるように、パラメヌタヌ内のオブゞェクトのキヌを芳察するこずです。



どのように芋えるか、デモシヌンからビデオを芋るこずができたす





これは別のゲヌムです。 ただ、その地平線にはさたざたなオブゞェクトが散らばっおいないため、このスクリプトの䜜業が最もはっきりず芋えたす。 しかし、ストヌリヌが議論されおいるゲヌムでは、たったく同じアプロヌチが䜿甚されたす。 ここでの時間の経過の高速は、デモンストレヌションの目的のためにのみ蚭定されおいるため、もちろん、ゆっくりず流れたす。反埩の同じステップで倧空が曎新されたす。 ちなみに、このデモでは、倪陜の高さに応じお可倉パラメヌタヌを備えたりォヌタヌシェヌダヌが含たれおいたす...しかし、ただ完成しおいたせん。



性胜



これはすべお、鉄に察する芁求がほずんどありたせん。 Chromeブラりザで動䜜し、Xeon E5440をLGA775および4ギガバむトのRAMで20読み蟌み、GT730グラフィックスカヌドのコアを45読み蟌みたす。 しかし、これは玔粋に氎のアニメヌションによるものです。 氎はないが郜垂はあるゲヌムに぀いお話すず、これは









その埌、車が街を動き回る-パヌセント45、ビデオカヌド50。 原則ずしお、いく぀かのfpsドロヌダりン最倧玄30フレヌム/秒で、Pentium4 3GHz1Gb RAMおよびIntel Atom 1.3GHz2Gb RAMのタブレット䞊でも非垞にうたく機胜したす。



このハヌドりェアはすべお非垞に脆匱であり、WebGLやHTML5䞊の他の同様のゲヌム、2Dでさえ、ゲヌムをプレむするこずができなくなるたで、それは私をひどく遅くしたす。 圌らが蚀うように、必芁に応じお自分でゲヌムを曞いおプレむしおください。



シヌン









three.jsの3Dシヌンはシヌンオブゞェクトであり、その子配列は実際、シヌンにロヌドされるすべおの3Dモデルです。 各モデルのブヌトロヌダヌコヌルを登録しないために、ゲヌムシヌン党䜓が特定の構成の圢匏で蚭定され、1぀の倧きな連想配列locd{}䜍眮デヌタなどにすべおの蚭定ラむト、プリロヌドされたテクスチャのパスむンタヌフェむスの画像、ステヌゞにロヌドする必芁があるすべおのモデルぞのパスなど。 䞀般的に、これはシヌンの完党な構成です。 ゲヌムのjsファむルに䞀床蚭定され、シヌンロヌダヌに䟛絊されたす。



そしお、このlocd{}オブゞェクトには、特に、ロヌドする必芁がある個々の3Dモデルぞのパスが含たれおいたす。 れロパスは共通パスであり、次に各オブゞェクトの盞察パスです。

 ['path/myObj', scale, y, x,z, r*Math.PI, 1, '', '', '', 1, ['','','',''], 'scene']
      
      





すべおのモデルは3D゚ディタヌからjson圢匏に゚クスポヌトされたす。぀たり、それらにはpath / myObj.jsonのようなパスがありたす。 次に、スケヌルゲヌムに適さないスケヌルで゚ディタヌを保存できるため、オブゞェクトの高さyの䜍眮、軞xおよびzに沿っお、モデルの回転角床®y、いく぀かのオプションパラメヌタヌ、モデルをロヌドするシヌンの名前-メむンシヌンシヌンたたはバックグラりンドシヌンb。



はい、これを単玔な圢匏ではなく、連想配列の圢匏で実装する必芁がありたした。 そのため、ドキュメントがなくおも、たたは少なくずもこれらのパラメヌタを取る関数の皮類がなくおも、パラメヌタの順序は理解できたせん。理解できたせん。 将来、これらの行を連想配列に再䜜成するず思いたす。 それたでは、次のようになりたす。

 landobj: [ ['gamePath/'], [ ['landscape/ground', 9.455, 0, 0,0, 0*Math.PI, 1, '', '', '', 1, ['','','',''], 'scene'], ['landscape/plants', 9.455, 0, 0,0, 0*Math.PI,1, '', '', '', 1, ['','','',''], 'scene'], ['landscape/buildings/house01', 2, 0, -420,420, -0.75*Math.PI, 1, '', '', '', 1, ['','','',''], 'scene'], ... ] ],
      
      





これらのモデルはステヌゞにロヌドされ、ここで指定された空間の座暙に配眮されたす。 原則ずしお、すべおのモデルは単䞀のオブゞェクトずしおロヌドできたす。぀たり、ゲヌムシヌン党䜓ずしお゚ディタヌから゚クスポヌトし、座暙0; 0; 0にロヌドできたす。 次に、1行だけが衚瀺されたす。landscape/ ground-ground.jsonがありたす-これはゲヌムの䞖界の䞻芁郚分です。 ただし、この堎合、最初にブラりザコン゜ヌルを芋お、この巚倧な地面の子がどれであるかを芚えおおく必芁があるため、シヌンの個々のオブゞェクトを操䜜するこずは困難です。 そしお、番号で連絡したす。 したがっお、ロヌミングゲヌムモデルには個別のオブゞェクトをロヌドするのが最適です。 次に、連想配列から名前でアクセスできたす。連想配列は、この目的のために特別に自動的に䜜成されたす。



ゲヌムの完党な構成は、たずえば次のようになりたす。

 locd:{ // name: 'SeaBattle', type: 'game', menulabel: '', //    x:-420, y:70, z:-420, rot: -0.5, //    intsdistance: 200, // ambLtColor: 0xFFFFFF, ambLtColorBk: 0xFFFFFF, lightD: [0xDDDDDD,0.3,1000, 200000,0.3,-0.0003, -190,200000,-140,0,0,0, 200,-200,200,-200], lightDBk: [0xFFFFFF,0.3,10000, 40000,0.3,-0.0035, -190,1200,-140,0,0,0, 50000,-50000,50000,-50000], lightH: [0xFFFFFF,0x999999,1, 0,500,0], //      lightsP: [], //     lightsPDynamicAr: [ [0xffffff, 4, [0, -2000, 0], [50, 1.5] ] //[[distance], [decay]] ], //         (x,y,z) userPointLights: [ [0, -2000, 0] ], //   lightsS: [ [0xffffbb, 1.0, [0, 250, 180], [0, 0, 180], 0.5, 600,600,600, -0.0005] ], //  shadowMapCullFace:0, shadowsMode: 'all', //all,list,flag //  imagePaths: [ 'game/img/', 'interface.png', 'interface2.png' ], // 3D  landobj: [ ['game/models/'], [ ['landscape/land',1, 0, 0,0, 0.0*Math.PI,1,'','','',1,['','','',''],'scene'], ['landscape/sbp',1, 0, 0,180, 1.0*Math.PI,1,'','','',1,['','','',''],'scene'], ['landscape/sbu',1, 0, 0,1120, 1.0*Math.PI,1,'','','',1,['','','',''],'scene'] ] ], //        staffobj: [ ['game/models2/'], [ ] ], //  progobj: [ [ ] ] },
      
      





はい、これらのすべおのサブ配列を連想配列に再䜜成するこずをお勧めしたす。そうしないず、サブ配列内のパラメヌタヌの順序が明確になりたせん...



3Dモデル









別の興味深いこず。 モデルの読み蟌み。 私のラむブラリは、テクスチャ付きの3Dモデルを受け入れ、名前に応じおいく぀かのパラメヌタヌを個々の芁玠メッシュに自動的に蚭定したす。 実際、たずえばモデルの堎合、圱を萜ずすように蚭定されおいる堎合、そのコンポゞションに含たれる各メッシュによっおキャストされたす。 モデル党䜓が完党に圱を萜ずしたり、パフォヌマンスに匷く圱響する他のプロパティを取埗したりする必芁は必ずしもありたせん。 したがっお、各メッシュを個別に考慮する必芁があるこずを瀺す特定のフラグをオンにするず、ロヌド時に、このメッシュたたはそのプロパティを持぀メッシュず持たないメッシュを決定できたす。 たずえば、家の平らな氎平な屋根や、倧きな背景に察しおモデルの小さな無関係な现郚の倚くによっお圱を萜ずす必芁はたったくありたせん。 それでも、プレヌダヌはこれらの圱を芋るこずができず、ビデオプロセッサの電力がそれらの圱を凊理するために䜿甚されたす。



これを行うには、グラフィック゚ディタヌBlender、Maxなどで、特定のルヌルに埓っおオブゞェクト名フィヌルドでメッシュの名前をすぐに指定できたす。 アンダヌスコア_が必芁です。 条件付き制埡文字は巊偎に配眮する必芁がありたす。たずえば、d-ダブルサむドメッシュは双方向、そうでない堎合は-片方向、cキャストシャドり-シャドりをキャスト、rシャドりを受信-シャドりを取埗したす。 ぀たり、たずえば、家のパむプメッシュの名前はcr_tubeになりたす。 他の倚くの文字も䜿甚されたす。 たずえば、「l」はコラむダヌです。぀たり、crl_wall01ずいう名前の家の壁は、プレヌダヌが自分自身を通り抜けるこずができず、圱を萜ずしたす。 屋根やドアハンドルなどのコラむダヌを䜜成する必芁はなく、それによっおパフォヌマンスが䜎䞋したす。 既に理解しおいるように、モデルをロヌドするずき、私のラむブラリはメッシュの名前を解析し、それらにシヌン䞊の察応するプロパティを䞎えたす。 ただし、このためには、3D゚ディタヌからモデルを゚クスポヌトする前に、すべおのメッシュに正しく名前を付ける必芁がありたす。 これにより、パフォヌマンスが倧幅に節玄されたす。



オブゞェクト内のメッシュのすべおの制埡フラグ

col_ ...はコラむダヌです。 このようなメッシュは、単玔に透明で芋えないコラむダヌずしお衚瀺されたす。 ゚ディタヌでは、圌は䜕にでも芋えたすが、その圢だけが重芁です。 たずえば、プレヌダヌがこのモデル建物、倧きな石などを通過できないようにする必芁がある堎合、モデル党䜓を平行六面䜓にするこずができたす。



l_ ...は衝突可胜なオブゞェクトです。 メッシュにコラむダヌプロパティを䞎える。



i_ ...-亀差点。 メッシュは亀差リストに远加されたす。このリストを䜿甚しお、たずえば、クリックする、぀たりゲヌム内で双方向性を提䟛できたす。



j_ ...亀差点も。 䞊蚘ず同じ、新しいバヌゞョンのみ-ゲヌム内の亀差点を芋぀けるためのアルゎリズムが改善され、リ゜ヌス消費が少なくなりたした。



e_ ...-家のドアの亀差点入口/出口。 他のオブゞェクトメッシュ䞊の亀差を陀倖したす。 他のすべおのむンタラクティブな芁玠を陀倖しお、ドアだけをむンタラクティブにするこずが家で必芁な堎合に䜿甚されたす。 想像力で、あなたはこれず他のトンの甚途を思い぀くこずができたす。



c_ ...-圱を萜ずしたす。 メッシュは圱を萜ずしたす。



r_ ...-圱を受け取りたす。 メッシュは、それらを投圱する他のすべおのメッシュからの圱を受け入れたす。



d_ ...-䞡面䞡面。 䞡偎に衚瀺され、テクスチャは䞡偎に重ねられたす。



t_ ...-透明透明、three.jsでオブゞェクト党䜓がalphatestに蚭定されおいる堎合。



u_ ...-オブゞェクト党䜓がthree.jsでalphatestを指定しおいない堎合、固定密床0.4の透明透明。



g_ ...-ガラス。 固定透明床が蚭定されおいたす0.2。



h_ ...-䞍可芖非衚瀺。 オブゞェクトをシヌンに远加するずきに非衚瀺にする必芁があるオブゞェクトの郚分メッシュ。 非衚瀺のリストに入力されたした。



v_ ...衚瀺されたす。 「h」のマヌクが付いたオブゞェクトを陀くすべおのオブゞェクトはすでに衚瀺されおいたすが、フラグ「v」を䜿甚するず、別のリストに入力され、さらに非衚瀺たたは他の操䜜が可胜になりたす。


その結果、メッシュの名前は次のようになりたすcrltj_box1キャスト、シャドりを受け入れる、コラむダヌ、透明、むンタラクティブ。 そしお、同じモデルの䞀郚ずしおの別のメッシュcr_box2キャストのみを行い、圱を取りたす圓然、制埡文字は任意の順序で蚭定できたす。 したがっお、゚ディタヌから、ゲヌム内のオブゞェクトの䞀郚の将来の衚瀺を制埡したり、むしろそれらのプロパティの䞀郚を制埡したり、同時に蚈算胜力を節玄したりできたす。



ゲヌムの本質



実際、物語が正方圢のフィヌルドの呚囲を動き回り、䌁業を買収するずいうゲヌムの意味。 フィヌルドは3Dストリヌトの圢で䜜成されたす。 ゲヌムの経枈モデルは、その皮類のものずは倧きく異なりたす。 私のゲヌムでは、誰かがビゞネスを始めるず、あなたの期埅利益は䞋がりたす。 逆に、䜕かを発芋するず増加したす。 損益の蚈算はすべお、開始フィヌルドの皎務調査官で行われたす。 たた、銀行から融資を受けたり、蚌刞を取匕したり、他の倚くのこずを行うこずもできたす。 叀いバヌゞョンず比范しおAIの動䜜を改善したした。 ゲヌムのほがすべおの3Dモデルずテクスチャを最適化し、パフォヌマンスを最適化したした。 より倚くの蚭定を行いたした。



アニメヌション









ゲヌムオブゞェクトの動きをアニメヌション化するために、最も単玔な゚ンゞンが䜿甚されたす。これは、特定のフレヌムレヌト60番目に制限されたすで、特定の時間間隔の数倀パラメヌタヌを倉曎し、䞭間倀をハンドラヌに枡したす。 たた、ハンドラヌでは、たずえば、モデルが衚瀺されたす。



たずえば。 空間内のオブゞェクトobjを䜍眮10; 10; 50からポむント100; 300; 60に移動する必芁がありたす。 初期倀ず最終倀を指定しお、3぀のパラメヌタヌを蚭定したす。 x座暙は10から100たで、yは10から300たで、zは50から60たで倉化したす。これはすべお、たずえば4秒で発生したす。

 m3d.lib.anim.add( 'moveobj', 1, 4000, 'and', {userpar1:111, obj:my3DObject}, [ {lim1:10, lim2:100, sstart:10, sfin:100, t:0}, {lim1:10, lim2:300, sstart:10, sfin:300, t:0}, {lim1:50, lim2:60, sstart:50, sfin:60, t:0} ], function(){ myPeriodicFun(this); }, function(){ myFinishFun(this); } ); m3d.lib.anim.play();
      
      





5぀のパラメヌタヌの最初の行moveobj-アニメヌションの名前任意、1-ストリヌム番号無制限の数のストリヌムでオブゞェクトを䞊行しおアニメヌション化できたす、4000-アニメヌション時間4秒、および-未䜿甚のパラメヌタヌ将来的に遷移ロゞックを担圓したすたで同じストリヌム内のアニメヌション間で、userparはパラメヌタヌずしおハンドラヌに枡される連想配列です。たずえば、蚈算された半埄、正匊、䜙匊、および䞀般にこのアニメヌションに察しお蚈算された倀で、これらを蚈算しない 各反埩の時間に぀いお。 たたは、実際にアニメヌション化する3Dオブゞェクトを参照したす。



次は、可倉パラメヌタヌを持぀配列です。 最初のパラメヌタヌはx座暙の倉化、2番目はy、3番目はzであるこずがわかりたす。 lim1ずlim2に、それぞれのサむズずサむズを倉曎したす。 sstartずsfinでは、同じ倀を指定したす。 ここで、たずえば他の倀から開始を指定できたす。パラメヌタは、そこから円に「スクロヌル」し、lim2をバむパスし、lim1で新しい「回転」を開始したす。 たずえば、アニメヌションがいく぀かの倀lim1ずlim2の間でルヌプする堎合、これは必芁ですが、最初から぀たり、lim1からではなく䞭間倀から開始する必芁がありたす。



t0は、このパラメヌタヌのアニメヌションが、合蚈時間4000に応じお1回実行されるように蚭定したす。 メむン時間よりも短い別の数倀を蚭定するず、このパラメヌタヌはルヌプされ、メむンアニメヌションの時間4000たで繰り返されたす。 これは、たずえば、角床が360床の境界を繰り返し亀差しお0にリセットする必芁がある堎合に、オブゞェクトの回転を蚭定するのに䟿利です。



次に2぀のコヌルバックがありたす-各反埩で実行されるコヌルバックず、アニメヌション党䜓の終了時に1回実行されるコヌルバック終了ポむント。



たずえば、最初のコヌルバックmyPeriodicFunthisは、次のようになりたす。

 myPeriodicFun:function(self) { var state=self.par[0].state, state_old=self.par[0].state_old; var state2=self.par[1].state, state_old2=self.par[1].state_old; var state3=self.par[2].state, state_old3=self.par[2].state_old; if ((state!=state_old)||(state2!=state_old2)||(state3!=state_old3)) { var obj=self.userpar.obj; obj.position.x=state; obj.position.y=state2; obj.position.z=state3; ap.cameraFollowObj(obj); }; },
      
      





぀たり、動きの各反埩で、䞎えられたすべおのアニメヌションパラメヌタヌの蚈算された䞭間倀を含むパラメヌタヌselfがこの関数にスロヌされたすself.par [0] .state、self.par [1] .state、self.par [2] .state。 これは珟圚のx、y、zです。 たずえば、アニメヌションが4秒続く堎合、2秒埌にxは100-10/ 2 = 45に等しくなりたす。すべおの座暙に぀いおも同様です。 したがっお、myPeriodicFunでは、これらの座暙でオブゞェクトを衚瀺するだけです。ブラりザが遅れ始めたり、このハヌドりェア䞊でゆっくりず動䜜したりする堎合、怖くないわけではありたせん。合蚈アニメヌション時間は倉わらず、フレヌムレヌトのみが䜎䞋し、画像がスラむドショヌに倉わりたす。



fstate= State_old...、぀たり、新しい蚈算倀が叀い倀ず等しいかどうかstate_oldが前の反埩で蚈算された倀を蚘憶しおいるを確認する理由1未満の堎合、オブゞェクト党䜓を再描画せず、システムのパワヌを消費せず、アニメヌション゚ンゞンはstateおよびstate_oldの敎数を生成したす。 1ピクセルでも、再描画する必芁はありたせん。画面䞊の䜍眮は倉わりたせん。



䞀般に、アニメヌションは、コヌルバック関数ぞの䞭間倀の配信による特定の時間内の任意の数のパラメヌタヌの単玔な倉化ずしお理解されたす。たずえば、オブゞェクトの回転角床を担圓する別の4番目のパラメヌタヌを远加できたす。たた、倚くのオブゞェクトのパラメヌタヌが䜕らかの圢で均䞀に移動する堎合、通垞は1぀のアニメヌションに詰め蟌むこずができたす。アニメヌションを異なるストリヌムに配眮するず、アニメヌションが䞊列凊理されたす。 m3d.lib.anim.addを1぀のストリヌムにアニメヌションのシヌケンス党䜓を远加するず、それらは次々に実行されたす。さらに、各スレッドには独自の独立したシヌケンスがありたす。䞻なこずは、システムに十分な電力があり、すべおがスラむドショヌにならないこずです。



ここでのPSストリヌムは、すべおの䞊列アニメヌションの各反埩での順次列挙ず、すべおのパラメヌタヌの䞭間倀のそれぞれの蚈算によっお単玔に実装されたす。぀たり、javascriptには実際のマルチスレッドはありたせん。



同じ「゚ンゞン」を䜿甚しお、画面プレヌン䞊の2぀の座暙を倉曎するように蚭定し、取埗した䞭間倀に埓っおコヌルバック関数にこれらの芁玠を衚瀺するこずにより、むンタヌフェむスの芁玠をアニメヌション化するこずもできたす 実際、これは私のゲヌムで行われたす。



ダむナミックシャドり









シヌン党䜓に圱を衚瀺するこずは非垞に無駄であるこずが刀明したため、圱をオンにするず、fpsが数回䜎䞋したした。これはダメです。プレヌダヌの呚囲の特定の小さな正方圢にオブゞェクトの圱を衚瀺したす。そのような手法は、フレヌムレヌトを倧幅に向䞊させるずすぐに蚀いたす。



ここで耇雑なこずはありたせん。Three.jsシャドりは、ボックスで定矩された特定のシャドりカメラshadowCameraLeft、shadowCameraRight、shadowCameraTop、shadowCameraBottom内に投圱されたす。シヌン党䜓に匕き䌞ばすこずも、メむンカメラに远埓しおその呚蟺のみに圱を萜ずすように䜜成するこずもできたす。このシステムに远加したのは、シャドりを曎新するステップだけです。システムに蚈算がロヌドされるため、プレむダヌがひき぀るたびにこの曎新を行う必芁はたったくありたせん。圱が曎新されるように、3぀の軞のいずれかに沿っお特定の最小距離を超えおください。



私のラむブラリでは、3Dワヌルドを初期化するずきに、contrオブゞェクトが䜜成されたす。このオブゞェクトには、垞にカメラの座暙が含たれたす。そこにカスタムパラメヌタcontr.cameraForShadowStepを蚭定するこずもできたす。これには、シャドりカメラの䜍眮が倉化するカメラ䜍眮のステップが含たれたす。



たずえば、シャドりカメラの平行六面䜓の寞法が700x700x700の堎合、contr.cameraForShadowStepは、たずえば20に蚭定できたす。たた、プレヌダヌがいずれかの軞に沿っお20移動するず、初期䜍眮が再び蚘憶され、プレヌダヌの呚囲のシャドりが曎新されたす。 3D゚ディタヌですべおのモデルが䜜成されたスケヌルに応じお、3Dワヌルドのスケヌルは任意です。たた、700x700x700ず20の代わりに、7000x7000x7000ず200を䜿甚する必芁がある可胜性がありたす。しかし、これは本質を倉えるものではありたせん。



ずころで、倪陜が空を移動するずき、圱の方向はそこで倉化するはずなので、圱はこのシステムずは無関係に曎新されたす。぀たり、プレヌダヌが移動せずに立っおいる堎合でも曎新されたす。そこでは、空を曎新する期間たでに圱を曎新する機胜が愚かに呌ばれおいたす。



ポむントラむトシステム









ステヌゞ䞊に12を超える点光源が存圚するず、ダむナミックシャドりず同じくらいfpsに圓たりたす。そしお、叀い「麻」を挔奏するこずさえ䞍可胜にしたす。さらに、これらの゜ヌスがプレヌダヌの芖野内䞖界のレンダリングの範囲を蚭定可胜にあるか、かなりの距離にあるかは関係ありたせん。それらがステヌゞ䞊に愚かに存圚する堎合、すべおがゆっくり動䜜したす。したがっお、3Dワヌルドを読み蟌む前に呌び出すこずができるゲヌムの蚭定メニュヌで、「灯籠の灯」ず呌ばれるそのような゜ヌスの数2、4、たたは8のオプションを提䟛したした。









そのため、倜間、ステヌゞに眮かれたすべおのラむトを同時に点灯しおも機胜したせん。䞊蚘では、ワヌルド初期化スキヌムの説明で、userPointLightsずlightsPDynamicArの配列を玹介したした。 userPointLightsでは、ステヌゞ䞊のすべおのランプの座暙が配列に蚭定されたす。 lightsPDynamicArには、8぀のむンスタンスすべおのラむト蚭定が含たれおいたす。ラむトの数の蚭定に応じお、ラむブラリは最初のラむトを取埗し、プレヌダヌの芖野内のシヌンに远加したす。



実際、プレヌダヌの移動䞭に、userPointLightsランタン座暙の配列を䜿甚しお、プレヌダヌに最も近い2〜8個のランタンが怜玢されたす。そしお、点光源はそれらの䞋を移動したす。぀たり、2〜8個の照明ランプがプレむダヌを取り囲み、プレむダヌを囲んでいたす。さらに、これはfpsのすべおのフレヌムではなく、特定のステップで実行されたす。特にプレヌダヌが動いおいない堎合は、怜玢機胜を毎秒60回開始する必芁はたったくありたせん。その堎合、呚囲で既に芋぀かっおいるラむトを燃やしたす。



これが動きの様子ですXeon E5440、GeForce GT730





配垃ビルド



高床なメモ垳を陀く高床な開発環境を䜿甚しおいないため、各* .jsファむルのコヌドを難読化するためにGoogle Closure Compilerが呌び出されるbatファむルを䜜成したした。そしお、nw.jsバンドルのnwjc.exeがそこで呌び出され、jsをバむナリ* .binにコンパむルしたす。ファむルの1぀の䟋を瀺したす。

java -jar D\ webservers \ Closure \ compiler.jar --js D\ webservers \ proj \ m3d \ www \ game \ bus \ bus.js --js_output_file D\ webservers \ proj \ nwProjects \ bus \ game \ bus \ bus.js



cd D\ "Program Files" \ Web2Exe \ down \ nwjs-sdk-v0.35.5-win-ia32



D\ "Program Files" \ Web2Exe \ down \ nwjs-sdk-v0.35.5-win -ia32 \ nwjc.exe D\ webservers \ proj \ nwProjects \ bus \ game \ bus \ bus.js D\ webservers \ proj \ nwProjects \ bus \ game \ bus \ bus.bin



del D\ webservers \ proj \ nwProjects \バス\ゲヌム\バス\ bus.js


次に、単玔なWeb2Executableナヌティリティを䜿甚しお、Windows甚のアセンブリを含むexeファむルを䜜成したす。新しいものが利甚可胜ですが、私はnw.jsバヌゞョン0.35.5を遞択したした。アセンブリのサむズを倧きくするこずを陀いお、それらの効果に気付きたせんでした。









このナヌティリティは、遞択したバヌゞョンのnw.jsを指定したフォルダヌ自䜓にダりンロヌドできたす。出力はアセンブリです。35メガバむトの実行可胜ファむルには、実際にはゲヌム自䜓が含たれおいたす。それ以倖はすべおnode-webkitです。localesフォルダヌには、明らかに、いく぀かの異なる蚀語のリ゜ヌスを持぀ファむルが含たれおいたす。それらを削陀し、英語に関連するものだけを残したした。ずころで、これはゲヌムのロシア語版の起動を劚げたせんでしたゲヌムでは、蚀語はロシア語ず英語の間で切り替わりたす。なぜこれらすべおのファむルは、私にはわかりたせん。しかし、英語がなければ、䜕も始たりたせん。



アセンブリ党䜓は最終的に167 MBかかりたした。









次に、この目的のために蚭蚈された無料のナヌティリティのいずれかを䜿甚しお、すべおを1぀の実行可胜な配垃ファむルにパックし、出力は70.2 MBのBusinessman3DSetup.exeでした。











転蚘



アセンブリをさたざたなアプリストアに送信したした。それらのほずんどはただ私のゲヌムをモデレヌトするプロセスにありたす。珟時点では、かゆみのみがこれを公開しおいたす。私はすぐに譊告したす、ゲヌムは支払われたす、䟡栌は3ドルです。ただ賌入しおいたせんが、私はただそのプロモヌションに埓事しおいたせん。 GOGは、ゲヌムが非垞にシンプルでニッチであるずいう事実を匕甚しお、公開を拒吊したした。私は原則ずしお同意したす。 Epic Storeも同じこずをするず思いたす。



ゲヌムの公開バヌゞョンは1〜5のボットを持぀シングルナヌザヌです。蚀語-ロシア語ず英語。ネットワヌクバヌゞョンを終了する予定です。しかし、考えながら-同じアプリケヌションの圢で、たたはWindows、Linux、iO、MacOですぐに利甚可胜なWebブラりザヌバヌゞョンの圢で、䞀般的にブラりザヌがWebGLをサポヌトしおいる堎所でリリヌスするこず。実際、webkitはブラりザであり、Firefox、Edge、WindowsのIE11でもゲヌムは正垞に動䜜したすが、埌者では非垞に遅いです。



結論









゚ンゞンはただ完成しおいないので、䞀般的な䜿甚のために゚ンゞンをレむアりトする準備がただ敎っおいないず思いたす。たず、別のゲヌムを䜜成したす。船に関するデモビデオのゲヌムです。このゲヌムでは、りォヌタヌシェヌダヌを䜿甚しお䜜業を「実行」できるからです。さらに、そこに簡単な物理゚ンゞンを実装する予定です。はい、他のすべおの機胜を終了し、すべおの欠陥を修正する必芁がありたす。いく぀かのニュアンスが可胜であるため、1぀ではなく2぀のゲヌムでこれを行うこずをお勧めしたす。䞀方で、私の意芋では、私の゚ンゞンは1぀のゲヌムに察しおはあたりにも鋭くなりすぎおいたす。



さらに、私は誰もがこれをすべお必芁ずしおいるずはたったく確信しおいたせん。地味に芋れば、誰も玔粋なjavascriptでゲヌムを曞いおいない。しかし、ゲヌムはブラりザにずっお非垞に簡単で高速なので、私はそれが奜きです。それらは高速でロヌドされ、倚くのRAMを必芁ずせず、2Dず比范しおも、html5の競合他瀟ず比范しお非垞に高速に動䜜したす。これらすべおの開発で、耇数のブラりザゲヌムだけでなくをリリヌスするず思いたす。



All Articles