Create a list of Button in Cocos2dx - cocos2d-x

When I create a list of button and I addTouchEventListener for it, like below code
for (int i = 0; i < btmPlay.size(); i++ )
{
btmPlay.at(i)->addTouchEventListener([&](Ref *sender, ui::Widget::TouchEventType type){
if (type == ui::Widget::TouchEventType::ENDED)
{
CCLOG("%i", i);
}
});
}
when I touch to the first button, the result is 12 ( btmPlay.size() = 13).
What errors?

In your closure, you're capturing the variable i by reference, and that's why clicking any button will print the same value, in this case 12. If, instead, you capture the variable i by value (by replacing [&] with [=]) then each button will print a different value in the range 0-12.
Btw, capturing i by reference in your example is also wrong, because by the time the closure is invoked, the variable is already out of scope, and printing it is UB.

Related

Looping through an array to display a quote

Attempting to loop through this array, stored in a JSON file. I want to be able to check if a quote is saved and then display it depending on whether it is saved or not.
_toggleCheck() {
var checked = !this.state.checked;
this.setState({ checked: checked });
// For loop to run through arrray and update booleans
for(int i = 0; i<quotesArray.length-1; i++;){
quotes.quotesArray[i].isSaved = checked;
}
this.props.onChange && this.props.onChange(this.props.name, checked);
}
In attempting to do this, I have come across this error and can not resolve it. Line 63 is the beginning of the for loop. I dont know how to use a for loop in react native and cant find any tutorials on line.
for(int i = 0; i<quotesArray.length-1; i++;){
^ remove this semicolon
By the way, are you sure you want i < quotesArray.length - 1 instead of i < quotesArray.length? You're skipping the last element when you add -1.

My OCR1A is changing even when 'if' condition is not met

I'm trying to code a simple PWM servo control that uses pin 11 on the Arduino Mega 2560. This servo should turn CW (clockwise) or CCW (counterclockwise) depending on pressing and holding one of the two buttons (L and R). The problem I seem to be running into is that the variable I have set to change the OCR1A(i) is incrementing even when the 'if' statements are not true. The buttons work as I've tested using the Serial.println(PINA) to make sure. I'm really not sure where I've gone wrong. I would appreciate any help.
void setup() {
// put your setup code here, to run once:
TCCR1A |= (1<<COM1A1)|(1<<WGM11)|(1<<WGM10);
TCCR1B = 0B00001100; // set mode 7 and prescale to 256
DDRB |= (1<<PB5); // data direction register for PORTB(pwm output pin 11)
DDRA = (1<<2)|(1<<3); // Last 2 digits of PORTA are inputs
Serial.begin(9600); //initialize the serial
}
void loop() {
int i = 63;
// This value controls the duty cycle, duty(%) = OCR1A/255*100
// 63 is just a random start position
OCR1A = i;
int swL;
int swR;
swL = PINA & 0b00000001;
swR = PINA & 0b00000010;
while(i<160) {
if (swR != 0b00000001) {
i++; // increments OCR1A when button R is pressed
Serial.println(PINA); // For testing button is pressed
Serial.println(OCR1A); // debugging use
Serial.println(i); // debugging use
delay(100);
}
if(swL != 0b00000010) {
i--; // negative increments when button L is pressed
Serial.println(PINA);
Serial.println(OCR1A);
Serial.println(i);
delay(100);
}
}
}
It seems like PINA & 0b00000001 provides some value to swL. Now I am not able to find the initial value of PINA but I assume that it is another variable having binary value and so when the two values perform a Bit-wise AND they provide a different value to swL.
I suppose this is the reason why the if condition
if (swL != 0b00000001) evaluates to TRUE and it then enters the if statement.
The same happens to the other variable swR and so it also enters the if statement.
I may be wrong but have a look at the lines:
swL = PINA & 0b00000001;
swR = PINA & 0b00000010;
Thanks, it turns out I just needed an extra set of eyes. My swR and swL were swapped. with a few other changes it now works as intended. Thank you all.

which method should i use to create a new keyboard using adobe flash

I'm trying to create a new keyboard somehow, for educational purposes.
I've written this code using actionscript 3.I've created an input text field (named it t1) .when the user presses q button on keyboard(which has an ASCII aquals 81 ) I want the letter b to be printed out on the text field so i've written this code :
stage.addEventListener(KeyboardEvent.KEY_DOWN, pressing);
function pressing(event:KeyboardEvent):void
{
//trace(event.keyCode);
if(event.keyCode==81)
t1.replaceSelectedText("b");
}
the problem was that the method replaceSelectedText prints the tow letters on the screen(q&b) which method can i use instead?
Any help would be appreciated.
When using the replaceSelectedText method, you first need to select the text you want to replace. This can be done with the "setSelection" method. This from the adobe help website:
setSelection(beginIndex:int, endIndex:int):void
"Sets as selected the text designated by the index values of the first and last characters, which are specified with the beginIndex and endIndex parameters."
At the moment, since you don't have any text selected, it appears to just be adding the text "b" as it's replacing nothing. Therefore, you should try first selecting the "q".
Alternatively, you can just use a different method. from the adobe help website:
replaceText(beginIndex:int, endIndex:int, newText:String):void
"Replaces the range of characters that the beginIndex and endIndex parameters specify with the contents of the newText parameter."
This would cut out an extra line of code.
I haven't actually done this myself, so if that doesn't work, here's the link to the adobe help page for Text Fields: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/TextField.html
I think that to do what you are looking for ( replace a char when it's typed ), a KeyboardEvent.KEY_DOWN is not enough, because when that event is fired, the text is not yet changed, so any change that you did in its handler to your text field will not cancel the insertion of the current typed char. Also, using KeyboardEvent.KEY_UP ( in addition to KeyboardEvent.KEY_DOWN ) will not resolve the problem, because you can fire n times a KeyboardEvent.KEY_DOWN event with the KeyboardEvent.KEY_UP event fired once !
So, I think that the best event that can do the job is the Event.CHANGE event which is fired every time the text of your text field is changed, so you can do like this :
// is there a char to replace ?
var replace_char:Boolean = false;
// the position of the char that we want to replace
var char_position:int = -1;
var text_input:TextField = new TextField();
text_input.type = 'input';
text_input.border = true;
text_input.addEventListener(Event.CHANGE, onTextChange);
function onTextChange(e:Event):void {
if(replace_char && char_position >= 0){
text_input.replaceText(char_position, char_position + 1, 'b');
replace_char = false;
}
}
addChild(text_input);
stage.addEventListener(KeyboardEvent.KEY_DOWN, _onKeyDown);
function _onKeyDown(e:KeyboardEvent):void {
if(e.keyCode == 81) {
replace_char = true;
char_position = text_input.selectionBeginIndex;
}
}
EDIT :
To use a list of keys and their equivalents, you can use an object to stock your keys like this :
// list of all keys (chars) and their equivalents
var chars:Object = {
81: 'b', // q => b
83: 'v', // s => v
68: 'c' // d => c
// other chars
}
var char_to_replace:int = -1;
// other instructions
function onTextChange(e:Event):void {
if(replace_char && char_position >= 0 && char_to_replace >= 0){
// get the equivalent of the pressed key from chars object using : chars[key_pressed]
text_input.replaceText(char_position, char_position + 1, chars[char_to_replace]);
replace_char = false;
}
}
// other instructions
function _onKeyDown(e:KeyboardEvent):void {
if(chars[e.keyCode]) {
replace_char = true;
// save the last pressed key to get its equivalent, or save this last one directly, to replace it next
char_to_replace = e.keyCode;
char_position = text_input.selectionBeginIndex;
}
}
Hope that can help.

as3 event listeners in for loop to pass dynamic variable to function

I need your help. I have an array with numbers, and I tried to pass a dynamic variable to a function in the mouse event listener. It works but not how I want. Whenever the mouse event listener is activated it passes the last value of that dynamic variable, not the value that was set. I tried to set this["n1"] and this["n2"] when passing to the function, but then the mouse event won't work (respond). How can I fix that? Here is my code:
var niz1:Array = [[1,2],[1,3],[3,4]];
var n,n1,n2;
for(n=0;n<3;n++){
n1=niz1[n][0];
n2=niz1[n][1];
this["hovermc"+n1+"_"+n2].addEventListener(MouseEvent.ROLL_OVER, function(e:MouseEvent) : void {hover_effect_in(null,n1,n2,0,0);});
this["hovermc"+n1+"_"+n2].addEventListener(MouseEvent.ROLL_OUT, function(e:MouseEvent) : void {hover_effect_out(null,n1,n2,0,0);});
}
function hover_effect_in(hovermc:MovieClip,h1:int,h2:int,h3:int,h4:int):void{
if(hovermc != null){
hovermc.hoverbg.alpha=0.7;
}
if(h1 != 0 && h2 != 0 && h3 == 0 && h4 == 0){
this["hovermc"+h1].hoverbg.alpha=0.7;
this["hovermc"+h2].hoverbg.alpha=0.7;
}
}
function hover_effect_out(hovermc:MovieClip,h1:int,h2:int,h3:int,h4:int):void{
if(hovermc != null){
hovermc.hoverbg.alpha=0;
}
if(h1 != 0 && h2 != 0 && h3 == 0 && h4 == 0){
this["hovermc"+h1].hoverbg.alpha=0;
this["hovermc"+h2].hoverbg.alpha=0;
}
}
You are getting those values for n1 and n2 because those are the values of those variable at the time the event function executes even though it might be different at the time the function is defined with the addeventlistener command.
I can't think of a simple way to do what you want to do with your code, but a more practical way would be to have your listener call "hover_effect_in" directly, and then based on the calling mc's name, "e.target.name", apply your array values based on the mc's name. So if name=hovermc_1_2 then n1=1 and n2=2. So, based on a button name, you assign your values in the button handler.
Or, the sophisticated way to do is make a class for "hovermc" which has all your basic code but each class carries one set of your niz1 values and gets assigned to each of your button mcs.

Using two eventlisteners for one function in Actionscript

I'm making a dots and boxes game in flash using actionscript 3.
Currently I'm completely stuck as I want the player to click two buttons before a line is displayed. I planned to do something like this using the if statement
if button1 and button2 clicked
line1 visible = true
I've also tried adding eventlisteners with one function
function showLine(e:Event):void {
blue0001.visible = true
}
dot00.addEventListener(MouseEvent.CLICK, showLine);
But as far as I know this can only be used when you want to click one button. Is there anyway to have two eventlisteners satisfyed before the function is carried out?
Also how would I (if i can) use the if statements to carry out this?
You would probably do something like this, pseudo-code:
Assume all of the dots are in a dots array.
for (var i: Number = 0; i < dots.length; i++) {
dots.addEventListener(MouseEvent.CLICK, dotClicked, false, 0, true);
}
dotSelected = null;
function dotClicked(evt:MouseEvent):void {
if (dotSelected && isNeighbor(evt.target, dotSelected)) {
showLineConnecting(evt.target, dotSelected)
dotSelected = null;
} else if (!dotSelected) {
highlightDot(evt.target);
dotSelected = evt.target;
} else {
showError("You must click an adjacent dot");
}
}
At the request of the OP, this is what's going on.
for (var i: Number = 0; i < dots.length; i++) {
dots.addEventListener(MouseEvent.CLICK, dotClicked, false, 0, true);
}
Add an event listener to every dot. Here I am assuming you already have an array of dots defined. Each instance in the Array would be a MovieClip (likely), Sprite, or another DisplayObject.
dotSelected = null;
We will use a variable to keep track of any currently selected dot. Since no dot will be selected when the game starts, we set it to null.
function dotClicked(evt:MouseEvent):void {
if (dotSelected && isNeighbor(evt.target, dotSelected)) {
showLineConnecting(evt.target, dotSelected)
dotSelected = null;
} else if (!dotSelected) {
highlightDot(evt.target);
dotSelected = evt.target;
} else {
showError("You must click an adjacent dot");
}
}
This is the function that will get called when any dot is clicked. For explanation's sake, let's take the first click of the game. dotSelected is null, so the first if is false. The second if though is true, because (!dotSelected) is true. So, we run some function I called highlightDot with the dot as the argument. That function could look something like this:
function hightlightDot(dot:Dot):void {
dot.gotoAndStop("selected");
}
Now a second click is made. Now the first part of the first if, dotSelected, is true. The second part is now evaluated. Again I put in a made up function isNeighbor. The isNeighbor function takes two arguments, the dot that was just clicked and the dot that has already been clicked. This function needs to make sure the two dots are adjacent. This could be something like...
function isNeighbor(dot1:Dot, dot2:Dot):void {
return ((dot1.xGrid == dot2.xGrid && Math.abs(dot1.yGrid - dot2.yGrid) == 1) || (Math.abs(dot1.xGrid - dot2.xGrid) == 1) && dot1.yGrid == dot2.yGrid));
}
The above function assumes that the instances of Dot have some properties xGrid and yGrid which defines where in the playing board they sit. If they are in the same row and 1 column apart they are neighbors. If they are in the same column and 1 row apart they are neighbors.
The last thing that happens in a function showLineConnecting is called. That function will again take the two adjacent dots as arguments. It will then draw a line between them in whatever way you choose to do that. Finally, dotSelected is set back to null, allowing another set of dots to be selected.
One thing I just realized, it would probably be helpful to have an additional property that gets triggered on a Dot when it is connected to all of its neighbors so it could no longer be selected.
You will also need logic to handle knowing that a box has been created. For that you would likely just iterate the possibilities given the line that was just drawn. For each line drawn there are only two possible boxes that have been created. So check them both. Watch out for edges.