Edit: I have now included a Player.as and a addchild
I've been trying to understand how to do this all day and again learned a lot in doing so. But I've come to a point that i need help.
I know I have to do this: create a Collisions var in the Back1 class.
Because the background called Back1 is the movieclip that contains the Collisions image
I found a good site or 2 that does a good job of explaining variables and classes but i still don't get how i should solve this problem
Research after variables and classes:
http://www.republicofcode.com/tutorials/flash/as3variables/
http://www.photonstorm.com/archives/1136/flash-game-dev-tip-1-creating-a-cross-game-communications-structure
the above problem results in the folowing error but i believe it is caused by not creating a Collisions var in the Back1 class
ArgumentError: Error #1063: Argument count mismatch on Bumper(). expected: 2, value 0.
at flash.display::MovieClip/gotoAndStop() at
DocumentClass/onRequestStart()DocumentClass.as:64] at
flash.events::EventDispatcher/dispatchEventFunction() at
flash.events::EventDispatcher/dispatchEvent() at
MenuScreen/onClickStart()MenuScreen.as:18]
package
{
import flash.display.MovieClip;
import flash.events.*;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.geom.Point;
import Bumper;
//import Back1;
public class Test extends MovieClip
{
public var leftBumping:Boolean = false;
public var rightBumping:Boolean = false;
public var upBumping:Boolean = false;
public var downBumping:Boolean = false;
public var leftBumpPoint:Point = new Point(-30,-55);
public var rightBumpPoint:Point = new Point(30,-55);
public var upBumpPoint:Point = new Point(0,-120);
public var downBumpPoint:Point = new Point(0,0);
public var scrollX:Number = 0;
public var scrollY:Number = 500;
public var xSpeed:Number = 0;
public var ySpeed:Number = 0;
public var speedConstant:Number = 4;
public var frictionConstant:Number = 0.9;
public var gravityConstant:Number = 1.8;
public var jumpConstant:Number = -35;
public var maxSpeedConstant:Number = 18;
public var doubleJumpReady:Boolean = false;
public var upReleasedInAir:Boolean = false;
public var keyCollected:Boolean = false;
public var doorOpen:Boolean = false;
public var currentLevel:int = 1;
public var animationState:String = "idle";
public var bulletList:Array = new Array();
public var enemyList:Array = new Array();
public var bumperList:Array = new Array();
public var back1:Back1;
public var collisions:Collisions;
//public var back1:Collisions = new Collisions ;
public var player:Player;
public function Test()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
public function init(e:Event):void
{
player = new Player(320, 360);
back1 = new Back1();
collisions = new Collisions();
//back1.collisions = new Collisons();
addBumpersToLevel1();
}
public function addBumpersToLevel1():void
{
addBumper(500, -115);
addBumper(740, -115);
}
public function addPlayerTolevel1():void
{
addPlayer(320, 360);
}
public function loop(e:Event):void
{
trace("back1.collisions "+back1.collisions);
trace("back1 "+back1);
trace("collisions "+collisions);
if (back1.collisions.hitTestPoint(player.x + leftBumpPoint.x,player.y + leftBumpPoint.y,true))
{
just in case i've added Bumper.as
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Bumper extends MovieClip{
public function Bumper(xLocation:int, yLocation:int) {
// constructor code
x = xLocation;
y = yLocation;
addEventListener(Event.ENTER_FRAME, bumper);
}
public function bumper(e:Event):void{
//code here
}
}
}
Player.as
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Player extends MovieClip {
public function Player(xLocation:int, yLocation:int) {
// constructor code
x = xLocation;
y = yLocation;
}
// public function removeSelf():void {
// trace("remove enemy");
// removeEventListener(Event.ENTER_FRAME, loop);
// this.parent.removeChild(this);
// }
}
}
the Back1.as file (note it's got to be instanced wrong)
package {
import flash.display.MovieClip;
public class Back1 extends MovieClip {
//public var collisions:Back1;
//what should i put here?
}
}
I am not sure I understand completely what you mean. The question is phrased strange.
I assume you want to achieve a collision between your background object (The Back class) and a player object? I can't see from the code you have posted what the player object is since there is no such variable in your Test class.
To test a collision check between two objects use the following code:
if(someObject.hitTestObject(anotherObject))
Or in your case when using hitTestPoint:
if(back1.hitTestPoint(player.x, player.y,true))
Then again I don't know from the code you have posted how the back1 class looks like. If it extends a MovieClip or Sprite and you have a Player class that does the same (OR any DisplayObject) this should work.
This:
Argument count mismatch on Bumper(). expected: 2, value 0.
The error you get seems to come from another place not shown in your code. I would assume you did not pass any parameters into the Bumper class' constructor.
Btw, is this a Flash IDE sample or some other program such as FlashDevelop or FlashBuilder? If you are using the Flash IDE and are trying to attach code to a movie clip instance placed out on the scene I don't think its possible to pass parameters to it. Sorry been a while since I've worked in the Flash IDE.
EDIT:
Here's some sample code:
//:: Change Back1 class to this
package {
import flash.display.MovieClip;
public class Back1 extends MovieClip {
public function Back1()
{
graphics.beginFill(0xFF0000);
graphics.drawRect(0, 0, 50, 50);
graphics.endFill();
}
}
}
//:: Then in your Main class (Or the Test class) add the following
var player:Player = new Player(25, 25);
var collidable:Back1 = new Back1();
addChild(player);
addChild(collidable);
//:: Goes in your loop/update
if (collidable.hitTestPoint(player.x, player.y, true))
{
trace("HIT PLAYER");
}
How you apply the graphics to the Back1 class is up to you, I just drew a simple box. It could be anything.
Set default parameters for Bumper class:
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Bumper extends MovieClip{
public function Bumper(xLocation:int = 0, yLocation:int = 0) {
// constructor code
x = xLocation;
y = yLocation;
addEventListener(Event.ENTER_FRAME, bumper);
}
public function bumper(e:Event):void{
//code here
}
}
}
Related
I want to define my variables in my game document class, then use some of those variables in my Movement class. However, when I use these variables in my movement class I get tons of Compiling Errors saying that they're all undefined.
Thus my question is, why are my public variables not passed over to my other class? I have imported the class by doing import game; so this leaves me confussed. I'm probably just doing it wrong, but help is much appreciated.
Timeline
addChild((new Movement));
Game Document Class
package
{
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class game extends MovieClip
{
public var area1:Boolean = true;
public var area2:Boolean = false;
public var area3:Boolean = false;
public var player1:Boolean = true;
public var playerPosKeeper_mc:MovieClip = new mc_PlayerPosKeeper();
public var up_dpad:MovieClip = new dpad_Up();
public var down_dpad:MovieClip = new dpad_Down();
public var left_dpad:MovieClip = new dpad_Left();
public var right_dpad:MovieClip = new dpad_Right();
public var menu_dpad:MovieClip = new dpad_Menu();
public var run_dpad:MovieClip = new dpad_Menu();
public var barrierRoof1_game:MovieClip = new game_BarrierRoof();
public var barrierRoof2_game:MovieClip = new game_BarrierRoof();
public var barrierSide1_game:MovieClip = new game_BarrierSide();
public var barrierSide2_game:MovieClip = new game_BarrierSide();
public function game()
{
trace("SUCCESS | Constructed Game Class");
}
}
}
Movement Class
package
{
import game;
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.TouchEvent;
import flash.net.dns.AAAARecord;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
public class Movement extends MovieClip
{
var inMotion:Boolean = false;
public function Movement()
{
trace("SUCCESS | Constructed Movement Class");
addChild(playerPosKeeper_mc);
playerPosKeeper_mc.x = 384;
playerPosKeeper_mc.y = 46;
addChild(up_dpad);
up_dpad.x = 55;
up_dpad.y = 336;
addChild(down_dpad);
down_dpad.x = 57;
down_dpad.y = 432;
addChild(left_dpad);
left_dpad.x = 19;
left_dpad.y = 372;
addChild(right_dpad);
right_dpad.x = 118;
right_dpad.y = 372;
addChild(menu_dpad);
menu_dpad.x = 61;
menu_dpad.y = 377;
addChild(run_dpad);
run_dpad.x = 684;
run_dpad.y = 369;
addChild(barrierRoof1_game);
barrierRoof1_game.x = 0;
barrierRoof1_game.y = 0;
addChild(barrierRoof2_game);
barrierRoof2_game.x = 0;
barrierRoof2_game.y = 470;
addChild(barrierSide1_game);
barrierSide1_game.x = 0;
barrierSide1_game.y = 0;
addChild(barrierSide2_game);
barrierSide2_game.x = 790;
barrierSide2_game.y = 0;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
up_dpad.addEventListener(TouchEvent.TOUCH_BEGIN, moveUpTouchBEGIN);
up_dpad.addEventListener(TouchEvent.TOUCH_END, moveUpTouchEND);
}
public function moveUpTouchBEGIN(e:TouchEvent):void
{
trace("Touch Began")
}
public function moveUpTouchEND(e:TouchEvent):void
{
trace("Touch Ended")
}
}
}
You are confused because "public" does not mean "global". Declaring variable as public means you want to grant an access to it to any entity, given the entity knows where that variable is.
Lets see what you have there.
Top display object: stage.
Main timeline: game is a child of stage.
MovieClips up_dpad, down_dpad and so on, all are fields of the game instance.
Movement: instance is a child of game.
In the Movement you are trying to access up_dpad and others, but they are kept as fields of game instance and have nothing to do with the Movement instance. That's why they are outside of Movement's addressing context.
So, if you want to have these variables declared as game fields, you need to address them from the Movement in a correct way.
Forget the timeline. In the Game (for the sake's sake never call classes in lowercase unless at the gunpoint) which is, I believe, a root document class:
public function Game()
{
trace("SUCCESS | Constructed Game Class");
// Pass reference to this instance to the constructor.
var aMove:Movement = new Movement(this);
// Add it as a child.
addChild(aMove);
}
In Movement:
public function Movement(main:Game)
{
trace("SUCCESS | Constructed Movement Class");
// Access variables inside Game instance via given reference.
addChild(main.playerPosKeeper_mc);
main.playerPosKeeper_mc.x = 384;
main.playerPosKeeper_mc.y = 46;
// ...and so on
}
These are basics of Object Oriented Programming. If you want to access anything inside an object, you need to access the object first.
I'm trying to do something very basic, add a movie clip from the library to the stage. I created a class called link that extends MovieClip. I have two movie clips in the library, the first one that is initially loaded contains buttons that should remove the first movie clip and load the second. However, I am unable to load the second using addChild(). I'm hoping that there is something obvious that I'm missing. I'm fairly new to AS3. Here is the code from the link class:
package classes.GEN1P0
{
import flash.display.SimpleButton;
import flash.display.*;
import flash.events.*;
import fl.controls.*;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
public class link extends MovieClip
{
public var links:Vector.<SimpleButton > = new Vector.<SimpleButton >;
public var sourceMap:redMC = new redMC ;
public var sourceMap2:blueMC = new blueMC ;
public var panZoomMap:PanZoomMap = new PanZoomMap(sourceMap,704,556.3);
public var diagram:PanZoomMap = new PanZoomMap(sourceMap2,704.45,556.3);
public var zoomControls:ZoomControls = new ZoomControls(panZoomMap);
public var zoomControls2:ZoomControls = new ZoomControls(diagram);
public var navWindow:NavigatorWindow = new NavigatorWindow(panZoomMap);
public var navWindow2:NavigatorWindow = new NavigatorWindow(diagram);
public function link()
{
}
/////////////////////////////
//Vector for Links
/////////////////////////////
public function linkVector():void
{
for (var m:int = 0; m < 2; m++)
{
var linkNumb:SimpleButton = RunWise_GEN_1P0_Electrical_Schematic.sourceMap.panner.schematic.link_movies.getChildAt(m);
if ((linkNumb is SimpleButton))
{
links.push(linkNumb);
var linkName:String = links[m].name;
}
}
for (var n:int = 0; n<links.length; n++)
{
links[n].addEventListener(MouseEvent.CLICK, linkTo);
}
function linkTo(e:Event):void
{
addChild(diagram);
diagram.x = 291.35;
diagram.y = 22.15;
RunWise_GEN_1P0_Electrical_Schematic.panZoomMap.parent.removeChild(RunWise_GEN_1P0_Electrical_Schematic.panZoomMap);
switch (e.target.name)
{
case "PPOS":
trace ("PPOS");
break;
case "PYKPOS":
trace ("PYKPOS");
break;
}
}
}
//End Code Here
}
}
Should be as simple as
var _link:link = new link();
addChild(_link);
Note: Typically when you create a Class in AS3 you use uppercase for the first letter of the Class name
public class Link extends MovieClip
I'm still really new about classes and stuffs. So, I tried making this and I got an error: Access of undefined property.
Why speedX and speedY var still error although I've defined it in public var in the main class?
Thanks!
EDITED: I've tried calling the variables from other class with main.speedX and main.speedY
But it got error : Cannot access a property or method of a null object reference.
at Ball/moveBall()
This is the Main code:
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Main extends MovieClip
{
public var speedX:Number = 5;
public var speedY:Number = 5;
public var speedMax:Number = 10;
private var ball:MovieClip = new Ball();
private var paddle:MovieClip = new Paddle();
public function Main()
{
paddle.addEventListener(Event.ENTER_FRAME, movePaddle);
addChild(ball);
addChild(paddle);
}
}
}
This is the Ball Movie Clip Code:
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Ball extends MovieClip
{ public var main:Main;
public function Ball()
{addEventListener(Event.ENTER_FRAME, moveBall);
main= new Main();
}
public function moveBall(e:Event):void
{
x += main.speedX;
y += main.speedY;
}
}
}
That's because your class Ball cannot access speedX and speedY inside the event callback. Why not add speedX and speedY to your Ball class directly instead ?
public class Ball extends MovieClip
{
public var speedX:Number;
public var speedY:Number;
public function Ball(sX:Number = 0, sY:Number = 0)
{
this.speedX = sX;
this.speedY = sY;
addEventListener(Event.ENTER_FRAME, moveBall);
}
public function moveBall(e:Event):void
{
x += speedX;
y += speedY;
}
}
Here's another possible solution where you would be passing main to ball to use the values of speed stored in Main.
public class Main extends MovieClip
{
public var speedX:Number = 5;
private var ball:MovieClip;
public function Main()
{
ball=new Ball(this);
addChild(ball);
}
}
and
public class Ball extends MovieClip
{
private var _main:Main;
public function Ball(main:Main)
{
_main=main;
addEventListener(Event.ENTER_FRAME, moveBall);
}
public function moveBall(e:Event):void
{
x += _main.speedX;
}
}
}
I'm making a vertical (constantly) scrolling shooter & am trying to instantiate objects based on a timer. For example: At 30 seconds, place a building # x, y.
My problem is that the "building" is instantiated when the game starts and then again at the 30 second mark - instead of only # the 30 second mark.
If anyone could steer me in the correct direction, it would be greatly appreciated.
package com.gamecherry.gunslinger
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class ObjectPlacer extends MovieClip
{
private var Build01Timer:Timer;
private var canPlace:Boolean = true;
private var stageRef:Stage;
private var startX:Number;
private var startY:Number;
private var time:int = 5000;
public function ObjectPlacer(stageRef:Stage) : void
{
this.stageRef = stageRef;
var Build01Timer = new Timer(time, 1);
Build01Timer.addEventListener(TimerEvent.TIMER, placeTimerHandler, false, 0, true);
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
Build01Timer.start();
}
private function loop(e:Event): void
{
if (canPlace)
{
var BuildingsLeft01:BuildingsLeft = new BuildingsLeft(stage, 720, -540);
BuildingsLeft01.scaleX = -1;
stageRef.addChildAt((BuildingsLeft01), 2);
canPlace = false;
}
}
private function placeTimerHandler(e: TimerEvent) : void
{
canPlace = true;
}
private function removeSelf() : void
{
removeEventListener(Event.ENTER_FRAME, loop);
if (stageRef.contains(this))
stageRef.removeChild(this);
}
}
}
Where am I going wrong?
Thank you for looking.
Here's the first of your class:
public class ObjectPlacer extends MovieClip
{
private var Build01Timer:Timer;
**private var canPlace:Boolean = true;**
You're setting it to TRUE at the start, set it to false, and that would solve your problem :)
the code below sets up a List object in the main controller class that uses a custom cell renderer (CustomListCell class). the CustomListCell class creates a Button object for the cell that will be used to delete itself from the List's DataProvider.
how can i properly access the parent List object from its custom cell renderer?
//Controller Class
private function createList():void
{
provider = new DataProvider(data);
list = new List();
list.width = 200;
list.height = 400;
list.rowHeight = 50;
list.dataProvider = provider;
list.setStyle("cellRenderer", CustomListCell);
}
-----
//CustomListCell Class
import fl.controls.Button;
public class CustomListCell extends Sprite implements ICellRenderer
{
public function CustomListCell()
{
var button:Button = new Button();
button.label = "Delete Cell";
button.addEventListener(MouseEvent_MOUSE_DOWN, deleteCellHandler);
addChild(button);
}
private function deleteCellHandler(evt:MouseEvent):void
{
//Access List/DataProvider Here
}
//required implemented ICellRenderer functions follow
}
UPDATE
the following is my working custom renderer that implements ICellRenderer with Flash v3 List component. the List's dataProvider consists of 2 elements for each cell: randomColor and randomNumber.
package
{
//Imports
import fl.controls.Button;
import fl.controls.List;
import fl.controls.listClasses.ICellRenderer;
import fl.controls.listClasses.ListData;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.geom.ColorTransform;
//Class
public class TouchListRenderer extends Sprite implements ICellRenderer
{
//Properties
private var cellWidthProperty:Number;
private var cellHeightProperty:Number;
private var dataProperty:Object;
private var listDataProperty:ListData;
private var selectedProperty:Boolean;
//Cell Display Objects
private var backgroundCanvas:MySprite = new MySprite();
private var numberTextField:TextField = new TextField();
private var button:Button = new Button();
//Constructor
public function TouchListRenderer()
{
}
//Size Setter (Getter Functions Intentionally Omitted)
public function setSize(width:Number, height:Number):void
{
cellWidthProperty = width;
cellHeightProperty = height;
}
//Data Setter
public function set data(value:Object):void
{
dataProperty = value;
}
//Data Getter
public function get data():Object
{
return dataProperty;
}
//List Data Setter
public function set listData(value:ListData):void
{
listDataProperty = value;
}
//List Data Getter
public function get listData():ListData
{
return listDataProperty;
}
//Selected Setter
public function set selected(value:Boolean):void
{
selectedProperty = value;
layout();
}
//Selected Getter
public function get selected():Boolean
{
return selectedProperty;
}
//Size And Layout
private function layout():void
{
var newColor:ColorTransform = new ColorTransform();
newColor.color = dataProperty.randomColor;
backgroundCanvas.transform.colorTransform = newColor;
backgroundCanvas.scaleX = cellWidthProperty / backgroundCanvas.width;
backgroundCanvas.scaleY = cellHeightProperty / backgroundCanvas.height;
numberTextField.text = dataProperty.randomNumber;
numberTextField.autoSize = TextFieldAutoSize.LEFT;
numberTextField.textColor = 0xFFFFFF;
numberTextField.x = 50;
numberTextField.y = cellHeightProperty / 2 - numberTextField.height / 2;
numberTextField.border = true;
numberTextField.selectable = false;
button.label = "Delete";
button.x = cellWidthProperty - button.width - 50;
button.y = cellHeightProperty / 2 - button.height / 2;
button.drawNow();
button.addEventListener(MouseEvent.MOUSE_DOWN, buttonClickEventHandler);
addChild(backgroundCanvas);
addChild(numberTextField);
addChild(button);
}
//Button Click Event Handler
private function buttonClickEventHandler(evt:MouseEvent):void
{
List(listDataProperty.owner).removeItemAt(listDataProperty.index);
}
//Style Setter
public function setStyle(style:String, value:Object):void
{
}
//Mouse State Setter
public function setMouseState(state:String):void
{
}
}
}
package
{
import flash.display.Sprite;
public class MySprite extends Sprite
{
public function MySprite()
{
graphics.beginFill(0xFF0000);
graphics.drawRect(0, 0, 10, 10);
graphics.endFill();
}
}
}
ugh! the answer was in front of me the whole time! next time remind me to check the docs:
List(listData.owner)
fl.controls.listClasses.ListData.owner
There are multiple ways to do this.
Here is a very hacky solution: Use an icon, and have that icon dispatch a close event.
The idea is you'll place a custom MovieClip in each list cell as icon. That icon will dispatch an event with the index of the cell clicked so you can remove it.
1st step: Make a basic custom event to pass cell index through:
package{
import flash.events.Event;
public class CloseEvent extends Event{
public static const CLOSE:String = 'close';
public var index:int;
public function CloseEvent(type:String,bubbles:Boolean = true,cancelable:Boolean=true){
super(type,bubbles,cancelable);
}
}
}
2nd step:: Draw a close icon or something, convert it to MovieClip and Export for Actionscript
3rd step: Add the event listener to dispatch the custom event when the close icon is clicked.
Inside the close icon Movie Clip I've placed the following actions:
import fl.controls.listClasses.CellRenderer;
//setup click
buttonMode = true;
if(parent) parent.mouseChildren = true;
addEventListener(MouseEvent.MOUSE_DOWN,dispatchClose);
//setup event
var closeEvent:CloseEvent = new CloseEvent(CloseEvent.CLOSE,true);
if(parent) closeEvent.index = CellRenderer(parent).listData.index;
//listen to click and pass on
function dispatchClose(event:MouseEvent):void {
dispatchEvent(closeEvent);
}
Very basic stuff, listen for mouse down, create an event and set the index and dispatch that event on click. The icon is added to a cell renderer, therefor the cell render is it's parent which it has a listData property among others, which holds the index of the cell.
So here's how the test snippet looks:
import fl.data.DataProvider;
var dp:DataProvider = new DataProvider();
for(var i:int = 0 ; i < 30 ; i++) dp.addItem({label:'item'+(i+1),icon:Close});
ls.dataProvider = dp;
addEventListener(CloseEvent.CLOSE,deleteItem);
function deleteItem(event:CloseEvent):void {
ls.removeItemAt(event.index);
}
Since the CloseEvent bubbles, we can catch it from outside the cell renderer's icon and tell the list to remove the item at that index. It's possible to do that within the icon, but it will be necessary to 'climb' up the hierarchy all the way to the list, and it's pretty hacky already.
I did this because, I was probably as lazy as #TheDarkIn1978 :P to implement the ICellRenderer functions. Then I looked at question code again and didn't understand why the custom cell extends a Sprite, when CellRenderer already implements the ICellRenderer functions already.
So here is my attempt to do it in a less hacky manner:
package{
import fl.controls.*;
import fl.controls.listClasses.*;
import fl.data.*;
import flash.events.*;
public class SCListCell extends CellRenderer implements ICellRenderer{
protected var closeButton:Button;
protected var closeEvent:CloseEvent;
override protected function configUI():void {
super.configUI();
closeButton = new Button();
closeButton.label = 'x';
closeButton.buttonMode = true;
closeButton.setSize(30,20);
closeButton.drawNow();
closeButton.addEventListener(MouseEvent.CLICK,close);
addChild(closeButton);
closeEvent = new CloseEvent(CloseEvent.CLOSE);
}
private function close(event:MouseEvent):void{
closeEvent.index = listData.index;
dispatchEvent(closeEvent);
}
override protected function drawLayout():void{
mouseChildren = true;
closeButton.x = width-closeButton.width;
}
}
}
Used the same CloseEvent to pass the index, and the custom cell has direct access to the listData object to fetch the index, so the sample snippet looks like this:
import fl.data.DataProvider;
var dp:DataProvider = new DataProvider();
for(var i:int = 0 ; i < 30 ; i++) dp.addItem({label:'item'+(i+1)});
ls.dataProvider = dp;
addEventListener(CloseEvent.CLOSE,deleteItem);
function deleteItem(event:CloseEvent):void {
ls.removeItemAt(event.index);
}
ls.setStyle('cellRenderer',SCListCell);
So to answer your question:
how can i properly access the parent
List object from its custom cell
renderer?
You can use the listData property of the cell renderer.
You can if you want to, but it means going up a few levels:
package{
import fl.controls.*;
import fl.controls.listClasses.*;
import fl.data.*;
import flash.events.*;
public class SCListCell extends CellRenderer implements ICellRenderer{
protected var closeButton:Button;
override protected function configUI():void {
super.configUI();
closeButton = new Button();
closeButton.label = 'x';
closeButton.buttonMode = true;
closeButton.setSize(30,20);
closeButton.drawNow();
closeButton.addEventListener(MouseEvent.CLICK,close);
addChild(closeButton);
}
private function close(event:MouseEvent):void{
List(this.parent.parent.parent).removeItemAt(listData.index);
}
override protected function drawLayout():void{
mouseChildren = true;
closeButton.x = width-closeButton.width;
}
}
}
Which leaves the list creation part as simple as:
import fl.data.DataProvider;
var dp:DataProvider = new DataProvider();
for(var i:int = 0 ; i < 30 ; i++) dp.addItem({label:'item'+(i+1)});
ls.dataProvider = dp;
ls.setStyle('cellRenderer',SCListCell);
CloseEvent isn't needed in this case.
HTH