2017-11-16 8 views
0

私はSurfaceViewを使って短い試合をしています。私の "船"は単なる白い矩形で、障害物は小惑星のビットマップです。小惑星が船に衝突すると、20個の破片(ただ10×10の白い点)があらゆる方向に飛んでいく爆発アニメーションが起こるはずです。ビットマップの爆発アニメーションが1つの場所で回転していて、外側に動かない

問題は、衝突が発生したときに、ここで示したように、すべての破片はちょうど、円の中に一箇所紡績に座っているということです。

screenshot of explosion

を爆発は確かに私の正確な位置で開始しません船。粒子はちょうど外側に動かない。コードを間違った場所に置いたことがありますか?誰が私がこれに間違っていたか知っていますか?ここで

クラスです:

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Matrix; 
import android.graphics.Paint; 
import android.graphics.Point; 
import android.graphics.Rect; 
import android.util.DisplayMetrics; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import java.util.Random; 


public class GameView extends SurfaceView implements Runnable, SurfaceHolder.Callback { 

    private Thread gameViewThread = null; 
    SurfaceHolder surfaceHolder; 
    boolean okToRun; 

    /* 
    SHIP AND ASTEROID STUFF 
    */ 
    private Ship ship; 
    private Point shipPoint; 
    private Rect textRect = new Rect(); 
    private float oldX; 
    private float oldY; 
    private AsteroidController asteroidController; 
    /* 
    END SHIP AND ASTEROID STUFF 
    */ 

    /* 
    GAME OVER STUFF 
    */ 
    private boolean isMoving = false; 
    private boolean isGameOver = false; 
    private long waitTime; 
    /* 
    END GAME OVER STUFF 
    */ 

    /* 
    EXPLOSION STUFF 
    */ 
    Bitmap explosionBMP; 
    private Matrix[] explosion = new Matrix[20]; 
    boolean isDestroyed = false; 
    boolean explosionStarted = false; 
    float[] explosionXPosition = new float[20]; 
    float[] explosionYPosition = new float[20]; 
    float explosionSpeed = 20.0f; 
    float[] explosionRotation = new float[20]; 
    /* 
    END EXPLOSION STUFF 
    */ 

