1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package tsukuba_bunko.peko.canvas.stage;
20
21 import java.awt.Dimension;
22 import java.awt.Graphics;
23 import java.awt.Graphics2D;
24 import java.awt.Image;
25
26 import java.awt.image.BufferedImage;
27
28 import java.util.Iterator;
29 import java.util.Map;
30
31 import javax.swing.JComponent;
32
33 import tsukuba_bunko.peko.Logger;
34
35 import tsukuba_bunko.peko.resource.ResourceManager;
36
37
38 /***
39 * 舞台(ステージ)を描画するキャンバスです。
40 * @author $Author: ppoi $
41 * @version $Revision: 1.3 $
42 */
43 public class StageCanvas extends JComponent {
44
45 /***
46 * serial version UID
47 */
48 private static final long serialVersionUID = -4344927132903559315L;
49
50 /***
51 * ステージ
52 */
53 private Stage _stage = null;
54
55 /***
56 * エフェクトを使用するかどうか
57 */
58 private boolean _usingEffect = false;
59
60 /***
61 * エフェクトマップ
62 */
63 private Map _effects = null;
64
65 /***
66 * 描画用オフスクリーンバッファ
67 */
68 private BufferedImage _screen = null;
69
70 /***
71 * 作業用オフスクリーンバッファ
72 */
73 private BufferedImage _working = null;
74
75 /***
76 * size cache
77 */
78 private Dimension _size = new Dimension();
79
80
81 /***
82 * <code>StageCanvas</code> のインスタンスを作成します。
83 */
84 public StageCanvas()
85 {
86 super();
87 initialize();
88 }
89
90
91 /***
92 * このキャンバスで描画するステージを設定します。
93 * @param stage ステージ
94 */
95 public void setStage( Stage stage )
96 {
97 if( _stage != null ) {
98 _stage.dispose();
99 }
100
101 _stage = stage;
102 _stage.setStageCanvas( this );
103 }
104
105 /***
106 * このキャンバスが現在描画しているステージを取得します。
107 * @return ステージ
108 */
109 public Stage getStage()
110 {
111 return _stage;
112 }
113
114 /***
115 * エフェクトを使用するかどうかを設定します。
116 * @param useEffect エフェクトを使用する場合 <code>true</code>、それ以外の場合 <code>false</code>
117 */
118 public void setUsingEffect( boolean useEffect )
119 {
120 _usingEffect = useEffect;
121 }
122
123 /***
124 * エフェクトを使用するかどうかを取得します。
125 * @return エフェクトを使用する場合 <code>true</code>、それ以外の場合 <code>false</code>
126 */
127 public boolean isUsingEffect()
128 {
129 return _usingEffect;
130 }
131
132 /***
133 * ステージキャンバスを初期化します。
134 */
135 private void initialize()
136 {
137 ResourceManager resources = ResourceManager.getInstance();
138 Dimension canvasSize = (Dimension)resources.getResource( "peko.canvas.canvas-size" );
139
140 super.setPreferredSize( canvasSize );
141 super.setSize( canvasSize );
142 _screen = new BufferedImage( canvasSize.width, canvasSize.height, BufferedImage.TYPE_INT_RGB );
143 _working = new BufferedImage( canvasSize.width, canvasSize.height, BufferedImage.TYPE_INT_RGB );
144
145 super.setLayout( null );
146 setDoubleBuffered( false );
147
148 _effects = new java.util.HashMap( 89 );
149
150 Effect effect = new tsukuba_bunko.peko.canvas.stage.effect.MofingEffect();
151 _effects.put( effect.getName(), effect );
152
153 effect = new tsukuba_bunko.peko.canvas.stage.effect.PataPataEffect();
154 _effects.put( effect.getName(), effect );
155
156 effect = (Effect)_effects.get( "immediate" );
157 if( effect == null ) {
158 effect = new tsukuba_bunko.peko.canvas.stage.effect.ImmediateEffect();
159 _effects.put( "immediate", effect );
160 }
161 _effects.put( null, effect );
162 }
163
164
165 /***
166 * キャンバスの描画内容を更新します。
167 */
168 public void updateCanvas()
169 {
170 updateCanvas( null );
171 }
172
173 /***
174 * 指定されたエフェクトを用いて、キャンバスの描画内容を更新します。
175 * @param effectName 更新時に使用するエフェクト名
176 */
177 public void updateCanvas( String effectName )
178 {
179 if( !isEnabled() ) {
180 return;
181 }
182
183 Graphics2D g2 = _working.createGraphics();
184 Dimension size = getSize( _size );
185
186 if( _stage.getSlide() == null ) {
187 Image image = _stage.getBackgroundImage();
188 if( image != null ) {
189 g2.drawImage( image, 0, 0, this );
190 }
191 else {
192 g2.setColor( _stage.getBackgroundColor() );
193 g2.fillRect( 0, 0, size.width, size.height );
194 }
195
196 Map actors = _stage.getActors();
197 if( actors != null ) {
198 Iterator itr = actors.values().iterator();
199 Actor actor = null;
200 Image looks = null;
201 int x = 0;
202 int y = 0;
203 while( itr.hasNext() ) {
204 actor = (Actor)itr.next();
205 looks = actor.getLooksImage();
206 if( looks != null ) {
207 x = computePosition( actor );
208 y = size.height - looks.getHeight( this );
209 g2.drawImage( looks, x, y, this );
210 }
211 }
212 }
213 }
214 else {
215 Image image = _stage.getSlideImage();
216 if( image != null ) {
217 g2.drawImage( image, 0, 0, this );
218 }
219 else {
220 g2.fillRect( 0, 0, size.width, size.height );
221 }
222 }
223
224 if( _usingEffect ) {
225 Effect effect = (Effect)_effects.get( effectName );
226 if( effect != null ) {
227 effect.process( this, _screen, _working );
228 }
229 else {
230 Logger.error( "[canvas.stage] unsuported effect name. :" + effect );
231 _screen.setData( _working.getRaster() );
232 repaint();
233 }
234 synchronized( this ) {
235 try {
236 wait( 100 );
237 }
238 catch( InterruptedException ie ) {
239 Logger.debug( "[canvas.stage] interrupted after effect.", ie );
240 }
241 }
242 }
243 else {
244 _screen.setData( _working.getRaster() );
245 repaint();
246 }
247 }
248
249 public void paintPageBackground( boolean visiblePage )
250 {
251 Graphics2D g2 = _screen.createGraphics();
252 g2.drawImage( _working, 0, 0, this );
253 if( visiblePage ) {
254 tsukuba_bunko.peko.PekoSystem.getInstance().getCanvasManager().getTextCanvas().paintPageBackground( g2 );
255 }
256 g2.dispose();
257 repaint();
258 }
259
260
261 /***
262 * 立ち位置を計算します。
263 * @param position 立ち位置の文字列表現
264 */
265 private int computePosition( Actor actor )
266 {
267 int halfWidth = actor.getLooksImage().getWidth( this ) / 2;
268 Dimension size = getSize( _size );
269 switch( actor.getPosition() ) {
270 case Actor.POSITION_CENTER:
271 return ((int)((float)size.width / 2f)) - halfWidth;
272 case Actor.POSITION_LEFT:
273 return ((int)((float)size.width / 4f)) - halfWidth;
274 case Actor.POSITION_RIGHT:
275 return ((int)((size.width / 4f) * 3f)) - halfWidth;
276 default:
277 return (int)actor.getAbsolutePosition() - halfWidth;
278 }
279 }
280
281
282
283
284 protected void paintComponent( Graphics g )
285 {
286 g.drawImage( _screen, 0, 0, this );
287 }
288 }