View Javadoc

    1   /*
    2    * All Rights Reserved.
    3    * Copyright (C) 1999-2005 Tsukuba Bunko.
    4    *
    5    * Licensed under the BSD License ("the License"); you may not use
    6    * this file except in compliance with the License.
    7    * You may obtain a copy of the License at
    8    *
    9    *       http://www.tsukuba-bunko.org/licenses/LICENSE.txt
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   * $Id: StageCanvas.java,v 1.3 2005/07/23 18:53:48 ppoi Exp $
    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 //	JComponent の実装
    283 //
    284 	protected void paintComponent( Graphics g )
    285 	{
    286 		g.drawImage( _screen, 0, 0, this );
    287 	}
    288 }