How use several item renderers in one in List? - actionscript-3

I decided to make a simple tool for social networking.
There is a list (in the picture), which has a complex itemRenderer which included two more itemRenderers (IR).
The first (social networks) get data from the global dataProvider, the second (resources) is formed depending on what social network in the first IR selected. The dataProvider of the second IR created on the basis of another dataProvider directly in IR code.
protected function soc_itemClickHandler(event:ItemClickEvent):void
{
if (event.label == 'selected') {
dp = new ArrayCollection();//dataprovider of the second IR
for (var k:int = 0; k < Copypaste.socials.length; k++)
{
for (var j:int = 0; j < Copypaste.resources.length; j++)
{
var socObj:Object = Copypaste.socials.getItemAt(k);
var resObj:Object = Copypaste.resources.getItemAt(j);
if (socObj.selected == true ||socObj.selected == 'true') {
if (resObj.social == socObj.uid) {
dp.addItem(resObj);
}
}
}
}
}
}
All fine, but the problems begin when I want to select another social network - one IR affect the other, the data do not match. And the List can be sorted by dragging of the items, then all the data in the second IR disappear, and the checkboxes in the first IR become disselect.
How to build the architecture of this app?

Related

How to hitTest same Objects in one Array?

I want to create a stacking Game. Where when you tap the screen for instance a block falls down and a new one appears where the other one originally was. Now when the User taps the screen again the same block falls down and if aligned correctly stacks on top of the first one so one and so one. Keep stacking until you miss.
I thought creating an array and pushing each new object to that array would be able to hitTest between each new one etc and have them stack on each other. I realized I don't quite understand how to go about doing this. New instances are created so I got that down. Here is my code so far:
private function engineLogic(e:Event):void
{
stackingHandler();
}
private function stackingHandler():void
{
for (var i:int = 0; i < aCatArray.length; i++)
{
var currentCat:mcCats = aCatArray[i];
//HIT TEST CATS
}
trace("NUMBER OF CATS: " + aCatArray.length);
}
private function onTap(e:MouseEvent):void
{
//Move Down
TweenLite.to(cats, 1.0, {y:(stage.stageHeight / 2) + 290, onComplete: addCats});
}
private function addCats():void
{
//Create Instance
cats = new mcCats();
//Add Objects
addChild(cats);
//Push to Array
aCatArray.push(cats);
}
I would appreciate any help from you guys. Maybe if you can push me in the right direction. Thank you in advance!
It looks like the cats variable holds the object that is currently falling?
In that case you'd do something like this:
private function stackingHandler():void
{
for (var i:int = 0; i < aCatArray.length; i++)
{
if(cats.hitTestObject(aCatArray[i])) {
// collision detected!
// kill the Tween
// set the y position of the `cats` object
// so it appears on top of the object it collided with (`aCatArray[i]`)
// (it may have moved slightly past the object before doing this check)
}
}
}
So you're looping through the array and hit testing cats against every object in the array one at a time.
It might make more sense to use a basic gravity simulation, or just linearly increasing the y value instead of using a Tween, but you didn't ask about that.
You might also want to set a flag for whether or not an object is currently falling and use that to determine whether or not to run the stackingHandler. Otherwise, you'll just be continually hit testing all the objects when nothing is moving.
This is how I was able to fix it. Creating a double for loop. Checking if they are equal to each other continue and check for hitTest:
private function stackingHandler():void
{
for (var i:int = 0; i < aCatArray.length; i++)
{
var currentCat:mcCats = aCatArray[i];
for (var j:int = 0; j < aCatArray.length; j++)
{
var newCat:mcCats = aCatArray[j];
if (currentCat == newCat) continue;
//Hit Test between Objects
if (newCat.hitTestObject(currentCat.mcHit) && newCat.bFlag == false)
{
//Stop Moving
newCat.stopMoving();
trace("HIT");
if (highScore == 0)
{
addCats();
trace("ADD CATS 1");
}else
{
TweenLite.delayedCall(0.6, addCats);
trace("ADD CATS 2");
}
//Add Points
highScore ++;
trace(highScore + " Score");
//Set Flag boolean
newCat.bFlag = true
}
}
}
}

