package com.nomnom.nomnomsnake;
import static com.nomnom.nomnomsnake.Globals.BAD_FRUITS;
import static com.nomnom.nomnomsnake.Globals.GOOD_FRUITS;
import static com.nomnom.nomnomsnake.Globals.NEUTRAL_FRUITS;
import static com.nomnom.nomnomsnake.Globals.RANDOM;
import static com.nomnom.nomnomsnake.Globals.REQUIRED_FRUIT_COUNTS;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import android.graphics.Canvas;
import android.graphics.PointF;
import com.nomnom.collision.CollisionChecker;
import com.nomnom.entities.fruit.Fruit;
import com.nomnom.entities.fruit.Fruit.FRUITSTATE;
public class Level
{
private static Level INSTANCE = null;
private Snake snake;
private PointF snakeDestination;
private int time;
/**
* Current level - 1
*/
private int currentLevel = 0;
private int remainingFruits;
private Set<Fruit> fruits = new HashSet<Fruit>();
public static Level instance() {
if (INSTANCE == null) {
INSTANCE = new Level();
}
return INSTANCE;
}
private Level() { }
public void initialize(int levelNum)
{
snake = new Snake(new PointF(Globals.LEVEL_WIDTH/2, Globals.LEVEL_HEIGHT/2));
currentLevel = levelNum;
remainingFruits = REQUIRED_FRUIT_COUNTS.get(levelNum);
spawnFruit();
// CollisionChecker.instance().registerSnakeHead(snake.getSnakeHead());
}
public void update(PointF touch, boolean isFingerDown)
{
if (isFingerDown)
{
this.snakeDestination = touch;
snake.update(snakeDestination);
CollisionChecker.instance().checkCollisions();
time++;
}
else
{
// TODO: pause screen
}
// animation updates regardless of finger touch
for (Fruit fruit : fruits) {
fruit.updateAnimation();
if (fruit.getState() == FRUITSTATE.removed)
fruits.remove(fruit);
}
if (fruits.size() <= 0)
spawnFruit();
}
public void draw(Canvas canvas)
{
snake.draw(canvas);
for (Fruit fruit : fruits) {
fruit.draw(canvas);
}
/*
//debugging text -------------------------------------------------------------
int posiy = 50;
PointF loc = snake.getSnakeHead().getCollisionBody().getCenter();
canvas.drawText("snake : " + loc.x + ", " + loc.y, 50, posiy, ImageHandler.normalPaint);
for (Fruit fruit : fruits) {
posiy += 30;
loc = fruit.getLocation();
canvas.drawText("fruit : " + loc.x + ", " + loc.y, 50, posiy, ImageHandler.normalPaint);
}
//----------------------------------------------------------------------------
*/
}
// TODO: test this
public void spawnFruit() {
// Clear all the fruits
for (Fruit fruit : fruits) {
fruit.delete();
}
fruits.clear();
SpawnPlaceCandidate[] candidates = new SpawnPlaceCandidate[3];
for (int i = 0; i < 3; i++) {
candidates[i] = new SpawnPlaceCandidate();
}
Arrays.sort(candidates);
int bestIndex = 0;
bestIndex = trySpawnFruit(bestIndex, GOOD_FRUITS.get(currentLevel), candidates);
bestIndex = trySpawnFruit(bestIndex, NEUTRAL_FRUITS.get(currentLevel), candidates);
bestIndex = trySpawnFruit(bestIndex, BAD_FRUITS.get(currentLevel), candidates);
}
public void fruitEaten() {
remainingFruits = remainingFruits - 1;
if (remainingFruits <= 0) {
// TODO(2011/02/13) next level
} else {
spawnFruit();
}
}
private int trySpawnFruit(int bestIndex, List<Class<? extends Fruit>> fruits,
SpawnPlaceCandidate[] candidates) {
if (!fruits.isEmpty()) {
Fruit newFruit = Fruit.createFruit(
fruits.get(RANDOM.nextInt(fruits.size())),
candidates[bestIndex].getSpawnPosition(),
snake);
bestIndex++;
this.fruits.add(newFruit);
}
return bestIndex;
}
private class SpawnPlaceCandidate implements Comparable<SpawnPlaceCandidate> {
private final Integer collidableCount;
private final PointF spawnPosition;
public SpawnPlaceCandidate() {
// don't want to spawn fruits right at the border of the screen
spawnPosition = new PointF(RANDOM.nextInt(Globals.LEVEL_WIDTH - 2*Globals.BORDER) + Globals.BORDER, RANDOM.nextInt(Globals.LEVEL_HEIGHT - 2*Globals.BORDER) + Globals.BORDER);
collidableCount = CollisionChecker.instance().countNearbyShapes(spawnPosition);
}
public PointF getSpawnPosition() {
return spawnPosition;
}
@Override
public int compareTo(SpawnPlaceCandidate other) {
return collidableCount.compareTo(other.collidableCount);
}
}
}
|