⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 array2.as

📁 一个2D基于verlet的Flash物理引擎。它用AS3编写而成。Fisix的目标是应用到游戏等计算量很大的实时应用中。尽管flash比c/c++要慢,很棒的物理引擎
💻 AS
字号:
/**
 * DATA STRUCTURES FOR GAME PROGRAMMERS
 * Copyright (c) 2007 Michael Baczynski, http://www.polygonal.de
 *
 * 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 de.polygonal.ds
{
	/**
	 * A two-dimensonal array build upon a single linear array.
	 */
	public class Array2 implements Collection
	{
		private var _a:Array;
		private var _w:int, _h:int;
		
		/**
		 * Initializes a two-dimensional array to match the given width and height.
		 * 
		 * @param w The width  (number of colums).
		 * @param h The height (number of rows).
		 */
		public function Array2(width:int, height:int)
		{
			_a = new Array((_w = width) * (_h = height));
			fill(null);
		}
		
		/**
		 * Indicates the width (colums).
		 * If a new width is set, the two-dimensional array is resized accordingly.
		 */
		public function get width():int
		{
			return _w;
		}
		
		public function set width(w:int):void
		{
			resize(w, _h);
		}
		
		/**
		 * Indicates the height (rows).
		 * If a new height is set, the two-dimensional array is resized accordingly.
		 */
		public function get height():int
		{
			return _h;
		}
		
		public function set height(h:int):void
		{
			resize(_w, h);
		}
		
		/**
		 * Sets each cells in the two-dimensional array to a given value.
		 * 
		 * @param item The item to be written into each cell.
		 */
		public function fill(item:*):void
		{
			var k:int = _w * _h;
			for (var i:int = 0; i < k; i++)
				_a[i] = item;
		}
		
		/**
		 * Reads the value at the given x/y index.
		 * No boundary check is performed, so you have to
		 * make sure that the input coordinates do not exceed
		 * the width or height of the two-dimensional array.
		 *
		 * @param x The x index.
		 * @param y The y index.
		 */
		public function get(x:int, y:int):*
		{
			return _a[int(y * _w + x)];
		}
		
		/**
		 * Writes data into the cell at the given x/y index.
		 * No boundary check is performed, so you have to
		 * make sure that the input coordinates do not exceed
		 * the width or height of the two-dimensional array.
		 *
		 * @param x The x index.
		 * @param y The y index.
		 * @param obj The item to be written into the cell.
		 */
		public function set(x:int, y:int, obj:*):void
		{
			_a[int(y * _w + x)] = obj;
		}
		
		/**
		 * Resizes the array to match the given width and height
		 * while preserving existing values.
		 * 
		 * @param w The new width (cols)
		 * @param h The new height (rows)
		 */
		public function resize(w:int, h:int):void
		{
			if (w <= 0) w = 1;
			if (h <= 0) h = 1;
			
			var copy:Array = _a.concat();
			
			_a.length = 0;
			_a.length = w * h;
			
			var minx:int = w < _w ? w : _w;
			var miny:int = h < _h ? h : _h;
			
			var x:int, y:int, t1:int, t2:int;
			for (y = 0; y < miny; y++)
			{
				t1 = y *  w;
				t2 = y * _w;
				
				for (x = 0; x < minx; x++)
					_a[int(t1 + x)] = copy[int(t2 + x)];
			}
			
			_w = w;
			_h = h;
		}
		
		/**
		 * Extracts the row at the given index.
		 * 
		 * @return An array storing the values of the row.
		 */
		public function getRow(y:int):Array
		{
			var offset:int = y * _w;
			return _a.slice(offset, offset + _w);
		}
		
		/**
		 * Extracts the colum at the given index.
		 * 
		 * @return An array storing the values of the column.
		 */
		public function getCol(x:int):Array
		{
			var t:Array = [];
			for (var i:int = 0; i < _h; i++)
				t[i] = _a[int(i * _w + x)];
			return t;
		}
		
		/**
		 * Shifts all columns by one column to the left.
		 * Columns are wrapped, so the column at index 0 is
		 * not lost but appended to the rightmost column.
		 */
		public function shiftLeft():void
		{
			if (_w == 1) return;
			
			var j:int = _w - 1, k:int;
			for (var i:int = 0; i < _h; i++)
			{
				k = i * _w + j;
				_a.splice(k, 0, _a.splice(k - j, 1));
			}
		}
		
		/**
		 * Shifts all columns by one column to the right.
		 * Columns are wrapped, so the column at the last index is
		 * not lost but appended to the leftmost column.
		 */
		public function shiftRight():void
		{
			if (_w == 1) return;
			
			var j:int = _w - 1, k:int;
			for (var i:int = 0; i < _h; i++)
			{
				k = i * _w + j;
				_a.splice(k - j, 0, _a.splice(k, 1));
			}
		}
		
		/**
		 * Shifts all rows up by one row.
		 * Rows are wrapped, so the first row is
		 * not lost but appended to bottommost row.
		 */
		public function shiftUp():void
		{
			if (_h == 1) return;
			
			_a = _a.concat(_a.slice(0, _w));
			_a.splice(0, _w);
		}
		
		/**
		 * Shifts all rows down by one row.
		 * Rows are wrapped, so the last row is
		 * not lost but appended to the topmost row.
		 */
		public function shiftDown():void
		{
			if (_h == 1) return;
			
			var offset:int = (_h - 1) * _w;
			_a = _a.slice(offset, offset + _w).concat(_a);
			_a.splice(_h * _w, _w);
		}
		
		/**
		 * Appends an array as a new row.
		 * If the given array is longer or shorter than the current width,
		 * it is truncated or widened to match the current dimensions.
		 *
		 * @param a The array to insert.
		 */
		public function appendRow(a:Array):void
		{
			a.length = _w;
			_a = _a.concat(a);
			_h++;
		}
		
		/**
		 * Prepends an array as a new row.
		 * If the given array is longer or shorter than the current width,
		 * it is truncated or widened to match the current dimensions.
		 * 
		 * @param a The array to insert.
		 */
		public function prependRow(a:Array):void
		{
			a.length = _w;
			_a = a.concat(_a);
			_h++;
		}
		
		/**
		 * Appends an array as a new column.
		 * If the given array is longer or shorter than the current height,
		 * it is truncated or widened to match the current dimensions.
		 * 
		 * @param a The array to insert.
		 */
		public function appendCol(a:Array):void
		{
			a.length = _h;
			for (var y:int = 0; y < _h; y++)
				_a.splice(y * _w + _w + y, 0, a[y]);
			_w++;
		}
		
		/**
		 * Prepends an array as a new column.
		 * If the given array is longer or shorter than the current height,
		 * it is truncated or widened to match the current dimensions.
		 * 
		 * @param a - The array to insert.
		 */
		public function prependCol(a:Array):void
		{	
			a.length = _h;
			for (var y:int = 0; y < _h; y++)
				_a.splice(y * _w + y, 0, a[y]);
			_w++;
		}
		
		/**
		 * Flips rows with cols and vice versa.
		 * This is equivalent of rotating the array about 180 degrees.
		 */
		public function transpose():void
		{
			var a:Array = _a.concat();
			for (var y:int = 0; y < _h; y++)
			{
				for (var x:int = 0; x < _w; x++)
					_a[int(x * _w + y)] = a[int(y * _w + x)];
			}
		}
		
		/**
		 * Checks if a given item exists.
		 * 
		 * @return True if the specified item is found, otherwise false.
		 */
		public function contains(obj:*):Boolean
		{
			var k:int = size;
			for (var i:int = 0; i < k; i++)
			{
				if (_a[i] === obj)
					return true;
			}
			return false;
		}
		
		/**
		 * Clears all elements.
		 */
		public function clear():void
		{
			_a = new Array(size);
		}
		
		/**
		 * Initializes an iterator object
		 * pointing to the first value (0, 0).
		 */
		public function getIterator():Iterator
		{
			return new Array2Iterator(this);
		}
		
		/**
		 * The total number of cells.
		 */
		public function get size():int
		{
			return _w * _h;
		}
		
		/**
		 * Checks if the 2d array is empty.
		 */
		public function isEmpty():Boolean
		{
			return false;
		}
		
		/**
		 * Converts the structure into an array.
		 * 
		 * @return An array storing the data of this structure.
		 */
		public function toArray():Array
		{
			var a:Array = _a.concat();
			
			var k:int = size;
			if (a.length > k) a.length = k;
			return a;
		}
		
		/**
		 * Returns a string representing the current object.
		 */
		public function toString():String
		{
			return "[Array2, width=" + width + ", height=" + height + "]";
		}
		
		/**
		 * Prints all elements (for debug/demo purposes only).
		 */
		public function dump():String
		{
			var s:String = "Array2\n{";
			var offset:int, value:*;
			for (var y:int = 0; y < _h; y++)
			{
				s += "\n" + "\t";
				offset = y * _w;
				for (var x:int = 0; x < _w; x++)
				{
					value = _a[int(offset + x)];
					s += "[" + (value != undefined ? value : "?") + "]";
				}
			}
			s += "\n}";
			return s;
		}
	}
}

import de.polygonal.ds.Array2;
import de.polygonal.ds.Iterator;

internal class Array2Iterator implements Iterator
{
	private var _a2:Array2;
	private var _xCursor:int;
	private var _yCursor:int;
	
	public function Array2Iterator(a2:Array2)
	{
		_a2 = a2;
		_xCursor = _yCursor = 0;
	}
	
	public function get data():*
	{
		return _a2.get(_xCursor, _yCursor);
	}
	
	public function set data(obj:*):void
	{
		_a2.set(_xCursor, _yCursor, obj);
	}
	
	public function start():void
	{
		_xCursor = _yCursor = 0;
	}
	
	public function hasNext():Boolean
	{
		return (_yCursor * _a2.width + _xCursor < _a2.size);
	}
	
	public function next():*
	{
		var item:* = data;
		
		if (++_xCursor == _a2.width)
		{
			_yCursor++;
			_xCursor = 0;
		}
		
		return item;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -