- なぜアンドロイド用の別の蛇?! 説明(説明付き);
- 私がそれをした方法-使用されたテクニック、少しのコード。
- デザインについて少し。
- Google Playゲーム、非標準使用。

興味のある方はカットをお願いします!
なぜアンドロイド用の別の蛇?!
秋になって、私のガールフレンドと私は海でリラックスしました。 温かい水、穏やかな水泳-これらすべてが頭の中でさまざまな思考の誕生につながります。 これらの考えの1つは、「帰りの飛行機で何をすべきか?」でした。 休息は本格的で、プログラミングを少し逃しました。 そこで、コーディングすることにしました! 何で? だから、Nideusは最近7インチにAIDEをインストールしました。何ですか?ゲームはシンプルです。しかし、ひねりが加えられています。
すぐに技術を選択するという疑問が生じました。 私は過去のゲーム( Pacman )をC ++ + OpenGL ES 2.0で作成しました。ここでは明示的なオーバーヘッドです。 Canvasについて心の隅から何かを聞き、少し読んで理解しました-必要なものを2つ与えます。 飛行機で4.5時間-エンジンの準備が整い、ヘビが歩き、それ自体に衝突し、6方向のスバイパに反応します。 そして...そして、さらに1か月ほど仕上げがありました。
結果として何が起こったのか:

スクリーンショット:メイン画面、Labyrinth "Mill"(ダークスキン)、Labyrinth "Teleport"(ライトスキン)
- 2種類のゲーム-迷路とクラシック。
- 3つのスキン。
- 次から次へと開く7つの難易度レベル。
ボーナスは、すぐにゲームを開始して試すことができる原始的なマップエディターと、多くの新しいエクスペリエンスでした。
どうやってやった
順番に始めましょう。
ホーム画面
彼は、コンポーネントのレイアウトが異なる一時停止画面です。

いくつかのコード
public class BackgroundView extends View { /* */ private Bitmap mBmp; @Override protected void onDraw(Canvas canvas) { /* , */ if(mBmp == null){ mBmp = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Config.ARGB_8888); Canvas c = new Canvas(mBmp); drawBackground(c); } canvas.drawBitmap(mBmp, 0, 0, null); } private void drawBackground(Canvas canvas){ canvas.drawRGB(180, 220, 70); /* , */ /* Path , , */ } }
このコードから何を学びますか? Canvasに描画する最初の(そして最も簡単な)方法。
View
から継承し、
void onDraw(Canvas canvas)
メソッドを再定義して、Canvasに好きなものを描画します。 このようにして、飛行機で書かれた最初のプロトタイプが描かれました。 動的更新の場合、
View
で
invalidate()
メソッドを呼び出す必要があり
View
。その後、 onDraw()が将来呼び出されます 。 保証なし。 集中的な描画のためにキャンバスを取得するより正確な方法を以下に説明します 。
設定画面

ここでは、原則として、ゲームのプレビューを除いて特別なものはありません。 これはかなり議論の余地のある決定のようですが、スキンを変更するときにプレイヤーに何が待っているかをすぐに見てもらいたいと思いました。 将来的には、スキンの数を増やす予定です。 また、振動をサポートするデバイスでは、この画面で振動のオン/オフを切り替えることができます。
ラビリンス選択画面

