GameModel.java :  » Game » androiddefense » com » androiddefense » engine » Android Open Source

Android Open Source » Game » androiddefense 
androiddefense » com » androiddefense » engine » GameModel.java
/**
 * 
 */
package com.androiddefense.engine;

import java.util.ArrayList;
import java.util.List;

import com.androiddefense.engine.coordinate.Coord;
import com.androiddefense.engine.enemy.Enemy_I;
import com.androiddefense.engine.enemy.PlainEnemy;
import com.androiddefense.engine.tile.PlainTile;
import com.androiddefense.engine.tile.Tile_I;
import com.androiddefense.engine.tower.PlainTower;
import com.androiddefense.engine.tower.Projectile_I;
import com.androiddefense.engine.tower.Tower_I;
import com.androiddefense.main.R;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;

/**
 * GameModel class
 * 
 * @author Steven Christou
 *
 */
public class GameModel implements GameModel_I {
  
  Tile_I[][] myGrid;
  ArrayList<Enemy_I> queuedEnemies = new ArrayList<Enemy_I> ();
  ArrayList<Enemy_I> myEnemies = new ArrayList<Enemy_I> ();
  ArrayList<Tower_I> myTowers = new ArrayList<Tower_I> ();
  Paint myBorderPaint;
  Rect myBorderRect;
  
  final Coord startSpot = new Coord(0, 1);
  private ArrayList<Projectile_I> myProjectiles = new ArrayList<Projectile_I>();
  
  public Bitmap scaledImage(Resources res, float px, int image) {
        Bitmap img = BitmapFactory.decodeResource(res, image);
        int w = img.getWidth();
        int h = img.getHeight();
        
        Matrix m = new Matrix();
        m.setScale(px / w, px / h);
        
        return Bitmap.createBitmap(img, 0, 0, w, h, m, true);
  }
  
