2017-11-18 201 views
0

我是Android Studio的初學者,我不知道這是如何完成的。我的遊戲可從我的github repo獲得。故事在於角色應該抓住掉落的物體。 enter image description here但是,我怎樣才能實現暫停/恢復功能?通常如何做?遊戲暫停/恢復功能

我的代碼

package dev.android.gamex; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Vibrator; 
import android.support.v4.view.MotionEventCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.Window; 
import android.widget.LinearLayout; 
import android.widget.TextView; 
import android.widget.Toast; 

import java.util.Random; 

public class MainActivity extends AppCompatActivity { 
    CatchGame cg; 
    boolean pause = false; 
    // start app 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     cg = new CatchGame(this, 5, "Jamie"); 
     setContentView(cg); 
     cg.setBackground(getResources().getDrawable(R.mipmap.jungle)); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main_menu, menu); 
     return true; 
    } 

    // method called when top right menu is tapped 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     super.onOptionsItemSelected(item); 
     int difficulty = cg.NBRSTEPS; 
     String name = cg.heroName; 

     switch (item.getItemId()) { 
      case R.id.item11: 
       cg = new CatchGame(this, 3, name); 
       setContentView(cg); 
       return true; 
      case R.id.item12: 
       cg = new CatchGame(this, 5, name); 
       setContentView(cg); 
       return true; 
      case R.id.item13: 
       cg = new CatchGame(this, 7, name); 
       setContentView(cg); 
       return true; 
      case R.id.item14: 
       cg = new CatchGame(this, 9, name); 
       setContentView(cg); 
       return true; 
      case R.id.item15: 
       cg = new CatchGame(this, 11, name); 
       setContentView(cg); 
       return true; 
      case R.id.item21: 
       cg = new CatchGame(this, difficulty, "Jamie"); 
       cg.setBackground(getResources().getDrawable(R.mipmap.jungle)); 

       setContentView(cg); 
       return true; 
      case R.id.item22: 
       cg = new CatchGame(this, difficulty, "Spaceship"); 
       cg.setBackground(getResources().getDrawable(R.mipmap.space)); 

       setContentView(cg); 
       return true; 
      default: 
       cg.paused = true; 
       return super.onOptionsItemSelected(item); 
     } 
    } 


} 


class CatchGame extends View { 
    int NBRSTEPS; // number of discrete positions in the x-dimension; must be uneven 
    String heroName; 
    int screenW; 
    int screenH; 
    int[] x; // x-coordinates for falling objects 
    int[] y; // y-coordinates for falling objects 
    int[] hero_positions; // x-coordinates for hero 
    Random random = new Random(); 
    int ballW; // width of each falling object 
    int ballH; // height of ditto 
    float dY; //vertical speed 
    Bitmap ball, hero; 
    int heroXCoord; 
    int heroYCoord; 
    int xsteps; 
    int score; 
    int offset; 
    boolean gameOver; // default value is false 
    boolean toastDisplayed; 
    boolean paused = false; 

    // constructor, load images and get sizes 
    public CatchGame(Context context, int difficulty, String name) { 
     super(context); 
     NBRSTEPS = difficulty; 
     heroName = name; 
     x = new int[NBRSTEPS]; 
     y = new int[NBRSTEPS]; 
     hero_positions = new int[NBRSTEPS]; 
     int resourceIdFalling = 0; 
     int resourceIdHero = 0; 
     if (heroName.equals("Jamie")) { 
      resourceIdFalling = R.mipmap.falling_object2; 
      resourceIdHero = R.mipmap.jamie; 
     } 
     if (heroName.equals("Spaceship")) { 
      resourceIdFalling = R.mipmap.falling_object; 
      resourceIdHero = R.mipmap.ufo; 
     } 
     ball = BitmapFactory.decodeResource(getResources(), resourceIdFalling); //load a ball image 
     hero = BitmapFactory.decodeResource(getResources(), resourceIdHero); //load a hero image 
     ballW = ball.getWidth(); 
     ballH = ball.getHeight(); 
    } 

    // set coordinates, etc. 
    void initialize() { 
     if (!gameOver) { // run only once, when the game is first started 
      int maxOffset = (NBRSTEPS - 1)/2; 
      for (int i = 0; i < x.length; i++) { 
       int origin = (screenW/2) + xsteps * (i - maxOffset); 
       x[i] = origin - (ballW/2); 
       hero_positions[i] = origin - hero.getWidth(); 
      } 
      int heroWidth = hero.getWidth(); 
      int heroHeight = hero.getHeight(); 

      hero = Bitmap.createScaledBitmap(hero, heroWidth * 2, heroHeight * 2, true); 
      heroYCoord = screenH - 2 * heroHeight; // bottom of screen 

     } 
     for (int i = 0; i < y.length; i++) { 
      y[i] = -random.nextInt(1000); // place items randomly in vertical direction 
     } 

     offset = (NBRSTEPS - 1)/2; // place hero at centre of the screen 
     heroXCoord = hero_positions[offset]; 

     // initialize or reset global attributes 
     dY = 2.0f; 
     score = 0; 
     gameOver = false; 
     toastDisplayed = false; 
    } 

