/** * eAdventure (formerly <e-Adventure> and <e-Game>) is a research project of the * <e-UCM> research group. * * Copyright 2005-2010 <e-UCM> research group. * * You can access a list of all the contributors to eAdventure at: * http://e-adventure.e-ucm.es/contributors * * <e-UCM> is a research group of the Department of Software Engineering * and Artificial Intelligence at the Complutense University of Madrid * (School of Computer Science). * * C Profesor Jose Garcia Santesmases sn, * 28040 Madrid (Madrid), Spain. * * For more info please visit: <http://e-adventure.e-ucm.es> or * <http://www.e-ucm.es> * * **************************************************************************** * * This file is part of eAdventure, version 2.0 * * eAdventure is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * eAdventure is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with eAdventure. If not, see <http://www.gnu.org/licenses/>. */ package es.eucm.ead.engine.gameobjects.trajectories.dijkstra; import com.badlogic.gdx.math.Vector2; import com.google.inject.Inject; import es.eucm.ead.engine.factories.SceneElementFactory; import es.eucm.ead.engine.game.GameState; import es.eucm.ead.engine.gameobjects.sceneelements.SceneElementGO; import es.eucm.ead.engine.gameobjects.trajectories.AbstractTrajectoryGO; import es.eucm.ead.model.elements.enums.CommonStates; import es.eucm.ead.model.elements.scenes.SceneElement; import es.eucm.ead.model.elements.trajectories.NodeTrajectory; import es.eucm.ead.model.interfaces.features.enums.Orientation; import es.eucm.ead.model.params.util.Position; public class NodeTrajectoryGO extends AbstractTrajectoryGO<NodeTrajectory> { /** * Pixels traveled per second */ private static final int PIXELS_PER_SECOND = 100; private DijkstraNodeTrajectoryGenerator generator; private boolean finishedSide = false; private boolean finished = false; private boolean firstUpdate = true; private Float initX; private Float initY; private Float initScale; private Float targetX; private Float targetY; private Float targetScale; private float totalTime; private Path path; private int currentSide; private int currentTime; private SceneElement sceneElement; private Vector2 direction = new Vector2(); @Inject public NodeTrajectoryGO(SceneElementFactory sceneElementFactory, GameState gameState) { super(gameState, sceneElementFactory); this.generator = new DijkstraNodeTrajectoryGenerator( sceneElementFactory, gameState); } @Override public void set(SceneElementGO movingElement, float destinationX, float destinationY, SceneElementGO target) { super.set(movingElement, destinationX, destinationY, target); this.sceneElement = movingElement.getElement(); currentTime = 0; path = generator.getTrajectory(this.trajectory, movingElement .getElement(), destinationX, destinationY, target); currentPath.clear(); for (PathSide side : path.getSides()) { currentPath.add(side.getEndNode().getPosition().getX()); currentPath.add(side.getEndNode().getPosition().getY()); } currentSide = 0; targetX = destinationX; targetY = destinationY; finished = false; firstUpdate = true; initScale = 1.0f; initX = movingElement.getX(); initY = movingElement.getY(); targetScale = 1.0f; currentTime = 0; totalTime = 0; updateTarget(); } @Override public void act(float delta) { movingElement = sceneElementFactory.get(sceneElement); currentTime += delta; if (!finished) { if (firstUpdate) { firstUpdate = false; gameState.setValue(sceneElement, SceneElement.VAR_STATE, CommonStates.WALKING.toString()); } if (finishedSide) { updateTarget(); } if (currentTime <= totalTime) { gameState.setValue(sceneElement, SceneElement.VAR_X, initX + (currentTime / totalTime) * (targetX - initX)); gameState.setValue(sceneElement, SceneElement.VAR_Y, initY + (currentTime / totalTime) * (targetY - initY)); gameState.setValue(sceneElement, SceneElement.VAR_SCALE, initScale + (currentTime / totalTime) * (targetScale - initScale)); } else { gameState.setValue(sceneElement, SceneElement.VAR_X, targetX); gameState.setValue(sceneElement, SceneElement.VAR_Y, targetY); finishedSide = true; } } if (finished) { movingElement.setState(CommonStates.DEFAULT.toString()); // if (path.isGetsTo() || effect.getTarget() == null) // super.finish(); } } private void updateTarget() { if (currentSide < path.getSides().size()) { PathSide side = path.getSides().get(currentSide); initX = gameState.getValue(movingElement.getElement(), SceneElement.VAR_X, 0f); initY = gameState.getValue(movingElement.getElement(), SceneElement.VAR_Y, 0f); initScale = gameState.getValue(movingElement.getElement(), SceneElement.VAR_SCALE, 1f); Position p = side.getEndPosition(currentSide == path.getSides() .size() - 1); targetX = p.getX(); targetY = p.getY(); targetScale = side.getEndScale(); currentTime = (int) (currentTime - totalTime); totalTime = ((side.getLength() / PIXELS_PER_SECOND) * 1000); gameState.setValue(movingElement.getElement(), NodeTrajectory.VAR_CURRENT_SIDE, side.getSide()); updateDirection(); currentSide++; finishedSide = false; } else { finished = true; } } private void updateDirection() { direction.set(targetX - initX, targetY - initY); int quadrant = (int) (((direction.angle() + 45) % 360) / 90); Orientation tempDirection; switch (quadrant) { case 0: tempDirection = Orientation.E; break; case 1: tempDirection = Orientation.S; break; case 2: tempDirection = Orientation.W; break; default: tempDirection = Orientation.N; break; } movingElement.setOrientation(tempDirection); } @Override public boolean isDone() { return finished; } @Override public boolean isReachedTarget() { if (target == null) { return true; } return path.isGetsTo(); } }