DFdou's Blog Life is short,Be yourself.

208/100

Flash全屏的那些事儿

说正事儿前也许你想要了解下这个内容:《Flash全屏后无法输入》
现在Adobe对全屏稍微做了点修改,真的是一点点修改……
相关文章在这里:Limited full-screen keyboard input

部分摘录:

Flash Player 9 does not allow keyboard input when displaying content in full-screen mode.
Flash Player 10 changes this, allowing for a limited number of keys to be usable in full-screen mode. These include Tab, the Spacebar, and the (up, down, left, right) arrow keys.

在FP9里边全屏状态下Flash是不允许和键盘输入的,当然ESC键除外。
而FP10修改之后变成了受限的全屏模式,目前只支持Tab,空格,4个箭头进行交互……
So,你要想在全屏状态下获得键盘输入,在正常情况下市不可能的。
不过昨天有个大哥发了个可以全屏厚输入的swf,所以呢,还是可行的,只是。。小弟不才,破解之后的代码搞不懂呀么搞不懂~~

Tagged as: No Comments
2907/100

The Evolution of Adobe Flash: From 1996 to 2010

越来越懒,啥都不想写……抄袭一个Flash的进化史~~

From http://www.pxleyes.com/blog/2010/07/evolution-of-flash-from-1996-to-2010/

Adobe Flash is arguably the most popular multimedia platform today. Users can watch videos, chat, and play games thanks to the capabilities of the Flash player. Content creators are afforded almost unlimited power due to ActionScript 3′s powerful features.

Flash wasn’t always the rich and advanced platform it is today, however. It started as a vector animation package named FutureSplash Animator in 1996 and 14 years later, it’s going strong, with a desktop, mobile, and server-side presence.

FutureSplash Animator – 1996

FutureSplash Animator Splash Intro Screen
The first version of Flash, called FutureSplash Animator, was created by Jon Gay and Charlie Jackson, co-founders of FutureWave software. It was the animation extension of FutureWave’s SmartSketch, a vector drawing application. The first version of FutureSplash Animator was shipped in 1996 and a mere 7 months later, Macromedia bought FutureWave and renamed FutureSplash to simply Flash.
FutureSplash Animator Interface Screenshot

Tagged as: Continue reading
1207/100

16 Useful Mathematical Formulas In ActionScript 3

From http://ntt.cc/2010/07/06/16-useful-mathematical-formulas-in-actionscript-3.html

1. Distance Between Two Points

dx = x2 – x1;
dy = y2 – y1;
dist = Math.sqrt(dx*dx + dy*dy);

2. Inching Formulas

sprite.x += (targetX - sprite.x) * easing;//easing: inching coefficient
sprite.y += (targetY - sprite.y) * easing;

3. Elastic Formulas

 vx += (targetX - sprite.x) * spring; //spring: elastic coefficient
vy += (targetY - sprite.y) * spring;
sprite.x += (vx *= friction); //friction: friction force
sprite.y += (vy *= friction);

4. Flexible Partial Shifts Formulas

var dx:Number = sprite.x - fixedX;
var dy:Number = sprite.y - fixedY;
var angle:Number = Math.atan2(dy, dx);
var targetX:Number = fixedX + Math.cos(angle) * springLength;
var targetY:Number = fixedX + Math.sin(angle) * springLength;

5. Rotation With Mouse Formulas

dx = mouseX - sprite.x;
dy = mouseY - sprite.y;
sprite.rotation = Math.atan2(dy, dx) * 180 / Math.PI;

6. Waveform Formulas

public function onEnterFrame1(event:Event):void {
ball.y=centerScale+Math.sin(angle)*range;
angle+=speed;
}

7. Heartthrob Formulas

public function onEnterFrame1(event:Event):void {
ball.scaleX=centerScale+Math.sin(angle)*range;
ball.scaleY=centerScale+Math.sin(angle)*range;
angle+=speed;
}

8. Circle Rotation Formulas

public function onEnterFrame(event:Event):void {
ball.x=centerX+Math.cos(angle)*radius;
ball.y=centerY+Math.sin(angle)*radius;
angle+=speed;
}

9. Get Circle Area

public function getArea():Number
{
// The formula is Pi times the radius squared.
return Math.PI * Math.pow((width / 2), 2);
}

10. Get Circumference Ratio

public function getCircumference():Number
{
// The formula is Pi times the diameter.
return Math.PI * width;
}

