A Flash Developer Resource Site

Results 1 to 5 of 5

Thread: Advanced TextField Class

  1. #1
    Zombie Coder EvilKris's Avatar
    Join Date
    Jun 2006
    Location
    Fukuoka, Japan.
    Posts
    796

    Advanced TextField Class

    Does anyone have in their posession or know of a free (AS3) class out there that does this:

    Basically writes to a textfield text within a movieclip frame like an old-style RPG (Final Fantasy VIII for example), meaning the text in the string wraps if there's too much text and the if the text fills the field dimensions it automatically stops and you can press a key or click the mouse to scroll down or clear+output the rest of the text.

    Optionally it might have the following-
    * outputs text typewriter style
    * allows for italics, bold, other colors, (ie html)

    Couldn't find anything while browsing through google. But I should imagine it's a pretty frequent request.
    ??

  2. #2
    Style Through Simplicity alillm's Avatar
    Join Date
    Mar 2004
    Location
    Wales
    Posts
    1,988
    I made something that did all of this except the different colours, formats etc for a game I was working on a while back. It was a rush job though and I dont think I still have it, but it didn't take me an hour to get it working, it shouldnt be that difficult to get your own class working.

    Ali

  3. #3
    Pencil Farmer cadin's Avatar
    Join Date
    Jul 2006
    Location
    Vancouver BC
    Posts
    323
    I made something like this recently too.
    Unfortunately I'm a crappy programmer, so it's very tightly coupled with the rest of my game, so I can't easily share it.

    The basics of it were pretty easy to figure out though.
    Start and ENTER_FRAME event that copies N characters from the current string into the text field. Listen for mouse events to either fill the text field if it's still typing on, or advance it to the next string if it's stopped.

  4. #4
    Funkalicious TOdorus's Avatar
    Join Date
    Nov 2006
    Location
    Nijmegen, Netherlands
    Posts
    697
    Story\Conversation.as
    Code:
    package Story 
    {
    	import flash.display.MovieClip;
    	import flash.text.TextField;
    	import Game.Battle;
    	import Renderer.Rendering;
    	import Tanks.Tank;
    	
    	/**
    	 * ...
    	 * @author DefaultUser (Tools -> Custom Arguments...)
    	 */
    	public class Conversation 
    	{
    		private var Screen:MovieClip
    		private var Render:Rendering
    		private var TheBattle:Battle
    		public var ConversGraph:MovieClip = new ConversationGraph()
    		public var Shouts:Array = []
    		private var FocusPoints:Array
    		public var Ended:Boolean = false
    		protected var ShoutNum:int = -1
    		protected var CharacterNum:int= 0
    		//
    		protected var CharPointTimerMax:int = 15
    		protected var CharTimerMax:int = 2
    		protected var CharTimer:int = 2
    		public var TimerMax:int = 50
    		protected var Timer:int = 150
    		private var CurrentShout:Shout
    		public var Tekst:TextField
    		public var AvatarGraph:MovieClip
    		//
    		public function Conversation(SCREEN:MovieClip, RENDER:Rendering, BATTLE:Battle, SHOUTS:Array,TEXTSPEED:int,PAUZE:int,FOCUSPOINTS:Array) 
    		{
    			Screen = SCREEN
    			Render = RENDER
    			TheBattle = BATTLE
    			Shouts = SHOUTS
    			FocusPoints = FOCUSPOINTS
    			//
    			ConversGraph.x = 6.6
    			ConversGraph.y = 348.4
    			Tekst = ConversGraph.TEKST
    			AvatarGraph = ConversGraph.AVATARS
    			CharTimerMax = 4 - TEXTSPEED
    			CharTimer = CharTimerMax
    			CharPointTimerMax = 12 * CharTimerMax
    			TimerMax = PAUZE
    			Timer = TimerMax
    		}
    		//
    		public function startConversation() {
    			Tekst.text = ""
    			CharacterNum = 0
    			CharTimer = 0
    			Timer = TimerMax//+(CurrentShout.Text.length*4)
    			//
    			updateShout()
    			Screen.addChild(ConversGraph)			
    		}
    		public function endConversation() {
    			if(Screen.contains(ConversGraph)){
    				Screen.removeChild(ConversGraph)
    			}
    			//
    			if(!TheBattle.Won){
    				var ScreenWhalf:Number = 0.5*Render.ScreenWidth
    				var ScreenHhalf:Number = 0.5*Render.ScreenHeigh
    				var TheTank:Tank = TheBattle.Team1[0]
    				Render.ScreenX = TheTank.X - ScreenWhalf
    				Render.ScreenY = TheTank.Y - ScreenHhalf
    			}
    		}
    		//
    		public function updateConversation() {
    			if (Tekst.length < CurrentShout.Text.length){
    				updateTekst()
    			} else {
    				//Text is run, check if pauze between shouts is done
    				if (Timer < 1) {
    					updateShout()
    				} else {
    					Timer--
    				}
    			}
    			
    		}
    		public function skip() {
    			if (Tekst.length < CurrentShout.Text.length) {
    				Tekst.text = CurrentShout.Text
    			} else {
    				updateShout()
    			}
    		}
    		protected function updateShout() {
    			ShoutNum++
    			if (ShoutNum >= Shouts.length) {
    				endConversation()
    				Ended = true
    			} else {
    				CurrentShout = Shouts[ShoutNum]
    				AvatarGraph.gotoAndStop(CurrentShout.Avatar)
    				focus()
    				//Reset
    				Tekst.text = ""
    				CharacterNum = 0
    				CharTimer = 0
    				Timer = TimerMax
    				/*
    				if (ShoutNum == Shouts.length - 1) {
    					Timer = TimerMax * 5
    				} else {
    					Timer = TimerMax//+(CurrentShout.Text.length*2)
    				}
    				*/
    			}
    		}
    		protected function updateTekst() {
    			if(CharTimer<1){
    				Tekst.appendText(CurrentShout.Text.charAt(CharacterNum))
    				Tekst.scrollV = Tekst.maxScrollV
    				//
    				if (CurrentShout.Text.charAt(CharacterNum) == "." || CurrentShout.Text.charAt(CharacterNum) == "!" || CurrentShout.Text.charAt(CharacterNum) == "?") {
    					CharTimer = CharPointTimerMax
    				} else {
    					CharTimer = CharTimerMax
    				}
    				CharacterNum++
    			} else {
    				CharTimer--
    			}
    		}
    		protected function focus():void {
    			var ScreenWhalf:Number = 0.5*Render.ScreenWidth
    			var ScreenHhalf:Number = 0.5*Render.ScreenHeigh
    			if (CurrentShout.FocusPointTeam > 0) {
    				var TheTank:Tank = TheBattle["Team"+CurrentShout.FocusPointTeam][CurrentShout.FocusPoint]
    				Render.ScreenX = TheTank.X - ScreenWhalf
    				Render.ScreenY = TheTank.Y - ScreenHhalf
    			} else if(CurrentShout.FocusPointTeam == 0) {
    				Render.ScreenX = FocusPoints[CurrentShout.FocusPoint].x - ScreenWhalf
    				Render.ScreenY = FocusPoints[CurrentShout.FocusPoint].y - ScreenHhalf
    			}
    			TheBattle.updateRender(false)
    		}
    		public function setBattle(BATTLE:Battle):void {
    			TheBattle = BATTLE
    		}
    	}
    	
    }
    You may rewrite some stuff, as Render is a singleton blitting class, a battle a singleton which handles all the character objects and focuspoints is meant to focus the camera on a certain character/position. You might want to extend the focus method, to do stuff like: spawn enemies/allies and stuff like that.

    Story\Shout.as
    Code:
    package Story 
    {
    	import flash.display.MovieClip;
    	
    	/**
    	 * ...
    	 * @author DefaultUser (Tools -> Custom Arguments...)
    	 */
    	public class Shout 
    	{
    		public var Avatar:String
    		public var Text:String
    		public var FocusPointTeam:int
    		public var FocusPoint:int
    		public function Shout(AVATAR:String, TEXT:String, FOCUSPOINTTEAM:int, FOCUSPOINT:int)
    		{
    			Avatar = AVATAR
    			Text = TEXT
    			FocusPoint = FOCUSPOINT
    			FocusPointTeam = FOCUSPOINTTEAM
    		}
    		
    	}
    	
    }
    I dubbed the stuff characters say Shouts. A converstation is a series of shouts. If a shout contains more text then the textfield can contain it scrolls down with the text. If a shout is finished it sets the timer, so it takes a while before it advances to the next shout. It updates a textfield in the screen movieclip and sets a movieclip inside the movieclip to the corresponding frame (to show who is talking, or an animation of what is happening during the text).

    I don't feel like rewriting it to the basics myself, but I don't think removing Render, Battle and Focus from the class is that hard. The skip function doesn't make the conversation wait for another skip, but sets a timer before it advances to another shout (quite like a shout has finished). I believe this is somewhat unusual for rpg's.

    If you got any questions: fire away.

  5. #5
    Zombie Coder EvilKris's Avatar
    Join Date
    Jun 2006
    Location
    Fukuoka, Japan.
    Posts
    796
    Ok thanks for the hints guys. TOdorus that class is great, I will definitely analyse and make use of it.
    Thanks so much.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center