ゼロからJavaScriptで2時間でIntel XDKでAndroid向けのDoodle Jumpゲームを作成する

こんにちは、Habr。



長い時間を経て記事を書くことはめったにありません。ビデオに素材を録音するのに慣れているので、自由に発言できます。 偶然、Intel XDKに関する記事を書くことにしましたが、可能性の概要だけでなく、非常に具体的なプロジェクトの例を使用して環境を分析しました。 私にとってのプロジェクトは、ゲーム「Doodle Jump」の「クローン」でした。



画像



パート1.プロジェクトの準備



PointJSエンジンを使用してJavaScriptで開発を行います(もしあれば、Googleは1分以内です)。



新しい空のプロジェクトを作成する最初の段階でした。 ここでは、原則として、すべてが非常に簡単です。



2. 1.下部にある[新しいプロジェクトの開始]ボタンを見つけ、[テンプレート]タブで[Standart HTML5]を選択して[作成]をクリックします。



画像



2.ここで、わずかなクリックでプロジェクト設定に移動します(はい、この青いフォルダーをクリックします)。



画像



3.さらに全体として、すべてが論理的に明確です。



画像



いくつかのポイントを説明します。

アプリIDは、アプリケーションまたは企業ドメインの一意の識別子です

ホワイトリスト-アプリケーションが許可するリクエストを許可

開発者証明書-アプリケーション証明書。 欠落している場合は、このドロップダウンメニューを使用して作成します。



画像



さらなる問題を避けるために、信頼できるデータを入力してください。

証明書に記入した後、アプリケーション証明書として選択できます。

Crosswalk Runtime-Cordovaをアプリケーションに統合するか(組み込み)、統合しないかを決定します(共有)



4.アイコンを入力します。



画像



サイズと形式は、環境の要件に厳密に従う必要があることに注意してください。



スプラッシュ画面については、これらはアプリケーションの読み込み画面であり、アプリケーションの読み込み中にユーザーに表示されます。 原則として、これには通常2秒弱かかりますが、この間に、たとえば何かのロゴを表示したり、広告を挿入したりできます。



Android用のゲームを作成しているため、残りのOSとプラットフォームを無効にします。



画像



アプリケーションのセットアップはこれで完了です。 プロジェクト自体の準備に進みます。



パート2.ファイルの準備



PointJSゲームエンジンを使用してゲームを作成します。これは、60 kbの重さで、完全にクロスプラットフォームで、最適化された便利なものです。 プロジェクトを準備します。



1. OSでプロジェクトフォルダーを開きます(OSで表示):



画像



次に、「www」フォルダーに移動します。これが作業フォルダーです。 すべてを削除し、index.htmlファイルを使用してエンジンを挿入します。



画像



これらのファイルをPointJS Webサイトからダウンロードしました。



「開発」タブでは、(ある程度馴染みのある)Bracketsエディターにあります。index.htmlファイルには次のコードがあります。



元のビューindex.html
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta name="viewport" content="width=device-width,user-scalable=no"/> <title>   PointJS</title> </head> <body> <script type="text/javascript" src="point.js"></script> <script type="text/javascript"> //   var pjs = new PointJS('2d', 400, 400); //      pjs.system.initFullPage(); //    var vector = pjs.vector; //     var log = pjs.system.log; //     var game = pjs.game; //     var point = vector.point; //     var camera = pjs.camera; //     var brush = pjs.brush; //     var OOP = pjs.OOP; //     var math = pjs.math; //       var touch = pjs.touchControl; touch.initTouchControl(); //    'game' game.newLoop('game', function () { //     game.fill('#D9D9D9'); //   ", !" brush.drawText({ x : 10, y : 10, text : ', !', size : 30, color : '#515151' }); }); //     60fps game.startLoop('game'); </script> </body> </html>
      
      









いくつかの変数はすでにここに追加されており、何かが事前に定義されています(コードのコメントを読みます)。 「エミュレート」列では、好きな電話とスケーリングを使用してその向きを設定し、同時にすべてが機能することを確認します。



画像



ファイルを把握し、プロジェクトを開始し、すべてが順調です。ゲームを作成する主要な段階に進みます。



パート3.ゲームの作成

異なるリンクや変数の宣言がたくさんあることはおそらく注目に値します。それらを別のファイルに配置します(新しい行はコメントアウトされています)。

init.js
 var pjs = new PointJS('2d', 400, 400); pjs.system.initFullPage(); var vector = pjs.vector; var log = pjs.system.log; var game = pjs.game; var point = vector.point; var size = vector.size; var camera = pjs.camera; var brush = pjs.brush; var OOP = pjs.OOP; var math = pjs.math; var touch = pjs.touchControl; touch.initTouchControl(); //        var width = game.getWH().w; var height = game.getWH().h; //            var del = height / 1000 / 5; //    delta-time      var dt; //        var score = 0; //   .  ,    var levelScore = 0; //      ( )        oldScore var tmpScore = localStorage.getItem('score'); var oldScore = tmpScore ? tmpScore : 0;
      
      