using Action Script 3 remove an object that appeared in the run time

I use this code to create list of words from an array and make them act like buttons
in the main page i have 2 buttons that activate the for loop to create the list of words
the problem is when i hit the second button in the main the list of words of the first button still shown on the screen, i need to remove the list first then activate the second loop
i used the removeChildAt() function but it didn't worked
what should i do ?
var words:Array = [];
var word:MovieClip=new MovieClip();
if(e.target.name=="glossumbolA"){
words=['School1','School2','School3','School4','School5','School6']
for (var j:int = 0; j < words.length; j++)
{
word = createTextButton(words[j]);
addChild(word);
word.addEventListener(MouseEvent.CLICK, wordButtonClick);
}
}
else if(e.target.name=="glossumbolB"){
words=['Class1','Class2']
for (var i:int = 0; i < words.length; i++)
{
word = createTextButton(words[i]);
addChild(word);
word.addEventListener(MouseEvent.CLICK, wordButtonClick);
}
}
function createTextButton(){
//code to make the word in the array a button
}
function wordButtonClick(){
//code to make an action when the word in the array clicked
}
you have multiple ways to do that:
1. create one new MovieClip inside 'word' (with name A), for glossumbolA and one new for glossumbolB (with name B), create buttons inside MCs. You can set 'visible' true || false for A and B. If glossumbolA button is clicked - check if B is visible, set visible to 0.
or
while (word.numChildren > 0) {
word.removeChildAt(0);
} then create new buttons

Segmentation fault while parallelizing STL List erase function

