Download presentation
Presentation is loading. Please wait.
Published byἉνανίας Αγγελίδης Modified over 6 years ago
1
Animated image sequences, fonts and image transforms
4.1. Graphics II Animated image sequences, fonts and image transforms
2
Animations Animated image sequences; playback speed and image source
3
Image Sequences An image sequence is simply a series of images, displayed one after the other. If the playback is fast a series of progressive images will appear as continuous, unbroken animation. Typically, how many frame/s are needed to give the appearance of unbroken animation? A – 50 frame/s B – 30 frame/s C – 20 frame/s D – 10 frame/s E – 5 frame/s
4
Image Sequences ● TV provides either 25 or 30 frame/s (PAL = 30)
● Consider the set of 6 images: ○ At 2 frame/s it is not smooth ○ At 10 frame/s it is reasonably smooth ● A typical animated cartoon run at 12 frame/s
5
Sequence Source Images to be played back as a sequence may reside within a number of different file structures, including: ● A series of files (1 image per file) ● A continuous image strip (1 file) ● An image sheet (1 file) Aside: For best performance, all images should be stored in an image sheet, with all animations using that sheet rendered together.
6
Image Sequence Playback
Animating a sequence of images
7
Image sequence playback
Playback of an image sequence can be integrated into the update/draw loop as follows: During the update phase determine when the next image in the sequence should be selected to provide the target number of frames/second During the draw phase, render the current selected image Aside: The following example is based on the ImageAssetSequence within the Java code repository
8
Image sequence playback (example implementation)
Assuming the images are stored as an array (or an array of rectangles into a single image sheet) the following parameters can be used to offer different playback options: playCount- number of times to play the animation (-1 = loop forever, 0 = pause) homeFrame – frame to display when not animating currentFrame – current frame to display animationPeriodms – number of ms which a single playback should take animationStartTime – start time of the animation (if playback has commenced) private BufferedImage[] images; private int playCount; private int homeFrame; private int currentFrame; private long animationPeriodms; private long animationStartTime; For example, an exploding barrel animation might be paused on the homeFrame (say first frame) until playback is started
9
The update() method determines the current frame that should be displayed in the animation. In turn the draw() method simply draws the current frame. public void update() { determineCurrentFrame(); } public void draw(Graphics2D graphics2D, int drawX, int drawY) { graphics2D.drawImage( images[currentFrame], drawX, drawY, null);
10
private int determineCurrentFrame() {
long currentTime = GetCurrentTime(); if (animinationStartTime == -1) animinationStartTime = currentTime; if (playCount > 0) { if (currentTime - animinationStartTime > (long) playCount * animationPeriodms) { playCount = 0; } if (playCount == 0) { currentFrame = homeFrame; } else { long timeIntoAniminationPeriod = (currentTime – animinationStartTime) % animationPeriodms; currentFrame = (int) ( (timeIntoAniminationPeriod * (long)images.length ) / animationPeriodms ); return currentFrame; A check is made to see if the animation has completed, in which case the playCount is reset to zero. Based on the current time, target animation period and playCount value the current frame is calculated and returned. The start time will be reset to -1 anytime the play count is changed. Aside: This is a slightly different version of the ImageAssetSequence implementation – the later ensures that the end frame of the animation is always drawn at least once.
11
In-Game Fonts Displaying textual information within games
12
The expense of drawing a font…
Early fonts were bitmap based. Most modern fonts (e.g. TrueType) are outline based, providing a set of line and curve equations describing the shape of each ‘glyph’ (character). When drawing a font, the outline is rendered and then filled by an ink colour. Generating text by doing this times per second is needlessly expensive. How can we improve performance? Render text once into a bitmap and use bitmap until text changes Revert to using a bitmap font
13
In-game fonts (using Java)
Load an image asset sequence holding the bitmap font characters. Create a base TextElement, holding the image sequence and a corresponding text-to- image mapping. Use the base TextElement to create text strings that can be drawn. TextElement guiText = new TextElement(this, (ImageAssetSequence) assetManager.retrieveAsset( "GUIFont" ), 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ“ "abcdefghijklmnopqrstuvwxyz" + ", ""); TextElement someText = guiText.getMatchingElement(“Hello!"); someText.draw(graphics2D, x, y);
14
In-game fonts (using XNA)
Specify and add a SpriteFont content asset (the SpriteFont converts any installed TrueType font into an XNB sprite sheet) Load in the SpriteFont within the game. Use the SpriteBatch. DrawString() method to render text. <Asset Type="Graphics:FontDescription"> <FontName>Courier New</FontName> <Size>10</Size> <Spacing>0</Spacing> <UseKerning>true</UseKerning> <Style>Regular</Style> SpriteFont spriteFont; SpriteBatch spriteBatch; spriteFont = content.Load<SpriteFont>("SpriteFont"); spriteBatch.Begin(); spriteBatch.DrawString( spriteFont, “Hello! ", position, Color.White); spriteBatch.End(); Aside: For more information on importing fonts, see:
15
Exercise: Using digit arrays
Assume you have a series of images representing the digits 0 to 9 stored in an array Develop an approach that will take a positive integer score and graphically illustrate it using the image sequence. ImageAsset[] digitImage = new ImageAsset[10]; Start 1 min 2 mins Finished 3 mins 30 sec 6 mins 9 mins 10 mins 8 mins 7 mins 5 mins 4 mins
16
Exercise: Using digit arrays
By using the modulus (%) operator the last digit in the score can be extracted and printed. Using integer division, the last digit can then be removed and the process iterated until no more digits remain. void drawScore( int targetScore ) { int scoreFragment = targetScore; do { int digit = scoreFragment % 10; digitImages[digit].Draw( ... ) scoreFragment = scoreFragment / 10; } while(scoreFragment > 9 ); } Aside: When drawing the images, it will be necessary to ensure the draw location of each image is determined. Additionally, the score will need to be drawn right-to-left.
17
Image Manipulation Basic forms of image transform
18
Consider game applicability
To do: Consider game applicability Basic forms of image transform A number of affine image transforms can be usefully employed within games, including: Resizing Rotating Fadding Flipping Depth of view effects Object rotation Appear / disappear effects Left / right / up / down sprite reuse
19
Image Transforms (Resizing)
For Java use: newWidth newHeight drawX, drawY newDrawX, newDrawY drawResizedImage( Graphics2D graphics2D, BufferedImage image, int drawX, int drawY, double scaleX, double scaleY ) { int newWidth = (int) (image.getWidth() * scaleX ); int newHeight = (int) (image.getHeight() * scaleY ); // Optional… if desired int newDrawX = drawX + image.getWidth()/2 - newWidth/2; int newDrawY = drawY + image.getHeight()/2 - newHeight/2; graphics2D.drawImage( image, newDrawX, newDrawY, newWidth, newHeight, null ); } For XNA use: The source texture will be scaled to fit the destination rectangle. SpriteBatch.Draw( Texture2D texture, Rectangle destinationRectangle, Color color )
20
Image Transforms (Rotation)
For Java use: drawRotatedImage( Graphics2D graphics2D, BufferedImage image, int drawX, int drawY, double rotationDeg ) { AffineTransform origAT = graphics2D.getTransform(); AffineTransform rotation = new AffineTransform(); rotation.rotate( Math.toRadians(rotationDeg), drawX + image.getWidth()/2, drawY + image.getHeight()/2 ); graphics2D.setTransform( rotation ); graphics2D.drawImage( image, drawX, drawY, null ); graphics2D.setTransform(origAT); } drawX, drawY For XNA use: SpriteBatch.Draw( Texture2D texture, Rectangle destinationRectangle, Nullable<Rectangle> sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth ) The source texture will be rotated around the specified origin
21
Image Transforms (Fading)
drawX, drawY Image Transforms (Fading) For Java use: drawFadedImage( Graphics2D graphics2D, BufferedImage image, int drawX, int drawY, float alpha ) { Composite origComposite = graphics2D.getComposite(); graphics2D.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha) ); graphics2d.drawImage( image, drawX, drawY, null); graphics2D.setComposite( origComposite ); } drawX, drawY For XNA use: Specify a colour with an alpha component < 256, e.g. for 50% fading new Color( ???, ???, ???, 128 ); SpriteBatch.Draw( Texture2D texture, Rectangle destinationRectangle, Color color )
22
Image Transforms (Flipping)
For Java use: drawX, drawY drawHorizFlip(Graphics2D graphics2D, BufferedImage image, int drawX, int drawY ) { int width = image.getWidth(); int height = image.getHeight(); graphics2d.drawImage( image, drawX, drawY+height, drawX+width, drawY, 0, 0, width, height, null); } drawImage( Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver obs) For XNA use: SpriteBatch.Draw( Texture2D texture, Rectangle destinationRectangle, Nullable<Rectangle> sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth ) SpriteEffects includes FlipVertically and FlipHorizontally
23
To do: Summary Today we explored:
The basics behind image sequence playback How in-game fonts can be efficiently rendered Some useful image transforms To do: Continue to explore image repository and select graphics Think about the types of image animation/transform and font usage in your game. Write code snippets to load / display and animate / transform images
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.