Search in sources :

Example 11 with AbstractObject

use of spacesettlers.objects.AbstractObject in project spacesettlers by amymcgovern.

the class Toroidal2DPhysics method isPathClearOfObstructions.

/**
 * Check to see if following a straight line path between two given locations would result in a collision with a provided set of obstructions
 *
 * @author Andrew and Thibault
 *
 * @param  startPosition the starting location of the straight line path
 * @param  goalPosition the ending location of the straight line path
 * @param  obstructions an Set of AbstractObject obstructions (i.e., if you don't wish to consider mineable asteroids or beacons obstructions)
 * @param  freeRadius used to determine free space buffer size
 * @return Whether or not a straight line path between two positions contains obstructions from a given set
 */
public boolean isPathClearOfObstructions(Position startPosition, Position goalPosition, Set<AbstractObject> obstructions, int freeRadius) {
    // Shortest straight line path from startPosition to goalPosition
    Vector2D pathToGoal = findShortestDistanceVector(startPosition, goalPosition);
    // Distance of straight line path
    double distanceToGoal = pathToGoal.getMagnitude();
    // Boolean showing whether or not the path is clear
    boolean pathIsClear = true;
    // Calculate distance between obstruction center and path (including buffer for ship movement)
    // Uses hypotenuse * sin(theta) = opposite (on a right hand triangle)
    // Vector from start position to obstruction
    Vector2D pathToObstruction;
    // Angle between vector from start position to obstruction
    double angleBetween;
    // Loop through obstructions
    for (AbstractObject obstruction : obstructions) {
        // If the distance to the obstruction is greater than the distance to the end goal, ignore the obstruction
        pathToObstruction = findShortestDistanceVector(startPosition, obstruction.getPosition());
        if (pathToObstruction.getMagnitude() > distanceToGoal) {
            continue;
        }
        // Ignore angles > 90 degrees
        angleBetween = Math.abs(pathToObstruction.angleBetween(pathToGoal));
        if (angleBetween > Math.PI / 2) {
            continue;
        }
        // Compare distance between obstruction and path with buffer distance
        if (pathToObstruction.getMagnitude() * Math.sin(angleBetween) < obstruction.getRadius() + freeRadius * 1.5) {
            pathIsClear = false;
            break;
        }
    }
    return pathIsClear;
}
Also used : Vector2D(spacesettlers.utilities.Vector2D) AbstractObject(spacesettlers.objects.AbstractObject)

Example 12 with AbstractObject

use of spacesettlers.objects.AbstractObject in project spacesettlers by amymcgovern.

the class Toroidal2DPhysics method advanceTime.

/**
 * Move all moveable objects and handle power ups.
 */
