Skip to content

Commit

Permalink
- MERGED: optimizations from komelgman (Thanks!)
Browse files Browse the repository at this point in the history
- ADDED: possibility to add a custom hitTest for nodes
- ADDED: new displayobject: Quad2D - A quad with four colors
- FIXED: spritesheet distribution in Sprite2DBatch
  • Loading branch information
Lars Gerckens committed Nov 15, 2011
1 parent d26772a commit e2b0d4e
Show file tree
Hide file tree
Showing 24 changed files with 408 additions and 140 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,15 @@ Important links:

# Changelog:

2011-11-15

- MERGED: optimizations from komelgman (Thanks!)
- ADDED: possibility to add a custom hitTest for nodes
- ADDED: new displayobject: Quad2D - A quad with four colors
- FIXED: spritesheet distribution in Sprite2DBatch

2011-11-14

- FIXED: device loss is working again :)

2011-11-06
Expand Down
6 changes: 2 additions & 4 deletions TODO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@
- blurmaterial
- solid / gradient quad as new object
- Zoë: A SWF animation exporter for the EaselJS library. ? more TextureAtlas tools?
- pixel perfect collisions -> save bitmapdata alpha channel? only 1-bit
- premultiplied / non premultiplied alpha - bug in particlesystem? dynamic per texturetype
- multiple worlds test
- camera zoom example for independent resolutions
- Sprite2DCloud - addChildAt - invalidation not THAT agressive if possible?
- premultiplied alpha bug for sprite2dcloud
- http://nulldesign.de/nd2d/forum/topic.php?id=64
- Dynamic TextureAtlas. Packing algorithm: http://www.codeproject.com/KB/web-image/rectanglepacker.aspx. font from bmp / font from textfield? new Font2D class! with textureatlas http://ge.runcode.us/q/get-bounds-of-filters-applied-to-flash-sprite-within-sprite http://www.blackpawn.com/texts/lightmaps/
- Sprite2DBatch setspritesheet of deeper nested childs bug

What I don't like about the spritesheets is:
- it's a pain to declare animations from a (cocos2D) spritesheet - it needs a simpler way like just sheet.playAnimation("foo*") and it would automatically build the animation with all assets named "foo001.png", "foo002.png", etc.
- and it seems inefficient to have to clone the spritesheet object.
About Sprite2DBatch: only addChildAt/removeChildAt are implemented and I'm not sure why addChild/removeChild aren't - maybe there's a hidden reason? Also invalidation in the *At methods seem a bit aggressive.
getChildByTag()

