/*
* 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.util.Set;
import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.geom.Vector2f;
import org.newdawn.slick.opengl.renderer.Renderer;
import org.newdawn.slick.opengl.renderer.SGL;
/**
* @author Wachirawut Thamviset
* @KhonKaen University
*
*/
public class ViewPort {
// ���˹觡�ͺ�����ʴ���
private float x = 0, y = 0, width = 800, height = 600;
private Vector2f moveTarget=new Vector2f(0,0);
private boolean moveState = false;
private int moveDelay = 100;
// ���˹觢ͧ view port �����Ҿ
private int screenX = 0, screenY = 0;
private Rectangle bound = new Rectangle(-1000, -1000, 2000, 2000);
private AbstractScene scene;
private int id = 0;
private Color borderColor = null;
private Color bgColor = null;
private Rectangle vrect = new Rectangle(0, 0, 800, 600);
protected ActorSet renderSet = null;
public ViewPort(int id) {
this.id = id;
}
public ViewPort(int id, AbstractScene scene, float x, float y) {
super();
this.id = id;
this.x = x;
this.y = y;
if (scene != null) {
this.width = scene.screen.getWidth();
this.height = scene.screen.getHeight();
this.scene = scene;
scene.add(this);
}
}
public float getCenterX() {
return x + width / 2;
}
public float getCenterY() {
return y + height / 2;
}
public float getScreenCenterX() {
return screenX + x + width / 2;
}
public float getScreenCenterY() {
return screenY + y + height / 2;
}
/**
* @return Returns the height.
*/
public int getHeight() {
return (int) height;
}
/**
* @return Returns the width.
*/
public int getWidth() {
return (int) width;
}
/**
* @return Returns the x.
*/
public float getX() {
return x;
}
/**
* @return Returns the y.
*/
public float getY() {
return y;
}
/**
* ���µ��˹觢ͧ viewPort �ҡ�ش���� dx,dy
*
* @param newx
* @param newy
*/
public void move(float dx, float dy,int delay) {
moveTo(x + dx, y + dy,delay);
}
public void move(float dx, float dy) {
moveTo(x + dx, y + dy,0);
}
/**
* ���µ��˹���������� �ͧ viewPort �㹨ش newx,newy
*/
public boolean moveTo(float x, float y) {
return moveTo(x,y,0);
}
public boolean moveTo(float x, float y,int delay) {
boolean flag = false;
moveDelay = delay;
int w = (int) (bound.getX() + bound.getWidth() - getWidth());
int h = (int) (bound.getY() + bound.getHeight() - getHeight());
moveState = true;
if (x < bound.getX()-20)
x = bound.getX()-20;
if (getWidth()<bound.getWidth() && x > w+20)
x = w+20;
if (y < bound.getY()-20)
y = bound.getY()-20;
if (getHeight()<bound.getHeight() && y > h+20)
y = h+20;
if (y != this.y) {
moveTarget.y = y;
flag = true;
}
if (x != this.x) {
moveTarget.x = x;
}
return true;
}
/**
* �� viewPort 价�� Actor ���� ����� Actor ��������ҧ��
*/
public void focus(Actor a) {
focus(a,0);
}
public void focus(Actor a,int delay) {
float w = width / 2;
float h = height / 2;
moveTo((float) a.getCenterX() - w, (float) a.getCenterY() - h,delay);
}
public float tran_x(float x) {
return x - this.x;
}
public float tran_y(float y) {
return y - this.y;
}
/**
* �ŧ��� x �ҡ viewport �������ش㴨�ԧ� �����Ҿ
*
* @param x
* @return
*/
public float toScreenX(float x) {
return x - this.x - this.screenX;
}
/**
* �ŧ��� y �ҡ viewport �������ش㴨�ԧ� �����Ҿ
*
* @param y
* @return
*/
public float toScreenY(float y) {
return y - this.y - this.screenY;
}
/**
* �ŧ��� y �ҡ viewport �������ش㴨�ԧ� �����Ҿ
*
* @param y
* @return
*/
public float toViewPortX(float x) {
return x + this.x - this.screenX;
}
public float toViewPortY(float y) {
return y + this.y - this.screenY;
}
public void setHeight(int height) {
if (scene != null) {
if (height <= 0 || height > scene.screen.getHeight())
height = scene.screen.getHeight();
}
this.height = height;
vrect.setHeight(height);
}
public void setWidth(int width) {
if (scene != null) {
if (width <= 0 || height > scene.screen.getWidth())
width = scene.screen.getWidth();
}
this.width = width;
vrect.setWidth(width);
}
public int getScreenX() {
return screenX;
}
public void setScreenPos(int x, int y) {
this.screenX = x;
this.screenY = y;
}
public int getScreenY() {
return screenY;
}
public float getMaxx() {
return bound.getX() + bound.getWidth();
}
public float getMaxy() {
return bound.getY() + bound.getHeight();
}
public float getMinx() {
return bound.getX();
}
public float getMiny() {
return bound.getY();
}
public AbstractScene getScene() {
return scene;
}
/**
* ��˹��ͺࢵ�ͧ ViewPort ViewPort ���������ö�����͡�͡����dz����ͺࢵ���
*
* @param x1
* @param y1
* @param x2
* @param y2
*/
public void setBounds(float x1, float y1, float x2, float y2) {
this.bound.setBounds(x1, y1, x2 - x1, y2 - y1);
}
/**
* ��Ǩ�ͺ��� actor ����� view ��������
*
* @param a
* @return
*/
Rectangle tmprect = new Rectangle(0, 0, 0, 0);
public boolean isInView(Actor a) {
Shape ab = a.getShape();
tmprect.setBounds(ab.getX(), ab.getY(), ab.getMaxX(), ab.getMaxY());
boolean v = tmprect.intersects(vrect);
return v;
}
public boolean isInView(Shape a) {
tmprect.setBounds(a.getX(), a.getY(), a.getMaxX(), a.getMaxY());
boolean v = tmprect.intersects(vrect);
return v;
}
/**
* ��Ǩ�ͺ��� actor ����� bound ��������
*
* @param a
* @return
*/
int n = 0;
public void render(ActorSet actorSet, Graphics g) {
// ��� actor �������� view ����Ҵ
Actor all[] = actorSet.toActorArray();
vrect.setBounds(x, y, width, height);
n = 0;
SGL GL = Renderer.get();
GL.glPushMatrix();
g.setClip((int) screenX, (int) screenY, (int) width,
(int) height);
g.translate(screenX - x, screenY - y);
for (int i = 0; i < all.length; i++) {
if (all[i].isDead())
continue;
if (all[i].isVisible() && isInView(all[i])) {
all[i].render(g);
n++;
}
}
g.clearClip();
GL.glPopMatrix();
}
/**
* ����Ѻ update �����ŵ������
*
* @param delta
*/
public void update(int delta) {
if(moveState){
float dx=moveTarget.x-x;
float dy=moveTarget.y-y;
if(moveDelay>1){
dx = dx*delta/moveDelay;
dy = dy*delta/moveDelay;
}
moveDelay=moveDelay-delta;
x=x+dx;
y=y+dy;
vrect.setY(y);
vrect.setX(x);
if((int)dx==0 && (int)dy==0){
moveState = false;
}
}
}
public void paint(Graphics g) {
}
public void render(Graphics g) {
SGL GL = Renderer.get();
if (bgColor != null) {
g.setColor(bgColor);
g.fillRect(screenX, screenY, width, height);
}
GL.glPushMatrix();
g.setClip((int) screenX, (int) screenY, (int) width, (int) height);
g.translate(screenX - x, screenY - y);
paint(g);
g.clearClip();
GL.glPopMatrix();
if (renderSet != null)
render(renderSet, g);
if (borderColor != null) {
g.setColor(borderColor);
g.drawRect(screenX, screenY, width, height);
}
}
public Color getBgColor() {
return bgColor;
}
public void setBgColor(Color bgColor) {
this.bgColor = bgColor;
}
public Color getBorderColor() {
return borderColor;
}
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
}