From: Kimmo R. <ki...@us...> - 2011-12-12 23:31:48
|
Update of /cvsroot/arianne/stendhal/src/games/stendhal/client/sprite In directory vz-cvs-4.sog:/tmp/cvs-serv28492/src/games/stendhal/client/sprite Modified Files: CompositeSprite.java Log Message: implemented blend once animations Index: CompositeSprite.java =================================================================== RCS file: /cvsroot/arianne/stendhal/src/games/stendhal/client/sprite/CompositeSprite.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** CompositeSprite.java 2 Dec 2011 21:44:53 -0000 1.3 --- CompositeSprite.java 12 Dec 2011 23:31:46 -0000 1.4 *************** *** 15,21 **** import java.awt.Graphics; import java.awt.Graphics2D; ! import java.awt.GraphicsEnvironment; ! import java.awt.Transparency; ! import java.awt.image.BufferedImage; import java.util.Arrays; import java.util.LinkedList; --- 15,19 ---- import java.awt.Graphics; import java.awt.Graphics2D; ! import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; *************** *** 23,26 **** --- 21,26 ---- import java.util.ListIterator; + import org.apache.log4j.Logger; + /** * A sprite that merges several {@link Sprite} objects to one, and pre-renders *************** *** 29,32 **** --- 29,34 ---- */ public class CompositeSprite implements Sprite { + private static final Logger logger = Logger.getLogger(CompositeSprite.class); + /** * Composition status flag. <code>true</code> it the static image layers *************** *** 41,45 **** /** Reference object made up from the meaningful slave references */ private final CompositeRef reference; - private BufferedImage buffer; /** --- 43,46 ---- *************** *** 94,105 **** // Composite of one non empty sprite. Just return that one. Sprite loner = slaves.get(0); ! if ((blend == null) || !(loner instanceof ImageSprite)) { return loner; } ! // Needs composition for the blending anyway. Fall through! Avoid ! // modifying the original sprite by making a copy of it. ! slaves.clear(); ! // Reference needs to be kept to get the composite reference right ! slaves.add(new ImageSprite(loner, loner.getReference())); default: // A proper composite. Return either a previously generated one, --- 95,102 ---- // Composite of one non empty sprite. Just return that one. Sprite loner = slaves.get(0); ! if (blend == null) { return loner; } ! // Needs composition for the blending anyway. Fall through! default: // A proper composite. Return either a previously generated one, *************** *** 143,165 **** composite(); } ! ! if (blend == null) { ! for (Sprite sprite : slaves) { ! sprite.draw(g, x, y); ! } ! } else { ! if (buffer == null) { ! buffer = GraphicsEnvironment.getLocalGraphicsEnvironment() ! .getDefaultScreenDevice().getDefaultConfiguration() ! .createCompatibleImage(getWidth(), getHeight(), Transparency.BITMASK); ! } ! Graphics2D g2d = buffer.createGraphics(); ! for (Sprite sprite : slaves) { ! sprite.draw(g2d, 0, 0); ! } ! g2d.setComposite(blend); ! adjSprite.draw(g2d, 0, 0); ! g2d.dispose(); ! g.drawImage(buffer, x, y, null); } } --- 140,145 ---- composite(); } ! for (Sprite sprite : slaves) { ! sprite.draw(g, x, y); } } *************** *** 216,219 **** --- 196,204 ---- } else { floor = (ImageSprite) current; + // Stacks with blends will always need a copy + if (blend != null) { + floor = new ImageSprite(floor); + copied = true; + } } } else { *************** *** 234,253 **** // Adjustment effect if (blend != null) { ! // Can handle only mergeable stacks ! if (slaves.size() == 1) { ! Sprite tmp = slaves.get(0); ! if (tmp instanceof ImageSprite) { ! Graphics g = ((ImageSprite) tmp).getGraphics(); ! if (g instanceof Graphics2D) { ! ((Graphics2D) g).setComposite(blend); ! adjSprite.draw(g, 0, 0); ! g.dispose(); ! } ! blend = null; ! adjSprite = null; } } } - composited = true; } --- 219,274 ---- // Adjustment effect if (blend != null) { ! // Blend individual stacks ! applyBlend(newSlaves); ! blend = null; ! adjSprite = null; ! } ! composited = true; ! } ! ! /** ! * Apply blend to individual sprites of the otherwise merged sprite stack. ! * ! * @param stack ! */ ! private void applyBlend(List<Sprite> stack) { ! ListIterator<Sprite> iter = stack.listIterator(); ! while (iter.hasNext()) { ! Sprite sprite = iter.next(); ! if (sprite instanceof ImageSprite) { ! Graphics g = ((ImageSprite) sprite).getGraphics(); ! if (g instanceof Graphics2D) { ! ((Graphics2D) g).setComposite(blend); ! adjSprite.draw(g, 0, 0); ! g.dispose(); ! } ! } else if (sprite instanceof AnimatedSprite) { ! /* ! * Create an animated sprite made of composite sprites. The ! * individual frames will use the usual mechanism to apply the ! * blend only once. ! */ ! AnimatedSprite parent = ((AnimatedSprite) sprite); ! Sprite[] frames = parent.frames; ! Sprite[] newFrames = new Sprite[frames.length]; ! List<Sprite> tmp = new ArrayList<Sprite>(1); ! for (int i = 0; i < frames.length; i++) { ! tmp.add(frames[i]); ! /* ! * The frames of an animated sprite can have the same ! * reference as the animated sprite itself, so we can not ! * use getComposite() to obtain shared instances. Just make ! * a new instance to avoid problems, even though it would ! * be nice to render once the partial stacks that appear in ! * more than one composite. ! */ ! newFrames[i] = new CompositeSprite(tmp, blend, adjSprite, null); ! tmp.clear(); } + iter.set(new AnimatedSprite(newFrames, parent.delays, true, null)); + } else { + logger.error("Unhandled sprite with a blend: " + sprite); } } } |