- GUI layer - no camera movement?
- getEnclosingRectangle for node2d?
- http://nulldesign.de/nd2d/forum/topic.php?id=86 TextField2D
2 changes: 2 additions & 0 deletions examples/Main.as
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ package {

import tests.BatchTest;
import tests.CameraTest;
import tests.QuadMaterialTest;
import tests.ColorTransformTest;
import tests.Font2DTest;
import tests.Grid2DTest;
Expand Down Expand Up @@ -116,6 +117,7 @@ package {
scenes.push(new SpeedTest());
scenes.push(new TextureAndRotationOptionsTest());
scenes.push(new Transform3DTest());
scenes.push(new QuadMaterialTest());

var tf:TextFormat = new TextFormat("Arial", 11, 0xFFFFFF, true);

Expand Down
2 changes: 1 addition & 1 deletion examples/tests/ColorTransformTest.as
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ package tests {
var atlas:TextureAtlas = new TextureAtlas(atlasTex.bitmapWidth, atlasTex.bitmapHeight, new XML(new textureAtlasXML()), 10, true);

atlas.addAnimation("blah", ["c01", "c02", "c03", "c04", "c05", "c06", "c07", "c08", "c09", "c10", "c11", "c12",
"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15"], true, true);
"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15"], true);

atlas.playAnimation("blah");

Expand Down
2 changes: 1 addition & 1 deletion examples/tests/MaskTest.as
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ package tests {
atlas.addAnimation("blah",
["c01", "c02", "c03", "c04", "c05", "c06", "c07", "c08", "c09", "c10", "c11", "c12",
"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15"],
true, true);
true);

atlas.playAnimation("blah");

Expand Down
50 changes: 50 additions & 0 deletions examples/tests/QuadMaterialTest.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* tests
* @Author: Lars Gerckens (lars@nulldesign.de)
* Date: 15.11.11 19:45
*/
package tests {

import de.nulldesign.nd2d.display.Quad2D;
import de.nulldesign.nd2d.display.Scene2D;
import de.nulldesign.nd2d.display.Sprite2D;
import de.nulldesign.nd2d.materials.Quad2DColorMaterial;
import de.nulldesign.nd2d.utils.ColorUtil;
import de.nulldesign.nd2d.utils.NumberUtil;

public class QuadMaterialTest extends Scene2D {

private var colorQuad:Quad2D;

public function QuadMaterialTest() {
colorQuad = new Quad2D(500.0, 500.0);
addChild(colorQuad);
}

override protected function step(elapsed:Number):void {
colorQuad.x = stage.stageWidth * 0.5;
colorQuad.y = stage.stageHeight * 0.5;
colorQuad.width = stage.stageWidth;
colorQuad.height = stage.stageHeight;

colorQuad.topLeftColor = ColorUtil.colorWithAlphaFromColor(
ColorUtil.mixColors(0xFF0000, 0x00FF00, NumberUtil.sin0_1(timeSinceStartInSeconds * 1.2)),
NumberUtil.sin0_1(timeSinceStartInSeconds * 1.3)
);

colorQuad.topRightColor = ColorUtil.colorWithAlphaFromColor(
ColorUtil.mixColors(0x00FF00, 0x0000FF, NumberUtil.sin0_1(timeSinceStartInSeconds * 1.4)),
NumberUtil.sin0_1(timeSinceStartInSeconds * 1.5)
);
colorQuad.bottomLeftColor = ColorUtil.colorWithAlphaFromColor(
ColorUtil.mixColors(0xFF0000, 0x00FF00, NumberUtil.sin0_1(timeSinceStartInSeconds * 1.6)),
NumberUtil.sin0_1(timeSinceStartInSeconds * 1.7)
);

colorQuad.bottomRightColor = ColorUtil.colorWithAlphaFromColor(
ColorUtil.mixColors(0x00FF00, 0x0000FF, NumberUtil.sin0_1(timeSinceStartInSeconds * 1.8)),
NumberUtil.sin0_1(timeSinceStartInSeconds * 1.9)
);
}
}
}
2 changes: 1 addition & 1 deletion examples/tests/TextureAtlasTest.as
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ package tests {
s.setSpriteSheet(atlas);

atlas.addAnimation("blah", ["c01", "c02", "c03", "c04", "c05", "c06", "c07", "c08", "c09", "c10", "c11", "c12",
"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15"], true, true);
"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15"], true);

atlas.playAnimation("blah");

