Android Open Source - CoreGame World






From Project

Back to project page CoreGame.

License

The source code is released under:

Copyright (c) 2011 Andrey Moiseev, http://o2genum.ru Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),...

If you think the Android project CoreGame 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

package ru.o2genum.coregame.game;
//from w ww  .  ja  v a  2s  . co m
import java.util.*;

import ru.o2genum.coregame.framework.*;
import ru.o2genum.coregame.framework.impl.*;
import ru.o2genum.coregame.framework.Pool.PoolObjectFactory;
import ru.o2genum.coregame.framework.Input.KeyEvent;
import ru.o2genum.coregame.framework.Input.TouchEvent;

import android.util.*;

/* I should have used pools for my objects not to make garbage
 * collector angry. As it freezes the game sometimes, 
 * I avoided some object creations. However, it doesn't help.
 */

public class World
{
  Random random = new Random();
  Game game;
  private final int DOTS_COUNT = 10;
  // In this case ArrayList is better than LinkedList:
  // list will never be resized.
  public List<Dot> dots = new ArrayList<Dot>(DOTS_COUNT);
  public Core core = new Core();
  public float offScreenRadius;
  private final float SHIELD_FACTOR = 20.0F;
  private final float ENERGY_FACTOR = 6.0F;

  private float time = 0.0F; // in seconds

  public enum GameState {Ready, Running, Paused, GameOver}

  public GameState state = GameState.Ready;

  private float difficulty = 0.04F; // Max 0.1F

  // Sounds
  // Dot collides with core
  Sound coreHurt;
  Sound coreHealth;
  Sound coreShield;
  // Dot collides with shield
  Sound shieldCollision;

  Sound gameOver;

  public World(Game game)
  {
    this.game = game;
    Graphics g = game.getGraphics();
    // Construct core
    core.coords = new VectorF((float) g.getWidth() / 2,
           (float) g.getHeight() / 2);
    core.shieldRadius = (float) g.getWidth() / 4;
    core.maxRadius = core.shieldRadius * 0.7F;
    core.angle = 0.0F;
    core.health = 1.0F;
    core.shieldEnergy = 0.0F;
    // Set offScreenRadius
    offScreenRadius = (float) Math.hypot((double) g.getWidth() / 2,
        (double) g.getHeight() / 2);
    // Max dot radius (when it's energy is 1.0F)
    Dot.maxRadius = core.maxRadius / 8.0F;
    loadSounds();
  }

  private void loadSounds()
  {
    Audio a = game.getAudio();
    coreHurt = a.newSound("core_hurt.wav");
    coreHealth = a.newSound("core_health.wav");
    coreShield = a.newSound("core_shield.wav");
    shieldCollision = a.newSound("shield_collision.wav");
    gameOver = a.newSound("game_over.wav");
  }

  // Restart the game  
  public void renew()
  {
    dots.clear();
    core.health = 1.0F;
    core.shieldEnergy = 0.0F;
    time = 0.0F;
    state = GameState.Ready;
    difficulty = 0.04F;
    generateStartDots(DOTS_COUNT);
  }
  // Add randomness
  private void generateStartDots(int count)
  {
    for(int i = 0; i < count; i++)
    {
      generateNewDot(true);
    }
  }

  private VectorF generateNewDotCoordsInRandomPlace()
  {
    double angle = random.nextDouble() * 2 * Math.PI;
    VectorF coords = new VectorF((float) Math.cos(angle), 
        (float) Math.sin(angle));
    coords = coords.multiply(core.shieldRadius + (offScreenRadius -
          core.shieldRadius) * random.nextFloat());
    return coords;
  }

  public void update(float deltaTime)
  {
    if(state == GameState.Ready)
      updateReady(deltaTime);
    if(state == GameState.Running)
      updateRunning(deltaTime);
    if(state == GameState.Paused)
      updatePaused(deltaTime);
    if(state == GameState.GameOver)
      updateGameOver(deltaTime);
  }

  private void doInput()
  {
      float orientAngle = game.getInput().getAzimuth();
    if(game.getInput().isTouchDown())
    {
      double touchX = (double) game.getInput().getTouchX();
      double touchY = (double) game.getInput().getTouchY();
      core.angle = 
        // Y-axis is inverted. See checkCollisionWithShield(...)
        // method
        normAngle(((float) (Math.atan2(-(touchY - core.coords.y), 
            touchX - core.coords.x) / (Math.PI * 2) *
        360.0)) - Core.GAP_ANGLE/2F);
    }
    else
    {
      core.angle = stabilizeAngle(orientAngle - Core.GAP_ANGLE/2F,
          core.angle, 8F);
    }
  }