11. Elliptic Rotation Formulas

public function onEnterFrame(event:Event):void {
ball.x=centerX+Math.cos(angle)*radiusX;
ball.y=centerY+Math.sin(angle)*radiusY;
angle+=speed;
}

12. Color operations

var t:uint=0×77ff8877
var s:uint=0xff000000
var h:uint=t&s
var m:uint=h>>>24
trace(m);

13. Hex to Decimal

trace(hexValue);

14. Decimal to Hex

decimalValue.toString(16);

15. Pick Up Color

red = color24 >> 16;
green = color24 >> 8 & 0xFF;
blue = color24 & 0xFF;
alpha = color32 >> 24;
red = color32 >> 16 & 0xFF;
green = color32 >> 8 & 0xFF;
blue = color232 & 0xFF;

16. Color Bit Arithmetic

color24 = red << 16 | green << 8 | blue;
color32 = alpha << 24 | red << 16 | green << 8 | blue;
Filed under: AIR+FB+AS3 No Comments
406/101

AS3-Water ripples

这是国外某友人在08年弄的一个东西,今天刚好在reader里看到,分享下吧:http://www.derschmale.com/2008/08/03/water-ripples-revisited-as3-only-version/

Demo:

Rippler.as:

/*
Copyright (c) 2008 NascomASLib Contributors.  See:

http://code.google.com/p/nascomaslib

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

package be.nascom.flash.graphics
{
    import flash.display.BitmapData;
    import flash.display.BitmapDataChannel;
    import flash.display.BlendMode;
    import flash.display.DisplayObject;
    import flash.events.Event;
    import flash.filters.ConvolutionFilter;
    import flash.filters.DisplacementMapFilter;
    import flash.geom.ColorTransform;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;

    /**
     *
     * The Rippler class creates an effect of rippling water on a source DisplayObject.
     *
     * @example The following code takes a DisplayObject on the stage and adds a ripple to it, assuming source is a DisplayObject already on the stage.
     *
     *     <listing version="3.0">
     *         import be.nascom.flash.graphics.Rippler;
     *
     *         // create a Rippler instance to impact source, with a strength of 60 and a scale of 6.
     *         // The source can be any DisplayObject on the stage, such as a Bitmap or MovieClip object.
     *         var rippler : Rippler = new Rippler(source, 60, 6);
     *
     *         // create a ripple with size 20 and alpha 1 with origin on position (200, 50)
     *         rippler.drawRipple(100, 50, 20, 1);
     * </listing>
     *
     * @author David Lenaerts
     * @mail david.lenaerts@nascom.be
     *
      */
    public class Rippler
    {
        // The DisplayObject which the ripples will affect.
        private var _source : DisplayObject;

        // Two buffers on which the ripple displacement image will be created, and swapped.
        // Depending on the scale parameter, this will be smaller than the source
        private var _buffer1 : BitmapData;
        private var _buffer2 : BitmapData;

        // The final bitmapdata containing the upscaled ripple image, to match the source DisplayObject
        private var _defData : BitmapData;

        // Rectangle and Point objects created once and reused for performance
        private var _fullRect : Rectangle;             // A buffer-sized Rectangle used to apply filters to the buffer
        private var _drawRect : Rectangle;            // A Rectangle used when drawing a ripple
        private var _origin : Point = new Point();    // A Point object to (0, 0) used for the DisplacementMapFilter as well as for filters on the buffer

        // The DisplacementMapFilter applied to the source DisplayObject
        private var _filter : DisplacementMapFilter;
        // A filter causing the ripples to grow
        private var _expandFilter : ConvolutionFilter;

        // Creates a colour offset to 0x7f7f7f so there is no image offset due to the DisplacementMapFilter
        private var _colourTransform : ColorTransform;

        // Used to scale up the buffer to the final source DisplayObject's scale
        private var _matrix : Matrix;

        // We only need 1/scale, so we keep it here
        private var _scaleInv : Number;

        /**
         * Creates a Rippler instance.
         *
         * @param source The DisplayObject which the ripples will affect.
         * @param strength The strength of the ripple displacements.
         * @param scale The size of the ripples. In reality, the scale defines the size of the ripple displacement map (map.width = source.width/scale). Higher values are therefor also potentially faster.
         *
         */
        public function Rippler(source : DisplayObject, strength : Number, scale : Number = 2)
        {
            var correctedScaleX : Number;
            var correctedScaleY : Number;

            _source = source;
            _scaleInv = 1/scale;

            // create the (downscaled) buffers and final (upscaled) image data, sizes depend on scale
            _buffer1 = new BitmapData(source.width*_scaleInv, source.height*_scaleInv, false, 0x000000);
            _buffer2 = new BitmapData(_buffer1.width, _buffer1.height, false, 0x000000);
            _defData = new BitmapData(source.width, source.height, false, 0x7f7f7f);

            // Recalculate scale between the buffers and the final upscaled image to prevent roundoff errors.
            correctedScaleX = _defData.width/_buffer1.width;
            correctedScaleY = _defData.height/_buffer1.height;

            // Create reusable objects
            _fullRect = new Rectangle(0, 0, _buffer1.width, _buffer1.height);
            _drawRect = new Rectangle();

            // Create the DisplacementMapFilter and assign it to the source
            _filter = new DisplacementMapFilter(_defData, _origin, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE, strength, strength, "wrap");
            _source.filters = [_filter];

            // Create a frame-based loop to update the ripples
            _source.addEventListener(Event.ENTER_FRAME, handleEnterFrame);

            // Create the filter that causes the ripples to grow.
            // Depending on the colour of its neighbours, the pixel will be turned white
            _expandFilter = new ConvolutionFilter(3, 3, [0.5, 1, 0.5, 1, 0, 1, 0.5, 1, 0.5], 3);

            // Create the colour transformation based on
            _colourTransform = new ColorTransform(1, 1, 1, 1, 128, 128, 128);

            // Create the Matrix object
            _matrix = new Matrix(correctedScaleX, 0, 0, correctedScaleY);

        }

        /**
         * Initiates a ripple at a position of the source DisplayObject.
         *
         * @param x The horizontal coordinate of the ripple origin.
         * @param y The vertical coordinate of the ripple origin.
         * @param size The size of the ripple diameter on first impact.
         * @param alpha The alpha value of the ripple on first impact.
         */
        public function drawRipple(x : int, y : int, size : int, alpha : Number) : void
        {
            var half : int = size >> 1;        // We need half the size of the ripple
            var intensity : int = (alpha*0xff & 0xff)*alpha;    // The colour which will be drawn in the currently active buffer

            // calculate and draw the rectangle, having (x, y) in its centre
            _drawRect.x = (-half+x)*_scaleInv;
            _drawRect.y = (-half+y)*_scaleInv;
            _drawRect.width = _drawRect.height = size*_scaleInv;
            _buffer1.fillRect(_drawRect, intensity);
        }

           /**
            * Returns the actual ripple image.
            */
        public function getRippleImage() : BitmapData
        {
            return _defData;
        }

        /**
         * Removes all memory occupied by this instance. This method must be called before discarding an instance.
         */
        public function destroy() : void
        {
            _source.removeEventListener(Event.ENTER_FRAME, handleEnterFrame);
            _buffer1.dispose();
            _buffer2.dispose();
            _defData.dispose();
        }

        // the actual loop where the ripples are animated
        private function handleEnterFrame(event : Event) : void
        {
            // a temporary clone of buffer 2
            var temp : BitmapData = _buffer2.clone();
            // buffer2 will contain an expanded version of buffer1
            _buffer2.applyFilter(_buffer1, _fullRect, _origin, _expandFilter);
            // by substracting buffer2's old image, buffer2 will now be a ring
            _buffer2.draw(temp, null, null, BlendMode.SUBTRACT, null, false);
            // scale up and draw to the final displacement map, and apply it to the filter
            _defData.draw(_buffer2, _matrix, _colourTransform, null, null, true);
            _filter.mapBitmap = _defData;
            _source.filters = [_filter];
            temp.dispose();
            // switch buffers 1 and 2
            switchBuffers();
        }

        // switch buffer 1 and 2, so that
        private function switchBuffers() : void
        {
            var temp : BitmapData;
            temp = _buffer1;
            _buffer1 = _buffer2;
            _buffer2 = temp;
        }
    }
}
Filed under: AIR+FB+AS3, Demo 1 Comment
1305/108