Expand Down
4 changes: 2 additions & 2 deletions src/de/nulldesign/nd2d/display/Font2D.as
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,12 @@ package de.nulldesign.nd2d.display {
var curChar:String;
var frame:int;
var childIdx:uint = 0;
var startX:Number = spriteSheet.spriteWidth * 0.5;
var startX:Number = spriteSheet.spriteWidth >> 1;

switch(textAlign) {

case TextAlign.CENTER:
startX -= (text.length * spriteSheet.spriteWidth) * 0.5;
startX -= (text.length * spriteSheet.spriteWidth) >> 1;
break;

case TextAlign.RIGHT:
Expand Down
53 changes: 32 additions & 21 deletions src/de/nulldesign/nd2d/display/Node2D.as
Original file line number Diff line number Diff line change
Expand Up @@ -476,12 +476,10 @@ package de.nulldesign.nd2d.display {
* @private
*/
internal function processMouseEvent(mousePosition:Vector3D, mouseEventType:String, cameraViewProjectionMatrix:Matrix3D):Node2D {

mouseEvents = new Vector.<MouseEvent>();
var childMouseNode:Node2D = null;
var result:Node2D = null;

if(mouseEnabled && mouseEventType) {

// transform mousepos to local coordinate system
localMouseMatrix.identity();
localMouseMatrix.append(worldModelMatrix);
Expand All @@ -497,39 +495,52 @@ package de.nulldesign.nd2d.display {
_mouseX = localMouse.x;
_mouseY = localMouse.y;

if(!isNaN(width) && !isNaN(height)) {
var oldMouseInNodeState:Boolean = mouseInNode;
var newMouseInNode:Boolean = hitTest();

var oldMouseInNodeState:Boolean = mouseInNode;
var newMouseInNode:Boolean = (mouseX >= -_width * 0.5 && mouseX <= _width * 0.5 && mouseY >= -_height * 0.5 && mouseY <= _height * 0.5);
if(newMouseInNode) {
if(!oldMouseInNodeState) {
mouseEvents.push(new MouseEvent(MouseEvent.MOUSE_OVER, true, false, localMouse.x, localMouse.y, null, false, false, false, (mouseEventType == MouseEvent.MOUSE_DOWN), 0));
}

if(newMouseInNode) {
if(!oldMouseInNodeState) {
mouseEvents.push(new MouseEvent(MouseEvent.MOUSE_OVER, true, false, localMouse.x, localMouse.y, null, false, false, false, (mouseEventType == MouseEvent.MOUSE_DOWN), 0));
}
mouseEvents.push(new MouseEvent(mouseEventType, true, false, localMouse.x, localMouse.y, null, false, false, false, (mouseEventType == MouseEvent.MOUSE_DOWN), 0));
childMouseNode = this;
mouseEvents.push(new MouseEvent(mouseEventType, true, false, localMouse.x, localMouse.y, null, false, false, false, (mouseEventType == MouseEvent.MOUSE_DOWN), 0));
result = this;

} else if(oldMouseInNodeState && !newMouseInNode) {
// dispatch mouse out directly, no hierarchy test
dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OUT, true, false, localMouse.x, localMouse.y, null, false, false, false, (mouseEventType == MouseEvent.MOUSE_DOWN), 0));
}
} else if(oldMouseInNodeState) {
// dispatch mouse out directly, no hierarchy test
dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OUT, true, false, localMouse.x, localMouse.y, null, false, false, false, (mouseEventType == MouseEvent.MOUSE_DOWN), 0));
}
}

var subChildMouseNode:Node2D;
for each(var child:Node2D in children) {
subChildMouseNode = child.processMouseEvent(mousePosition, mouseEventType, cameraViewProjectionMatrix);
for(var i:Number = children.length - 1; i >= 0; --i) {
subChildMouseNode = children[i].processMouseEvent(mousePosition, mouseEventType, cameraViewProjectionMatrix);
if(subChildMouseNode) {
childMouseNode = subChildMouseNode;
result = subChildMouseNode;
break;
}
}

// set over to false, if one of our childs stole the event
if(childMouseNode != this) {
if(result != this) {
mouseInNode = false;
}

return childMouseNode;
return result;
}

/**
* Overwrite and do your own hitTest if you like
* @return
*/
protected function hitTest():Boolean {
if(isNaN(_width) || isNaN(_height)) {
return false;
}

var halfWidth:Number = _width >> 1;
var halfHeight:Number = _height >> 1;
return (_mouseX >= -halfWidth && _mouseX <= halfWidth && _mouseY >= -halfHeight && _mouseY <= halfHeight);
}

internal function setStageAndCamRef(value:Stage, cameraValue:Camera2D):void {
Expand Down
107 changes: 107 additions & 0 deletions src/de/nulldesign/nd2d/display/Quad2D.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**
* de.nulldesign.nd2d.display
* @Author: Lars Gerckens (lars@nulldesign.de)
* Date: 15.11.11 19:49
*/
package de.nulldesign.nd2d.display {

import de.nulldesign.nd2d.geom.Face;
import de.nulldesign.nd2d.geom.Vertex;
import de.nulldesign.nd2d.materials.BlendModePresets;
import de.nulldesign.nd2d.materials.Quad2DColorMaterial;
import de.nulldesign.nd2d.utils.TextureHelper;

import flash.display3D.Context3D;

public class Quad2D extends Node2D {

protected var faceList:Vector.<Face>;
protected var material:Quad2DColorMaterial;

public function get topLeftColor():uint {
return faceList[0].v1.color;
}

public function set topLeftColor(value:uint):void {
var v:Vertex = faceList[0].v1;
v.color = value;
material.modifyColorInBuffer(0, v.r, v.g, v.b, v.a);
}

public function get topRightColor():uint {
return faceList[0].v2.color;
}

public function set topRightColor(value:uint):void {
var v:Vertex = faceList[0].v2;
v.color = value;
material.modifyColorInBuffer(1, v.r, v.g, v.b, v.a);
}

public function get bottomRightColor():uint {
return faceList[0].v3.color;
}

public function set bottomRightColor(value:uint):void {
var v:Vertex = faceList[0].v3;
v.color = value;
material.modifyColorInBuffer(2, v.r, v.g, v.b, v.a);
}

public function get bottomLeftColor():uint {
return faceList[1].v3.color;
}

public function set bottomLeftColor(value:uint):void {
var v:Vertex = faceList[1].v3;
v.color = value;
material.modifyColorInBuffer(3, v.r, v.g, v.b, v.a);
}

public function Quad2D(pWidth:Number, pHeight:Number) {

_width = pWidth;
_height = pHeight;

faceList = TextureHelper.generateQuadFromDimensions(pWidth, pHeight);
material = new Quad2DColorMaterial();

topLeftColor = 0xFFFF0000;
topRightColor = 0xFF00FF00;
bottomRightColor = 0xFF0000FF;
bottomLeftColor = 0xFFFFFF00;

blendMode = BlendModePresets.NORMAL_NO_PREMULTIPLIED_ALPHA;
}

override public function get numTris():uint {
return faceList.length;
}

override public function get drawCalls():uint {
return material.drawCalls;
}

override public function handleDeviceLoss():void {
super.handleDeviceLoss();
if(material)
material.handleDeviceLoss();
}

override protected function draw(context:Context3D, camera:Camera2D):void {

material.blendMode = blendMode;
material.modelMatrix = worldModelMatrix;
material.viewProjectionMatrix = camera.getViewProjectionMatrix(false);
material.render(context, faceList, 0, faceList.length);
}

override public function dispose():void {
if(material) {
material.dispose();
material = null;
}
super.dispose();
}
}
}
2 changes: 1 addition & 1 deletion src/de/nulldesign/nd2d/display/Sprite2D.as
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
package de.nulldesign.nd2d.display {

import de.nulldesign.nd2d.geom.Face;
import de.nulldesign.nd2d.materials.ASpriteSheetBase;
import de.nulldesign.nd2d.materials.texture.ASpriteSheetBase;
import de.nulldesign.nd2d.materials.Sprite2DMaskMaterial;
import de.nulldesign.nd2d.materials.Sprite2DMaterial;
import de.nulldesign.nd2d.materials.texture.Texture2D;
Expand Down
2 changes: 1 addition & 1 deletion src/de/nulldesign/nd2d/display/Sprite2DBatch.as
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
package de.nulldesign.nd2d.display {

import de.nulldesign.nd2d.geom.Face;
import de.nulldesign.nd2d.materials.ASpriteSheetBase;
import de.nulldesign.nd2d.materials.texture.ASpriteSheetBase;
import de.nulldesign.nd2d.materials.Sprite2DBatchMaterial;
import de.nulldesign.nd2d.materials.texture.Texture2D;
import de.nulldesign.nd2d.utils.StatsObject;
Expand Down
11 changes: 6 additions & 5 deletions src/de/nulldesign/nd2d/display/Sprite2DCloud.as
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ package de.nulldesign.nd2d.display {
import de.nulldesign.nd2d.geom.Face;
import de.nulldesign.nd2d.geom.UV;
import de.nulldesign.nd2d.geom.Vertex;
import de.nulldesign.nd2d.materials.ASpriteSheetBase;
import de.nulldesign.nd2d.materials.texture.ASpriteSheetBase;
import de.nulldesign.nd2d.materials.shader.Shader2D;
import de.nulldesign.nd2d.materials.shader.ShaderCache;
import de.nulldesign.nd2d.materials.texture.Texture2D;
Expand Down Expand Up @@ -61,6 +61,7 @@ package de.nulldesign.nd2d.display {
* - Mouseevents are disabled and won't work for childs
* - Reordering childs (add, remove) is very expensive. Try to avoid it! A Sprite2DBatch might work better in this case
* - Subchilds are not rendered. The cloud will only render it's own childs, you can't nest nodes deeper with a cloud.
* - rotationX,Y won't work for Sprite2DCloud childs
*/
public class Sprite2DCloud extends Node2D {

Expand Down Expand Up @@ -320,12 +321,12 @@ package de.nulldesign.nd2d.display {
sy = child.scaleY;

if(spriteSheet) {
sx *= spriteSheet.spriteWidth * 0.5;
sy *= spriteSheet.spriteHeight * 0.5;
sx *= spriteSheet.spriteWidth >> 1;
sy *= spriteSheet.spriteHeight >> 1;
atlasOffset = spriteSheet.getOffsetForFrame();
} else {
sx *= texture.textureWidth * 0.5;
sy *= texture.textureHeight * 0.5;
sx *= texture.textureWidth >> 1;
sy *= texture.textureHeight >> 1;
atlasOffset.x = 0.0;
atlasOffset.y = 0.0;
}
Expand Down
Loading

0 comments on commit e2b0d4e

Please sign in to comment.