  // Removes accelerometer noise and makes
  // core shield rotate smooth when user touches / untouches
  // the screen (and game switch accelerometer / touchscreen control).
  // Stabilisation increases, as factor value becomes larger.
  private float stabilizeAngle(float real, float current, float factor)
  {
    real = normAngle(real);
    current = normAngle(current);
    // Stabilisation should choose shortest way
    // (is it better to rotate clockwise or counterclockwise?)
    if(current - real > 180F)
      real += 360;
    if(real - current > 180F)
      real -= 360;
    // (current + current + current ... + real) / numberOfElements
    return normAngle((current * factor + real) / (factor + 1F));
  }

  private void updateReady(float deltaTime)
  {
    if(checkTouchUp() || checkMenuUp())
      state = GameState.Running;
  }
  
  private boolean checkTouchUp()
  {
    for(TouchEvent event : game.getInput().getTouchEvents())
    {
      if(event.type == TouchEvent.TOUCH_UP)
        return true;
    }
    return false;
  }

  private boolean checkMenuUp()
  {
    for(KeyEvent event : game.getInput().getKeyEvents())
    {
      if(event.keyCode == android.view.KeyEvent.KEYCODE_MENU)
      {
        if(event.type == KeyEvent.KEY_UP)
          return true;
      }

    }
    return false;
  }

  private void updatePaused(float deltaTime)
  {
    if(checkTouchUp() || checkMenuUp())
      state = GameState.Running;
  }

  private void updateGameOver(float deltaTime)
  {
    if(checkTouchUp() || checkMenuUp())
      renew();
  }

  private void updateRunning(float deltaTime)
  {
    checkTouchUp(); // Just to clear touch event buffer

    if(checkMenuUp())
      state = GameState.Paused;

    countTime(deltaTime);

    doInput();

    generateNewDots(DOTS_COUNT);

    handleCollisions();
    moveDots(deltaTime);
    decreaseShieldEnergy(deltaTime);
  }

  private void decreaseShieldEnergy(float deltaTime)
  {
    if(core.shieldEnergy > 0.0F)
    {
      core.shieldEnergy -= deltaTime / SHIELD_FACTOR;
      if(core.shieldEnergy < 0.0F)
      core.shieldEnergy = 0.0F;
    }
  }

  private void generateNewDots(int neededCount)
  {
    float rand = random.nextFloat();
    if(neededCount > dots.size())
      generateNewDot(false);
  }

  private void increaseDifficulty()
  {
    difficulty += 0.00005F;
  }

  private void generateNewDot(boolean atStart)
  {
    float linearSpeed = 10.0F * difficulty;
    Dot dot = new Dot();
    if(atStart)
    {
      dot.coords = generateNewDotCoordsInRandomPlace();
    }
    else
    {
      dot.coords = generateNewDotAtOffScreenRadius();
      increaseDifficulty();
    }
    VectorF speed = new VectorF(
        linearSpeed * (-dot.coords.x / dot.coords.length()),
         linearSpeed * (-dot.coords.y / dot.coords.length()));
    dot.speed = speed;
    dot.coords.addToThis(core.coords);
    dot.energy = random.nextFloat();
    if(dot.energy <= 0.3F)
      dot.energy = 0.3F;
    float typeRand = random.nextFloat();
    Dot.Type type;
    if (typeRand >= 0.9)
      type = Dot.Type.Shield;
    else if (typeRand >= 0.8)
      type = Dot.Type.Health;
    else
      type = Dot.Type.Enemy;
    dot.type = type;
    dots.add(dot);
  }

  private void countTime(float deltaTime)
  {
    time += deltaTime;
  }

  public String getTime()
  {
    int seconds = (int) time;
    int minutes = seconds / 60;
    seconds %= 60;
    String result = "";
    if(minutes > 0)
      result += minutes + ":";
    result += String.format("%02d", seconds);
    return result;
  }

  private VectorF generateNewDotAtOffScreenRadius()
  {
    float angle = random.nextFloat() * ((float)(2 * Math.PI));
    VectorF coords =
         new VectorF(offScreenRadius * ((float) Math.cos(angle)),
          offScreenRadius * ((float) Math.sin(angle)));
    return coords;
  }
  private void moveDots(float deltaTime)
  {
    for(Dot dot : dots)
    {
      dot.coords.addToThis(dot.speed.x * deltaTime * 100.0F,
          dot.speed.y * deltaTime * 100.0F);
    }
  }

  private void handleCollisions()
  {
    Iterator<Dot> iterator = dots.iterator();
    while(iterator.hasNext())
    {
      handleCollision(iterator.next(), iterator);
    }
  }

