Android Open Source - FlappyCow Game View






From Project

Back to project page FlappyCow.

License

The source code is released under:

MIT License

If you think the Android project FlappyCow listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * GameView//from   ww  w  .j a va2 s  .  com
 * Probably the most important class for the game
 * 
 * @author Lars Harmsen
 * Copyright (c) <2014> <Lars Harmsen - Quchen>
 */

package com.quchen.flappycow;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import com.quchen.flappycow.Game.MyHandler;
import com.quchen.flappycow.sprites.Background;
import com.quchen.flappycow.sprites.Coin;
import com.quchen.flappycow.sprites.Cow;
import com.quchen.flappycow.sprites.Frontground;
import com.quchen.flappycow.sprites.NyanCat;
import com.quchen.flappycow.sprites.Obstacle;
import com.quchen.flappycow.sprites.PauseButton;
import com.quchen.flappycow.sprites.PlayableCharacter;
import com.quchen.flappycow.sprites.PowerUp;
import com.quchen.flappycow.sprites.Toast;
import com.quchen.flappycow.sprites.Tutorial;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Message;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class GameView extends SurfaceView{
  
  /** Milliseconds for game timer tick */
  public static final long UPDATE_INTERVAL = 50;
  
  private Timer timer = new Timer();
  private TimerTask timerTask;
  
  /** The surfaceholder needed for the canvas drawing */
  private SurfaceHolder holder;
  
  private Game game;
  private PlayableCharacter player;
  private Background bg;
  private Frontground fg;
  private List<Obstacle> obstacles = new ArrayList<Obstacle>();
  private List<PowerUp> powerUps = new ArrayList<PowerUp>();
  
  private PauseButton pauseButton;
  volatile private boolean paused = true;
  
  private Tutorial tutorial;
  private boolean tutorialIsShown = true;

  public GameView(Context context) {
    super(context);
    this.game = (Game) context;
    setFocusable(true);

    holder = getHolder();
    player = new Cow(this, game);
    bg = new Background(this, game);
    fg = new Frontground(this, game);
    pauseButton = new PauseButton(this, game);
    tutorial = new Tutorial(this, game);
  }
  
  private void startTimer() {
    setUpTimerTask();
    timer = new Timer();
    timer.schedule(timerTask, UPDATE_INTERVAL, UPDATE_INTERVAL);
  }
  
  private void stopTimer() {
    if (timer != null) {
      timer.cancel();
      timer.purge();
    }
    if (timerTask != null) {
      timerTask.cancel();
    }
  }
  
  private void setUpTimerTask() {
    stopTimer();
    timerTask = new TimerTask() {
      @Override
      public void run() {
        GameView.this.run();
      }
    };
  }
  
  @Override
  public boolean performClick() {
    return super.performClick();
    // Just to remove the stupid warning
  }
  
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    performClick();
    if(event.getAction() == MotionEvent.ACTION_DOWN){
      if(tutorialIsShown){
        // dismiss tutorial
        tutorialIsShown = false;
        resume();
        this.player.onTap();
      }else if(paused){
        resume();
      }else{
        if(pauseButton.isTouching((int) event.getX(), (int) event.getY()) && !this.paused){
          pause();
        }else{
          this.player.onTap();
        }
      }
    }
    return true;
  }
  
  /**
   * content of the timertask
   */
  public void run() {
    checkPasses();
    checkOutOfRange();
    checkCollision();
    createObstacle();
    move();

    draw();
  }
  
  /**
   * Draw Tutorial
   */
  public void showTutorial(){
    player.move();
    pauseButton.move();
    
    while(!holder.getSurface().isValid()){
      /*wait*/
      try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); }
    }
    
    Canvas canvas = holder.lockCanvas();
    drawCanvas(canvas, true);
    tutorial.move();
    tutorial.draw(canvas);
    holder.unlockCanvasAndPost(canvas);
  }
  
  public void pause(){
    stopTimer();
    paused = true;
  }
  
  public void drawOnce(){
    (new Thread(new Runnable() {
      @Override
      public void run() {
        if(tutorialIsShown){
          showTutorial();
        } else {
          draw();
        }
      }
    })).start();
  }
  
  public void resume(){
    paused = false;
    startTimer();
  }
  
  /**
   * Draws all gameobjects on the surface
   */
  private void draw() {
    while(!holder.getSurface().isValid()){
      /*wait*/
      try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); }
    }
    Canvas canvas = holder.lockCanvas();
    drawCanvas(canvas, true);
    holder.unlockCanvasAndPost(canvas);
  }

  /**
   * Draws everything normal,
   * except the player will only be drawn, when the parameter is true
   * @param drawPlayer
   */
  private void drawCanvas(Canvas canvas, boolean drawPlayer){
    bg.draw(canvas);
    for(Obstacle r : obstacles){
      r.draw(canvas);
    }
    for(PowerUp p : powerUps){
      p.draw(canvas);
    }
    if(drawPlayer){
      player.draw(canvas);
    }
    fg.draw(canvas);
    pauseButton.draw(canvas);
    
    // Score Text
    Paint paint = new Paint();
    paint.setColor(Color.BLACK);
    paint.setTextSize(getScoreTextMetrics());
    canvas.drawText(game.getResources().getString(R.string.onscreen_score_text) + " " + game.accomplishmentBox.points
            + " / " + game.getResources().getString(R.string.onscreen_coin_text) + " " + game.coins,
            0, getScoreTextMetrics(), paint);
  }
  
  /**
   * Let the player fall to the ground
   */
  private void playerDeadFall(){
    player.dead();
    do{
      player.move();
      draw();
      // sleep
      try { Thread.sleep(UPDATE_INTERVAL/4); } catch (InterruptedException e) { e.printStackTrace(); }
    }while(!player.isTouchingGround());
  }
  
  /**
   * Checks whether an obstacle is passed.
   */
  private void checkPasses(){
    for(Obstacle o : obstacles){
      if(o.isPassed()){
        if(!o.isAlreadyPassed){
          o.onPass();
          createPowerUp();
        }
      }
    }
  }
  
  /**
   * Creates a toast with a certain chance
   */
  private void createPowerUp(){
    if((powerUps.size() < 1) && (Math.random()*100 < 20)){
      // If no powerUp is present and 20% chance
      powerUps.add(new Coin(this, game));
    }
    // Toast
    if(game.accomplishmentBox.points >= 40 && powerUps.size() < 1 && !(player instanceof NyanCat)){
      // If no powerUp is present and you have more than / equal 40 points
      if(Math.random()*100 < 33){  // 33% chance
        powerUps.add(new Toast(this, game));
      }
    }
  }
  
  /**
   * Checks whether the obstacles or powerUps are out of range and deletes them
   */
  private void checkOutOfRange(){
    for(int i=0; i<obstacles.size(); i++){
      if(this.obstacles.get(i).isOutOfRange()){
        this.obstacles.remove(i);
        i--;
      }
    }
    for(int i=0; i<powerUps.size(); i++){
      if(this.powerUps.get(i).isOutOfRange()){
        this.powerUps.remove(i);
        i--;
      }
    }
  }
  
  /**
   * Checks collisions and performs the action
   */
  private void checkCollision(){
    for(Obstacle o : obstacles){
      if(o.isColliding(player)){
        o.onCollision();
        gameOver();
      }
    }
    for(int i=0; i<powerUps.size(); i++){
      if(this.powerUps.get(i).isColliding(player)){
        this.powerUps.get(i).onCollision();
        this.powerUps.remove(i);
        i--;
      }
    }
    if(player.isTouchingEdge()){
      gameOver();
    }
  }
  
  /**
   * if no obstacle is present a new one is created
   */
  private void createObstacle(){
    if(obstacles.size() < 1){
      obstacles.add(new Obstacle(this, game));
    }
  }
  
  /**
   * Update sprite movements
   */
  private void move(){
    for(Obstacle o : obstacles){
      o.setSpeedX(-getSpeedX());
      o.move();
    }
    for(PowerUp p : powerUps){
      p.move();
    }
    
    bg.setSpeedX(-getSpeedX()/2);
    bg.move();
    
    fg.setSpeedX(-getSpeedX()*4/3);
    fg.move();
    
    pauseButton.move();
    
    player.move();
  }
  
  /**
   * Changes the player to Nyan Cat
   */
  public void changeToNyanCat(){
    game.accomplishmentBox.achievement_toastification = true;
    if(game.getGamesClient().isConnected()){
      game.getGamesClient().unlockAchievement(getResources().getString(R.string.achievement_toastification));
    }else{
      game.handler.sendMessage(Message.obtain(game.handler,1,R.string.toast_achievement_toastification, MyHandler.SHOW_TOAST));
    }
    
    PlayableCharacter tmp = this.player;
    this.player = new NyanCat(this, game);
    this.player.setX(tmp.getX());
    this.player.setY(tmp.getY());
    this.player.setSpeedX(tmp.getSpeedX());
    this.player.setSpeedY(tmp.getSpeedY());
    
    game.musicShouldPlay = true;
    Game.musicPlayer.start();
  }
  
  /**
   * return the speed of the obstacles/cow
   */
  public int getSpeedX(){
    // 16 @ 720x1280 px
    int speedDefault = this.getWidth() / 45;
    
    // 1,2 every 4 points @ 720x1280 px
    int speedIncrease = (int) (this.getWidth() / 600f * (game.accomplishmentBox.points / 4));
    
    int speed = speedDefault + speedIncrease;
    
    return Math.min(speed, 2*speedDefault);
  }
  
  /**
   * Let's the player fall down dead, makes sure the runcycle stops
   * and invokes the next method for the dialog and stuff.
   */
  public void gameOver(){
    pause();
    playerDeadFall();
    game.gameOver();
  }
  
  public void revive() {
    game.numberOfRevive++;
    
    // This needs to run another thread, so the dialog can close.
    new Thread(new Runnable() {
      @Override
      public void run() {
        setupRevive();
      }
    }).start();
  }
  
  /**
   * Sets the player into startposition
   * Removes obstacles.
   * Let's the character blink a few times.
   */
  private void setupRevive(){
    game.gameOverDialog.hide();
    player.setY(this.getHeight()/2 - player.getWidth()/2);
    player.setX(this.getWidth()/6);
    obstacles.clear();
    powerUps.clear();
    player.revive();
    for(int i = 0; i < 6; ++i){
      while(!holder.getSurface().isValid()){/*wait*/}
      Canvas canvas = holder.lockCanvas();
      drawCanvas(canvas, i%2 == 0);
      holder.unlockCanvasAndPost(canvas);
      // sleep
      try { Thread.sleep(UPDATE_INTERVAL*6); } catch (InterruptedException e) { e.printStackTrace(); }
    }
    resume();
  }
  
  /**
   * A value for the position and size of the onScreen score Text
   */
  public int getScoreTextMetrics(){
    return (int) (this.getHeight() / 21.0f);
    /*/ game.getResources().getDisplayMetrics().density)*/
  }
  
  public PlayableCharacter getPlayer(){
    return this.player;
  }
  
  public Game getGame(){
    return this.game;
  }

}




Java Source Code List

com.quchen.flappycow.About.java
com.quchen.flappycow.AccomplishmentBox.java
com.quchen.flappycow.GameOverDialog.java
com.quchen.flappycow.GameView.java
com.quchen.flappycow.Game.java
com.quchen.flappycow.MainActivity.java
com.quchen.flappycow.StartscreenView.java
com.quchen.flappycow.Util.java
com.quchen.flappycow.sprites.Background.java
com.quchen.flappycow.sprites.Coin.java
com.quchen.flappycow.sprites.Cow.java
com.quchen.flappycow.sprites.Frontground.java
com.quchen.flappycow.sprites.NyanCat.java
com.quchen.flappycow.sprites.Obstacle.java
com.quchen.flappycow.sprites.PauseButton.java
com.quchen.flappycow.sprites.PlayableCharacter.java
com.quchen.flappycow.sprites.PowerUp.java
com.quchen.flappycow.sprites.Rainbow.java
com.quchen.flappycow.sprites.Spider.java
com.quchen.flappycow.sprites.Sprite.java
com.quchen.flappycow.sprites.Toast.java
com.quchen.flappycow.sprites.Tutorial.java
com.quchen.flappycow.sprites.WoodLog.java