I've ran into a weird problem with flash, I have an array of 92 buttons, at first it was all contained in a single array, the buttons up to the first 20th buttons work, the rest don't.
The buttons will take the user to the next scene basically.
So I tried to breakup the array into multiple arrays, so the first array contains the first 20, the second array the 21-40th and so on, the fifth array contains the 81-92 buttons.
The problem now is I will get this error message:
TypeError #1010: A term is undefined and has no properties
and it'll break all the buttons, rendering all the buttons unusable.
Therefore, I commented out the
for (var a=0; a<buttons.length; a++)
{
firstarray[a].addEventListener(MouseEvent.CLICK,ArraySelectOne);
secondarray[a].addEventListener(MouseEvent.CLICK,ArraySelectOne);
thirdarray[a].addEventListener(MouseEvent.CLICK,ArraySelectOne);
fourtharray[a].addEventListener(MouseEvent.CLICK,ArraySelectOne);
//fiftharray[a].addEventListener(MouseEvent.CLICK,ArraySelectOne);
}
in my button spawn function and the buttons from the first to fourth array works flawlessly well except the fifth, which when clicked, nothing happens.
So I tired to create a new function whereby it was only the fiftharray in it and called the new function in the spawner, same error, breaks everything.
Then I thought was there a button naming issue whereby i mistyped something, I took the button names in the fifth array and pasted them into the start of the fourtharray, replacing what was in it plus commenting out the fiftharray from my script.
The once unworkable buttons (81 to 92) worked, but now (61 to 80) didn't.
I tried combining all the arrays using the comarray, but only the first 20 buttons worked.
So I am wondering if is there a fix or something to solve this problem, much help is appreciated!
There is no need to have multiple arrays, remove them. The last array is obviously shorter than the rest and that's messing up your code -> you are pointing to an index that doesn't exist in your last array.
There is actually no need to have an array. You have 92 buttons, that's a nice bunch. Why not to put it to a movieclip instead? What's the need of the array?
Let's assume you select all your buttons and put them inside of movieclip called buttonsClip. Now you can just use this code, without typing all the instance names out to put them to the array (like the tutorial did it... that may work for 8 buttons, but 92... come on :) ):
import flash.display.MovieClip;
import flash.events.MouseEvent;
for(var i:uint=0; i<buttonsClip.numChildren; i++) {
var b:MovieClip = buttonsClip.getChildAt(i) as MovieClip; //Assuming the buttons are movieclips
b.addEventListener(MouseEvent.CLICK, onClick);
}
function onClick(e:MouseEvent):void {
trace(e.target.name);
}
I know this Question is currently 8 years old, but maybe this will help another person that is searching for the same thing.
I had pretty much the same problem and in my case it was just that I accidently skipped a number while naming all the Symbols in the libary that I wanted to be in this array. I had 42 Symbols but because of this mistake the function to load the array had 43 and obviously the program was confused about that.
Related
I want my swift code to create buttons using colors. I know I want to declare array but some of the things I have tried are not working. What I tried below is not working. I have tried to do various forms of wrapping but it did not work. The goal of this code is to not use any storyboards and do everything by code.
var red,blue = UIButton()
One compact way to declare two variables in one line is to use tuple notation:
let (red,blue) = (UIButton(), UIButton())
Perhaps that's what you're asking for. But there is no array in the story; it's hard to see why you mention arrays in the first place.
On the other hand, if you really do want an array as you claim, then it's hard to see what the names red and blue are for, since the elements of an array do not have names (with regard to the array). You could make an array of two new buttons by saying:
let arrayOfTwoButtons = (0..<2).map {_ in UIButton()}
I woukld like to form an Array which contains the widths of each label inside the customTableCell. As illustrated in the attached image, I managed to extract all the widths I am interested in but they are not all in the same array. Any idea how can I extrac t all the widths in ONE array?
#BrunoPastre is correct, but appending is also not the way to assign the values in the array. This function will be run many times for some cells, as you scroll up and down. You will end up with the same widths listed many times at different places in the array.
You should create the array with the right dimension, then assign them as cellsWidthsArray[indexPath.row] = cell.cellTextLabel.frame.size.width.
You should create your array only once, not every time tableView(_: UITableView, cellForRowAt: IndexPath) -> UITableViewCell is called. This can be achieved by moving the declaration of your array, on line 83, to somewhere outside of the function scope, but inside the class scope, like line 92. When you do that, cellsWitdhsArray will become a class variable, or an attribute, that can be accessed from anywhere inside the class
That method is called once per cell, if you declare a local variable cellsWidthArray its not going to persist across multiple calls of that function.
What you need is to "save" this array somewhere that isn't a local, temporary scope. The best way to do this is to save it as a property on the class.
I can see in your code you already have another array thats a property: tableViewRowsInsideSectionsArray. Scroll up to (hopefully) the very top of the class declaration in the same scope add your own cellsWidthArray.
It should look something like
class MyViewController {
...
private var cellsWidthArray: [CGFloat] = []
...
That way that local array isn't lost every time the function ends - it's owned by the view controller and is available anywhere within that class as long as that class exists.
HOWEVER, it may not work as you expect because another issue with that method (tableView(cellForRowAt:) is that it's only called when a cell is being displayed (visible on the screen). And it will be called multiple times if you scroll a cell off and back on the screen.
You can solve potential duplication by creating a dictionary where the key is something uniquely identifying the cell (it seems like its just going to be the text here) and the value is the width. Something like:
class MyViewController {
...
private var cellsWidthDictionary: [String: CGFloat] = [:]
...
func tableView(cellForRowAt:) { // I didn't feel like typing it all out
...
cellsWidthDictionary[theTextYouAreUsing] = width
But you now have another issue, the way you are getting the width, accessing the frame of the label just after you set the text, might not actually be correct. This function just prepares the cell, auto layout and frame adjustments might happen later.
A simple one line solution one might be tempted to do is to force a layout on the cell, after setting the text on the label, something like:
cell.cellTextLabel.sizeToFit() or cell.layoutIfNeeded()
that will just adjust the frame of the label to perfectly wrap the existing content.. but a much better solution would be to actually calculate it..
You could use https://developer.apple.com/documentation/foundation/nsstring/1531844-size
something like
let labelSize = (label.text?.size(attributes: [NSFontAttributeName: UIFont(name: label.font.fontName , size: label.font.pointSize)!]))
then accessing labelSize.width
You're still left with the problem of only having that function called when a cell is about to be displayed on the screen. You can either manually scroll through every cell to build that table if you're using it for debugging/testing/informative purposes. But otherwise you would need to do something else...
Fortunately, Swift has a function that calculates the size a string would take - you just have to make sure you specify the text/font/size/any other styling elements. I pointed it out above... you can just iterate through all the strings that you're feeding into the cells and generate the dictionary right then and there as soon as you get the data.
Keep in mind this assumes a single line, if you have a max width for the label or other constraints that would cause the text to be cut off you would need to be even more explicit - I encourage you to google how to calculate the size of a label based off your needs if so.
So when writing a game on Khan Academy When I try to remove a bullet from the array I run into the error "Object does not support method splice" I have been checking my code for hours and have not found out why it does not work. Ideas?
EDIT: The code used to remove a bullet is bullets[i].splice(i,1); and that is what errors out my code.
MVCE:
var bullets = [];
var bullet= function(x,y,blah)
{
//code that is not important here
};
bullets.push(bullet(0,0,30));
for(var I = 0; I < bullets.length; I++){
if(bulletRemove){
bullets[I].splice(i,1)
}
}
You have a variable named bullets:
var bullets = [];
(Side note: Why is there a random curly bracket right before this line?)
This bullets variable is an array. It holds instances of the Bullet class:
bullets.push(new Bullet(x, y, 10, player.x+bSize/2, player.y+bSize/2));
You can use the array to access a Bullet at a particular index, and then you can call functions of the Bullet class on that instance:
bullets[i].move();
You can also call the splice() function on the array itself:
bullets.splice(i,1);
However, you can't call the splice() function on a particular Bullet instance!
bullets[i].splice(i,1);
This line is taking an instance of Bullet from the i index of the bullets array, and then trying to call the splice() function from the Bullet class. But the Bullet class doesn't have a splice() function! This is what's causing the error.
Instead, you probably meant to call it on the array itself:
bullets.splice(i,1);
In the future, please please please try to narrow your problem down before posting a question. Try to post an MCVE instead of your entire project. You could have put together an example program that used just a few lines to create a hard-coded array and used that to demonstrate your problem. Chances are you would have found the problem yourself in the process of creating the MCVE!
I have a page full of mc_card's and want the user to choose which ones to add to their deck.
click a card and cardChosen = true for that card;
click again and cardChosen = false;
This works fine.
Upon choosing a card the frame number is stored in an array. Each card is on a separate frame and there are no duplicates.
Main.cardArray.push(this.currentFrame);
Upon clicking it again, I want to remove that frame number from the array:
Main.cardArray.splice(this.currentFrame, 1);
After I splice the array, I trace it, and I'm getting weird results. Sometimes it works like I would expect, but then it removes the wrong numbers and sometimes doesnt remove them at all.
splice() works in another way, that you try to use.
Here is statement:
splice(startIndex:int, deleteCount:uint, ... values):Array
So, first arg - start index in array to delete, and second arg - how much elements must be deleted from the start index.
K. I'm getting stuck here.
I'm trying to make an array with different color values.
My problem is that when I do...
teamColor[i] = currentColor... all color values in my array turn into the currentColor.
(I would upload more code, but that would be a massive mess, considering that I have code everywhere with references from movie clips that are as far as 3 layers deep. HOWEVER, this would be irrelevant anyways (probably), because I tested this with color values on my main timeline, without any references to or from anything deeply nested)
I'm GUESSING that this is just some horrible bug, but if it's not (and I hope it isn't), please guide me in what to do to fix this problem.
I would like to add that I tried adding strings in there and that the strings remained their original, intended, value, while the color exhibited the same phenomenon.
[Partially resolved]:
I changed my code by creating separate variables for each color instead of putting the variables into an array (not what I really wanted to do, but it works). My code looks like this:
`
if (teamColor != 0)
{
this["team"+teamColor+"Color"] = new ColorTransform(0,0,0,1,currentColor.redOffset,currentColor.greenOffset,currentColor.blueOffset,0)
teamColor = 0
namebox.addboxes()//function in a movieclip
}`
teamColor is now an int that is changed based on which box a user clicks from a movie clip that has a dynamically generated name, based off of what the variable value in a loop was when it was created. (E.G: 'tempboxname[ttns].name = i;')
teamColor is then equal to that name when the user clicks it.
I have another movieclip with colors in it and the above function is called to check if any teamColor change has occurred, and if it has, act accordingly. (The idea of having teamColor equal to 0 is so that if the user clicks twice, nothing changes. I other conditionals for other colors, all within the same function).
That is how I fixed me code.
It's not what I wanted, because it's not an array (meaning a seemingly infinite number of teamColors, and thus, teams) but it'll do for me. If anyone has any suggestions, feel free to suggest.
I'm no ActionScript wiz, but what it looks like to me is that currentColor is an object that is being passed into the array by reference. This means that all array entries that you assigned currentColor will be pointing at the same currentColor object, not a copy. My advice is to make a copy and then assign that into the array.
It would be much better if you could give me more code to look at. For instance, the loop that contains that code segment would be nice. If I find a different error I'll edit my answer.
here i'm creating and then adding simple 0xRRGGBB color objects into a vector. the color objects are then parsed into 0xRRGGBB hexadecimal strings and traced.
certainly it's not exactly what your looking for, but hopefully it will help you.
var red:uint = 0xFF0000;
var green:uint = 0x00FF00;
var blue:uint = 0x0000FF;
var colors:Vector.<uint> = new Vector.<uint>()
colors.push(red, green, blue);
for each (var color:uint in colors)
{
var output:String = color.toString(16);
while (output.length < 6)
output = "0" + output;
trace("0x" + output.toUpperCase());
}
Output:
//0xFF0000
//0x00FF00
//0x0000FF