Package com.googlecode.jumpnevolve.graphics.world

Source Code of com.googlecode.jumpnevolve.graphics.world.World

/*
* Copyright (C) 2010 Erik Wagner and Niklas Fiekas
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.
*
* This program 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, see <http://www.gnu.org/licenses/>.
*/

package com.googlecode.jumpnevolve.graphics.world;

import java.util.ArrayList;
import java.util.LinkedList;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.StateBasedGame;

import com.googlecode.jumpnevolve.graphics.AbstractState;
import com.googlecode.jumpnevolve.graphics.BackgroundDrawable;
import com.googlecode.jumpnevolve.graphics.Drawable;
import com.googlecode.jumpnevolve.graphics.Engine;
import com.googlecode.jumpnevolve.graphics.ForegroundDrawable;
import com.googlecode.jumpnevolve.graphics.GraphicUtils;
import com.googlecode.jumpnevolve.graphics.Pollable;
import com.googlecode.jumpnevolve.graphics.ResourceManager;
import com.googlecode.jumpnevolve.math.ShapeFactory;
import com.googlecode.jumpnevolve.math.Vector;

/**
* Eine grundlegende World für die Engine. Sie enthält alle Objekte, die auf dem
* Bildschirm dargestellt werden sollen.
*
* TODO: Hinzufügen und Entfernen von Objekten prüfen
*
* @author Erik Wagner und Niklas Fiekas
*/
public class World extends AbstractState {

  private ArrayList<LinkedList<AbstractObject>> objectList;

  public final int subareaWidth;

  public final int horizontalSubareas;

  public final int width, height;

  private ArrayList<Pollable> pollables = new ArrayList<Pollable>();

  private ArrayList<Drawable> drawables = new ArrayList<Drawable>();

  private ArrayList<ForegroundDrawable> foregroundDrawables = new ArrayList<ForegroundDrawable>();

  private ArrayList<BackgroundDrawable> backgroundDrawables = new ArrayList<BackgroundDrawable>();

  private ArrayList<AbstractObject> objects = new ArrayList<AbstractObject>();

  private ArrayList<AbstractObject> deletedObjects = new ArrayList<AbstractObject>();

  private Camera camera;

  private boolean screenAlreadyConfigured;

  private boolean polling;

  private ArrayList<Object> addings = new ArrayList<Object>();

  private String background = "landscape-photo.png";

  public World(int width, int height, int subareaWidth) {
    this.subareaWidth = subareaWidth;
    this.width = width;
    this.height = height;
    this.horizontalSubareas = (int) Math.ceil((float) width
        / (float) subareaWidth);
    this.objectList = new ArrayList<LinkedList<AbstractObject>>(
        this.horizontalSubareas);
    for (int i = 0; i < this.horizontalSubareas; i++) {
      this.objectList.add(new LinkedList<AbstractObject>());
    }

  }

  @Override
  public void poll(Input input, float secounds) {
    for (Object obj : this.addings) {
      this.add(obj);
    }
    this.addings.clear();
    this.polling = true;
    this.deletedObjects.clear();
    for (AbstractObject object : this.objects) {
      object.startRound(input);
    }
    for (AbstractObject object : this.deletedObjects) {
      this.removeObject(object);
    }
    for (Pollable pollable : this.pollables) {
      pollable.poll(input, secounds);
    }
    for (AbstractObject object : this.objects) {
      object.endRound();
    }
    this.polling = false;
  }

  /**
   * Setzt die Kamera für das World-Objekt
   *
   * @param camera
   *            Die neue Kamera
   */
  public void setCamera(Camera camera) {
    this.camera = camera;
  }

  /**
   * @return Die Kamera, die aktuell verwendet wird
   */
  public Camera getCamera() {
    return this.camera;
  }

  /**
   * Fügt der World ein neues Objekt hinzu. Während gerade die poll-Methode
   * aller Objekte aufgerufen wird, werden die Objekte zwischen gespeichert
   * und am Anfang des nächsten poll-Aufrufes des World-Objekts hinzugefügt.
   * Die Objekte werden nach {@link Pollable}, {@link Drawable} und
   * {@link AbstractObject} sortiert, für die jeweilige Art werden bei jedem
   * Frame die entsprechenden Methoden aufgerufen (poll(), draw(),
   * startRound() und endRound()).
   *
   * @param object
   *            Das neue Objekt
   */
  public void add(Object object) {
    if (polling == false) {
      if (object != null) {
        if (object instanceof Pollable) {
          if (!this.pollables.contains(object)) {
            this.pollables.add((Pollable) object);
          }
        }
        if (object instanceof Drawable) {
          if (object instanceof BackgroundDrawable) {
            if (!this.backgroundDrawables.contains(object)) {
              this.backgroundDrawables
                  .add((BackgroundDrawable) object);
            }
          } else if (object instanceof ForegroundDrawable) {
            if (!this.foregroundDrawables.contains(object)) {
              this.foregroundDrawables
                  .add((ForegroundDrawable) object);
            }
          } else {
            if (!this.drawables.contains(object)) {
              this.drawables.add((Drawable) object);
            }
          }
        }
        if (object instanceof AbstractObject) {
          if (!this.objects.contains(object)) {
            this.objects.add((AbstractObject) object);
            addToObjectList((AbstractObject) object);
            if (object instanceof ObjectGroup) {
              for (AbstractObject obj : ((ObjectGroup) object)
                  .getObjects()) {
                this.add(obj);
              }
            }
          }
        }
      }
    } else {
      this.addings.add(object);
    }
  }

  private void addToObjectList(AbstractObject object) {
    int start = object.getStartSubarea(subareaWidth, objectList.size() - 1);
    int end = object.getEndSubarea(subareaWidth, objectList.size() - 1);
    for (int i = start; i <= end; i++) {
      this.objectList.get(i).add(object);
    }
  }