    // method called when the screen opens 
    @Override 
    public void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
     screenW = w; 
     screenH = h; 
     xsteps = w/NBRSTEPS; 
     initialize(); 
    } 

    // method called when the "game over" toast has finished displaying 
    void restart(Canvas canvas) { 

     toastDisplayed = true; 

     initialize(); 
     draw(canvas); 
    } 

    // update the canvas in order to display the game action 
    @Override 
    public void onDraw(Canvas canvas) { 
     if (toastDisplayed) { 
      restart(canvas); 
      return; 
     } 
     super.onDraw(canvas); 

     int heroHeight = hero.getHeight(); 
     int heroWidth = hero.getWidth(); 
     int heroCentre = heroXCoord + heroWidth/2; 

     Context context = this.getContext(); 

     // compute locations of falling objects 
     for (int i = 0; i < y.length; i++) { 
      if (!paused) { 
       y[i] += (int) dY; 
      } 
      // if falling object hits bottom of screen 
      if (y[i] > (screenH - ballH) && !gameOver) { 
       dY = 0; 
       gameOver = true; 
       paused = true; 
       int duration = Toast.LENGTH_SHORT; 

       final Toast toast = Toast.makeText(context, "GAME OVER!\nScore: " + score, duration); 
       toast.show(); 
       Handler handler = new Handler(); 
       handler.postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         toast.cancel(); 
         toastDisplayed = true; 
        } 
       }, 3000); 
       //Vibrator v = (Vibrator) context.getSystemService(context.VIBRATOR_SERVICE); 
       // Vibrate for 3000 milliseconds 
       //v.vibrate(3000); 

      } 
      // if the hero catches a falling object 
      if (x[i] < heroCentre && x[i] + ballW > heroCentre && 
        y[i] > screenH - ballH - heroHeight) { 

       y[i] = -random.nextInt(1000); // reset to new vertical position 
       score += 1; 
      } 

      LinearLayout layout = new LinearLayout(this.getContext()); 

      TextView textView = new TextView(context); 
      textView.setVisibility(View.VISIBLE); 
      String str = "Score: " + score; 
      textView.setText(str); 
      layout.addView(textView); 

      layout.measure(canvas.getWidth(), canvas.getHeight()); 
      layout.layout(0, 0, canvas.getWidth(), canvas.getHeight()); 

      layout.draw(canvas); 

     } 

     canvas.save(); //Save the position of the canvas. 

     for (int i = 0; i < y.length; i++) { 
      canvas.drawBitmap(ball, x[i], y[i], null); //Draw the ball on the canvas. 
     } 
     canvas.drawBitmap(hero, heroXCoord, heroYCoord, null); //Draw the hero on the canvas. 

     canvas.restore(); 
     //Call the next frame. 
     invalidate(); 
    } 

    // event listener for when the user touches the screen 
    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if (paused) { 
      paused = false; 
     } 
     int action = MotionEventCompat.getActionMasked(event); 
     if (action != MotionEvent.ACTION_DOWN || gameOver) { // non-touchdown event or gameover 
      return true; // do nothing 
     } 
     int coordX = (int) event.getX(); 
     int xCentre = (screenW/2) - (hero.getWidth()/2); 
     int maxOffset = hero_positions.length - 1; // can't move outside right edge of screen 
     int minOffset = 0; // ditto left edge of screen 
     if (coordX < xCentre && offset > minOffset) { // touch event left of the centre of screen 
      offset--; // move hero to the left 
     } 
     if (coordX > xCentre && offset < maxOffset) { // touch event right of the centre of screen 
      offset++; // move hero to the right 
     } 
     heroXCoord = hero_positions[offset]; 

     return true; 
    } 
} 

回答

1

不錯的遊戲!

  • 您已經實現了pause功能,所以我只是用它。
  • 添加視圖裏面的onDraw()是非常糟糕的,因爲它使應用程序太慢。所以請保留onDraw()以外的繁重工作。爲了更新分數,我添加了新的界面OnScoreListener
  • 而且,我添加了暫停/播放按鈕。

enter image description here

代碼是:

package dev.android.gamex; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.os.Bundle; 
import android.os.Handler; 
import android.support.v4.view.MotionEventCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.MotionEvent; 
import android.view.View; 
import android.widget.Button; 
import android.widget.LinearLayout; 
import android.widget.TextView; 
import android.widget.Toast; 

import java.util.Random; 

public class MainActivity extends AppCompatActivity { 
    CatchGame cg; 
    public TextView textView; 

    // start app 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     LinearLayout mainLayout = new LinearLayout(this); 
     mainLayout.setOrientation(LinearLayout.VERTICAL); 

     LinearLayout menuLayout = new LinearLayout(this); 
     menuLayout.setBackgroundColor(Color.parseColor("#FFFFFF")); 

     textView = new TextView(this); 
     textView.setVisibility(View.VISIBLE); 
     String str = "Score: 0"; 
     textView.setText(str); 
     menuLayout.addView(textView); 

     Button button = new Button(this); 
     button.setText("Pause"); 
     button.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       togglePausePlay(); 
      } 
     }); 
     menuLayout.addView(button); 
     mainLayout.addView(menuLayout); 

     cg = new CatchGame(this, 5, "Jamie", onScoreListener); 
     cg.setBackground(getResources().getDrawable(R.mipmap.jungle)); 
     mainLayout.addView(cg); 

     setContentView(mainLayout); 
    } 

    private void togglePausePlay() { 
     if (cg.paused) { 
      // play 
      Toast.makeText(MainActivity.this, "Play", Toast.LENGTH_SHORT).show(); 
     } else { 
      // pause 
      Toast.makeText(MainActivity.this, "Pause", Toast.LENGTH_SHORT).show(); 
     } 

     cg.paused = !cg.paused; 
    } 

    private OnScoreListener onScoreListener = new OnScoreListener() { 
     @Override 
     public void onScore(int score) { 
      textView.setText("Score: " + score); 
     } 
    }; 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main_menu, menu); 
     return true; 
    } 

    // method called when top right menu is tapped 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     super.onOptionsItemSelected(item); 
     int difficulty = cg.NBRSTEPS; 
     String name = cg.heroName; 

     switch (item.getItemId()) { 
      case R.id.item11: 
       cg = new CatchGame(this, 3, name, onScoreListener); 
       setContentView(cg); 
       return true; 
      case R.id.item12: 
       cg = new CatchGame(this, 5, name, onScoreListener); 
       setContentView(cg); 
       return true; 
      case R.id.item13: 
       cg = new CatchGame(this, 7, name, onScoreListener); 
       setContentView(cg); 
       return true; 
      case R.id.item14: 
       cg = new CatchGame(this, 9, name, onScoreListener); 
       setContentView(cg); 
       return true; 
      case R.id.item15: 
       cg = new CatchGame(this, 11, name, onScoreListener); 
       setContentView(cg); 
       return true; 
      case R.id.item21: 
       cg = new CatchGame(this, difficulty, "Jamie", onScoreListener); 
       cg.setBackground(getResources().getDrawable(R.mipmap.jungle)); 

       setContentView(cg); 
       return true; 
      case R.id.item22: 
       cg = new CatchGame(this, difficulty, "Spaceship", onScoreListener); 
       cg.setBackground(getResources().getDrawable(R.mipmap.space)); 

       setContentView(cg); 
       return true; 
      default: 
       cg.paused = true; 
       return super.onOptionsItemSelected(item); 
     } 
    } 


} 

interface OnScoreListener { 
    void onScore(int score); 
} 

class CatchGame extends View { 
    int NBRSTEPS; // number of discrete positions in the x-dimension; must be uneven 
    String heroName; 
    int screenW; 
    int screenH; 
    int[] x; // x-coordinates for falling objects 
    int[] y; // y-coordinates for falling objects 
    int[] hero_positions; // x-coordinates for hero 
    Random random = new Random(); 
    int ballW; // width of each falling object 
    int ballH; // height of ditto 
    float dY; //vertical speed 
    Bitmap ball, hero; 
    int heroXCoord; 
    int heroYCoord; 
    int xsteps; 
    int score; 
    int offset; 
    boolean gameOver; // default value is false 
    boolean toastDisplayed; 
    boolean paused = false; 

    OnScoreListener onScoreListener; 

    // constructor, load images and get sizes 
    public CatchGame(Context context, int difficulty, String name, OnScoreListener onScoreListener) { 
     super(context); 
     NBRSTEPS = difficulty; 
     heroName = name; 
     this.onScoreListener = onScoreListener; 

     x = new int[NBRSTEPS]; 
     y = new int[NBRSTEPS]; 
     hero_positions = new int[NBRSTEPS]; 
     int resourceIdFalling = 0; 
     int resourceIdHero = 0; 
     if (heroName.equals("Jamie")) { 
      resourceIdFalling = R.mipmap.falling_object2; 
      resourceIdHero = R.mipmap.jamie; 
     } 
     if (heroName.equals("Spaceship")) { 
      resourceIdFalling = R.mipmap.falling_object; 
      resourceIdHero = R.mipmap.ufo; 
     } 
     ball = BitmapFactory.decodeResource(getResources(), resourceIdFalling); //load a ball image 
     hero = BitmapFactory.decodeResource(getResources(), resourceIdHero); //load a hero image 
     ballW = ball.getWidth(); 
     ballH = ball.getHeight(); 
    } 