AS3-LightOut

来个LightOut小游戏,至于LightOut是啥,可以看这里:http://en.wikipedia.org/wiki/Lights_Out_%28game%29
如果该页面被和谐,那可以看下@dfdou的简单介绍,LightOut是一个开/关游戏,游戏的目的很简单,在5x5的的方阵里,把全部的图换成亮着的状态就过关了,Demo里是白色方块代表亮起状态。
规则是点击一个方块,在方块4周的4个方块和方块本身的状态会发生改变,是亮起就变成关掉,是关掉就变成亮起~

Demo在这里:

下边来讲下代码部分,比较简单,3个类搞定。

405/102

AS3-Key Control Codes Define Class

先来看下这个:http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/ui/Keyboard.html
这里边是AIR里的键盘对应类,不过很奇怪的是有些STRING_F32 : String = "?"的格式
F32算是保留键,不过STRING_DOWNARROW : String = "?"这个就很奇怪了,这个是啥键,不是小键盘的向下键?

Flash就没这么好命了,你只能自己写键盘对应的键值,不过有好人把对应键整理了出来,原地址是在这里:http://ntt.cc/2010/05/03/flash-key-control-codes-define-class.html

Copy下:

package {
	public class KeyControlCode {
		public static  var KEY_BACKSPACE:uint=8;
		public static  var KEY_TAB:uint=9;
		public static  var KEY_ENTER:uint=13;
		public static  var KEY_SHIFT:uint=16;
		public static  var KEY_CONTROL:uint=17;
		public static  var KEY_PAUSE:uint=19;
		public static  var KEY_CAPSLOCK:uint=20;
		public static  var KEY_ESC:uint=27;
		public static  var KEY_SPACEBAR:uint=32;
		public static  var KEY_PAGEUP:uint=33;
		public static  var KEY_PAGEDOWN:uint=34;
		public static  var KEY_END:uint=35;
		public static  var KEY_HOME:uint=36;
		public static  var KEY_LEFT:uint=37;
		public static  var KEY_UP:uint=38;
		public static  var KEY_RIGHT:uint=39;
		public static  var KEY_DOWN:uint=40;
		public static  var KEY_INSERT:uint=45;
		public static  var KEY_DELETE:uint=46;
		public static  var KEY_0:uint=48;
		public static  var KEY_1:uint=49;
		public static  var KEY_2:uint=50;
		public static  var KEY_3:uint=51;
		public static  var KEY_4:uint=52;
		public static  var KEY_5:uint=53;
		public static  var KEY_6:uint=54;
		public static  var KEY_7:uint=55;
		public static  var KEY_8:uint=56;
		public static  var KEY_9:uint=57;
		public static  var KEY_A:uint=65;
		public static  var KEY_B:uint=66;
		public static  var KEY_C:uint=67;
		public static  var KEY_D:uint=68;
		public static  var KEY_E:uint=69;
		public static  var KEY_F:uint=70;
		public static  var KEY_G:uint=71;
		public static  var KEY_H:uint=72;
		public static  var KEY_I:uint=73;
		public static  var KEY_J:uint=74;
		public static  var KEY_K:uint=75;
		public static  var KEY_L:uint=76;
		public static  var KEY_M:uint=77;
		public static  var KEY_N:uint=78;
		public static  var KEY_O:uint=79;
		public static  var KEY_P:uint=80;
		public static  var KEY_Q:uint=81;
		public static  var KEY_R:uint=82;
		public static  var KEY_S:uint=83;
		public static  var KEY_T:uint=84;
		public static  var KEY_U:uint=85;
		public static  var KEY_V:uint=86;
		public static  var KEY_W:uint=87;
		public static  var KEY_X:uint=88;
		public static  var KEY_Y:uint=89;
		public static  var KEY_Z:uint=90;
		public static  var KEY_NUMPAD_0:uint=96;
		public static  var KEY_NUMPAD_1:uint=97;
		public static  var KEY_NUMPAD_2:uint=98;
		public static  var KEY_NUMPAD_3:uint=99;
		public static  var KEY_NUMPAD_4:uint=100;
		public static  var KEY_NUMPAD_5:uint=101;
		public static  var KEY_NUMPAD_6:uint=102;
		public static  var KEY_NUMPAD_7:uint=103;
		public static  var KEY_NUMPAD_8:uint=104;
		public static  var KEY_NUMPAD_9:uint=105;
		public static  var KEY_NUMPAD_MULTIPLY:uint=106;
		public static  var KEY_PLUS:uint=107;
		public static  var KEY_SUBTRACT:uint=109;
		public static  var KEY_DOT:uint=110;
		public static  var KEY_DIVISION:uint=111;
		public static  var KEY_F1:uint=112;
		public static  var KEY_F2:uint=113;
		public static  var KEY_F3:uint=114;
		public static  var KEY_F4:uint=115;
		public static  var KEY_F5:uint=116;
		public static  var KEY_F6:uint=117;
		public static  var KEY_F7:uint=118;
		public static  var KEY_F8:uint=119;
		public static  var KEY_F9:uint=120;
		public static  var KEY_F11:uint=122;
		public static  var KEY_F12:uint=123;
		public static  var KEY_F13:uint=124;
		public static  var KEY_F14:uint=125;
		public static  var KEY_F15:uint=126;
		public static  var KEY_NUMLOCK:uint=144;
		public static  var KEY_SCROLLLOCK:uint=145;
		public static  var KEY_SEMICOLON:uint=186;
		public static  var KEY_EQUAL:uint=187;
		public static  var KEY_COMMA:uint=188;
		public static  var KEY_MINUS:uint=189;
		public static  var KEY_PERIOD:uint=190;
		public static  var KEY_SLASH:uint=191;
		public static  var KEY_BACKQUOTE:uint=192;
		public static  var KEY_LEFTBRACKET:uint=219;
		public static  var KEY_BACKSLASH:uint=220;
		public static  var KEY_RIGHTBRACKET:uint=221;
		public static  var KEY_QUOTE:uint=222;
	}
}