  /**
   * Wird aufgerufen, wenn ein Objekt seine Position verändert hat
   *
   * @param object
   *            Das Objekt, dessen Position sich verändert hat
   */
  public void changedPosition(AbstractObject object) {
    int start = object.getStartSubarea(subareaWidth, objectList.size() - 1);
    int end = object.getEndSubarea(subareaWidth, objectList.size() - 1);
    int oldStart = object.getOldStartSubarea(subareaWidth,
        objectList.size() - 1);
    int oldEnd = object.getOldEndSubarea(subareaWidth,
        objectList.size() - 1);
    if (start < oldStart) {
      for (int i = start; i < oldStart; i++) {
        this.objectList.get(i).add(object);
      }
    }
    if (start > oldStart) {
      for (int i = oldStart; i < start; i++) {
        this.objectList.get(i).remove(object);
      }
    }
    if (end > oldEnd) {
      for (int i = oldEnd + 1; i <= end; i++) {
        this.objectList.get(i).add(object);
      }
    }
    if (end < oldEnd) {
      for (int i = end + 1; i <= oldEnd; i++) {
        this.objectList.get(i).remove(object);
      }
    }
  }

  /**
   * Entfernt das Objekt beim nächsten poll-Aufruf für das World-Objekt aus
   * diesem
   *
   * @param object
   *            Das Objekt, das entfernt werden soll
   */
  public void removeFromWorld(AbstractObject object) {
    this.deletedObjects.add(object);
  }

  private void removeObject(AbstractObject object) {
    this.pollables.remove(object);
    this.foregroundDrawables.remove(object);
    this.drawables.remove(object);
    this.backgroundDrawables.remove(object);
    this.objects.remove(object);
    /*
     * int start = (int) (object.getHorizontalStart()) / this.subareaWidth;
     * int end = (int) (object.getHorizontalEnd()) / this.subareaWidth; if
     * (start < 0) { System.out.println("Korrektur 0" +
     * object.getClass().getName()); start = 0; } if (end < 0) {
     * System.out.println("Korrektur 0" + object.getClass().getName()); end
     * = 0; }
     *
     * if (start > objectList.size()) { System.out.println("Korrektur high"
     * + object.getClass().getName()); start = objectList.size(); } if (end
     * > objectList.size()) { System.out.println("Korrektur high" +
     * object.getClass().getName()); end = objectList.size(); } for (int i =
     * start; i <= end; i++) { this.objectList.get(i).remove(object); }
     */
    for (int i = 0; i < this.objectList.size(); i++) {
      while (this.objectList.get(i).contains(object)) {
        this.objectList.get(i).remove(object);
      }
    }
  }

  /**
   * Ermittelt alle Objekte die wenigstens eine Subarea mit dem Objekt teilen
   * (Nachbarn)
   *
   * @param object
   *            Das Objekt, für das die Nachbarn gesucht werden
   * @return Die Nachbarn des Objekts
   */
  public ArrayList<LinkedList<AbstractObject>> getNeighbours(
      AbstractObject object) {
    int start = object.getStartSubarea(subareaWidth, objectList.size() - 1);
    int end = object.getEndSubarea(subareaWidth, objectList.size() - 1);
    ArrayList<LinkedList<AbstractObject>> returns = new ArrayList<LinkedList<AbstractObject>>();
    for (int i = start; i <= end; i++) {
      returns.add(this.objectList.get(i));
    }
    return returns;
  }

  public void setBackground(String imageFile) {
    if (imageFile.equals("default")) {
      imageFile = "landscape.png";
    }
    this.background = imageFile;
  }

  /**
   * @return Der gesamte Dateipfad aus dem das Hintergrundbild geladen wird
   */
  public String getBackgroundFile() {
    return "backgrounds/" + background;
  }

  protected void drawBackground(Graphics g) {
    GraphicUtils.drawImage(g, ShapeFactory
        .createRectangle(new Vector(this.width / 2.0f,
            this.height / 2.0f), this.width, this.height),
        ResourceManager.getInstance()
            .getImage(this.getBackgroundFile()));
  }

  /**
   * Bereitet den Grafikkontext für das Zeichnen vor (Kameraeinstellungen,
   * Zoom, Hintergrund)
   *
   * @param g
   *            Der Grafikkontext
   */
  protected void configScreen(Graphics g) {
    // TODO: Zoom und Kameraeinstellungen prüfen
    g.scale(zoomX, zoomY);

    // Kameraeinstellung anwenden
    if (this.camera != null) {
      Vector cameraPosition = this.camera.getPosition();
      g.translate(Engine.getInstance().getWidth() / zoomX / 2.0f
          - cameraPosition.x, Engine.getInstance().getHeight()
          / zoomY / 2.0f - cameraPosition.y);
    }
    this.drawBackground(g);
    screenAlreadyConfigured = true;
  }

  @Override
  public void draw(Graphics g) {
    if (!screenAlreadyConfigured) {
      this.configScreen(g);
    }

    // Andere Objekte zeichnen
    for (BackgroundDrawable drawable : this.backgroundDrawables) {
      drawable.draw(g);
    }
    for (Drawable drawable : this.drawables) {
      drawable.draw(g);
    }
    for (ForegroundDrawable drawable : this.foregroundDrawables) {
      drawable.draw(g);
    }
    screenAlreadyConfigured = false;
  }

  @Override
  public void init(GameContainer container, StateBasedGame game)
      throws SlickException {
    // Zur Zeit nicht benötigt
  }

}
TOP

Related Classes of com.googlecode.jumpnevolve.graphics.world.World

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.