    // set coordinates, etc. 
    void initialize() { 
     if (!gameOver) { // run only once, when the game is first started 
      int maxOffset = (NBRSTEPS - 1)/2; 
      for (int i = 0; i < x.length; i++) { 
       int origin = (screenW/2) + xsteps * (i - maxOffset); 
       x[i] = origin - (ballW/2); 
       hero_positions[i] = origin - hero.getWidth(); 
      } 
      int heroWidth = hero.getWidth(); 
      int heroHeight = hero.getHeight(); 

      hero = Bitmap.createScaledBitmap(hero, heroWidth * 2, heroHeight * 2, true); 
      heroYCoord = screenH - 2 * heroHeight; // bottom of screen 

     } 
     for (int i = 0; i < y.length; i++) { 
      y[i] = -random.nextInt(1000); // place items randomly in vertical direction 
     } 

     offset = (NBRSTEPS - 1)/2; // place hero at centre of the screen 
     heroXCoord = hero_positions[offset]; 

     // initialize or reset global attributes 
     dY = 2.0f; 
     score = 0; 
     gameOver = false; 
     toastDisplayed = false; 
    } 

    // method called when the screen opens 
    @Override 
    public void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
     screenW = w; 
     screenH = h; 
     xsteps = w/NBRSTEPS; 
     initialize(); 
    } 

    // method called when the "game over" toast has finished displaying 
    void restart(Canvas canvas) { 

     toastDisplayed = true; 

     initialize(); 
     draw(canvas); 
    } 

    // update the canvas in order to display the game action 
    @Override 
    public void onDraw(Canvas canvas) { 
     if (toastDisplayed) { 
      restart(canvas); 
      return; 
     } 
     super.onDraw(canvas); 

     int heroHeight = hero.getHeight(); 
     int heroWidth = hero.getWidth(); 
     int heroCentre = heroXCoord + heroWidth/2; 

     Context context = this.getContext(); 

     // compute locations of falling objects 
     for (int i = 0; i < y.length; i++) { 
      if (!paused) { 
       y[i] += (int) dY; 
      } 
      // if falling object hits bottom of screen 
      if (y[i] > (screenH - ballH) && !gameOver) { 
       dY = 0; 
       gameOver = true; 
       paused = true; 
       int duration = Toast.LENGTH_SHORT; 

       final Toast toast = Toast.makeText(context, "GAME OVER!\nScore: " + score, duration); 
       toast.show(); 
       Handler handler = new Handler(); 
       handler.postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         toast.cancel(); 
         toastDisplayed = true; 
        } 
       }, 3000); 
       //Vibrator v = (Vibrator) context.getSystemService(context.VIBRATOR_SERVICE); 
       // Vibrate for 3000 milliseconds 
       //v.vibrate(3000); 

      } 
      // if the hero catches a falling object 
      if (x[i] < heroCentre && x[i] + ballW > heroCentre && 
        y[i] > screenH - ballH - heroHeight) { 

       y[i] = -random.nextInt(1000); // reset to new vertical position 
       score += 1; 
       onScoreListener.onScore(score); 
      } 


     } 

     canvas.save(); //Save the position of the canvas. 

     for (int i = 0; i < y.length; i++) { 
      canvas.drawBitmap(ball, x[i], y[i], null); //Draw the ball on the canvas. 
     } 
     canvas.drawBitmap(hero, heroXCoord, heroYCoord, null); //Draw the hero on the canvas. 

     canvas.restore(); 
     //Call the next frame. 
     invalidate(); 
    } 

    // event listener for when the user touches the screen 
    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if (paused) { 
      paused = false; 
     } 
     int action = MotionEventCompat.getActionMasked(event); 
     if (action != MotionEvent.ACTION_DOWN || gameOver) { // non-touchdown event or gameover 
      return true; // do nothing 
     } 
     int coordX = (int) event.getX(); 
     int xCentre = (screenW/2) - (hero.getWidth()/2); 
     int maxOffset = hero_positions.length - 1; // can't move outside right edge of screen 
     int minOffset = 0; // ditto left edge of screen 
     if (coordX < xCentre && offset > minOffset) { // touch event left of the centre of screen 
      offset--; // move hero to the left 
     } 
     if (coordX > xCentre && offset < maxOffset) { // touch event right of the centre of screen 
      offset++; // move hero to the right 
     } 
     heroXCoord = hero_positions[offset]; 

     return true; 
    } 
} 
+0

精彩!有用! –