Package kku.cs.fgl

Source Code of kku.cs.fgl.AbstractScene

/*
* Foogl (Friendly Object Oriented Game Library)
* Copyright (c) 2008 Wachirawut Thamviset.
*
* This program 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.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package kku.cs.fgl;

import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Collections;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;

import javax.imageio.ImageIO;

import kku.cs.fgl.actor.ImageActor;

import org.lwjgl.opengl.GL11;
import org.newdawn.slick.Color;
import org.newdawn.slick.Font;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.Music;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;
import org.newdawn.slick.opengl.renderer.Renderer;
import org.newdawn.slick.opengl.renderer.SGL;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.state.transition.Transition;

/**
* AbstractScene ������Ѻ���ҧ�ҡ ���������ö�������©ҡ �ء�ҡ��ͧ extends
* �ҡ AbstractScene ��кǹ��÷ӧҹ
* <Ol>
* <li>���ҧ�ҡ ���� new ��˹� id ��� gamePane
* <li>��������¡ enterScene(id) <br>
* ����繡�����¡�����á init() �ж١���¡���ӧҹ <br>
* �ҡ��� enter( ) �ж١���¡���ӧҹ
* <li>������ʶҹС���ѹ �ء��ͺ��÷ӧҹ���ա�����¡ <br>
* <code>update( )</code> ���ͤӹdz ��� ��Ѻ��ا������<br>
* <code>paint( )</code> �����Ҵ˹�Ҩ�
*
* <li>������ա�����¡ enterScene 价�� scene ��� <br>
* leave( ) �ж١���¡���ӧҹ
* </ol>
*
* @author Wachirawut Thamviset
*
*/
abstract public class AbstractScene extends BasicGameState implements
    ActorGroupListener {

  private int ID;

  private Vector actorGroups = new Vector();

  private Vector viewPorts = new Vector();

  private Vector collisionManagers = new Vector();

  protected GamePane gamePane;

  protected GameContainer screen;

  private Color bgcolor = Color.black;

  private TreeMap soundMap = new TreeMap();

  private boolean inited = false;

  String musicfile = null;

  private ViewPort defView;

  private ActorGroup defGroup;

  protected static SGL GL = Renderer.get();

  private String screenShotFile = null;

  public AbstractScene(int id, GamePane gamePane) {
    super();
    this.gamePane = gamePane;
    this.ID = id;

    gamePane.addState(this);
    screen = gamePane.getScreen();

    defView = new ViewPort(0, this, 0, 0);
    defGroup = new ActorGroup(0);
    add(defView);
    add(defGroup);
  }

  /**
   * ���� Actor ����㹩ҡ ���������㹡��������ش
   *
   * @param a
   */
  public void add(Actor a) {
    add(a, 0);
  }

  /**
   * ���� Actor ����㹩ҡ���к������Ţ����� (groupid) ��ҡ��������ѧ�����
   * ActorGroup ����ж١���ҧ������ѵ��ѵ�
   *
   * @param a
   * @param groupid
   */
  public void add(Actor a, int groupid) {
    ActorGroup g = getGroup(groupid);
    if (g == null) {
      g = new ActorGroup(groupid);
      add(g);
    }
    g.add(a);
  }

  /**
   * ����������ͧ Actor
   *
   * @param g
   */
  public void add(ActorGroup g) {
    ActorGroup old = getGroup(g.getId());
    if (old != null) {
      actorGroups.remove(old);
    }
    g.scene = this;
    g.addActorListListener(this);
    actorGroups.add(g);
    Collections.sort(actorGroups, g);
  }

  /**
   * ���� CollisionManager ������Ѻ��Ǩ�ͺ��ê��ѹ�ͧ Actor
   *
   * @param v
   */
  public void add(CollisionManager v) {
    if (!collisionManagers.contains(v))
      collisionManagers.add(v);
  }

  /**
   * ���� ViewPort ������Ѻ�Ǻ������˹���С���ʴ���
   *
   * @param v
   */
  public void add(ViewPort v) {
    if (!viewPorts.contains(v))
      viewPorts.add(v);
  }

  /**
   * �������§�Ϳ࿤ ���кت��ͧ͢���§ ��� ������§
   * ���ٻẺ����������� .ogg ��� .wav
   *
   * @param name
   *            �繪��ͧ͢���§
   * @param soundfile
   *            �繪������
   */
  public void addSound(String name, String soundfile) {
    try {
      soundMap.put(name, soundfile);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * Clear all scene data. ź�����ŷ���������
   * ActorGroup,sound,viewport,collisionManagers
   *
   */
  public void clear() {
    for (int i = 0; i < actorGroups.size(); i++) {
      ((ActorGroup) actorGroups.get(i)).clear();
    }
    actorGroups.clear();
    soundMap.clear();
    viewPorts.clear();
    collisionManagers.clear();
    add(defView);
    add(defGroup);
  }

  /**
   * ���ҧ������ͧ Actor (ActorGroup) ���к� id
   *
   * @param id
   * @return
   */
  public void createActorGroup(int... id) {
    for (int i : id) {
      ActorGroup g = getGroup(i);
      if (g == null) {
        g = new ActorGroup(i);
        add(g);
      }
    }
  }

  public ActorGroup getDefGroup() {
    return defGroup;
  }

  public ViewPort getDefView() {
    return defView;
  }

  /**
   * ���ҧ��Ǥӹdz��ê��ѹ�ͧ actor ���к� id �ͧ ActorGroup �������Ǩ�ͺ
   * ��������ӵ�Ǩ�ͺ��� actor � group1 �ա�ê��ѹ�Ѻ actor � group2
   * ������� <br>
   * group1 ����繡�����ͧ actor ����繵���Ф� <br>
   * group2 ����繡�����ͧ ����ع�׹
   *
   * @param group1
   *            �������� 1 �繡�����鹷ҧ
   * @param group2
   *            �������� 2 �繡�����������
   * @return
   */
  public CollisionManager createCollisionManager(int group1, int group2) {
    ActorGroup g1 = getGroup(group1);
    ActorGroup g2 = getGroup(group2);
    if (g1 != null && g2 != null) {
      CollisionManager m = new CollisionManager();
      m.setGroup(g1, g2);
      add(m);
      return m;
    }
    return null;
  }

  abstract public void enter();

  /**
   * �١���¡������� scene ���١���¡��ӧҹ
   */
  public void enter(GameContainer container, StateBasedGame game)
      throws SlickException {
    // System.out.println("Scene Enter");
    if (musicfile != null) {
      // System.out.println("play "+musicfile);
      MusicPlayer.play(musicfile);
    }
    if (!inited)
      init(container, game);
    enter();
  }

  /**
   * ���¡�����������÷ӧҹ� scene ���� ���к� {@link Transition}
   *
   * @param id
   * @param leave
   * @param enter
   */
  public final void enterScene(int id, Transition leave, Transition enter) {
    gamePane.enterScene(id, leave, enter);
  }

  public final void enterScene(int id) {
    gamePane.enterScene(id);
  }

  public int getActorCount() {
    ActorGroup groups[] = new ActorGroup[actorGroups.size()];
    actorGroups.toArray(groups);
    int n = 0;
    for (int i = 0; i < groups.length; i++) {
      n = n + groups[i].count();
    }
    return n;
  }

  public Font getFont(int font) {
    return gamePane.getFont(font);
  }

  public GamePane getGamePane() {
    return gamePane;
  }

  public ActorGroup getGroup(int id) {
    for (int i = 0; i < actorGroups.size(); i++) {
      ActorGroup g = (ActorGroup) actorGroups.get(i);
      if (g.getId() == id)
        return g;
    }
    return null;
  }

  public int getID() {
    return ID;
  }

  public Sound getSound(String name) {
    Object s = soundMap.get(name);
    if (s == null)
      return null;
    if (!(s instanceof Sound)) {
      String file = s.toString();
      try {
        s = new Sound(file);
      } catch (SlickException e) {
        e.printStackTrace();
        s = null;
      }
      soundMap.put(name, s);
    }
    return (Sound) s;
  }

  abstract public void init();

  public void init(GameContainer container, StateBasedGame game)
      throws SlickException {
    if (!inited)
      init();
    inited = true;
  }

  public boolean isInit() {
    return inited;
  }

  abstract public void leave();

  public void leave(GameContainer container, StateBasedGame game)
      throws SlickException {
    if (musicfile != null)
      MusicPlayer.stop();
    leave();
  }

  public void paint(Graphics g) {
    ViewPort views[] = new ViewPort[viewPorts.size()];
    viewPorts.toArray(views);
    if (changeActor) {
      for (int i = 0; i < views.length; i++) {
        views[i].renderSet = new ActorSet();
      }
      ActorGroup groups[] = new ActorGroup[actorGroups.size()];
      actorGroups.toArray(groups);
      if (groups.length > 0) {
        ActorSet set;
        for (int j = 0; j < groups.length; j++) {
          if (groups[j].getViewPort() == null) {
            set = defView.renderSet;
          } else {
            set = groups[j].getViewPort().renderSet;
          }
          for (int i = 0; i < groups[j].count(); i++) {
            set.put(groups[j].get(i));
          }
        }
      }
      changeActor = false;
    } else {

    }
    for (int i = 0; i < views.length; i++) {
      views[i].render(g);
      // views[i].renderSet = null;
    }
  }

  public void playMusic(String filename) {
    try {
      musicfile = filename;
      if (inited)
        MusicPlayer.play(filename);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void playSound(String name) {
    Sound s = getSound(name);
    if (s != null)
      s.play();
  }

  public void playSound(String name, float x, float y) {
    playSound(name, x, 1, y);
  }

  public void playSound(String name, float x, float y, float z) {
    float w = screen.getWidth();
    float h = screen.getHeight();
    x = 2 * (x - w / 2) / w;
    y = 2 * (h / 2 - y) / h;
    Sound s = getSound(name);
    // System.out.println("play at " + x + "," + y);
    if (s != null)
      s.playAt(x, y, z);
  }

  /**
   * Remove actor from allGroup
   *
   */
  public void remove(Actor a) {
    for (int i = 0; i < actorGroups.size(); i++) {
      getGroup(i).remove(a);
    }
  }

  public void remove(Actor a, int groupno) {
    ActorGroup g = getGroup(groupno);
    if (g != null)
      g.remove(a);
  }

  public void remove(CollisionManager v) {
    collisionManagers.remove(v);
  }

  public void remove(ViewPort v) {
    viewPorts.remove(v);
  }

  final public void render(GameContainer container, StateBasedGame game,
      Graphics g) throws SlickException {
    if (!inited) {
      // g.setFont(getFont(0));
      init(container, game);
    }
    screen = container;
    paint(g);
    if (screenShotFile != null) {
      saveScreen(g);
      screenShotFile = null;
    }
  }

  final public void update(GameContainer container, StateBasedGame game,
      int delta) throws SlickException {
    if (delta > 60)
      delta = 60;
    ViewPort views[] = new ViewPort[viewPorts.size()];
    viewPorts.toArray(views);
    for (int i = 0; i < views.length; i++) {
      views[i].update(delta);
    }

    ActorGroup groups[] = new ActorGroup[actorGroups.size()];
    actorGroups.toArray(groups);
    // ź actor ��� dead �͡�ҡ list
    for (int i = 0; i < groups.length; i++) {
      groups[i].removeDead();
    }
    update(delta);
    for (int i = groups.length - 1; i >= 0; i--) {
      groups[i].removeDead();
      // ���¡ processInput ���ͨѴ��� input
      groups[i].processInput(screen.getInput());
      // ���¡ update ������� actor ������ update �����ŵ���ͧ
      groups[i].update(delta);
    }
    // ���¡ collisionManagers ���͵�Ǩ�ͺ��ê�
    for (int i = 0; i < collisionManagers.size(); i++) {
      ((CollisionManager) collisionManagers.get(i)).update();
    }
    for (int i = 0; i < groups.length; i++) {
      groups[i].removeDead();
    }
  }

  public Input getInput(){
    return screen.getInput();
  }
  private boolean changeActor = true;

  public void actorAdded(Actor a) {
    changeActor = true;
  }

  public void actorRemoved(Actor a) {
    changeActor = true;
  }

  abstract public void update(int delta);

  public void screenShot(String screenShotFile) {
    this.screenShotFile = screenShotFile;
  }

  private void saveScreen(Graphics g) {
    int w = screen.getWidth();
    int h = screen.getHeight();
    ByteBuffer target = ByteBuffer.allocateDirect(w * h * 3).order(
        ByteOrder.nativeOrder());
    int[] framepixels = new int[w * h];

    GL11.glReadPixels(0, 0, w, h, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE,
        target);
    int bindex = 0;
    for (int y = 0; y < h; y++) {
      for (int x = 0; x < w; x++) {
        bindex = ((y * w) + x) * 3;
        framepixels[((h - y - 1) * w) + x] = // framepixels[ (y * width)
                            // + x];
        0xFF000000 // A
            | ((target.get(bindex) & 0x000000FF) << 16) // R
            | ((target.get(bindex + 1) & 0x000000FF) << 8) // G
            | ((target.get(bindex + 2) & 0x000000FF) << 0); // B
      }
    }

    BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

    try {
      img.setRGB(0, 0, w, h, framepixels, 0, w);
      ImageIO.write(img, "PNG", new File(screenShotFile));
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}
TOP

Related Classes of kku.cs.fgl.AbstractScene

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.