コンペへの参加LudumDare#33

競技の2日間すべてでゲームの素晴らしいアイデアが思い浮かばなかったという事実にもかかわらず、私は数日で行われたいくつかの小さな開発を共有したいと思います。 おそらく記事は読者を見つけるでしょうし、誰かはまだトレンディなエンジンの代わりにpure-javaが好きです。



これは私の5回目の参加であり、毎回すべての手紙を一から書きます。 たまたま、グラフィックスを扱うための基本的な方法を書いている最中(思ったほど多くはありません)、何を書くべきかを思いつきます。 時々何かが出てきます。



画像



詳細を説明しないと、ゲームは非常に原始的です。 日が経つにつれて、あなたはあらゆる面からの騎士によって攻撃される遅いモンスターを制御します。 しかし、夜が来るとすぐに状況は劇的に変化し、今ではあなたは騎士を退治することができる非常に賢い片目モンスターです。 しかし、すべてがそれほどバラ色ではないので、私は攻撃的な行動(夜)に自動制御を持ち込み、あなたのためにほとんどすべてを行いました:私は殺し、新しい犠牲者、騎士を探しました。



カップル全体の興味深い瞬間(開発者にとって)は、おそらくタイルと暗視の生成であり、魚眼効果に似た可視性を大きく歪めます。 ところで、効果は退屈からそれ自体で判明しました。 事実、私は自分がゲームに適したアイデアを思い付かなかったという考えに苦しんでいましたが、やめるには遅すぎました。



これらのポイントをさらに詳しく見てみましょう。 まず、ナイトビジョン:



画像



通常、レンダリングは最初にオフスクリーンバッファーで行われ、すべてのゲーム要素が描画されるとすぐに、ノイズ、歪みなどの後処理を行う必要があります。



レンダリング後
public void postRender(Bitmap screenBitmap, Graphics2D g2d) { //     int[] pixels = screenBitmap.pixels; //   for (int i = 0; i < pixels.length; i++) { //     int x = i % screenBitmap.w - GameComponent.WIDTH / 2; int y = i / screenBitmap.w - GameComponent.HEIGHT / 2; //            //    x    ,      //       ,     0..255 double angle = (x / (double) screenBitmap.h * y / (double) screenBitmap.h) * Math.PI * 2.0 * (255 - dayFactor) / 255.0; //      int xx = (int) (x * Math.cos(angle) - y * Math.sin(angle)) + GameComponent.WIDTH / 2; int yy = (int) (y * Math.cos(angle) + x * Math.sin(angle)) + GameComponent.HEIGHT / 2; //      ,    if (xx >= 0 && yy >= 0 && xx < screenBitmap.w && yy < screenBitmap.h) { int c = pixels[xx + yy * screenBitmap.w]; int r = (c >> 16) & 0xff; int g = (c >> 8) & 0xff; int b = (c >> 0) & 0xff; //   gray scale,    //https://ru.wikipedia.org/wiki/%D0%9E%D1%82%D1%82%D0%B5%D0%BD%D0%BA%D0%B8_%D1%81%D0%B5%D1%80%D0%BE%D0%B3%D0%BE int m = (r * 30 + g * 59 + b * 11) / 100; //          r = (r + m) / 2 * dayFactor / 255; g = (g + m) / 2 * dayFactor / 255; b = (b + m) / 2 * dayFactor / 255; //     ,         postData[i] = 0xff << 24 | r << 16 | g << 8 | b; } else { //    ,  " "       int rnd = (int) (random.nextDouble() * 16); postData[i] = 0xff << 24 | (0x4C + rnd) << 16 | rnd << 8 | rnd; } } //         ,     . for (int i = 0; i < postData.length; i++) { pixels[i] = postData[i]; } g2d.setColor(Color.WHITE); g2d.drawString("score: " + score, 10, GameComponent.HEIGHT - 10); }
      
      







質問はないはずです。 もちろん、いくつかの値で遊んで、より快適な効果を達成できます。



ビッグ33 MB GIF
画像



次に、タイル生成について説明します。 原則として、ここに秘密はありません。2Dゲームの作成に携わったことがある場合、1つのテクスチャを別のテクスチャに転送するには16タイルが必要であることを知っています。 私たちのタスクは、これらのタイルを生成することです。 それでは、各タイルには4つの角度があり、1つのタイルから別のタイルへの移行を前提として、16種類のテクスチャを作成する必要があると考えてみましょう。 このメソッドを使用して生成されたテクスチャの例は、アイソメへの変換を除きます。



画像



しかし、ここでアイソメのないゲームの簡単な例を考えてみましょう。



テクスチャジェネレーター
  //       1616,   16       public static BufferedImage[] generate(int[] t0, int[] t1, int sz) { double iSz = 1.0 / sz; BufferedImage[] result = new BufferedImage[16]; for (int i = 0; i < 16; i++) { //        result[i] = new BufferedImage(sz, sz, BufferedImage.TYPE_INT_RGB); int[] data = new int[sz * sz]; //  4     //  ,        i   4  int a = (i >> 0) & 1; int b = (i >> 1) & 1; int c = (i >> 2) & 1; int d = (i >> 3) & 1; //   for (int y = 0; y < sz; y++) { double yp = y * iSz; for (int x = 0; x < sz; x++) { double xp = x * iSz; //   ab      t = xp double ab = a + (b - a) * xp; //  cd    t = xp double cd = c + (d - c) * xp; //   ab  cd     t = yp double val = ab + (cd - ab) * yp; //...  -    val //       ,        val if (val < 0) val = 0; if (val > 1.0) val = 1.0; //    1  2      t = val int c0 = t0[x + y * sz]; int c1 = t1[x + y * sz]; int col = Mth.lerpRGB(c0, c1, val); //     data[x + y * sz] = col; } } result[i].setRGB(0, 0, sz, sz, data, 0, sz); } return result; }
      
      







そして今、最もおいしい:生成されたマップに基づいて取得したタイルを表示する方法? 答えはとても簡単です。



レンダリング水タイル法
  public void render(Graphics2D g2d, Level level, int x, int y, int xOffs, int yOffs) { int xx = x >> 4; int yy = y >> 4; int t = 0; //           if (level.getTile(xx, yy) != Tile.water) t += 1; //     if (level.getTile(xx + 1, yy) != Tile.water) t += 2; //     if (level.getTile(xx, yy + 1) != Tile.water) t += 4; //      if (level.getTile(xx + 1, yy + 1) != Tile.water) t += 8; g2d.drawImage(Art.waterToGrassTiles[t], x - xOffs, y - yOffs, null); }
      
      







それだけです。 素晴らしいことは何もありませんが、そのような些細なことから多くの喜びを得ることができます。



All Articles