Copy link to clipboard
Copied
Hi.
I created a class based on a great tutorial. It works and all that. Then I learned from another tutorial and that works great. The problem is that I'm trying to fuse them together and am just under the comprehension level for this. Could someone take a look and help me out, preferably explaining why I keep getting this error? I'll try and be as clear as possible about my needs and I'll show the code:
Needs:
I want to create a button using AS3 that goes into a folder and grabs an image. I want to be able to use this over and over again so I can have, for example, three buttons that are different sizes with different images in them on the stage at the same time. I created (or learned to create) this class called Image in order to do so.
package {
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.net.URLRequest;
import flash.display.Loader;
import flash.events.MouseEvent;
import flash.events.Event;
//import flashx.textLayout.elements.InlineGraphicElement;
public class Image extends Sprite{
private var _label:String;
private var _fontName:String;
private var _fontSize:int;
private var _fontColor:uint;
private var _embedFonts:Boolean;
private var _bkgdColor:uint;
private var _width:Number;
private var _height:Number;
private var _myImage:String;
public function Image( label:String = "Click Here",
fontName:String = "Arial",
fontSize:int = 14,
fontColor:uint = 0x000000,
embedFonts:Boolean = false,
bkgdColor:uint = 0xFFCC00,
width:Number = 150,
height:Number = 30,
myImage:String = "images/course_icons/default.png") {
// BEGIN constructor code ..........................................................................................
// giving private variables a reusable public variable name
_label = label;
_fontName = fontName;
_fontSize = fontSize;
_fontColor = fontColor;
_embedFonts = embedFonts;
_bkgdColor = bkgdColor;
_width = width;
_height = height;
_myImage = myImage;
buttonMode = true;
mouseChildren = false;
// this calls the below funtion whenever this class is called
draw();
// END constructor code .............................................................................................
}
// function called to draw the box for the background
private function draw():void{
//first remove any existing elements, if any:
while(this.numChildren > 0) {
this.removeChildAt(0);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
LINE 61 var imgRequest:URLRequest = new URLRequest(myImage);
var imgLoader:Loader = new Loader();
this.addChild (imgLoader);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
}
// creates a new shape named 'bkgd' and gives it properties
var bkgd:Shape = new Shape();
bkgd.graphics.beginFill(_bkgdColor);
bkgd.graphics.drawRect(0, 0, _width, _height);
bkgd.graphics. endFill();
addChild(bkgd);
// this is the TextFormat class
var tFormat:TextFormat = new TextFormat();
tFormat.font = _fontName;
tFormat.size = _fontSize;
tFormat.color = _fontColor;
// this is the TextField attributes
var tField:TextField = new TextField;
tField.multiline = true;
tField.wordWrap = true;
tField.selectable = false;
tField.embedFonts = _embedFonts;
tField.defaultTextFormat = tFormat;
tField.autoSize = TextFieldAutoSize.CENTER;
tField.antiAliasType = AntiAliasType.ADVANCED;
tField.text = _label;
tField.x = _width / 2 - tField.width / 2;
tField.y = _height / 2 - tField.height / 2;
addChild(tField);
}
// creating 'setter' functions that allow private variables in classes to be assigned new values at any time from the outside
// uses the 'set' keyword to create a function that from outside the class can be treated like a property
public function set label(value:String) :void{
_label = value;
draw();
}
public function set fontName(value:String) :void{
_fontName = value;
draw();
}
public function set fontColor(value:int) :void{
_fontColor = value;
draw();
}
public function set fontSize(value:int) :void{
_fontSize = value;
draw();
}
public function set embedFonts(value:Boolean) :void{
_embedFonts = value;
draw();
}
public function set bkgdColor(value:int) :void{
_bkgdColor = value;
draw();
}
public override function set width(value:Number) :void{
_width = value;
draw();
}
public override function set height(value:Number) :void{
_height = value;
draw();
}
LINE 151 public override function set imagePic(value:String) :void{
_imagePic = value;
draw();
}
}
}
-------------------------------------------------
Inside the FLA that uses the class I have the following code:
var btn1:Image = new Image();
btn1.label = "Weatherization Weatherization Weatherization";
btn1.fontColor = 0xFFFFFF; //white
btn1.width = 100;
btn1.height = 100;
btn1.fontSize = 11;
btn1.bkgdColor = 0xFF0000; // red
btn1.x = 200;
LINE 12 btn1.myImage = "images/course_icons/w.png";
addChild (btn1);
Issues:
As the code stands as written above, I get this error:
Line 151 1020: Method marked override must override another method.
If I comment out the whole snippet of Line 151 and test it I get this error:
Line 61 1120: Access of undefined property myImage.
And if I comment out that code (line 61-63 is the whole snippet) I get this error, which pertains to the code in the FLA:
Line 12 1119: Access of possibly undefined property myImage through a reference with static type Image.
And if I comment out that code it gives me the correct box, color, location, text, etc, but no image filling the box
------------------------------------------
Any help would be very welcome
Thanks in advance,
Van
> it came back with "this is hard" eight times
No wonder Your script is fundamentally wrong that you are wiping off everything and start all over again and again every time one of the following properties is changed: _label, _fontName, _fontSize, _fontColor, _embedFonts, _bkgdColor, _width, _height, _myImage. In fact you should get "this is hard" 9 times not 8 times (because there are 9 properties)
You have to ask yourself what do you want to achieve here. From your code I can see that you want
...Copy link to clipboard
Copied
You are extending Sprite and overriding a method named imagePic - but there is no imagePic method in Sprite to be overridden... Have you tried simply removing 'override' from the method signature?
Copy link to clipboard
Copied
Line 151
Remove the word "override" because you are not overriding the function
Line 61
"myImage" should be "_myImage"
Line 12
"btn1.myImage" should be "btn1.imagePic"
Just a quick glance though, so you may have some other issues too - if so let us know
Copy link to clipboard
Copied
151 - I removed 'override' and changed imagePic to _myImage which is the var name I am using (imagePic was old)
61 - I changed "myImage" to "_myImage"
12 - I made that change but had to change it back to myImage because I wasn't using "imagePic" anymore and think I might have left that in there by mistake and wasy pulling this error - Line 12 1119: Access of possibly undefined property imagePic through a reference with static type Image.
So, after making all the changes you suggested I pulled this error.
Error: Error #1502: A script has executed for longer than the default timeout period of 15 seconds.
at Image/draw()
at Image/set label()
at base_fla::MainTimeline/frame1()
Not a very informative error. However:
- base.fla is where the error with line 12 was originally, and I now changed it to 'myImage'
- Image is the class file
if you would like me put the full code on again after these changes just let me know. I didn't want to put it on this time so the page wasn't a thousand miles high and scare people away! =D
Copy link to clipboard
Copied
The reason you are getting the script execution timeout error is this section of your code:
while(this.numChildren > 0) {
this.removeChildAt(0);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
var imgRequest:URLRequest = new URLRequest(myImage);
var imgLoader:Loader = new Loader();
this.addChild (imgLoader);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
}
You will never get out of this infinite loop because you are adding a child after removing one forever. Move the bits in between //>>> outside the loop.
I bet there are other issues too but one thing at a time
Copy link to clipboard
Copied
Well, the good news is that there were no reported errors.
=D
The bad news is that the image didn't show up in the box that was created. There WAS a box, red, with text in it just like it is coded, just no image. I double checked the path of the image and that can't be the problem. I put the images in the same folder and changed the path to just btn1.myImage = "w.png"; which I am pretty sure is correct.
I put the code that you showed me (between the //>>>>>>>>>>>) out of the loop (duh! what was I thinking?) and put it directly below the TextField section so it is the last thing in that function draw().
I also went in and moved anything to do with _myImage or myImage var just below the label variable thinking that it might actually be hidden below a red box but it didn't seem to make a diff.
Copy link to clipboard
Copied
Listen to the "complete" event to see if your loading is actually completing.
Copy link to clipboard
Copied
I put a trace in the set myImage section
public function set myImage(value:String) :void{
_myImage = value;
//trace ("did this happen");
draw();
}
and saw that the trace did indeed happen, but still no image. Maybe I don't know what you mean by 'listen to the complete event'. I'm sorry to keep bothering you and I am very grateful. You have been super helpful so far and I have learned from you. It is funny...I've been doing AS for like 8 years now but it just escapes me so much. Perhaps it is because I'm a graphic artist/illustrator and my mind doesn't work like a programmers. =/
Copy link to clipboard
Copied
What I meant was to set up the listener for your imgLoader:
private function loadImage():void {
var imgRequest:URLRequest = new URLRequest(_myImage);
var imgLoader:Loader = new Loader();
imgLoader.contentLoaderInfo.addEventListener(Event.OPEN, imgLoaderOpen);
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaderComplete);
this.addChild (imgLoader);
}
private function imgLoaderOpen(e:Event):void {
trace("imgLoader load started");
}
private function imgLoaderComplete(e:Event):void {
trace("imgLoader load completed");
}
Copy link to clipboard
Copied
I got an error on the three functions ( I cut and pasted your code):
Line 69 1013: The private attribute may be used only on class property definitions. (which is private function loadImage():void { )
Line 77 1013: The private attribute may be used only on class property definitions. (which is private function imgLoaderOpen(e:Event):void { )
Line 81 1013: The private attribute may be used only on class property definitions. (which is private function imgLoaderComplete(e:Event):void { )
package {
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.net.URLRequest;
import flash.display.Loader;
import flash.events.MouseEvent;
import flash.events.Event;
//import flashx.textLayout.elements.InlineGraphicElement;
public class Image extends Sprite{
private var _label:String;
private var _myImage:String;
private var _fontName:String;
private var _fontSize:int;
private var _fontColor:uint;
private var _embedFonts:Boolean;
private var _bkgdColor:uint;
private var _width:Number;
private var _height:Number;
public function Image( label:String = "Click Here",
myImage:String = "default.png",
fontName:String = "Arial",
fontSize:int = 14,
fontColor:uint = 0x000000,
embedFonts:Boolean = false,
bkgdColor:uint = 0xFFCC00,
width:Number = 150,
height:Number = 30) {
// BEGIN constructor code ..........................................................................................
// giving private variables a reusable public variable name
_label = label;
_myImage = myImage;
_fontName = fontName;
_fontSize = fontSize;
_fontColor = fontColor;
_embedFonts = embedFonts;
_bkgdColor = bkgdColor;
_width = width;
_height = height;
buttonMode = true;
mouseChildren = false;
// this calls the below funtion whenever this class is called
draw();
// END constructor code .............................................................................................
}
// function called to draw the box for the background
private function draw():void{
//first remove any existing elements, if any:
while(this.numChildren > 0) {
this.removeChildAt(0);
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
/*var imgRequest:URLRequest = new URLRequest(_myImage);
var imgLoader:Loader = new Loader();
this.addChild (imgLoader);*/
private function loadImage():void {
var imgRequest:URLRequest = new URLRequest(_myImage);
var imgLoader:Loader = new Loader();
imgLoader.contentLoaderInfo.addEventListener(Event.OPEN, imgLoaderOpen);
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaderComplete);
this.addChild (imgLoader);
}
private function imgLoaderOpen(e:Event):void {
trace("imgLoader load started");
}
private function imgLoaderComplete(e:Event):void {
trace("imgLoader load completed");
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// creates a new shape named 'bkgd' and gives it properties
var bkgd:Shape = new Shape();
bkgd.graphics.beginFill(_bkgdColor);
bkgd.graphics.drawRect(0, 0, _width, _height);
bkgd.graphics. endFill();
addChild(bkgd);
// this is the TextFormat class
var tFormat:TextFormat = new TextFormat();
tFormat.font = _fontName;
tFormat.size = _fontSize;
tFormat.color = _fontColor;
// this is the TextField attributes
var tField:TextField = new TextField;
tField.multiline = true;
tField.wordWrap = true;
tField.selectable = false;
tField.embedFonts = _embedFonts;
tField.defaultTextFormat = tFormat;
tField.autoSize = TextFieldAutoSize.CENTER;
tField.antiAliasType = AntiAliasType.ADVANCED;
tField.text = _label;
tField.x = _width / 2 - tField.width / 2;
tField.y = _height / 2 - tField.height / 2;
addChild(tField);
}
// creating 'setter' functions that allow private variables in classes to be assigned new values at any time from the outside
// uses the 'set' keyword to create a function that from outside the class can be treated like a property
public function set label(value:String) :void{
_label = value;
draw();
}
public function set myImage(value:String) :void{
_myImage = value;
draw();
//trace ("did this happen");
}
public function set fontName(value:String) :void{
_fontName = value;
draw();
}
public function set fontColor(value:int) :void{
_fontColor = value;
draw();
}
public function set fontSize(value:int) :void{
_fontSize = value;
draw();
}
public function set embedFonts(value:Boolean) :void{
_embedFonts = value;
draw();
}
public function set bkgdColor(value:int) :void{
_bkgdColor = value;
draw();
}
public override function set width(value:Number) :void{
_width = value;
draw();
}
public override function set height(value:Number) :void{
_height = value;
draw();
}
}
}
Copy link to clipboard
Copied
> I cut and pasted your code
You cut it all right but paste it wrong Paste it outside of the draw() function, and call loadImage() from draw().
Copy link to clipboard
Copied
I pasted the loadImage function under draw(), and in draw I placed loadImage(); to call that function.
It went without any errors, but id didn't call the trace text, nor did the image show up on the swf.
draw code |
---|
private function draw():void{ //BEGIN first remove any existing elements, if any::::::::::::::: while(this.numChildren > 0) { this.removeChildAt(0); } //END first remove any existing elements, if any::::::::::::::::: // START BOX/TEXT CREATION ************************************************************************************ // creates a new shape named 'bkgd' and gives it properties var bkgd:Shape = new Shape(); bkgd.graphics.beginFill(_bkgdColor); bkgd.graphics.drawRect(0, 0, _width, _height); bkgd.graphics. endFill(); addChild(bkgd); // this is the TextFormat class var tFormat:TextFormat = new TextFormat(); tFormat.font = _fontName; tFormat.size = _fontSize; tFormat.color = _fontColor; // this is the TextField attributes var tField:TextField = new TextField; tField.multiline = true; tField.wordWrap = true; tField.selectable = false; tField.embedFonts = _embedFonts; tField.defaultTextFormat = tFormat; tField.autoSize = TextFieldAutoSize.CENTER; tField.antiAliasType = AntiAliasType.ADVANCED; tField.text = _label; tField.x = _width / 2 - tField.width / 2; tField.y = _height / 2 - tField.height / 2; addChild(tField); // END BOX/TEXT CREATION *************************************************************************************** loadImage(); } // END function called to draw the box for the background /////////////////////////////////// // START LOAD IMAGE ========================================================== private function loadImage():void { var imgRequest:URLRequest = new URLRequest(_myImage); var imgLoader:Loader = new Loader(); imgLoader.contentLoaderInfo.addEventListener(Event.OPEN, imgLoaderOpen); imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaderComplete); this.addChild (imgLoader); } private function imgLoaderOpen(e:Event):void { trace("imgLoader load started"); } private function imgLoaderComplete(e:Event):void { trace("imgLoader load completed"); } // END LOAD IMAGE ============================================================= |
I just placed a trace "this is hard" inside of the loadImage function and it came back with "this is hard" eight times in the output box.
Copy link to clipboard
Copied
> it came back with "this is hard" eight times
No wonder Your script is fundamentally wrong that you are wiping off everything and start all over again and again every time one of the following properties is changed: _label, _fontName, _fontSize, _fontColor, _embedFonts, _bkgdColor, _width, _height, _myImage. In fact you should get "this is hard" 9 times not 8 times (because there are 9 properties)
You have to ask yourself what do you want to achieve here. From your code I can see that you want to (A) create a button dynamically, and (B) change everything after the button is created at will. Do you really want to achieve (B)? If so do you really want to change all of the 9 properties? If you want to change everything why don't you create a new button and just replace it?
Well, having said that it's easy either way - let me know if you want me to come up with a clean code!
Copy link to clipboard
Copied
Whew. I thought I was going crazy but it just turns out I'm stupid!
Well, here is what I would like to achieve:
I want to be able pull images, swf, and even video (if possible) from a folder into an interactive presentation.
- Say the first scene opens up and has 10 unique icons on it, each being either selectible or not (depending on circumstances like 'you do not have access to the information associate with this icon but I want to show it to you greyed out so you know that this exists in case you want access"). I would need to place them 5 side by side and 2 rows so I assume I would need access to altering the x and y properties.
so the user clicks a 'next button' which takes them to the next 'scene'....
- where there will be three swfs and 3 images (pngs for example) that the user will be able to select and interact with ( for the images think 'make bigger so we can see the details', and for the swf think of a diagram that is paused until they select it). once selected the image/swf will center itself on the stage and any text/navigation, etc 'behind it' will need to be 'greyed out' and have the interactivity turned off until the user closes/stops the swf from animating. now this might need to have the x, y, xScale, yScale alterable since the image/swf will center itself on the stage once selected
so the user clicks a 'next button' which takes them to the next 'scene'....
- where there is a brief video of a man chopping wood or something. again, like the swfs, everything that is not the video will have to be greyed out and disengaged while the video is playing.
the icons on the first scene will all be 100/100px, but will be different from each other. There will be text under each like 'class 101', 'class 102', etc.
the swf's on the second scene will be side by side, 200/300px, and will be at rest until triggered by a mouse click or something
the video on the third scene will be 400/400px and will be at rest until engaged somehow. the numbers are just an example. I just want to let you know that not all the elements (images, etc) will be the same size or in the same location.
I don't think I really need to change the colors of anything on the fly, nor do I need to change the text on the fly. But I would like to be able to create a button or image using the technique like 'button01.y = 70'.
I hope this makes sense. I really, REALLY appreciate your patience with me on this. I've learned enough to be dangerous with AS3, but I'm not a natural programmer so figuring out stuff is sometimes like pulling teeth. if you need me to make a few mock ups of the scenes just let me know and I can do that and upload them to my web page.
Thanks man.
Van
Copy link to clipboard
Copied
> I don't think I really need to change the colors of anything on the fly, nor do I need to change the text on the fly. But I would like to be able to create a button or image using the technique like 'button01.y = 70'.
Then you do not need public setters. You just pass all the parameters when you instanciate your class.
Copy link to clipboard
Copied
Thanks for all the help and advice! I really appreciate it and you helped me to learn some pretty important stuff. Sorry I'm so slow with this stuff but I'm an artist not a programmer so sometimes its like pulling teeth! =D
As for the main issue of not pulling the images in, it was because I left out the code: imgLoader.load(imgRequest); within the loadImage function.
I'm going to start over with this project. It was really mainly to learn a few techniques, which I have done. I have a more focused vision on this (with a lot of help from you), so I think it should go more smoothly. I really, really, REALLY appreciate the help you have given me. Thanks for your time!
Van
Copy link to clipboard
Copied
No worries
Find more inspiration, events, and resources on the new Adobe Community
Explore Now