  private void handleCollision(Dot dot, Iterator<Dot> iterator)
  {
    float lengthToCoreCenter = (float)
      Math.hypot((double)(dot.coords.x - core.coords.x),
          (double)(dot.coords.y - core.coords.y)); 
    if(Math.abs(lengthToCoreCenter - 
          core.shieldRadius) <= dot.maxRadius * dot.energy +
        Core.SHIELD_WIDTH)
      checkCollisionWithShield(dot, iterator);
    else if (lengthToCoreCenter - core.maxRadius * core.health <=
           dot.maxRadius * dot.energy)
      handleCollisionWithCore(dot, iterator);
  }

  private void checkCollisionWithShield(Dot dot, Iterator<Dot> iterator)
  {
    // I normalize (move into (0; 360) interval) angles
    // in some places. Don't know if it's needed.
    if(core.shieldEnergy > 0.0F)
    {
      iterator.remove();
      shieldCollision.play(dot.energy);
      game.getVibration().vibrate(30);
    }
    else
    {
    // Pay attention at -v.y! Y-axis is inverted, 
    // because it points downwards.
    float dotAngle = (float) Math.atan2((double) - 
        (dot.coords.y - core.coords.y),
           (double) (dot.coords.x - core.coords.x));
    dotAngle = dotAngle / (((float) Math.PI) * 2.0F) * 360.0F;
    dotAngle = normAngle(dotAngle);
    // For example, dotAngle = 3, and core.angle = 365
    // We need to solve this somehow:
    core.angle = normAngle(core.angle);
    while(dotAngle < core.angle)
    {
      dotAngle += 360.0F;
    }
    // OK, and check if dotAngle is within the gap
    if(!((dotAngle > core.angle) &&
             (dotAngle < core.angle + core.GAP_ANGLE)))
    {
      iterator.remove();
      shieldCollision.play(dot.energy);
      game.getVibration().vibrate(30);
    }
    }
  }

  private float normAngle(float angle)
  {
    float angle2 = angle;
    while(angle2 < 0.0F)
      angle2 += 360.0F;

    while(angle2 > 360.0F)
      angle2 -= 360.0F;

    return angle2;
  }

  private void handleCollisionWithCore(Dot dot, Iterator<Dot> iterator)
  {
    if(dot.type == Dot.Type.Enemy)
    {
    core.health -= dot.energy / ENERGY_FACTOR;
    if(core.health < 0.0F)
    {
      state = GameState.GameOver;
      gameOver.play(1F);
      game.getVibration().vibrate(10);
      game.getVibration().vibrate(40);
      game.getVibration().vibrate(100);
      core.health = 0.0F;
    }
    coreHurt.play(dot.energy);
    }
    else if (dot.type == Dot.Type.Health)
    {
    core.health += dot.energy / ENERGY_FACTOR;
    if(core.health > 1.0F)  
    {
      core.health = 1.0F;
    }
    coreHealth.play(dot.energy);
    }
    else if(dot.type == Dot.Type.Shield)
    {
      core.shieldEnergy += dot.energy;
      if(core.shieldEnergy > 1.0F)
        core.shieldEnergy = 1.0F;
      coreShield.play(dot.energy);
    }
    iterator.remove();
    game.getVibration().vibrate(30);
  }

}




Java Source Code List

ru.o2genum.coregame.framework.Audio.java
ru.o2genum.coregame.framework.FileIO.java
ru.o2genum.coregame.framework.Game.java
ru.o2genum.coregame.framework.Graphics.java
ru.o2genum.coregame.framework.Input.java
ru.o2genum.coregame.framework.Pool.java
ru.o2genum.coregame.framework.Screen.java
ru.o2genum.coregame.framework.Sound.java
ru.o2genum.coregame.framework.Vibration.java
ru.o2genum.coregame.framework.impl.AndroidAudio.java
ru.o2genum.coregame.framework.impl.AndroidFastRenderView.java
ru.o2genum.coregame.framework.impl.AndroidFileIO.java
ru.o2genum.coregame.framework.impl.AndroidGame.java
ru.o2genum.coregame.framework.impl.AndroidGraphics.java
ru.o2genum.coregame.framework.impl.AndroidInput.java
ru.o2genum.coregame.framework.impl.AndroidOrientationHandler.java
ru.o2genum.coregame.framework.impl.AndroidSound.java
ru.o2genum.coregame.framework.impl.AndroidVibration.java
ru.o2genum.coregame.framework.impl.KeyboardHandler.java
ru.o2genum.coregame.framework.impl.MultiTouchHandler.java
ru.o2genum.coregame.framework.impl.OrientationHandler.java
ru.o2genum.coregame.framework.impl.SingleTouchHandler.java
ru.o2genum.coregame.framework.impl.TouchHandler.java
ru.o2genum.coregame.game.Core.java
ru.o2genum.coregame.game.Dot.java
ru.o2genum.coregame.game.GameActivity.java
ru.o2genum.coregame.game.GameScreen.java
ru.o2genum.coregame.game.VectorF.java
ru.o2genum.coregame.game.World.java