用法很简单,以前需要记键值,现在就用这里的键名就好了~感谢整理出来的那哥们。

Tagged as: 2 Comments
2004/102

AS3-Sokoban推箱子-寻路扩展

恩,是寻路扩展,而不是自动求解~自动求解那个实在过于复杂,不考虑呀么不考虑。
先看demo:

依然是前几天的Sokoban,只不过修改了下地图数据,另外加了个点击寻路功能。
在要去的点上点一下鼠标,就会自动移过去了。
下边来说下具体实现。

1404/1011

AS3-Sokoban推箱子

先是Demo:

方向键控制移动,红色的方块是你~
UI嘛,就不说了,网上偷了点图,就这么放着了,有兴趣的可以弄弄呗。

Source code:https://dl.dropbox.com/u/477487/flash/game/sokoban.rar

PS:如果该地址被和谐,而你又想要源代码,联系我,服务很周到的~

推箱子的实现方法很多,各有各的做法,下边是我的实现方式:
Sokoban.as:

package {
	import flash.display.Sprite;
	import flash.events.Event;
	/**
	 * ...
	 * @author DFdou
	 */
	public class Sokoban extends Sprite {
		private var _lv = 0;
		private var _map:Map;

		public function Sokoban() {
			init();
		}
		private function init() {
			_map = new Map(_lv);
			addChild(_map);

			var role:Role = new Role(stage,_map,_lv);
			addChild(role);
		}

	}
}

