How would you do this (#29382)?

21 posts

Flag Post

Just a quick one for you all to have an attempt at:

The Problem
You have a 2-dimensional array, where there are WH number of Tiles. The number of tiles in the x-axis is W, and the number of tiles in the y-axis is H.

The tiles are stored such that referencing the 2-d array – which I will call array from now on – at array[2][0] would point to the tile at X position 0, and Y position (Notice the Y & X reference order may be backwards to what you might expect).

So, in summary so far, you basically just have an array storing many tiles in different positions, with an easy method of accessing them directly if you know their X and Y values.

Now, you must produce a solution which will tween the alpha value of each tiles from 0, to 1. The order must be like so;

First, the very top left tile (AKA, the X:0, Y:0) will fade in first (in fadeTime). Once this has fully faded in (so once fadeTime has elapsed), the next tiles to fade in will be the tiles to the very right (AKA, the X:1, Y:0) and bottom (AKA, the X:0, Y:1) tiles which will do the same as above. Once these two tiles have finished fading in, then the tile to the right of these, and the bottom of these (Which may be the same tiles) will fade in.

Example picture of the order tiles should fade in: http://i47.tinypic.com/fvdwyd.png

Note, that the W and H values are not fixed, and your solution should account for variable values and length of the array, and not just hardcore for 1 W and H combination.

EDIT: This is number #29382 because it just is, live with it…

 
Flag Post
fadeList:Vector<Tile>;

fadeTile(x,y)
{
if(y<H)
if(x<W)
fadeList.push(map[y][x]);
}

update(){
for(x:Tile in fadeList)
{
x.alpha*=0.9;
if(x.fading!=true && x.alpha<0.01)
{
x.fading = true;
fadeTile(x.x,x.y+1);
fadeTile(x.x+1,x.y)
}
}
}

class Tile
{
var x
var y
var fading
}

Or you could time it and after x frames increment major then

i = major;
 while(i--){j++;fade(i,j)}
 
Flag Post
import caurina.transitions.Tweener;
var arr:Vector.<tile> = {...};

for(var i = 0; i < W; i++) {  //arrays done in the forwards direction due to ease of
                              //understanding of what it's doing
	for(var j = 0; j < H; i++) {
		Tweener.addTween(arr[j][i], {time:1, delay:i+j});  //the delay on any given tile
		                                                   //is equal to it's cardinal
		                                                   //distance (x-dist + y-dist) from
		                                                   //the origin
	}
}
 
Flag Post

Originally posted by Draco18s:

Pretty much identical to the approach I went with.

for(var a:int=0;a<W;++a){
    for(var b:int=0;b<H;++b){
        TweenLite.to(grid[b][a],fadeTime,{alpha:1,delay:a+b});
    }
}
 
Flag Post

Tweener variants are a preference. I tend to use Tweener because I tend to need some of the functions that aren’t available in TweenLite. Notably .isTweening()

 
Flag Post

I only really use TweenLite because it was the only tweening framework which had some super-specialised function I needed a long time ago. I might switch to an alternative (Maybe Tweener as you use) because it feels quite bulky when just using it for basic applications such as this, plus as you say, it is missing a few small functions which I find quite annoying in TweenLite.

 
Flag Post

Most of my projects aren’t super-important in terms of optimization (“play video, make text show up on screen, save user’s place in the program, drag and drop and multiple choice quizes”) so it’s “bulk” never bothered me.

 
Flag Post

I started messing about with the Tweener library this morning and replaced all my TweenLite references in a project to Tweener references, and have so far noticed a 5-10% speed increase. I also stripped the Tweener library down to a bit more of a bare-bones version, removing some of the slow parts the original developer had in there, and removing the stuff I will probably never use, and managed to get a further 10-15% speed increase. In a fairly resource-intensive tween-crazy project, it has sped the thing up quite nicely.

 
Flag Post

Last time I checked, GO was the fastest tween engine.

 
Flag Post

Why would you need a tween engine for something like this???

 
Flag Post
Originally posted by qwerber:

Why would you need a tween engine for something like this???

There are some programming challenges that are trivial to solve when you start using Tween engines (or the like).

If I were to pose a difficult physics question, and you went with 2DBox (Box2D? I forget its real name) because it takes only ten or so lines, that would be a valid solution. Same here. Manually tracking which objects are fading and how far along, etc. etc. is a very tricky thing to do inside an update loop. Instead we opted for a subroutine function that trivializes the whole issue.

 
Flag Post

Yes; But the code I wrote wasn’t that long and difficult to implement.

 
Flag Post
Originally posted by qwerber:

Why would you need a tween engine for something like this???

In terms of something simple like this, it isn’t massively necessary, just easier and quicker.

However in terms of something much more complex, sequenced and confusing, using a Tween library is much easier than manually tracking 1000’s of objects animation and alpha states and changing accordingly.

 
Flag Post
Originally posted by qwerber:

Yes; But the code I wrote wasn’t that long and difficult to implement.

And? I’m trading that to make it easier on myself to code. If efficiency comes down to it later, then yeah, maybe I could optimize, but this is way easier than a manual tracking.

 
Flag Post

This probably isn’t how I’d do it, but whatever:

const W:uint = 7
const H:uint = 5
const FADE_TIME:uint = 1000
const WIDTH:uint = 25
const PADDING:uint = 10

for(var i:uint = 0; i < H; i++)
	for(var j:uint = 0; j < W; j++)
		createTile(PADDING + j * (WIDTH + PADDING), PADDING + i * (WIDTH + PADDING), (i + j) * FADE_TIME)

function createTile(x:Number, y:Number, d:Number):void {
	var t:Shape = new Shape()
	addChild(t)
	t.x = x
	t.y = y
	t.alpha = 0
	t.graphics.beginFill(0xFF0000)
	t.graphics.drawRect(0, 0, WIDTH, WIDTH)
	t.addEventListener(Event.ENTER_FRAME, fadeIn)
	function fadeIn(e:Event):void {
		var g:uint = getTimer()
		if(g > d) {
			t.alpha = (g - d) / FADE_TIME
			if(g > (d + FADE_TIME)) t.removeEventListener(Event.ENTER_FRAME, fadeIn)
		}
	}
}
 
Flag Post
Originally posted by DPbrad:
Originally posted by qwerber:

Why would you need a tween engine for something like this???

In terms of something simple like this, it isn’t massively necessary, just easier and quicker.

However in terms of something much more complex, sequenced and confusing, using a Tween library is much easier than manually tracking 1000’s of objects animation and alpha states and changing accordingly.

Au contraire.
Tween engines are good for simple stuff like this; you can afford to hit performance in favour of readability when you’re only going to do something once, like a transition, or an init method, but you don’t want to kill performance by using a tween engine on thousands of objects in an important part of your application’s logic.

There are a bunch of laggy games because of “hey, it’s easier” mentality.

 
Flag Post

Generally I can be pretty aware of if what I’m using it for is going to have a frame rate impact or not. Or I can go “shit, frame rate is crap, what do I have that I don’t need?” and go “well, this is the only place I’m using tweener” and find another way.

 
Flag Post
Originally posted by Senekis93:
Originally posted by DPbrad:
Originally posted by qwerber:

Why would you need a tween engine for something like this???

In terms of something simple like this, it isn’t massively necessary, just easier and quicker.

However in terms of something much more complex, sequenced and confusing, using a Tween library is much easier than manually tracking 1000’s of objects animation and alpha states and changing accordingly.

Au contraire.
Tween engines are good for simple stuff like this; you can afford to hit performance in favour of readability when you’re only going to do something once, like a transition, or an init method, but you don’t want to kill performance by using a tween engine on thousands of objects in an important part of your application’s logic.

There are a bunch of laggy games because of “hey, it’s easier” mentality.

I never said using a Tween engine would run faster, just a lot easier & quicker to code. Even with thousands of objects all having properties tweened around, the actual speed increase from doing things manually is pretty negligble (In my experience anyway).

Note: Especially if you are using a well optimized tweening engine.

 
Flag Post

If you run into performance issues, it might be better to only add one tween at a time

private var cursorX:int = -1;
private var cursorY:int = 0;
private var tiles:Vector.<Tile>;

private function fade():void{
    if(++cursorX >= tiles.length){
        cursorX = 0; 
        if(++cursorY >= tiles[0].length) return;
    }
    Tweenlite.to(tiles[cursorX][cursorY], DELAY, {alpha:1,onComplete:fade});
}

Personally, I almost always use 1D arrays for 2D data because it’s much easier to iterate through. If you need to access a 1D array as if it’s 2D you just do

function getTile(X:int,Y:int):void{
    return tiles[Y*WIDTH+X];
}

where WIDTH is the maximum x index.

 
Flag Post

Yeah, I use the same setup Rivaledsouls in my own personal projects, but this was a project I inherited from elsewhere and all these type of arrays were in 2d format.

 
Flag Post

If you’re running into performance issues due to graphical effects then you’re doing it wrong.