/** * Check if 'quelPerso' is colliding with the given element. * * @param x * @param y * @param quelElement * @param quelPerso * @param rayon * @return Perso */ private boolean checkCollisionOnPerso( int x, int y, Element quelElement, Perso quelPerso, int rayon) { if (quelPerso.isZildo() && quelElement != null && quelElement.getDesc() instanceof ElementDescription) { ElementDescription d = (ElementDescription) quelElement.getDesc(); if (d.isPushable() && quelElement.vx + quelElement.vy != 0f) { return false; } } int tx = (int) quelPerso.getX(); int ty = (int) quelPerso.getY(); PersoDescription descToCompare = quelPerso.getDesc(); int rayonPersoToCompare = rayon; if (descToCompare != null) { rayonPersoToCompare = descToCompare.getRadius(); } // Do we have a Perso in parameters ? Perso perso = null; if (quelElement != null && quelElement.getEntityType().isPerso()) { perso = (Perso) quelElement; } if (EngineZildo.collideManagement.checkCollisionCircles( x, y, tx, ty, rayon, rayonPersoToCompare)) { if (perso != null && perso.isZildo() && perso.linkedSpritesContains(quelPerso)) { // Collision entre Zildo et l'objet qu'il porte dans les mains => on laisse } else if (quelElement == null || quelElement.getLinkedPerso() != quelPerso) { return true; } } // No collision return false; }
/** * Translate every entities with the given offset. * * @param p_offset * @param p_translateZildo TRUE=Translate Zildo too / FALSE=Don't touch him */ public void translateEntities(Point p_offset, boolean p_translateZildo) { for (SpriteEntity entity : spriteEntities) { if (!entity.clientSpecific && (!entity.isZildo() || p_translateZildo)) { if (entity.getEntityType().isElement()) { Element e = (Element) entity; if (e.getLinkedPerso() != null && e.getLinkedPerso().isZildo()) { continue; } } entity.x += p_offset.x; entity.y += p_offset.y; entity.setAjustedX(entity.getAjustedX() + p_offset.x); entity.setAjustedY(entity.getAjustedY() + p_offset.y); } } }
// ///////////////////////////////////////////////////////////////////////////////////// // clearSpritesWithoutZildo // ///////////////////////////////////////////////////////////////////////////////////// // -Delete every sprites in the entities list // -Clean the sort array // -Reinitializes local camera // ///////////////////////////////////////////////////////////////////////////////////// public void clearSprites(boolean includingZildo) { // Get Zildo to avoid to remove it Perso zildo = EngineZildo.persoManagement.getZildo(); // Destroy entities List<SpriteEntity> listToRemove = new ArrayList<SpriteEntity>(); for (SpriteEntity entity : spriteEntities) { if (entity != null) { boolean canDelete = true; if (entity == zildo) { // This IS Zildo ! So we keep him canDelete = includingZildo; } else if (entity.getEntityType().isElement()) { Element element = (Element) entity; if (zildo != null && element.getLinkedPerso() == zildo) { // This is an element related to zildo, so we can't // remove it now canDelete = includingZildo; } } else if (entity.getEntityType().isPerso()) { canDelete = false; } if (canDelete) { listToRemove.add(entity); } } } for (SpriteEntity entity : listToRemove) { deleteSprite(entity); } walkableEntities.clear(); }
/** * Find an element near a given one.<br> * WARNING: it's an unoptimized method, contrary to {@link #collideSprite(int, int, Element)}, but * it's used only once when player press action key. So it's acceptable now. * * @param x * @param y * @param quelElement * @param radius * @return Element */ public Element collideElement( int x, int y, Element quelElement, int radius, SpriteDescription... expectedDesc) { Perso perso = null; if (quelElement != null && quelElement.getEntityType().isPerso()) { perso = (Perso) quelElement; } for (SpriteEntity entity : spriteEntities) { if (entity.getEntityType().isElement()) { if (entity != quelElement) { int tx = (int) entity.x; int ty = (int) entity.y; if (EngineZildo.collideManagement.checkCollisionCircles(x, y, tx, ty, radius, radius)) { if (perso != null && perso.isZildo() && perso.linkedSpritesContains(entity)) { // Collision between hero and object he's carrying => let it go } else if (quelElement == null || quelElement.getLinkedPerso() != entity) { // Check that found element is one of expected ones if (expectedDesc != null && expectedDesc.length > 0) { for (SpriteDescription sDesc : expectedDesc) { if (sDesc == entity.getDesc()) { return (Element) entity; } } continue; // Check next one } Element elem = (Element) entity; // Found an element, but is it really the most pertinent ? (ex:shadow) if (elem.getLinkedPerso() != null) { return elem.getLinkedPerso(); } return elem; } } } } } return null; }
/** * Do sprite's stuff * * <ul> * <li>animate sprites & persos * <li> * <li>delete if need (the only place to do this) * </ul> * * @param p_blockMoves TRUE=don't animate perso except Zildo */ public void updateSprites(boolean p_blockMoves) { spriteUpdating = true; spriteEntitiesToAdd.clear(); // Backup current entities, if backup buffer is empty if (EngineZildo.game.multiPlayer && backupEntities.size() == 0) { for (SpriteEntity entity : spriteEntities) { SpriteEntity cloned = entity.clone(); backupEntities.put(cloned.getId(), cloned); } } sprColli.initFrame(spriteEntities); persoColli.initFrame(EngineZildo.persoManagement.tab_perso); boolean blockNPC = p_blockMoves || temporaryBlocked; // Do perso animations // Mandatory to do that first, because one perso can be connected to // other sprites int compt = EngineZildo.compteur_animation; // % (3 * 20); for (SpriteEntity entity : spriteEntities) { if (entity.getEntityType().isPerso()) { Perso perso = (Perso) entity; boolean allowedToMoveAndCollide = !blockNPC || /*perso.getInfo() == PersoInfo.ZILDO ||*/ perso.getFollowing() != null; if (allowedToMoveAndCollide) { // Animate persos perso.animate(compt); } perso.finaliseComportement(compt); updateSprModel(perso); SpriteModel spr = perso.getSprModel(); if (allowedToMoveAndCollide) { perso.manageCollision(); } if (!perso.isZildo()) { // Non-zildo sprite haven't same way to display correctly (bad...) perso.setAjustedX(perso.getAjustedX() - (spr.getTaille_x() / 2)); perso.setAjustedY(perso.getAjustedY() - (spr.getTaille_y() - 3)); } } } List<SpriteEntity> toDelete = new ArrayList<SpriteEntity>(); for (Iterator<SpriteEntity> it = spriteEntities.iterator(); it.hasNext(); ) { SpriteEntity entity = it.next(); if (toDelete.contains(entity)) { continue; // It's a dead one } Element element = null; // Calcul physique du sprite if (entity.dying) { toDelete.add(entity); } else if (entity.getEntityType().isEntity()) { entity.animate(); } else if (entity.getEntityType().isElement()) { // X, vX, aX, ... element = (Element) entity; if (!blockNPC || element.isLinkedToZildo()) { element.animate(); if (element.dying) { SpriteEntity linkedOne = element.getLinkedPerso(); // L'élément est arrivé au terme de son existence : on le supprime de la liste if (linkedOne != null && EntityType.ELEMENT == linkedOne.getEntityType()) { toDelete.add(linkedOne); } toDelete.add(element); } else { if (element.isVisible()) { updateSprModel(element); } } } } } // Remove what need to for (SpriteEntity entity : toDelete) { deleteSprite(entity); if (entity.getEntityType().isPerso()) { persoColli.notifyDeletion((Perso) entity); } else { sprColli.notifyDeletion(entity); } } spriteUpdating = false; spriteEntities.addAll(spriteEntitiesToAdd); }