public void advanceTime(int currentTimeStep, Map<UUID, SpaceSettlersPowerupEnum> powerups) {
    this.currentTimeStep = currentTimeStep;
    // heal any base injuries
    for (Base base : bases) {
        base.updateEnergy(base.getHealingIncrement());
    }
    // detect collisions across all objects
    detectCollisions();
    // get the power ups and create any objects (weapons) as necessary
    for (UUID key : powerups.keySet()) {
        AbstractObject swobject = getObjectById(key);
        // if the object is not alive or it is not actionable, then ignore this
        if (!swobject.isAlive() || (!(swobject instanceof AbstractActionableObject))) {
            continue;
        }
        // otherwise, handle the power up
        handlePowerup((AbstractActionableObject) swobject, powerups.get(key));
    }
    // now move all objects that are moveable (which may include weapons)
    for (AbstractObject object : allObjects) {
        // skip non-moveable objects or dead object
        if (!object.isMoveable() || !object.isAlive()) {
            continue;
        }
        Position currentPosition = object.getPosition();
        // is it a ship that can be controlled?
        if (object.isControllable()) {
            Ship ship = (Ship) object;
            AbstractAction action = ship.getCurrentAction();
            // handle a null action
            if (action == null) {
                action = new DoNothingAction();
            }
            // need to clone the ship and space because otherwise the ship can affect
            // itself inside AbstractAction
            Movement actionMovement = action.getMovement(this.deepClone(), ship.deepClone());
            Position newPosition = applyMovement(currentPosition, actionMovement, timeStep);
            if (newPosition.isValid()) {
                ship.setPosition(newPosition);
            } else {
                ship.setPosition(currentPosition);
            }
            // spend ship energy proportional to its acceleration (old formula used velocity) and mass (new for space settlers
            // since resources cost mass)
            // double penalty = ENERGY_PENALTY * -Math.abs(ship.getPosition().getTotalTranslationalVelocity());
            double angularAccel = Math.abs(actionMovement.getAngularAccleration());
            double angularInertia = (3.0 * ship.getMass() * ship.getRadius() * angularAccel) / 2.0;
            double linearAccel = actionMovement.getTranslationalAcceleration().getMagnitude();
            double linearInertia = ship.getMass() * linearAccel;
            int penalty = (int) Math.floor(ENERGY_PENALTY * (angularInertia + linearInertia));
            ship.updateEnergy(-penalty);
            // this isn't the most general fix but it will work for now (also has to be done for bases)
            if (ship.isShielded()) {
                ship.updateEnergy(-PowerupToggleShield.SHIELD_STEP_COST);
            }
        // if (!ship.isAlive()) {
        // System.out.println("Ship " + ship.getTeamName() + ship.getId() + " is dead");
        // }
        } else {
            // move all other types of objects
            Position newPosition = moveOneTimestep(currentPosition);
            object.setPosition(newPosition);
        }
        // if any ships or bases are frozen, decrement their frozen count
        if (object instanceof AbstractActionableObject && !object.isControllable()) {
            AbstractActionableObject actionable = (AbstractActionableObject) object;
            actionable.decrementFreezeCount();
        }
    }
    // go through and see if any bases have died
    Set<Base> basesClone = new LinkedHashSet<Base>(bases);
    for (Base base : basesClone) {
        // this isn't the most general fix but it will work for now (also has to be done for bases)
        if (base.isShielded()) {
            base.updateEnergy(-PowerupToggleShield.SHIELD_STEP_COST);
        }
        if (!base.isAlive()) {
            base.setAlive(false);
            removeObject(base);
            base.getTeam().removeBase(base);
        }
    }
    // from when it was called inside updateEnergy
    for (Ship ship : ships) {
        if (ship.getEnergy() <= 0 && ship.isAlive() == true) {
            // drop any resources that the ship was carrying
            ResourcePile resources = ship.getResources();
            // Spawn a new AiCore with the same velocity magnitude and direction as its parent ship.
            // handle dropping the core if the ship died
            Position corePosition = ship.getPosition();
            corePosition.setTranslationalVelocity(ship.getPosition().getTranslationalVelocity());
            corePosition.setAngularVelocity(ship.getPosition().getAngularVelocity());
            AiCore shipCore = new AiCore(corePosition, ship.getTeamName(), ship.getTeamColor());
            this.addObject(shipCore);
            if (resources.getTotal() > 0) {
            // Position newPosition = ship.getPosition();
            // newPosition.setTranslationalVelocity(new Vector2D(0,0));
            // newPosition.setAngularVelocity(0.0);
            // Asteroid newAsteroid = new Asteroid(newPosition, true, ship.getRadius(), true, resources);
            // this.addObject(newAsteroid);
            // distributeResourcesToNearbyAsteroids(ship.getPosition(), resources);
            // System.out.println("Adding a new asteroid with resources " + newAsteroid.getResources().getTotal() +
            // " due to death, total is " + asteroids.size());
            // System.out.println("Ship died and " + resources.getTotal() + " has been added to an asteroid");
            }
            // set the ship to dead last (so we can grab its resources first)
            ship.setAlive(false);
        }
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ResourcePile(spacesettlers.objects.resources.ResourcePile) AbstractActionableObject(spacesettlers.objects.AbstractActionableObject) Movement(spacesettlers.utilities.Movement) Position(spacesettlers.utilities.Position) Base(spacesettlers.objects.Base) AiCore(spacesettlers.objects.AiCore) AbstractObject(spacesettlers.objects.AbstractObject) Ship(spacesettlers.objects.Ship) UUID(java.util.UUID) AbstractAction(spacesettlers.actions.AbstractAction) DoNothingAction(spacesettlers.actions.DoNothingAction)

Example 13 with AbstractObject

use of spacesettlers.objects.AbstractObject in project spacesettlers by amymcgovern.

the class Toroidal2DPhysics method detectCollisions.

/**
 * Step through all the objects and ensure they are not colliding.  If they are,
 * call the collision handler for those objects.  Sometimes you bounce (asteroids)
 * and sometimes you pick the object up (beacons), etc.
 */
private void detectCollisions() {
    // would prefer to iterate over the set (as this is inefficient) but
    // the set iterator collides a with b and then b with a, allowing them to
    // pass through one another!
    AbstractObject[] allObjectsArray = (AbstractObject[]) allObjects.toArray(new AbstractObject[allObjects.size()]);
    // loop through all pairs of objects and see if they are colliding
    for (int i = 0; i < allObjectsArray.length; i++) {
        AbstractObject object1 = allObjectsArray[i];
        if (!object1.isAlive()) {
            continue;
        }
        for (int j = i + 1; j < allObjectsArray.length; j++) {
            AbstractObject object2 = allObjectsArray[j];
            if (!object2.isAlive()) {
                continue;
            }
            // skip them if they are the same object
            if (object1.equals(object2)) {
                continue;
            }
            double distance = findShortestDistance(object1.getPosition(), object2.getPosition());
            if (distance < (object1.getRadius() + object2.getRadius())) {
                collisionHandler.collide(object1, object2, this);
            }
        }
    }
}
Also used : AbstractObject(spacesettlers.objects.AbstractObject)

Example 14 with AbstractObject

use of spacesettlers.objects.AbstractObject in project spacesettlers by amymcgovern.

the class HumanTeamClient method getMovementStart.

/**
 * Look at the last key pressed by the human and do its movement
 */
@Override
public Map<UUID, AbstractAction> getMovementStart(Toroidal2DPhysics space, Set<AbstractActionableObject> actionableObjects) {
    HashMap<UUID, AbstractAction> actions = new HashMap<UUID, AbstractAction>();
    for (AbstractObject actionable : actionableObjects) {
        if (actionable instanceof Ship) {
            // get the current position
            Ship ship = (Ship) actionable;
            Position myPosition = ship.getPosition();
            Vector2D currentVelocity = myPosition.getTranslationalVelocity();
            RawAction action = null;
            double angularVel = myPosition.getAngularVelocity();
            // if the key was up or down, accelerate along the current line
            if (lastKeyPressed == HumanKeyPressed.UP) {
                Vector2D newVel = new Vector2D(HUMAN_ACCEL * Math.cos(myPosition.getOrientation()), HUMAN_ACCEL * Math.sin(myPosition.getOrientation()));
                newVel.add(currentVelocity);
                action = new RawAction(newVel, 0);
            } else if (lastKeyPressed == HumanKeyPressed.DOWN) {
                Vector2D newVel = new Vector2D(-HUMAN_ACCEL * Math.cos(myPosition.getOrientation()), -HUMAN_ACCEL * Math.sin(myPosition.getOrientation()));
                newVel.add(currentVelocity);
                action = new RawAction(newVel, 0);
            }
            // if the key was right or left, turn
            if (lastKeyPressed == HumanKeyPressed.RIGHT) {
                action = new RawAction(0, HUMAN_TURN_ACCEL);
            } else if (lastKeyPressed == HumanKeyPressed.LEFT) {
                action = new RawAction(0, -HUMAN_TURN_ACCEL);
            }
            // was the mouse clicked?
            if (lastMouseClick != null) {
                if (mouseClickMove == null || mouseClickMove.isMovementFinished(space) || space.findShortestDistance(lastMouseClick, myPosition) > CLICK_DISTANCE) {
                    mouseClickMove = new MoveAction(space, myPosition, lastMouseClick);
                    graphicsToAdd.add(new StarGraphics(3, super.teamColor, lastMouseClick));
                    LineGraphics line = new LineGraphics(myPosition, lastMouseClick, space.findShortestDistanceVector(myPosition, lastMouseClick));
                    line.setLineColor(super.teamColor);
                    graphicsToAdd.add(line);
                }
                actions.put(actionable.getId(), mouseClickMove);
            } else {
                actions.put(actionable.getId(), action);
            }
        } else {
            // can't really control anything but the ship
            actions.put(actionable.getId(), new DoNothingAction());
        }
    }
    return actions;
}
Also used : HashMap(java.util.HashMap) Position(spacesettlers.utilities.Position) RawAction(spacesettlers.actions.RawAction) LineGraphics(spacesettlers.graphics.LineGraphics) MoveAction(spacesettlers.actions.MoveAction) Vector2D(spacesettlers.utilities.Vector2D) AbstractObject(spacesettlers.objects.AbstractObject) Ship(spacesettlers.objects.Ship) UUID(java.util.UUID) StarGraphics(spacesettlers.graphics.StarGraphics) AbstractAction(spacesettlers.actions.AbstractAction) DoNothingAction(spacesettlers.actions.DoNothingAction)

Example 15 with AbstractObject

use of spacesettlers.objects.AbstractObject in project spacesettlers by amymcgovern.

the class HumanTeamClient method getMovementEnd.

@Override
public void getMovementEnd(Toroidal2DPhysics space, Set<AbstractActionableObject> actionableObjects) {
    // reset so the human has to press again to move again (otherwise
    // it does strange things like fly when you don't tell it anything on
    // acceleration!)
    lastKeyPressed = HumanKeyPressed.NONE;
    for (AbstractObject actionable : actionableObjects) {
        if (actionable instanceof Ship) {
            Ship ship = (Ship) actionable;
            if (!ship.isAlive()) {
                lastMouseClick = null;
                mouseClickMove = null;
            }
        }
    }
}
Also used : AbstractObject(spacesettlers.objects.AbstractObject) Ship(spacesettlers.objects.Ship)

Aggregations

AbstractObject (spacesettlers.objects.AbstractObject)20 Ship (spacesettlers.objects.Ship)15 UUID (java.util.UUID)12 AbstractAction (spacesettlers.actions.AbstractAction)12 DoNothingAction (spacesettlers.actions.DoNothingAction)12 HashMap (java.util.HashMap)11 Position (spacesettlers.utilities.Position)6 Flag (spacesettlers.objects.Flag)5 MoveToObjectAction (spacesettlers.actions.MoveToObjectAction)4 Base (spacesettlers.objects.Base)4 Vector2D (spacesettlers.utilities.Vector2D)3 LinkedHashSet (java.util.LinkedHashSet)2 MoveAction (spacesettlers.actions.MoveAction)2 Team (spacesettlers.clients.Team)2 SpacewarGraphics (spacesettlers.graphics.SpacewarGraphics)2 AbstractActionableObject (spacesettlers.objects.AbstractActionableObject)2 AiCore (spacesettlers.objects.AiCore)2 Asteroid (spacesettlers.objects.Asteroid)2 Beacon (spacesettlers.objects.Beacon)2 Graphics2D (java.awt.Graphics2D)1