ゲーム「Doodle Jump」の背景は「ノートブックシート」、つまりセルです。このような効果を作成するには、次の内容のgrid.jsファイルを作成します。

grid.js
 //    (  ,        del) var sizeX = 200 * del, sizeY = 200 * del; //    var drawGrid = function () { // ,        X  Y var x = width / sizeX, y = height / sizeY; //      OOP.forXY(x, y, function (x, y) { //    -    X  Y,   brush.drawRectS({ x : (sizeX + 2)*x, //   X y : (sizeY + 2)*y, //  Y fillColor : 'white', //   w : sizeX, h : sizeY //    }); }); };
      
      







背景がグレー表示されていることを忘れないでください。したがって、互いに5pxの距離で白い長方形を描画すると、これらのギャップがメッシュになります。



これで、グリッドを描画するには、ゲームループでdrawGrid()関数を呼び出すだけで十分で、背景がグリッドで塗りつぶされます。



画像



背景をグリッドで埋めることは良いことですが、確かに良いことですが、私たちはゲームをやっています! したがって、先に進みましょう!

これで、ゲームのメニューを作成して、プレーヤーが自分の記録を確認し、1つのレベルで得点した金額を確認し、負けた場合はゲームを再開できるようになります(負けた場合は、同じメニューにスローします)。 これを行うには、別のファイルを作成して入力します。



menu.js
 //  ,         var newGame = game.newTextObject({ text : ' ', //    font : 'serif', //   size : 300*del, //   (  del) color : '#363636' //   }); //         newGame.setPositionCS(point(width/2, height/2)); //   ,        var drawMenu = function () { //  ,   newGame.draw(); //      brush.drawTextLinesS({ x : newGame.x, //      " " y : newGame.y + newGame.h, //          lines : [': '+Math.abs(oldScore), ' : '+Math.abs(levelScore)], //   ? font : 'serif', //  size : 250*del, //  color : '#363636' //  }); //        touch,     // ,       " " if (touch.isPeekObject(newGame)) { //  -  createLevel(10); //       (   ) return game.setLoop('game'); //          'game' } };
      
      









しかし、インデックスファイルはすぐに「ゲーム」サイクルを開始することを覚えています。修正しましょう。