文档类要干的事儿就是生成一个map,一个role。

104/101

Flash – Demo41

Demo:

部分Code:
AUIS.as

package org.nwhy.auis {
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.MouseEvent;

	public class AUIS extends Sprite {
		private var itemHolder:Sprite;

		public function AUIS() {
			init();
		}
		private function init() {
			initStage();
			initListeners();
			initItems();
		}
		private function initStage() {
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			stage.frameRate = 55;
		}
		private function initListeners() {
			stage.addEventListener(MouseEvent.MOUSE_DOWN, mClick);
		}
		private function initItems() {
			itemHolder = new Sprite();
			addChild(itemHolder);
			itemHolder.x = 150;
			itemHolder.y = 80;
			ItemFactory.createRandomItems(itemHolder,150);
		}
		private function mClick(e:MouseEvent) {
			var sp:Sprite = new Sprite();
			addChild(sp);
			sp.x = mouseX;
			sp.y = mouseY;
			//生成14个item
			ItemFactory.createClickEffectItems(sp);
		}
	}
}
3103/103

Android-一些关于代码优化的事儿

内容来自这里:http://www.madhome.org/read.php?tid=1769
直接引用了,唉,看来有不少细节要注意。

简介

对于占用资源的系统,有两条基本原则:不要做不必要的事 不要分配不必要的内存
所有下面的内容都遵照这两个原则。
有些人可能马上会跳出来,把本节的大部分内容归于“草率的优化”(参见[The Root of All Evil]),不可否认微优化(micro-optimization,代码优化,相对于结构优化)的确会带来很多问题,诸如无法使用更有效的数据结构和算法。但是在手持设备上,你别无选择。假如你认为Android虚拟机的性能与台式机相当,你的程序很有可能一开始就占用了系统的全部内存(内存很小),这会让你的程序慢得像蜗牛一样,更遑论做其他的操作了。
Android的成功依赖于你的程序提供的用户体验。而这种用户体验,部分依赖于你的程序是响应快速而灵活的,还是响应缓慢而僵化的。因为所有的程序都运行在同一个设备之上,都在一起,这就如果在同一条路上行驶的汽车。而这篇文档就相当于你在取得驾照之前必须要学习的交通规则。如果大家都按照这些规则去做,驾驶就会很顺畅,但是如果你不这样做,你可能会车毁人亡。这就是为什么这些原则十分重要。
当我们开门见山、直击主题之前,还必须要提醒大家一点:不管VM是否支持实时(JIT)编译器(它允许实时地将Java解释型程序自动编译成本机机器语言,以使程序执行的速度更快。有些 JVM包含JIT编译器。),下面提到的这些原则都是成立的。假如我们有目标完全相同的两个方法,在解释执行时foo()比bar()快,那么编译之后,foo()依然会比bar()快。所以不要寄希望于编译器可以拯救你的程序。