    /* 
    SCREEN DIMENSIONS 
    */ 
    DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); 
    int gameWidth = displayMetrics.widthPixels; 
    int gameHeight = displayMetrics.heightPixels; 
    /* 
    END SCREEN DIMENSIONS 
    */ 

    public GameView(Context context) { 
     super(context); 

     surfaceHolder = this.getHolder(); 
     okToRun = true; 

     ship = new Ship(new Rect(100, 100, 200, 200), Color.WHITE); 
     shipPoint = new Point(gameWidth/2, 3 * gameHeight/4); 
     ship.update(shipPoint); 

     asteroidController = new AsteroidController(context); 

     //JUST SPAWNING ONE ASTEROID FOR NOW 
     asteroidController.createAsteroid(1); 

     //JUST A 10 x 10 WHITE DOT 
     explosionBMP = BitmapFactory.decodeResource(getResources(), R.drawable.explosion_debris); 

     //DON'T WANT A NULL POINTER RIGHT OFF THE BAT 
     for(int i = 0; i < explosion.length; i++) { 
      explosion[i] = new Matrix(); 
     } 

     setFocusable(true); 
    } 

    @Override 
    public void run() { 
     while(okToRun) { 
      if(!surfaceHolder.getSurface().isValid()) { 
       continue; 
      } 
      Canvas gameCanvas = surfaceHolder.lockCanvas(); 

      this.update(); 
      this.draw(gameCanvas); 
      surfaceHolder.unlockCanvasAndPost(gameCanvas); 
     } 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 

     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 

       isMoving = true; 
       oldX = event.getX(); 
       oldY = event.getY(); 
       if (isGameOver && System.currentTimeMillis() - waitTime >= 3000) { 
        isGameOver = false; 
        resetGame(); 
       } 
       break; 
      case MotionEvent.ACTION_MOVE: 
       if (!isGameOver && isMoving) { 

        /* 
        THIS CODE ALLOWS TOUCH EVENT TO BE ANYWHERE ON SCREEN WHILE 
        SHIP MOVES ACCORDINGLY 
        */ 
        float newX = event.getX(); 
        float newY = event.getY(); 
        float deltaX = getOffsetCoords(oldX, newX, shipPoint.x); 
        float deltaY = getOffsetCoords(oldY, newY, shipPoint.y); 
        shipPoint.set((int) deltaX, (int) deltaY); 
        oldX = newX; 
        oldY = newY; 
       } 
       return false; 
     } 
     return true; 
    } 

    /* 
    GET THE DIFFERENCE IN SHIP COORDS AND TOUCH COORDS 
    */ 
    private float getOffsetCoords(float oldVal, float newVal, float current) { 
     return current + (newVal - oldVal); 
    } 




    @Override 
    public void draw(Canvas canvas) { 
     super.draw(canvas); 

     //RANDOMS FOR STARS 
     Random random0 = new Random(); 
     Random random1 = new Random(); 

     //BACKGROUND 
     canvas.drawColor(Color.BLACK); 
     Bitmap single_pixel_star = BitmapFactory.decodeResource(getResources(), R.drawable.single_pixel_star); 
     Bitmap three_pixel_star = BitmapFactory.decodeResource(getResources(), R.drawable.three_pixel_star); 

     //Draw random stars on the canvas 
     canvas.drawBitmap(single_pixel_star, random0.nextInt(canvas.getWidth() - single_pixel_star.getWidth()), random0.nextInt(canvas.getHeight() - three_pixel_star.getHeight()), null); 
     canvas.drawBitmap(three_pixel_star, random1.nextInt(canvas.getWidth() - three_pixel_star.getWidth()), random1.nextInt(canvas.getHeight() - three_pixel_star.getHeight()), null); 

     //DRAW ASTEROID(s) 
     asteroidController.render(canvas); 
     //DRAW SHIP 
     ship.draw(canvas); 


     if (isGameOver) { 

      ship.removeShip(); 

      isDestroyed = true; 
      explosionStarted = true; 

      Paint gameOverPaint = new Paint(); 
      gameOverPaint.setTextSize(200); 
      gameOverPaint.setColor(Color.RED); 
      showGameOver(canvas, gameOverPaint, "YOU LOSE!"); 

      /* 
      SHIP GOES KABOOM! 
      */ 
      for(int i = 0; i < explosion.length; i++) { 
       canvas.drawBitmap(explosionBMP, explosion[i], null); 
      } 

     } 
    } 
    public void update() { 
     if (!isGameOver) { 
      ship.update(shipPoint); 
      asteroidController.update(); 

      if (asteroidController.isCollision(ship)) { 
       isGameOver = true; 
       waitTime = System.currentTimeMillis(); 
      } 
     } 
     Matrix[] localExplosionDebris = new Matrix[20]; 
     if(explosionStarted) { 
      for(int i = 0; i < explosionXPosition.length; i++) { 
       explosionXPosition[i] = getShipPointX(); 
       explosionYPosition[i] = getShipPointY(); 
       Random rand = new Random(); 
       explosionRotation[i] = (float) rand.nextInt(360); 
      } 
      explosionStarted = false; 
     } 
     for(int i = 0; i < localExplosionDebris.length; i++) { 
      localExplosionDebris[i] = new Matrix(); 
     } 
     if(isDestroyed) { 
      for(int i = 0; i < localExplosionDebris.length; i++) { 
       float debrisXSpeed = (float) Math.sin(explosionRotation[i]*(Math.PI/180)) * explosionSpeed - .2f; 
       float debrisYSpeed = (float) Math.cos(explosionRotation[i]*(Math.PI/180)) * explosionSpeed - .2f; 

       explosionXPosition[i] += debrisXSpeed; 
       explosionYPosition[i] -= debrisYSpeed; 

       localExplosionDebris[i].postRotate(0, explosionBMP.getWidth()/2, explosionBMP.getHeight()/2); 
       localExplosionDebris[i].postTranslate(explosionXPosition[i], explosionYPosition[i]); 

       explosion[i].set(localExplosionDebris[i]); 
      } 
     } 
    } 

    /* 
    SHOW GAME OVER TEXT ON THE CENTER OF THE SCREEN UNTIL 3 SECONDS HAVE PASSED AND TOUCH EVENT OCCURS 
    */ 
    private void showGameOver(Canvas canvas, Paint paint, String gameOverString) { 
     paint.setTextAlign(Paint.Align.LEFT); 
     canvas.getClipBounds(textRect); 
     int canvasH = textRect.height(); 
     int canvasW = textRect.width(); 
     paint.getTextBounds(gameOverString, 0, gameOverString.length(), textRect); 
     float textX = canvasW/2f - textRect.width()/2f - textRect.left; 
     float textY = canvasH/2f - textRect.height()/2f - textRect.bottom; 
     canvas.drawText(gameOverString, textX, textY, paint); 
    } 

    /* 
    RESET SHIP TO ORIGINAL LOCATION AND COLOR 
    */ 
    public void resetGame() { 
     ship = new Ship(new Rect(100, 100, 200, 200), Color.WHITE); 
     shipPoint = new Point(gameWidth/2, 3 * gameHeight/4); 

     //TODO STOP BG MUSIC ONCE FILE IS ADDED 
     //TODO RESET SCORE ONCE ADDED 
    } 


    public void pause() { 
     okToRun = false; 
     while(true) { 
      try { 
       gameViewThread.join(); 
      } catch(InterruptedException e) { 
       Log.d("ERROR", e.getMessage()); 
      } 
      break; 
     } 
     gameViewThread = null; 
    } 

    public void resume() { 
     okToRun = true; 
     gameViewThread = new Thread(this); 
     gameViewThread.start(); 

    } 

    /* 
    SELF EXPLANATORY 
    */ 
    public int getShipPointX() { 
     return shipPoint.x; 
    } 

    public int getShipPointY() { 
     return shipPoint.y; 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 

    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 

    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 

    } 
} 

答えて

0

私はいくつかのブール変数を並べ替えて、私は今、爆発を持っています。文の場合は、次のでは、あなたは私がコメントアウトものを見ることができます。

if (isGameOver) { 

     ship.removeShip(); 

     //isDestroyed = true; 
     //explosionStarted = true; 
     Paint gameOverPaint = new Paint(); 
     gameOverPaint.setTextSize(200); 
     gameOverPaint.setColor(Color.RED); 
     showGameOver(canvas, gameOverPaint, "YOU LOSE!"); 

     /* 
     SHIP GOES KABOOM! 
     */ 
     for(int i = 0; i < explosion.length; i++) { 
      canvas.drawBitmap(explosionBMP, explosion[i], null); 
     } 

    } 

別ではif文、私はその後、ANでそれらをリセットし、その文をコメントアウト真偽値(上図)を置き、条件を追加しましたelse:

if (!isGameOver) { 
     ship.update(shipPoint); 
     asteroidController.update(); 

     if (asteroidController.isCollision(ship) && !isDestroyed) { //<--added the && !isDestroyed 
      isGameOver = true; 
      isDestroyed = true; //<-- added this 
      explosionStarted = true; //<-- and this 
      waitTime = System.currentTimeMillis(); 
     } else { 
      isGameOver = false; //<-- then reset here 
      isDestroyed = false; //<-- and here 
      explosionStarted = false; //<-- and here 
     } 
    } 

すべて完了しました。 :-)

Showing proof that it works now

関連する問題