  public GameModel(int width, int height, Resources res) {
    if (width < 2 || height < 2) {
      throw new IllegalArgumentException("You should make a larger Tower grid: " + width + ", " + height);
    }

    Bitmap projectileImg = scaledImage(res, 5.0f, R.drawable.bullet);

    myGrid = new Tile_I[width][height];
    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
          myGrid[x][y] = new PlainTile(x, y, res);
          if (x % 3 == 0 && y % 3 == 0) {
            try {
            addTower(
              new PlainTower(
                new Coord(x * GameModel_I.TILE_SIZE, y * GameModel_I.TILE_SIZE), projectileImg), 
                new Coord(x, y));
          } catch (Exception e) {
            Log.i("GameModel", "adding bad tower type at: " + x + ", " + y);
          }
          }
        }
    }
    
    Bitmap enemyImg = scaledImage(res, (float)GameModel_I.TILE_SIZE, R.drawable.enemy);
        for (int e = 0; e < 10; e++) {
          queuedEnemies.add(new PlainEnemy(enemyImg, startSpot, startSpot));
    }
        
    myBorderPaint = new Paint();
    myBorderPaint.setARGB(255, 155, 155, 155);
    myBorderPaint.setStyle(Paint.Style.STROKE);
    
    myBorderRect = new Rect(0, 0, width * GameModel_I.TILE_SIZE, height * GameModel_I.TILE_SIZE);
    
    myGrid[width - 1][height - 1].setEnemyDest();
    calculateDistances();
  }
  
  private void calculateDistances() {
    for (int x = 0; x < myGrid[0].length; x++) {
        for (int y = 0; y < myGrid.length; y++) {
          if (myGrid[x][y].getDist() == 0) {
            setNeighborsDist(x, y, 0);
          }
        }
    }
  }
  
  private boolean inBounds(int x, int y) {
    return  x < myGrid[0].length && x >= 0 &&
        y < myGrid.length && y >= 0;
  }
  
  private void setNeighborsDist(int x, int y, int iters) {
    if (iters > 20) {
      return; 
    }
    int[][] myCoords = new int[][]{ 
        {x - 1, y - 1},  
        {x - 1, y },  
        {x - 1, y + 1},  
        {x, y - 1},  
        {x, y + 1},  
        {x + 1, y - 1},  
        {x + 1, y},  
        {x + 1, y + 1},  
    };
    
    int curDist = myGrid[x][y].getDist();

    for (int[] c : myCoords) {
      int myX = c[0];
      int myY = c[1];
      
      if (inBounds(myX, myY) && 
        myGrid[myX][myY].getTower() == null &&
          (myGrid[myX][myY].getDist() == -1 || 
           curDist + 1 < myGrid[myX][myY].getDist())) 
      {
        myGrid[myX][myY].setDist(curDist + 1);
        // Log.i("GameModel","setNeighborsDist " + x + ", " + y + ", " + (curDist + 1));
        setNeighborsDist(myX, myY, iters + 1);
      }
    }
  }
  
  public Coord getNextSmallestDist(Coord origCoord) {
    final int x = origCoord.x;
    final int y = origCoord.y;
    final Coord[] myCoords = new Coord[] {
        // new Coord(x - 1, y - 1),
        new Coord(x - 1, y),
        // new Coord(x - 1, y + 1),
        new Coord(x, y - 1),
        new Coord(x, y + 1),
        // new Coord(x + 1, y - 1),
        new Coord(x + 1, y),
        // new Coord(x + 1, y + 1),
    };
    
    int currentDist = myGrid[x][y].getDist();
    Coord minCoord = null;

    for (Coord c : myCoords) {
      if (inBounds(c.x, c.y) && 
        myGrid[c.x][c.y].getDist() != -1 &&
        myGrid[c.x][c.y].getDist() <= currentDist)
      {
        currentDist = myGrid[c.x][c.y].getDist();
        minCoord = new Coord(c.x, c.y);
      }
    }
    Log.i("GameModel","next smallest from " + origCoord + " is " + minCoord);
    return minCoord;
  }

  public void addTower(Tower_I t, final Coord coord) throws Exception {
    if (myGrid[coord.x][coord.y].accepts(t))
    {
      myGrid[coord.x][coord.y].setTower(t);
      myTowers.add(t);
    }
    else {
      throw new Exception("tile doesn't accept that kind of tower: " + coord + ", " + t);
    }
  }
  
  private boolean enemyInStartSpot() {
    for (Enemy_I e : myEnemies) {
      if (e.currentlyAt(startSpot)) {
        Log.i("GameModel","startSpot: " + startSpot + ", enemy at startSpot: " + e);
        return true;
      }
    }
    return false;
  }
  
  public List<Enemy_I> getWithinRange(List<Enemy_I> myEnemies, int dist, Coord loc) {
    ArrayList<Enemy_I> ret = new ArrayList<Enemy_I>();
    for (Enemy_I e : myEnemies) {
      if (e.getScreenLoc().isWithin(dist, loc)) {
        ret.add(e);
      }
    }
    return ret;
  }
  
  public void stepForward() {
    Log.i("GameModel", "stepForward starting, queuedEnemies: " + queuedEnemies.size() +
        ", myEnemies: " + myEnemies.size());
    if (!enemyInStartSpot() && queuedEnemies.size() > 0) {
      Log.i("GameModel", "adding enemy to grid: " + queuedEnemies.get(0));
      myEnemies.add(queuedEnemies.remove(0));
    }

    for (Tower_I t : myTowers) {
      Projectile_I p = t.fireAt(getWithinRange(myEnemies, GameModel_I.TILE_SIZE, t.getScreenLoc()));
      if (p != null) {
        myProjectiles.add(p);
      }
    }

    ArrayList<Projectile_I> newPs = new ArrayList<Projectile_I>();
    for (Projectile_I p : myProjectiles) {
      p.moveForward();
      if (!p.atTarget()) {
        newPs.add(p);
      }
    }
    myProjectiles = newPs;

    for (Enemy_I e : myEnemies) {
      e.moveForward(this);
    }
  }
  
  public void draw(Canvas canvas) {
    Log.i("GameModel", "draw starting");
    for (int x = 0; x < myGrid[0].length; x++) {
        for (int y = 0; y < myGrid.length; y++) {
          if (myGrid[x][y] != null) {
            myGrid[x][y].draw(canvas);
          }
        }
    }
    for (Enemy_I e : myEnemies) {
      e.draw(canvas);
    }
    for (Projectile_I p : myProjectiles) {
      p.draw(canvas);
    }
    canvas.drawRect(myBorderRect, myBorderPaint);
  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.