/* Vob.java * * Copyright (c) 2000, Ted Nelson and Tuomas Lukka * * You may use and distribute under the terms of either the GNU Lesser * General Public License, either version 2 of the license or, * at your choice, any later version. Alternatively, you may use and * distribute under the terms of the XPL. * * See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of * the licenses. * * This software 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 README * file for more details. * */ /* * Written by Tuomas Lukka */ package org.gzigzag; import java.util.*; import java.awt.*; /** A vob or visual object shown on the screen. * Vobs are constant read-only objects like Strings. *

* Vobs should be able to render themselves quickly for animations; * caching relevant information in this structure is therefore a good idea. *

* The minimal vob implementation simply implements the * render(Graphics, int, int, int, int, int) method. */ public abstract class Vob extends Renderable { public static final String rcsid = "$Id: Vob.java,v 1.1 2001/01/20 08:56:19 bfallenstein Exp $"; public int w, h; /** The cell associated with this vob. * This may be set to null for things that are - well - just * things rendered. But those should be in a minority always. */ public ZZCell c; /** The vob we are interpolating with. * Storing it here is a pure speed hack: in reality it'd belong in * a hashtable somewhere. But this is crucial for the frame rate. */ protected Vob interpTo; /** A 3-tuple with the global coordinates for this vob. * Conceptually this belongs in the VobStore, but I can't think of a * clean, not too wasteful implementation. */ protected int[] coords; /** The lowest-level VobSet this was placed into. */ public VobSet vobset; public Vob(ZZCell c) { this.c = c; } /** Get the visual center of this vob. */ public Point getCenter(Point p) { p.x = w/2; p.y = h/2; return p; } /** Get the visual center of this vob. */ public Point getCenter() { return getCenter(new Point()); } /** Render this vob at the given coordinates. * Default: render nothing. * You may override either this function or one or both of * render(Graphics, int, int) and renderInterp(Graphics, int, int, int, int, float). */ public void render(Graphics g, int mx, int my, int md, int mw, int mh) { } /** Render this vob. * May be overridden; default implementation uses render(g, x, y, w, h, d); */ public void render(Graphics g, x, y, d) { render(g, x, y, d, w, h); } /** Render an interpolated version of this vob. * Default implementation uses render(g, x, y, d, w, h) with linearly * interpolated coordinates. */ public void renderInterp(Graphics g, float fract) { Vob r = interpTo; if(r==null) return; render(g, (int)(x + fract*(r.x-x)), (int)(y + fract*(r.y-y)), (int)(d + fract*(r.d-d)), (int)(w + fract*(r.w-w)), (int)(h + fract*(r.h-h)) ); } /** Whether it would make visually sense to interpolate * this vob. * Default implementation: whether the sum of the squares of * the differences of the coordinates and widths is more than 100. * Not a terribly useful measure but good enough. */ public boolean isInterpUseful() { Vob r = interpTo; if(r==null) return false; return (r.x - x) * (r.x - x) + (r.y - y) * (r.y - y) + (r.w - w) * (r.w - w) + (r.h - h) * (r.h - h) > 100; } /** Returns an object telling what was hit. * Default implementation: returns null. */ public Object hit(int x, int y) { return null; } /** A convenience routine to check whether a point * is inside the defining rectangle. * If the vob is (as many are) rectangular, this routine can * be used to check the hit. */ public final boolean insideRect(int x0, int y0) { return x0 >= x && y0 >= y && x0 < x+w && y0 < y+h; } }