避免建立对象

世界上没有免费的对象。虽然GC为每个线程都建立了临时对象池,可以使创建对象的代价变得小一些,但是分配内存永远都比不分配内存的代价大。

如果你在用户界面循环中分配对象内存,就会引发周期性的垃圾回收,用户就会觉得界面像打嗝一样一顿一顿的。
所以,除非必要,应尽量避免尽力对象的实例。下面的例子将帮助你理解这条原则:
当你从用户输入的数据中截取一段字符串时,尽量使用substring函数取得原始数据的一个子串,而不是为子串另外建立一份拷贝。这样你就有一个新的String对象,它与原始数据共享一个char数组。 如果你有一个函数返回一个String对象,而你确切的知道这个字符串会被附加到一个StringBuffer,那么,请改变这个函数的参数和实现方式,直接把结果附加到StringBuffer中,而不要再建立一个短命的临时对象。

一个更极端的例子是,把多维数组分成多个一维数组。
int数组比Integer数组好,这也概括了一个基本事实,两个平行的int数组比 (int,int)对象数组性能要好很多。同理,这试用于所有基本类型的组合。 如果你想用一种容器存储(Foo,Bar)元组,尝试使用两个单独的Foo[]数组和Bar[]数组,一定比(Foo,Bar)数组效率更高。(也有例外的情况,就是当你建立一个API,让别人调用它的时候。这时候你要注重对API接口的设计而牺牲一点儿速度。当然在API的内部,你仍要尽可能的提高代码的效率)

总体来说,就是避免创建短命的临时对象。减少对象的创建就能减少垃圾收集,进而减少对用户体验的影响。

使用本地方法

当你在处理字串的时候,不要吝惜使用String.indexOf(), String.lastIndexOf()等特殊实现的方法(specialty methods)。这些方法都是使用C/C++实现的,比起Java循环快10到100倍。

使用实类比接口好

假设你有一个HashMap对象,你可以将它声明为HashMap或者Map:
Map myMap1 = new HashMap();
HashMap myMap2 = new HashMap();
哪个更好呢?
按照传统的观点Map会更好些,因为这样你可以改变他的具体实现类,只要这个类继承自Map接口。传统的观点对于传统的程序是正确的,但是它并不适合嵌入式系统。调用一个接口的引用会比调用实体类的引用多花费一倍的时间。
如果HashMap完全适合你的程序,那么使用Map就没有什么价值。如果有些地方你不能确定,先避免使用 Map,剩下的交给IDE提供的重构功能好了。(当然公共API是一个例外:一个好的API常常会牺牲一些性能)

用静态方法比虚方法好

如果你不需要访问一个对象的成员变量,那么请把方法声明成static。静态方法执行的更快,因为它可以被直接调用而不需要一个虚函数表。另外你也可以通过声明体现出这个函数的调用不会改变对象的状态。

不用getter和setter

在很多本地语言如C++中,都会使用getter(比如:i = getCount())来避免直接访问成员变量(i = mCount)。在C++中这是一个非常好的习惯,因为编译器能够内联访问,如果你需要约束或调试变量,你可以在任何时候添加代码。
在Android上,这就不是个好主意了。虚方法的开销比直接访问成员变量大得多。在通用的接口定义中,可以依照OO的方式定义getters和setters,但是在一般的类中,你应该直接访问变量。