ゲームにはあまり多くの迷路はありませんが、8。今後、それらを追加する予定です。 各行には、迷宮、その名前、個人および世界記録のアイコンがあります。 プレーヤーがGoogle Playゲームにログインしていない場合、彼の個人記録は自動的に世界になります。 迷路は連続して開き、難易度も異なります。 そして、ここで、おそらく、Google Playゲームを使用する非標準的な方法について話す時が来ました...
Google Playゲームのカスタム使用
むしろ、成果のサブシステム。 私はそれを成果達成と呼びました。 確かに私はこれを思いついた最初の人ではありませんでしたが、この方法の説明は見つかりませんでした。 蹴らないでください=)
ゲームに特定の「ロック解除」が表示された場合-たとえば、私の場合のようにレベルや迷路を開くと、すぐに問題が発生します-プレーヤーに2つのデバイスがある場合はどうなりますか? 例えば、スマートフォンとタブレット? どこでも1つのデバイスでロック解除されたコンテンツを彼に使用させる方法は? サーバーがあり、それをサポートする時間があれば、すべてがオープンワークになります。 そして、私のように、どちらもどちらもなければ、次のトリックが出てくるかもしれません:
ユーザーがコンテンツのロックを解除したら、実績をロック解除します。
キャップコード
Games.Achievements.unlock(getApiClient(), achievementName);
また、コンテンツのオープン性を確認する必要がある場合は、この成果を事前に確認してください(事前に可能です)。
別のコード
PendingResult<LoadAchievementsResult> pendingResult = Games.Achievements.load(getApiClient(), true); pendingResult.setResultCallback(new LoadAchievementsResultCallback());
同時に、ダウンロードした実績をすぐに取得できる場所のどこかにキャッシュすることをお勧めします。 また、プレーヤーがログインしていない場合に、ロックされていない実績をキャッシュするには、まだログインしているときにそれらのロックを解除する必要があります。
なぜこれがGoogle Playゲームの非標準的な使用方法なのですか? ドキュメントは基本的に、成果はユーザーの気分を高めるためのそのようなthatであることを示しています。 しかし、それらは非常に役立つこともあります。 そして、私はそれがクールだと思います。 この方法を使用して、迷路と難易度を解除します。
それではゲーム自体について話しましょう
ゲームフィールドは15x15の六角形の正方形です。 タイルの2次元配列によって論理的に表され、各タイルには次の要素があります。
- 「次の」タイルの座標-ヘビとテレポーターの体内で使用されます。
- 「死すべき」という旗は、再び蛇の体と迷宮の壁です。
- タイルの種類-食べ物、スーパーフード、ヘビ、壁、テレポート、空;
したがって、死亡チェックは単一のフラグに等しく、テレポートを介して移動することは、単に移動するよりも高価ではありません。 フィールドは
IDrawer
インターフェイスを実装するクラスを使用して描画されるため、スキンの数は時間の経過とともに増加します。
上記では、Canvasでレンダリングする最も簡単な方法を説明しました。 動的レンダリングのより適切な方法は、
SurfaceView
から継承し、別のスレッドでレンダリングすることです。 主なポイントに焦点を当てます。
SurfaceView
し、
SurfaceView
イベントを受け取るために
SurfaceView
実装します。
コード
public class GameView extends SurfaceView implements SurfaceHolder.Callback{ public GameView(Context context){ super(context); getHolder().addCallback(this); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } }
DrawThread
を描くフローを書き
DrawThread
:
コード
public class DrawThread extends Thread { private boolean mRunning = false; private SurfaceHolder mSurfaceHolder; public DrawThread(SurfaceHolder surfaceHolder) { mSurfaceHolder = surfaceHolder; } public void setRunning(boolean running) { mRunning = running; } @Override public void run() { Canvas canvas; while (mRunning) { canvas = null; try { canvas = mSurfaceHolder.lockCanvas(null); if (canvas == null){ continue; } /* canvas */ } finally { if (canvas != null) { mSurfaceHolder.unlockCanvasAndPost(canvas); } } try{ //let other threads do they work Thread.sleep(15); }catch(InterruptedException e){ } } } }
SurfaceView
戻り、Surfaceを作成するときにレンダリングフローを開始します。
コード
@Override public void surfaceCreated(SurfaceHolder holder) { /* , Canvas , */ mDrawThread = new DrawThread(holder); mDrawThread.setRunning(true); mDrawThread.start(); }
そして、Surfaceの破壊後にクリーンアップすることを忘れないでください:
コード
@Override public void surfaceDestroyed(SurfaceHolder holder) { destroy(); } /* , surfaceDestroyed() , destroy() "" */ public synchronized void destroy(){ if(mDrawThread == null){ return; } boolean retry = true; mDrawThread.setRunning(false); while (retry){ try{ mDrawThread.join(); retry = false; } catch (InterruptedException ignored){ } } mDrawThread = null; }
IDrawer
と
Game
戦闘コードでは、
GameView
に渡します。 レンダリングフローでは、ロジックも再計算されます。
結論
小さなゲーム(クローンを含む)を作成するだけでなく、独自のゲーム以外のプロジェクトを作成することも非常に便利です。 特に便利なのは、快適ゾーンから抜け出す方法です。これにより、多くの新しい有用な情報をすばやく学習できます。 数時間の小さな投影から、非常に興味深いゲームを作成できます。
キャンバス描画技術は、特殊効果が不要な小さなゲームに適しています。
Android向けのJavaでゲームを書くことは、特にあなたが孤独である場合、C ++で書くよりもはるかに簡単です。
良い週末をお過ごしください、そして明けましておめでとうございます!