index.htmlファイルを書き換えます
 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta name="viewport" content="width=device-width,user-scalable=no"/> <title>   PointJS</title> </head> <body> <script type="text/javascript" src="point.js"></script> <script type="text/javascript" src="init.js"></script> <script type="text/javascript" src="grid.js"></script> <script type="text/javascript" src="menu.js"></script> <script type="text/javascript"> game.newLoop('menu', function () { game.fill('#D9D9D9'); drawGrid(); //    drawMenu(); //       }); game.startLoop('menu'); //    menu </script> </body> </html>
      
      









結果を見てみましょう:



画像



「New Game」をクリックすると、「game」にゲームサイクルが定義されておらず、「createLevel」関数がないためエラーが発生しますが、まだ気にしません。ゲームサイクルを作成して一時的にゲームを開始します彼は、「startLoop」コマンドを調整します。



ゲームサイクルについて説明します。

 game.newLoop('game', function () { //   ,     Delta-Time   dt = game.getDT(20); game.fill('#D9D9D9'); //   drawGrid(); //   drawLevel(); // -      drawPlayer(); // -     //     ?   brush.drawTextS({ x : 10, y : 10, //  (    ) text : 'Score: '+Math.abs(score), //  size : 300*del, //  color : '#515151',//  font : 'serif' //  }); });
      
      







ここで、ゲームを起動するとエラーが発生するため、drawLevel関数をコメントアウトしますが、drawPlayer関数について説明します。 新しいファイルを作成します。



pl.js
 //      var pl = game.newImageObject({ x : 0, y : 0, //  ,      w : 744 * del, h : 670 * del, // .     744  670,      file : 'img/pl.png' //    }); var dy = 2 * del; // ,      var dmax = 50 * del; //   var dx = 0; // ,      //       var drawPlayer = function () { //   . ,    Y ! if (pl.y < score) { score = Math.ceil(pl.y); } pl.draw(); //   pl.move(point(0, dy*dt)); //       delta-time dy += dy < dmax ? del*dt : 0; // ,        () //      () if (touch.isDown()) { if (touch.getPositionS().x > width/2) //      (   ) dx = 30*del; //      ( ) else //  dx = -30*del; //      () //  ,        if (dx > 0) { //   pl.setFlip(0, 0); //   (    "" ) if (pl.x > width) { //       pl.x = -pl.w; //      } } else if (dx < 0) { //    pl.setFlip(1, 0); //   if (pl.x+pl.w < 0) { //  ,     ,     pl.x = width; //   } } pl.move(point(dx*dt, 0)); //          } // ,       ,    ,   //    ,       ,  ,    //   ,    if (pl.getPositionS().y > score + 5000 * del) { levelScore = score; //    ( ,     ?) if (score < oldScore) { //     ,   oldScore = score; //    localStorage.setItem('score', score); //     } return game.setLoop('menu'); //      ,     } //   ,        ,      . camera.moveTimeC(vector.pointPlus(point(width/2, pl.getPositionC().y), point(0, -500*del)), 10); };
      
      







プレーヤーの最初の写真:



画像



エンジンへのAPIでカメラシフト機能を確認できます。 カメラをプレーヤーの位置にスムーズに移動し、カメラをわずかに500 *デルピクセル下に移動して少し下に移動すると簡単に言います。 この場合、カメラを左右に移動せず、カメラの中心は常に画面の幅の半分(幅/ 2)になります。



実行すると、次の図が表示されます。



画像



ここで、コメントした場合にcreateLevelおよびdrawLevel関数のコメントを外します。 別のファイルを作成して入力します。



blocks.js
 //   ,   var blocks = []; //  ,          dy2 = false; //     createBlock     (   ) var createBlock = function () { if (dy2 === false) { //       ,       dy2 = height - 60*del*4; //      } else { //    ,        ( ) dy2 = blocks[blocks.length-1].y - 500*del - math.random(500*del, 800*del); //     } blocks.push(game.newImageObject({ //      w : 200 * del*4, h : 60 * del*4, //  file : 'img/block.png', //    x : math.random(0, width - 200*del*4), //      y : dy2, //       })); }; //       //    ,      var oldBlock; //      ,     ?  ?    " " var createLevel = function (i) { //       pl.y = 0; //      ,       pl.x = 0; score = 0; //    OOP.forInt(i, function () { //      createBlock(); //        }); oldBlock = blocks[blocks.length-1] //      ,  -    ( ) }; //       ,    ,     var rePositionBlock = function (el) { //  ,      var x = math.random(0, width - 200*del*4), //       y = oldBlock.y - 500*del - //    oldBlock,      math.random(500*del, 800*del); //     ,      el.setPosition(point(x, y)); //     oldBlock = el; //       ,     ( ) }; //           var drawLevel = function () { //     OOP.forArr(blocks, function (el) { // ,       if (camera.getPosition().y + height + 2000*del < el.y) { //    rePositionBlock(el); //   } el.draw(); //   //      ,   if (pl.isStaticIntersect(el.getStaticBox()) && dy > 0) { //    ,      if (pl.y+pl.h < el.y+el.h/3) //     ,  ,         ,         dy = -50*del; //  ,   } }); };
      
      









ブロック画像:



画像



これですべて、作成するファイルはなくなりました。 最小形式のゲームの準備ができました:



画像



今の説明:

delは除数 、ピクセルのすべての値を乗算するために使用される係数です。 画面の高さは異なる可能性があるため、この要因は画面によっても異なり、動的にスケーリングされるサイズを乗算する他のオブジェクトを作成します。



デルタ時間(別名dt)は時間の要因です。 最後にレンダリングされたフレームから現在のフレームまでに経過したミリ秒単位の時間は、異なるパワーのデバイスでゲームを実行するときに、移動時のアニメーションと速度を滑らかにするために使用されます。



コンパイルについて。 インテルXDKサーバーで実行されます。これは、コンピューターが弱いユーザーに適しています。

そして、毎秒が彼のアイデアを盗もうとしていることを確かに知っている人にとっては悪い



一般に、問題はないはずです。プロジェクトをビルドするOSを選択し、証明書のパスワードを指定するだけの[ビルド]タブがあります。 コンパイル後、完成したプロジェクトをメールにダウンロードするためのリンクを受け取ります。プログラムから直接ダウンロードすることもできます。 サーバーからファイルをダウンロードした後、それらは削除されます。



プロジェクトソースのダウンロードアーカイブのダウンロード



実行するには、Google Chromeでindex.htmlファイルを開き、コンソールを開き(CTRL + SHIFT + J)、タッチスクリーンエミュレーションモードを有効にします。これにより、Intel XDKをインストールせずにゲームをプレイできます。



画像



Ready APKのダウンロードAPKのダウンロード

エミュレータで実行するか、実際のデバイスにインストールする必要があります。



開発プロセスの理解を深めるために、ビデオを添付します。



ビデオ形式の同じ記事
開発の最初の1時間:







開発の2時間目:








All Articles