4番目の部分は非常に興味深いことを約束します。 その中で、レーザー銃、鏡、反射の作成を検討します。 読む前に前の部分を読んでください。
パート1
パート2
パート3
面白い?
ステップ1.制限。
少しずつ始めましょう。 誰もが知っているように、理想的なレーザーは光の速度で移動し、その経路に障害物がなければ、停止することはまずありません。 私たちのLaserLineは完璧ではありません。最初にすべきことは、競技場から「飛ぶ」機会を与えないことです。 これを行うには、GameObjectsMapクラスにメソッドを追加します。
public static boolean outOfArea(Point pos) {
return pos.x < 0 || pos.y < 0 || pos.x > WIDTH - 1
|| pos.y > HEIGHT - 1;
}
* This source code was highlighted with Source Code Highlighter .
構築中にこの方法でレーザーの位置を確認します。
ステップ2. LaserGun。
レーザークラスに加えて、回転してレーザーの動きを妨げることができるレーザー銃のクラスがあった記事の2番目の部分を皆さんが覚えていることを願っています。 フィールドを追加します。
private LaserLine mLaserLine;
コンストラクターに追加します。
mLaserLine = new LaserLine(new Point(posX, posY), angle);
attachToメソッドで、次を追加します。
scene.getChild(GameObjectsMap.LASER_LAYER).attachChild(mLaserLine);
さて、今私たちの銃はレーザーを持っていますが、それは見えません。 彼を見るには、彼が通過する一連のポイントを彼に尋ねる必要があります。 これを行うには、LaserGunクラスでメソッドを記述します。
public void buildLaser(GameObject[][] map) {
mLaserLine.setAngle(getAngle());
mLaserLine.build(map);
}
* This source code was highlighted with Source Code Highlighter .
ここではすべてが一目でわかります。レーザーパスは初期方向とそのパス内のオブジェクトに依存しますが、これにはマップが必要でした。 しかし、LaserLine.build()メソッドはまだ存在しません。 彼の世話をします。
public void build(GameObject[][] map) {
sBuilder.buildPath( this , map);
buildLines();
}
* This source code was highlighted with Source Code Highlighter .
メソッドは短いですが、sBuilderについてはまだ説明していません。 隠された魔法があります。 LaserLineクラスに追加することを忘れないでください:
private static LaserLineBuilder sBuilder = new LaserLineBuilder();
静的にしたので、各レーザーに個別のコピーがないことが確実になります。これにより、メモリが節約され、速度にプラスの効果があります。
ステップ3. LaserBuilder
レーザーの構造がどのように見えるかを示します。
public class LaserLineBuilder {
private static final int MAX_STEPS = 200;
public void buildPath(LaserLine laserLine, GameObject[][] map) {
laserLine.clearPoints();
int step = 0;
int angle = laserLine.getAngle();
Point position = new Point(laserLine.getStartPosition());
GameObject gameObject;
while (step < MAX_STEPS) {
nextPosition(position, angle);
if (GameObjectsMap.outOfArea(position)) {
laserLine.addPoint(position);
return ;
}
gameObject = map[position.x][position.y];
if (gameObject == null ) {
continue ;
} else {
laserLine.addPoint(position);
int reflection = gameObject.onLaser(angle);
if (reflection < 0) {
return ;
} else {
angle = reflection;
}
}
}
laserLine.addPoint(position);
}
private void nextPosition(Point position, final int angle) {
switch (angle) {
case DynamicGameObject.DEG_0:
position.x++;
break ;
case DynamicGameObject.DEG_90:
position.y++;
break ;
case DynamicGameObject.DEG_180:
position.x--;
break ;
case DynamicGameObject.DEG_270:
position.y--;
break ;
case DynamicGameObject.DEG_45:
position.x++;
position.y++;
break ;
case DynamicGameObject.DEG_135:
position.x--;
position.y++;
break ;
case DynamicGameObject.DEG_225:
position.x--;
position.y--;
break ;
case DynamicGameObject.DEG_315:
position.x++;
position.y--;
break ;
default :
break ;
}
}
}
* This source code was highlighted with Source Code Highlighter .
順番に行きましょう。 200レーザーステップの制限、理由は明らかだと思います。 さらに、最初のレーザーポイントは作成時に追加され、LaserGunの座標と一致します。残りのポイントは、ゲームエリアを離れるとき、停止するとき、および反射するときに追加されます。 最初は、各セルの通過に沿ってポイントが追加されていましたが、 Mirrors Mazeではまだこのような状態です。 しかし、そこではAndEngineは使用されませんでした。
nextPositionには、説明が不要であることが望まれます。
ステップ4.ミラー。
これまでのところ、レーザーを反射できるオブジェクトはありませんでした。 次に、そのようなものを作成し、すべてが意図したとおりに機能するかどうかを確認する必要があります。 目的のテクスチャを追加することを忘れないでください。
public class Mirror extends DynamicGameObject {
public Mirror(final int posX, final int posY, final int angle,
final TextureRegion region) {
super(posX, posY, angle, region);
}
@Override
void attachTo(Scene scene) {
scene.getChild(GameObjectsMap.GAME_OBJECTS_LAYER).attachChild(
getSprite());
}
@Override
int onLaser( int angle) {
int a = getAngle() % 4;
if (angle == (a + 1) % 8) return (a + 7) % 8;
if (angle == (a + 7) % 8) return (a + 1) % 8;
if (angle == (a + 3) % 8) return (a + 5) % 8;
if (angle == (a + 5) % 8) return (a + 3) % 8;
return -1;
}
}
* This source code was highlighted with Source Code Highlighter .
新しいゲームオブジェクトの作成は非常に簡単です。 ネタバレをせずに行うことができます。onLaserメソッドがどのように機能するかについては、興味のある読者にお任せします。 双方向ミラーの準備ができました。 GameObjectsMapに初期化を追加するために残ります。
ステップ4:レーザーを初期化します。
すべての操作の後、addメソッドは次のようになります。
public void add(Type type, final int posH, final int posW, final int angle) {
GameObject object = null ;
switch (type) {
case lasergun:
LaserGun l = new LaserGun(posH, posW, angle, mTextures
.getLaserGun());
mLaserGuns.add(l);
object = l;
break ;
case mirror:
object = new Mirror(posH, posW, angle, mTextures.getMirror());
break ;
case target:
break ;
default :
break ;
}
mMap[posH][posW] = object ;
}
* This source code was highlighted with Source Code Highlighter .
しかし、より便利な作業と銃が必要なため、ミラーの追加に限定しませんでした。
private LinkedList mLaserGuns;
そして
public void buildLasers() {
for (LaserGun gun : mLaserGuns) {
gun.buildLaser(mMap);
}
}
* This source code was highlighted with Source Code Highlighter .
さて、何が起こったのか見てみましょう。 StageActivityでコードを追加します。
private void initMap() {
mGameObjectsMap = new GameObjectsMap(mTextures);
mGameObjectsMap.add(Type.lasergun, 0, 0, 3);
mGameObjectsMap.add(Type.lasergun, 3, 2, 7);
mGameObjectsMap.add(Type.lasergun, 3, 4, 4);
mGameObjectsMap.add(Type.mirror, 3, 3, 3);
mGameObjectsMap.addToScene(mEngine.getScene());
mGameObjectsController = new GameObjectsController(mGameObjectsMap, this );
final Scene scene = getEngine().getScene();
mGameObjectsMap.buildLasers();
}
* This source code was highlighted with Source Code Highlighter .
結果として、楽しいものが表示されます。
今日はこれで十分です。 ご清聴ありがとうございました。 私は質問、アドバイス、提案を喜んでいます。
ソースコード。