I am trying to parallelize my C++ code using Open MP but I am running into Segmentation fault, the serial version is running fine. I used gdb debugger and I know the error is occurring while erasing one of the elements of the STL List.
In the code below I have a vector which contains particle pairs with IDs(boxID1 and boxID2) and each particle has a Actual Contact List associated with it. Then I add and delete if or if not the particles are in contact in a given list.
Is there a way to avoid this error while erasing?
Contact newcontact;
bool isPresentIntheList;
list<Contact>::iterator it;
#pragma omp parallel for private(newcontact, isPresentIntheList, it)
for(long int i=0; i<overlapVector.size(); i++)
{
isPresentIntheList = false;
it = (*particlesPointerVector)[overlapVector[i].boxID2]->ActualContactList.begin();//iterator for Actual Contact List of the particle with ID = overlapVector[i].boxID2
if((*particlesPointerVector)[overlapVector[i].boxID2]->ActualContactList.size() != 0) //if ACL size doesn't have a size = 0
{
for(long int j=0; it!=(*particlesPointerVector)[overlapVector[i].boxID2]->ActualContactList.end(); j++)
{
if(it->particlei->ID == overlapVector[i].boxID1)
{
isPresentIntheList = true;
}
if(isPresentIntheList)
{
if(IsContact(*it, timestep))//checking if the overlapping pair is in contact or not
{
it++;//do nothing that means overlapping pair is in contact
}
else//remove that pair from ACL if it is not in contact
{
{
newcontact.particlei = (*it).particlei;
newcontact.particlej = (*it).particlej;
/*ERROR occurring here*/
it = (*particlesPointerVector)[overlapVector[i].boxID2]->ActualContactList.erase(it);//no it++ required as it automatically points to the next container after erasing
}
}
}
else if(!isPresentIntheList)
it++;
}
}

Object removed from screen before the relevant command is called (Error #1009)

I'm sorry if it's asking for too much, but I'm too confused by now. I'm making this really simple shooter game for my nephew in AS3. It all seems to be working just fine, except for one really annoying error that keeps popping up every second or third time the game is launched.
IT is Error #1009: Cannot access a property or method of a null object reference. The problem is always with parent.removeChild(this) command in the relevant class (EnemyClass, BulletClass or MissileClass). This happens in two cases: either when checkFinishConditions method in Main is called and the EnemyClass instance needs to be deleted. So if I get the #1009 error does this mean the instance has already been deleted? The second situation is when inst.hitTestObject(enemyInstance) is checked in Main class. Does this mean the EnemyClass instance has already been deleted somehow? I'm totally lost here to be honest.
private function checkCollision():void
{
//loop through missiles
for (var i:int = 0; i < aMissileArray.length; i++) {
//get the current missile
var currentMissile:missileClass = aMissileArray[i];
//loop through enemies
for (var j:int = 0; j < aEnemyArray.length; j++) {
var thisEnemy:EnemyClass = aEnemyArray[j];
if (currentMissile.hitTestObject(thisEnemy)) {
var thisExplode:ExplosionClass = new ExplosionClass(thisEnemy.x,thisEnemy.y);
addChild(thisExplode);
currentMissile.destroyThis();
aMissileArray.splice(i,1);
thisEnemy.deleteEnemy();
aEnemyArray.splice(j, 1);
aDamageArray.splice(j, 1);
scoreValueText += 1;
j--;
i--;
}
//break;
}
}
//loop through bullets
for (var l:int = 0; l < aBulletArray.length; l++) {
//get the current missile
var currentBullet:BulletClass = aBulletArray[l];
//loop through enemies
for (var k:int = 0; k < aEnemyArray.length; k++) {
var currentEnemy:EnemyClass = aEnemyArray[k];
if (currentBullet.hitTestObject(currentEnemy)) {
currentBullet.destroyThis();
aBulletArray.splice(l, 1);
aDamageArray[k] -= 1;
l--;
if (aDamageArray[k] < 1) {
//create an explosion
var thisBulletExplode:ExplosionClass = new ExplosionClass(currentEnemy.x,currentEnemy.y);
addChild(thisBulletExplode);
currentEnemy.deleteEnemy();
aEnemyArray.splice(k, 1);
aDamageArray.splice(k, 1);
scoreValueText += 1;
k--;
}
break;
}
}
}
}
There is alot of code to look over, but one potential issue I see is here :
for each(var currentDieEnemy:EnemyClass in aEnemyArray) {
aEnemyArray.splice(0, 1);
currentDieEnemy.deleteEnemy();
}
The potential issue is that you are 'assuming' that the order of this loop is sequential based on the actual index order of the Array. You might want to stick a trace in there to verify that is actually what is happening, because I believe it's possible that they can be out of order.
See this question for details -- For-Each Loop AS3: Is the direction guaranteed?
So imagine the scenario where the 3rd item in the array is first and you splice the item at the 0 index. Now, you have an item in the array that is removed from the display list, but not from the array. So what happens when you get to that item ? Pretty much what you are describing will happen since the parent property is null, since you already removed it from the display list.
The way to fix that is to do something like this :
while (aEnemyArray.length > 0)
{
var currentDieEnemy:EnemyClass = aEnemyArray[0];
currentDieEnemy.deleteEnemy();
aEnemyArray.splice(0,1);
}
I found another issue in this block of code :
for (var j:int = 0; j < aEnemyArray.length; j++) {
var thisEnemy:EnemyClass = aEnemyArray[j];
if (currentMissile.hitTestObject(thisEnemy)) {
var thisExplode:ExplosionClass = new ExplosionClass(thisEnemy.x,thisEnemy.y);
addChild(thisExplode);
currentMissile.destroyThis();
aMissileArray.splice(i,1);
thisEnemy.deleteEnemy();
aEnemyArray.splice(j, 1); // now array composition is different.
aDamageArray.splice(j, 1);
scoreValueText += 1;
}
}
When you loop through an Array and splice an item at the loop index, you have to realize what happens to the composition of the array. Here's an example
Suppose enemy3 needs to be spliced because of a collision. Given your code, this is what happens :
Before (j == 2)
(0) enemy1
(1) enemy2
(2) enemy3
(3) enemy4
(4) enemy5
AFTER
(0) enemy1
(1) enemy2
(2) enemy4
(3) enemy5
So when the loop continues, j will now increment and equal 3.
The result is that enemy4 doesn't get evaluated as the composition of the array collapses to fill the hole created by the splice and you didn't adjust your loop index variable.
So, what you can do in that situation is simply decrement the loop index variable at the end of the block like so :
aEnemyArray.splice(j, 1); // now array composition is different.
aDamageArray.splice(j, 1);
scoreValueText += 1;
j--; // decrement loop index variable.
So while this is one solution, the main point to take away here is the change in the composition of your Array after a splice.
Yep, you are splicing your objects from arrays in a weird way. First, you are traversing the array forwards and splicing in the loop. This can lead to issues of several bullets not trigger collisions when they should, or say not move. See, if you are running your loop for bullets at index i, once you call bullets.splice(i,1); the bullet that was to be iterated next becomes at position i, then you increment i and that bullet remains unprocessed.
Next, you have nested loops, and in the inner loop you are removing an object from OUTER loop. This means once you did a removal of the outer loop's object, your inner loop is now invalidated, you have to preemptively terminate inner loop.
//loop through bullets
for (var l:int = aBulletArray.length-1; l>=0; l--) {
// first, traverse both arrays backwards
//get the current missile
var currentBullet:BulletClass = aBulletArray[l];
//loop through enemies
for (var k:int = aEnemyArray.length-1; k>=0; k--) {
var currentEnemy:EnemyClass = aEnemyArray[k];
if (currentBullet.hitTestObject(currentEnemy)) {
currentBullet.destroyThis();
aBulletArray.splice(l, 1);
aDamageArray[k] -= 1;
if (aDamageArray[k] < 1) {
//create an explosion
var thisExplode:ExplosionClass = new ExplosionClass(currentEnemy.x,currentEnemy.y);
addChild(thisExplode);
currentEnemy.deleteEnemy();
aEnemyArray.splice(k, 1);
aDamageArray.splice(k, 1);
scoreValueText += 1;
}
// and since we don't have "currentBullet" anymore, do this
break;
}
}
}
Fix all the other iterations through your arrays where you do splicing, like I did in this part of code, and you should avoid 1009 errors in these loops.
Also, you should not post your entire project code, but instead post only relevant parts, say an entire function that's reported as throwing an error, and explain which line is producing the error - it's written as number in the error's stack trace.

Order of instances in 3D Flash

I'm making cube of 9 cubes in Flash As3. However i cant rotate it properly due to order of indexes whole adding then to stage.
First im creating cube of 6 squares, then wall of 9 cubes, and at the end cube of 3 walls.
It is all fine, however when i rotate it to the left, order of cubes is inverted and it ruins whole composition. I know i coul dinamicly change index based on rotation but it would be a loooooooot of work.
Any ideas how could i do it better way?
Here is actual model:
http://test.mrowa.topdivision.pl/kostka/3DTest.html
If you are using the Flash's display list you would have to sort the sprites based on their z.
Here is some code that would sort the children of a DisplayObjectContainer based on their z position, call this whenever some object changes its position.
public function sortChildren(container:DisplayObjectContainer):void
{
var objects:Vector.<DisplayObject> = new Vector.<DisplayObject>;
for (var i:int = 0; i < container.numChildren; i++)
{
objects.push(container.getChildAt(i));
}
objects.sort(sortCompare);
var index:int = 0;
for (var j:int = 0; j < objects.length; j++)
{
index = container.getChildIndex(objects[j]);
if (index != j)
container.setChildIndex(objects[j], j);
}
}
private function sortCompare(a:DisplayObject, b:DisplayObject):int
{
return (a.z - b.z);
}
You can move the objects member to be a class member and add/remove items to it whenever you add/remove items to/from the stage so that you don't have to fill the whole array every time this function is called.