将成员变量缓存到本地

访问成员变量比访问本地变量慢得多,下面一段代码:

for (int i = 0; i < this.mCount; i++)
dumpItem(this.mItems);

最好改成这样:

int count = this.mCount;
Item[] items = this.mItems;
for (int i = 0; i < count; i++)
dumpItems(items);

(使用”this”是为了表明这些是成员变量)
另一个相似的原则是:永远不要在for的第二个条件中调用任何方法。如下面方法所示,在每次循环的时候都会调用getCount()方法,这样做比你在一个int先把结果保存起来开销大很多。

for (int i = 0; i < this.getCount(); i++)
dumpItems(this.getItem(i));

同样如果你要多次访问一个变量,也最好先为它建立一个本地变量,例如:

protected void drawHorizontalScrollBar(Canvas canvas, int width, int height) {
if (isHorizontalScrollBarEnabled()) {
int size = mScrollBar.getSize(false);
if (size <= 0) {
size = mScrollBarSize;
}
mScrollBar.setBounds(0, height - size, width, height);
mScrollBar.setParams(
computeHorizontalScrollRange(),
computeHorizontalScrollOffset(),
computeHorizontalScrollExtent(), false);
mScrollBar.draw(canvas);
}
}

这里有4次访问成员变量mScrollBar,如果将它缓存到本地,4次成员变量访问就会变成4次效率更高的栈变量访问。
另外就是方法的参数与本地变量的效率相同。

2903/104

FP10-FileReference.save()

Flash Player10支持的一个API,10以下不支持,就别挣扎了~
Demo:

功能很简单,点击那个不太起眼的Download下载图片。
代码也十分的简单:

import com.adobe.images.JPGEncoder;

btn_download.addEventListener(MouseEvent.MOUSE_DOWN,download);
function download(e:MouseEvent){
	var bit:BitmapData = new BitmapData(505,460);
	bit.draw(bitmap);
	var file:FileReference = new  FileReference();
	var jpg:JPGEncoder = new JPGEncoder(100);
	file.save(jpg.encode(bit),"bitmap.jpg");
}

com.adobe是Adobe出的扩展类包,去下一个吧,挺好用的。
整个过程就是生成一个Bitmap,然后调用FileReference.save()保存到本地呗~

1803/103

AS3-Mapppp~的一个生成方案

最近的一个Android里碰到一个Map的应用,做了下这个东西,这个东西挺简单的,就是根据给出的数组生成一个Map。
Demo出来玩下先:

大小是800*500,想看全景的点这里呗:http://nwhy.org/nwhy/game/MapConvert.swf

整个实现过程很简单,MapConvert.as:

/*
VERSION: 1.0 DATE:2010/03/18
ACTIONSCRIPT VERSION: 3.0
AUTHOR: DFdou
Copyright 2009, http://nwhy.org. All rights reserved.
*/
package{
	import flash.display.Sprite;

	public class MapConvert extends Sprite{
		private var map:Map;
		private var mapID:uint;

		public function MapConvert(){
			mapID = 0;
			map = new Map(mapID);
			addChild(map);
		}
	}
}

文档类干的事灰常简单,传一个mapID生成一个Map,加到显示列表,就完事儿了。
Map.as:

/*
VERSION: 1.0 DATE:2010/03/18
ACTIONSCRIPT VERSION: 3.0
AUTHOR: DFdou
Copyright 2009, http://nwhy.org. All rights reserved.
*/
package{
	import flash.display.Sprite;

	public class Map extends Sprite{
		private var data:Array;

		public function Map(id:uint){
			data = MapData.MAP[id];
			var row:uint = data.length;
			for(var i:uint = 0;i<row;i++){
				var col:uint = data[i].length;
				for(var j:uint = 0;j<col;j++){
					if(data[i][j]!=0){
						var tile:Tile = new Tile();
						tile.gotoAndStop(data[i][j]);
						tile.x = j * 50;
						tile.y = i * 50;
						addChild(tile);
					}
				}
			}
		}
	}
}

Map类也很简单,根据传过来的mapID载入对应的Map数组,然后就生成Tile来填充呗~
最后是示例性数据结构MapData.as:

/*
VERSION: 1.0 DATE:2010/03/18
ACTIONSCRIPT VERSION: 3.0
AUTHOR: DFdou
Copyright 2009, http://nwhy.org. All rights reserved.
*/
package {
	public class MapData {
		public static  const MAP:Array = [
										  [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10],
										   [0,1,0,0,14,0,0,0,0,0,0,0,6,0,0,0],
										   [0,0,1,0,0,0,0,0,5,0,12,0,1,0,0,0],
										   [0,0,0,0,9,0,0,0,0,0,0,0,0,0,3,0],
										   [0,0,5,1,5,5,0,0,0,0,1,0,0,0,3,0],
										   [0,0,0,0,0,0,0,0,0,0,6,4,0,3,0,0],
										   [0,0,5,0,0,4,1,0,0,0,0,9,0,12,0,0],
										   [0,0,0,0,0,0,0,0,0,0,11,0,1,0,0,0],
										   [0,0,0,2,0,0,2,0,0,0,3,10,9,9,0,0],
										   [0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],
										  ];
	}
}
Tagged as: 3 Comments
903/107

Flash-APE物理引擎学习<二>

昨天整理了下代码,新的Demo在这里:

在说具体实现之前,丢个Flash物理引擎在产品展示中的应用:http://www.carlosulloa.com/.
这是一款汽车产品的展示平台,用方向键控制机车移动,点鼠标左键复位汽车初始位置。
不过,这个不是2d物理引擎完成的,而是基于PV3D的,,,,恩,3D物理引擎是在比较难搞……有时间尝试整理下……

下边来说下Demo的具体实现,首先要收下物理引擎,物理引擎是干嘛用的呢?
物理引擎是一个处理物理现象的引擎。

那什么是物理现象呢?
举个例子,一个风筝在天上飞,它会受到风力,阻力,摩擦力,还有重力,绳子的作用力,etc。。。而物理引擎就是帮你处理这些力的一个框架集。
你要做的就是给它个重力,然后都作用在风筝上,至于这些里之间的相互作用,都由引擎来搞定。

下边来代码,先是文档类,也就是主容器了:

package org.nwhy.bubble_bobble{
	import flash.display.*;
	import flash.events.Event;
	import org.cove.ape.*;

	public class BubbleBobble extends Sprite{
		private var bulletHolder:Group;

		public function BubbleBobble(){
			init();
		}
		private function init(){
			initStage();
			initGroups()
		}
		private function initStage(){
			stage.scaleMode = StageScaleMode.NO_SCALE;//设置为不缩放
			//stage.align = StageAlign.TOP_LEFT;
			stage.frameRate = 55;//设置帧频
			stage.addEventListener(Event.ENTER_FRAME, run);
		}
		private function initGroups(){
			//初始化2D物理引擎
			APEngine.init(1/4);
			APEngine.container = this;
			APEngine.addForce(new VectorForce (false,0,1));//加上重力

			//放bullet的容器,bullet就是那个各种颜色的球~
			bulletHolder = new Group(true);
			APEngine.addGroup(bulletHolder);

			//加入墙壁
			var wall:Wall = new Wall();
			APEngine.addGroup(wall);

			//gun,就是下边那个大伯说有点像啥的那个啥……囧一个
			var gunGroup:GunGroup = new GunGroup(stage);
			APEngine.addGroup(gunGroup);

			//设置bullet的碰撞检测内容
			bulletHolder.addCollidableList(new Array(wall,gunGroup));
		}
		private function run(e:Event) {
			APEngine.step();
			APEngine.paint();
		}
		//增加bullet的对外接口
		public function addBullet(bullet:CircleParticle){
			bulletHolder.addParticle(bullet);
		}
	}
}

这里边干的事就是加入各种Group(APE物理引擎里的碰撞单元是Particle,单个或多个Particle组成Group),至于Group里具体是啥Group里自己处理。

503/102

Flash – APE物理引擎学习<一>

APE是什么就不介绍了,下边先上Demo:


点击鼠标发射子弹,击中那个囧就过关了。
代码实现其实也很简单,APE里边所有的Item都是以Group的形式存在。
在这个Demo里,上边的5个球是一组,例子里是Avatar类,里边有5个WheelParticle,不知道为何CircleParticle没有旋转的。

403/105

AS3-留言板(GuestBook)更新

http://guestbook.nwhy.org/
做了下更新,主要是把原来的方块改成了很有爱的表情,顺便把随机运动改成了撞碰。

Tagged as: 5 Comments
Page 1 of 121234510...Last »