
>> 前往貼圖購買頁
推薦一下,這組貼圖完全是用procreate在iPad2上繪製完成,十分好用。
>> http://procreate.si/
Flash, Actionscript, Animation, Game, Multimedia, User Interface,Mobile...
void Start () { gameObject.AddComponent<LWFObject>(); LWFObject _lwfObj = gameObject.GetComponent<LWFObject>(); _lwfObj.Load("test.swf/test","test.swf/");//.bytes文字檔的路徑及存放素材圖檔的路徑 LWF.Movie _movie = _lwfObj.lwf.rootMovie.AttachMovie("linkage_id","instance_id"); }
fscommand("event", "sendMessage");
//在LWFObject裏 SetEventHandler("sendMessage", (movie, button) => { // doSomeThing });
Futile.atlasManager.LoadAtlas("Atlases/textures"); Futile.atlasManager.LoadFont("ImpactFont","ImpactFont.png","Atlases/ImpactFont"); //使用圖形時: _background = new FSprite("background.png"); //使用字型時: _label = new FLabel("ImpactFont","Tap the BaoZi to Start!!");
//Button用法 _myBtn = new FButton("原本的圖.png", "壓下去的圖.png ", "音效名"); //event是用+的方式偵聽 _myBtn.SignalRelease += onTapFunction; private void onTapFunction(FButton obj){ Main.instance.gotoTitle(); } //Label _myLabel = new FLabel("字型名稱","文字內文"); _myLabel.text = "改字的內容" //Label本身沒有width, height,要用textRect Debug.Log(_myLabel.textRect.width) Debug.Log(_myLabel.textRect.height)
//要先加入MultiTouch的介面 public class PageGame : FContainer, FMultiTouchableInterface { override public void HandleAddedToStage(){ //啟用 Futile.touchManager.AddMultiTouchTarget(this); base.HandleAddedToStage(); } override public void HandleRemovedFromStage(){ //停用 Futile.touchManager.RemoveMultiTouchTarget(this); base.HandleRemovedFromStage(); } //touches包含了目前所有動作中的點的資訊 public void HandleMultiTouch(FTouch[] touches){ foreach(FTouch _touch in touches){ if(_touch.phase == TouchPhase.Began){ //do something } } } }
//把某個function加入到Futile系統的Update事件中,效果類似於Flash的EnterFrame Futile.instance.SignalUpdate += myFunction; private void myFunction () { //do something } //取消就用減的 Futile.instance.SignalUpdate -= myFunction; //加入跟移出場景時的事件,名稱及效果都與Flash的類似,FSprite, FContainer, FButton這些都有這個事件 override public void HandleAddedToStage(){ } override public void HandleRemovedFromStage(){ }
//基本用法,寫法跟TweenLite很像 Go.to( someTransform, 4f, new GoTweenConfig().position( new Vector3( 10, 10, 10 ) ) ); //由於GoKit不是只設計給Futile用的,而是設計給Unity用的,所以上一行會用3d的座標 //在Futile裏用的話,可以這樣寫 Go.to( instanceOfMyClass, 3f, new TweenConfig().floatProp("scale",scaleTarget*0.25f) ); //同時要變多個屬性的話,可以一直接在後面: Go.to( instanceOfMyClass, 3f, new TweenConfig().floatProp("scale",scaleTarget*0.25f).floatProp("y",100) ); //也可以用TweenChain一次設定一整串Tween var tween1 = new Tween(this, 0.1f, new TweenConfig().floatProp("scaleY",scaleTarget*0.3f).floatProp("scaleX",scaleTarget*1.4f).floatProp("y",_yTarget)); var tween2 = new Tween(this, 0.1f, new TweenConfig().floatProp("scaleY",scaleTarget*1.4f).floatProp("scaleX",scaleTarget*0.3f).floatProp("y",_yTarget + height)); var tween3 = new Tween(this, 0.1f, new TweenConfig().floatProp("scale",scaleTarget*0.25f).floatProp("y",_yTarget)); var chain = new TweenChain(); chain.append(tween1).append(tween2).append(tween3); chain.setOnCompleteHandler(C=>{ //do something } ); chain.play();其他更詳細的用法,請自己上官網去看。
using UnityEngine; using System.Collections; public class Main : MonoBehaviour { private FContainer _currentPage; public static Main instance; // Use this for initialization void Start () { instance = this; FutileParams futileParams = new FutileParams (true,true,false,false); futileParams.AddResolutionLevel(960,1,1,""); futileParams.origin = new Vector2(0.5f,0.5f); Futile.instance.Init(futileParams); Futile.atlasManager.LoadAtlas("Atlases/textures"); Futile.atlasManager.LoadFont("ImpactFont","ImpactFont.png","Atlases/ImpactFont"); //FSprite _bg = new FSprite("background.png"); //Futile.stage.AddChild(_bg); gotoTitle(); } public void gotoTitle(){ if(_currentPage != null)_currentPage.RemoveFromContainer(); _currentPage = new PageTitle(); Futile.stage.AddChild(_currentPage); } public void gotoGame(){ if(_currentPage != null)_currentPage.RemoveFromContainer(); _currentPage = new PageGame(); Futile.stage.AddChild(_currentPage); } // Update is called once per frame void Update () { } }
using UnityEngine; using System.Collections; public class PageTitle : FContainer, FSingleTouchableInterface { private FSprite _background; private FSprite _mainLogo; private FLabel _label; public PageTitle(){ _background = new FSprite("background.png"); AddChild(_background); _mainLogo = new FSprite("mainLogo.png"); AddChild(_mainLogo); _label = new FLabel("ImpactFont","Tap the BaoZi to Start!!"); _label.color = Color.white; _label.y = -260; _label.scale = 2; AddChild(_label); doBreath(); doShake (); FContainer _test = new FContainer (); AddChild (_test); //var bb = new FButton( //bb.SignalRelease += onRelease; } override public void HandleAddedToStage(){ Futile.touchManager.AddSingleTouchTarget(this); base.HandleAddedToStage(); } override public void HandleRemovedFromStage(){ Futile.touchManager.RemoveSingleTouchTarget(this); base.HandleRemovedFromStage(); } public bool HandleSingleTouchBegan(FTouch touch) { //Debug.Log("Touch"); return true; } public void HandleSingleTouchMoved(FTouch touch) { //Debug.Log("Move"); } public void HandleSingleTouchEnded(FTouch touch) { //Debug.Log("Ended"); Vector2 pos = _mainLogo.GlobalToLocal(touch.position); if(_mainLogo.textureRect.Contains(pos)){ //Debug.Log("Oh"); Main.instance.gotoGame(); } } public void HandleSingleTouchCanceled(FTouch touch) { //Debug.Log("Canceled"); } private void doBreath(){ //Debug.Log("doBreath"); var tween1 = new Tween(_mainLogo, 2.5f, new TweenConfig().floatProp("scale",1.05f).setEaseType(EaseType.QuadInOut)); var tween2 = new Tween(_mainLogo, 2.5f, new TweenConfig().floatProp("scale",1).setEaseType(EaseType.QuadInOut)); var chain = new TweenChain(); chain.append(tween1).append(tween2); chain.setOnCompleteHandler(C=>{ doBreath(); } ); chain.play(); } private void doShake () { //Debug.Log("doShake"); var r = RXRandom.Float()*16 - 8; var tween1 = new Tween(_mainLogo, 0.05f, new TweenConfig().floatProp("rotation",r).setEaseType(EaseType.BackOut)); var tween2 = new Tween(_mainLogo, 0.1f, new TweenConfig().floatProp("rotation",-r).setEaseType(EaseType.BackOut)); var tween3 = new Tween(_mainLogo, 0.1f, new TweenConfig().floatProp("rotation",r).setEaseType(EaseType.BackOut)); var tween4 = new Tween(_mainLogo, 0.1f, new TweenConfig().floatProp("rotation",-r).setEaseType(EaseType.BackOut)); var tween5 = new Tween(_mainLogo, 0.05f, new TweenConfig().floatProp("rotation",0).setEaseType(EaseType.BackOut)); var chain = new TweenChain(); chain.appendDelay(RXRandom.Float()*5+3).append( tween1).append(tween2).append(tween3).append(tween4).append(tween5); chain.setOnCompleteHandler(C=>{ doShake(); } ); chain.play(); } // Update is called once per frame void Update () { } }
using UnityEngine; using System.Collections; using System.Collections.Generic; public class PageGame : FContainer, FMultiTouchableInterface { private FSprite _background; private FButton _exitBtn; private int _frameCount; private int _createBaoziTime; private int _baoziMaxCount; private int _liveTimeLimit; private FContainer _baozisContainer; private FContainer _baozisCrushContainer; private List_baoziList; private FLabel _scoreLabel; private FLabel _lifeLabel; private FLabel _overLabel; private int _score; private int _life ; private bool _isPlaying; //private List // Use this for initialization public PageGame () { //Debug.Log("OOOKKK"); _background = new FSprite("background.png"); AddChild(_background); init(); } private void setDiffcult(){ if(_score < 10){ _createBaoziTime = 45; _baoziMaxCount = 5; _liveTimeLimit = 300; }else if(_score < 30 && _score >=10){ _createBaoziTime = 40; _baoziMaxCount = 10; _liveTimeLimit = 250; }else if(_score < 70 && _score >=30){ _createBaoziTime = 30; _baoziMaxCount = 15; _liveTimeLimit = 250; }else if(_score < 100 && _score >=70){ _createBaoziTime = 25; _baoziMaxCount = 20; _liveTimeLimit = 200; }else if(_score >=100){ _createBaoziTime = 20; _baoziMaxCount = 25; _liveTimeLimit = 150; } } private void init(){ _baoziList = new List (); _baozisContainer = new FContainer(); AddChild(_baozisContainer); _baozisCrushContainer = new FContainer(); AddChild(_baozisCrushContainer); _scoreLabel = new FLabel("ImpactFont","SCORE: 000"); _scoreLabel.y = Futile.screen.halfHeight-32; _scoreLabel.scale = 2; _scoreLabel.x = -Futile.screen.halfWidth+_scoreLabel.textRect.width; AddChild(_scoreLabel); _lifeLabel = new FLabel("ImpactFont","LIFE: 010"); _lifeLabel.y = Futile.screen.halfHeight-32; _lifeLabel.scale = 2; _lifeLabel.x = Futile.screen.halfWidth-_lifeLabel.textRect.width; AddChild(_lifeLabel); _overLabel = new FLabel("ImpactFont","GAME OVER"); _overLabel.scale = 5; AddChild(_overLabel); _exitBtn = new FButton("exit.png"); AddChild(_exitBtn); _exitBtn.SignalRelease += onClickExit; _exitBtn.x = Futile.screen.halfWidth-_exitBtn.sprite.width/2 -8; _exitBtn.y = -Futile.screen.halfHeight + _exitBtn.sprite.height/2 + 8; } private void onClickExit(FButton obj){ Main.instance.gotoTitle(); } override public void HandleAddedToStage(){ _frameCount = 0; _score = 0; setDiffcult(); _life = 10; _isPlaying = true; _overLabel.isVisible = false; Futile.instance.SignalUpdate += signalUpdate; Futile.touchManager.AddMultiTouchTarget(this); base.HandleAddedToStage(); } override public void HandleRemovedFromStage(){ Futile.instance.SignalUpdate -= signalUpdate; Futile.touchManager.RemoveMultiTouchTarget(this); base.HandleRemovedFromStage(); } private void addScore(){ _score ++; setDiffcult(); string _str = _score.ToString(); while(_str.Length < 3){ _str = "0"+_str; } _scoreLabel.text = "SCORE: "+_str; } public void HandleMultiTouch(FTouch[] touches){ if(!_isPlaying)return; foreach(FTouch _touch in touches){ if(_touch.phase == TouchPhase.Began){ for(int i = _baoziList.Count -1; i>=0; i--){ Baozi _baozi = _baoziList[i]; Vector2 _touchPos = _baozi.GlobalToLocal(_touch.position); if(_baozi.textureRect.Contains(_touchPos)){ crushBaozi(_baozi); addScore(); break; } } } } } private void decLife(){ _life --; string _str = _life.ToString(); while(_str.Length < 3){ _str = "0"+_str; } _lifeLabel.text = "LIFE: "+_str; if(_life<=0){ gameOver(); } } private void gameOver(){ _overLabel.isVisible = true; _isPlaying = false; } // Update is called once per frame private void signalUpdate () { if(!_isPlaying)return; if(_frameCount % _createBaoziTime ==0 && _baoziList.Count<_baoziMaxCount){ createBaozi(); } _frameCount++; for(int i = _baoziList.Count -1; i>=0; i--){ Baozi _baozi = _baoziList[i]; _baozi.liveTime ++; if(_baozi.liveTime >= _liveTimeLimit){ _baoziList.Remove(_baozi); _baozi.doHiding(); decLife (); //_baozi.RemoveFromContainer(); } //Vector2 _touchPos = _baozi.GlobalToLocal(_touch.position); //if(_baozi.textureRect.Contains(_touchPos)){ //crushBaozi(_baozi); //break; //} } } private void crushBaozi(Baozi _baozi){ BaoziCrush _baoziCrush = new BaoziCrush(); //_baoziCrush.scale = _baozi.scale; _baoziCrush.x = _baozi.x; _baoziCrush.y = _baozi.y-_baozi.height*0.3f; _baoziCrush.setCrush(_baozi.scaleTarget); _baozisCrushContainer.AddChild(_baoziCrush); _baoziList.Remove(_baozi); _baozi.RemoveFromContainer(); } private void createBaozi(){ Baozi _baozi = new Baozi(); //_baozi.x = RXRandom.Range(-Futile.screen.halfWidth,Futile.screen.halfWidth); //_baozi.y = RXRandom.Range(-Futile.screen.halfHeight,Futile.screen.halfHeight); _baozisContainer.AddChild(_baozi); _baozi.doIntro(); _baoziList.Add(_baozi); } }
using UnityEngine; using System.Collections; public class Baozi : FSprite { public float scaleTarget; public int liveTime; private float _yTarget; // Use this for initialization public Baozi():base ("baozi.png"){ x = RXRandom.Range(-Futile.screen.halfWidth + width/2,Futile.screen.halfWidth - width/2); _yTarget = y = RXRandom.Range(-Futile.screen.halfHeight + 100,Futile.screen.halfHeight - height/2-32); scaleTarget = scale = (1-(_yTarget+Futile.screen.halfHeight)/Futile.screen.height) + 0.3f; //scaleTarget = scale = RXRandom.Float()*0.5f + 0.5f; } public void doIntro(){ //_scaleTarget *=1.05f; this.scale = scaleTarget*0.25f; var tween1 = new Tween(this, 0.1f, new TweenConfig().floatProp("scaleY",scaleTarget*1.2f).floatProp("y",_yTarget + height*2)); var tween2 = new Tween(this, 0.1f, new TweenConfig().floatProp("scaleY",scaleTarget*0.3f).floatProp("scaleX",scaleTarget*1.4f).floatProp("y",_yTarget)); var tween3 = new Tween(this, 0.1f, new TweenConfig().floatProp("scale",scaleTarget).setEaseType(EaseType.BackOut)); var chain = new TweenChain(); chain.append(tween1).append(tween2).append(tween3); chain.setOnCompleteHandler(C=>{ liveTime = 0; } ); chain.play(); } public void doHiding(){ var tween1 = new Tween(this, 0.1f, new TweenConfig().floatProp("scaleY",scaleTarget*0.3f).floatProp("scaleX",scaleTarget*1.4f).floatProp("y",_yTarget)); var tween2 = new Tween(this, 0.1f, new TweenConfig().floatProp("scaleY",scaleTarget*1.4f).floatProp("scaleX",scaleTarget*0.3f).floatProp("y",_yTarget + height)); var tween3 = new Tween(this, 0.1f, new TweenConfig().floatProp("scale",scaleTarget*0.25f).floatProp("y",_yTarget)); var chain = new TweenChain(); chain.append(tween1).append(tween2).append(tween3); chain.setOnCompleteHandler(C=>{ this.RemoveFromContainer(); } ); chain.play(); } // Update is called once per frame void Update () { } }
using UnityEngine; using System.Collections; public class BaoziCrush : FSprite { // Use this for initialization public BaoziCrush():base ("baoziCrush.png"){ //scale = RXRandom.Float()*0.5f + 0.5f; //x = RXRandom.Range(-Futile.screen.halfWidth + width/2,Futile.screen.halfWidth - width/2); //y = RXRandom.Range(-Futile.screen.halfHeight + 100,Futile.screen.halfHeight - height/2); } public void setCrush(float _scaleTarget){ _scaleTarget *=1.05f; this.scale = _scaleTarget/2; var tween1 = new Tween(this, 0.1f, new TweenConfig().floatProp("scale",_scaleTarget).setEaseType(EaseType.BackOut)); var tween2 = new Tween(this, 1.0f, new TweenConfig().floatProp("alpha",0f).setEaseType(EaseType.QuadInOut)); var chain = new TweenChain(); chain.append(tween1).append(tween2); chain.setOnCompleteHandler(C=>{ this.RemoveFromContainer(); //Debug.Log("Killed"); } ); chain.play(); } //private void destory(){ // this.RemoveFromContainer(); //} // Update is called once per frame void Update () { } }
using UnityEngine; using System.Collections; public class MyGame : MonoBehaviour { // Use this for initialization void Start () { FutileParams futileParams = new FutileParams(true,true,true,true); futileParams.AddResolutionLevel(480,1,1,""); Futile.instance.Init(futileParams); Futile.atlasManager.LoadImage("baozi"); FSprite mySprite = new FSprite("baozi"); Futile.stage.AddChild(mySprite); } // Update is called once per frame void Update () { } }
using UnityEngine; using System.Collections; public class MyGame : MonoBehaviour { private FSprite _mySprite; // Use this for initialization void Start () { FutileParams futileParams = new FutileParams(true,true,true,true); futileParams.AddResolutionLevel(480,1,1,""); Futile.instance.Init(futileParams); Futile.atlasManager.LoadImage("baozi"); _mySprite = new FSprite("baozi"); Futile.stage.AddChild(_mySprite); } // Update is called once per frame void Update () { _mySprite.rotation ++; } }
var monster1:SpriterMC = SpriterMCFactory.createSpriterMC("monster", "xml/monster.scml"); monster1.play(); //Note: SpriterMC's will not actually start playing or show up on stage until SpriterMC.SPRITER_MC_READY is broadcast //Add each SpriterMC to a Juggler, just like a regular Starling MovieClip myJuggler.add(monster1);但他們另外提供了事先做好TextureAtlas的做法,並且推薦用這種:
var monster1:SpriterMC = SpriterMCFactory.createSpriterMC("monster", "xml/monster.scml", _textureAtlas); monster1.playbackSpeed = 1.5; //Demonstrating playbackSpeed, which is like Scale, 1 == 100%. You can also set negative values to play backward monster1.play(); //Note: SpriterMC's will not actually start playing or show up on stage until SpriterMC.SPRITER_MC_READY is broadcast //Add each SpriterMC to a Juggler, just like a regular Starling MovieClip myJuggler.add(monster1);但我個人測試結果是,你必需使用TextureAtlas的寫法,否則使用第一種的話,執行時會出現error。
protected function init():void{ loadTexture('assets/heroTA.png') } private function loadTexture(_url:String):void { var _loader:Loader = new Loader(); _loader.contentLoaderInfo.addEventListener(starling.events.Event.COMPLETE, textureLoadedHandler); _loader.load(new URLRequest(_url)); } private function textureLoadedHandler(e:*):void { _heroTexture = Texture.fromBitmap(Bitmap(e.target.loader.content)); loadTextureAtlasXML("assets/heroTA.xml"); } private function loadTextureAtlasXML(_url:String):void { var _urlLoader:URLLoader = new URLLoader(new URLRequest(_url)); _urlLoader.addEventListener(starling.events.Event.COMPLETE, atlasXMLLoadedHandler); } private function atlasXMLLoadedHandler(e:*):void { var _xml:XML = XML(e.target.data); _textureAtlas = new TextureAtlas(_heroTexture, _xml); createCharacters(); } private function createCharacters():void { _hero = SpriterMCFactory.createSpriterMC("heroIK", "assets/heroIK/heroIK.scml",_textureAtlas,spriterReadyHandler,true); } private function spriterReadyHandler(e:starling.events.Event):void { _hero.x= 100 _hero.y=380 _hero.setAnimationByName('idle') _hero.play(); addChild(_hero); Starling.juggler.add(_hero) }
private function onClickJump(e:MouseEvent):void{ if(_hero.currentAnimation.name == 'jump')return; _hero.setAnimationByName('jump') _hero.loop=false; _hero.play() _hero.addEventListener(starling.events.Event.ENTER_FRAME,onEnterCheck); } protected function onEnterCheck(e:starling.events.Event):void{ if(_hero.isComplete){ _hero.removeEventListener(starling.events.Event.ENTER_FRAME,onEnterCheck); _hero.setAnimationByName('idle') _hero.loop=true; } }這邊我使用ENTER_FRAME不斷去check他的isComplete是否為true,如此才能知道他是不是播完了。而在使用isComplete時,有兩個注意事項:
internal function play():void { //if we aren't looping and play was called while the animation was on its last frame, restart it if (!_loop && _currentKeyIndex == _lastFrameIndex) { _currentTime = mainKeys[_firstFrameIndex].time; //this is gonna make currentTime 0 or the length of the animation, depending on which way the animation is playing _currentKeyIndex = _firstFrameIndex; } _animationEnded = false;//maso add _isPlaying = true; }修改過後就能正常執行了。
//**注意:SpriterAS是建立在Starling之上的,必需在Starling內 //**使用下列程式才能有作用。 protected var spLoader:SpriterLoader; protected function init():void{ spLoader = new SpriterLoader(); spLoader.completed.add(onSpriterLoadComplete); //SpriterLoader可一次載入多個scml檔,所以參數是填一個array,可代入多個scml位置 spLoader.load(['assets/hero/hero.scml'],1) } protected function onSpriterLoadComplete(spLoader:SpriterLoader):void { //從loader中取得動畫,以scml名稱為索引 hero = spLoader.getSpriterClip('hero') //idle是hero.scml裏其中一段animation的名稱 hero.play("idle") hero.x = 100 hero.y =300 addChild(hero) Starling.juggler.add(hero) }這裏需要注意一點是,spLoader必需是class內的固定成員,不可以是function中的區域變數,例如我試過以下這樣寫的話,onSpriterLoadComplete將無法被觸發:
protected function init():void{ var spLoader:SpriterLoader = new SpriterLoader();//不能用區域宣告 spLoader.completed.add(onSpriterLoadComplete); spLoader.load(['assets/hero/hero.scml'],1) }
private function onClickFight0(e:MouseEvent):void { hero.play("fight_0") hero.addCallback(onOverFight,400)//400ms後呼叫onOverFight } protected function onOverFight():void{ if(hero.animation.name != 'idle')hero.play("idle") }直接使用 play("animation名稱"),即可切換動畫。
addCallback(回call的function, 回call時間, 是否只執行一次)
private function onClickBlink(e:MouseEvent):void { hero.swapPiece("head_0", "head_1"); TweenLite.delayedCall(.1,hero.unswapPiece,['head_0']) }swapPiece("A", "B")可將動畫中的A圖換成B圖。
private function getHandPos():Point{ var handImg:Image //Starling中的Image handImg = hero.getImage("leftHand_0"); return new Point(handImg.x,handImg.y) }粒子效果非本篇重點,所以特效的部份就不多寫,上述程式只針對取得拳頭位置做示範,不過這邊要注意,取得的handImg.x及y後,記得還要加上hero.x及y,才是拳頭在畫面上看到的位置。
private function onClickDropHead(e:MouseEvent):void { var headImg:Image = hero.getImage("head_0") if(headImg.y>-100){//弱弱的用y的位置來判斷目前頭的狀況 hero.includePiece(headImg);//組回 return; } hero.excludePiece(headImg,true)//脫離 TweenLite.to(headImg,.6,{y:25,ease:Bounce.easeOut}) }
private function onSlideFPS(e:Event):void { _stage.frameRate = _fpsSlider.value } private function onSlideSpeed(e:Event):void { hero.playbackSpeed = _speedSlider.value }這邊就沒什麼好解說的了,playbackSpeed代1的話表示正常進度,2為兩倍,0.5為半速,以此類推。