1084: Syntax error: expecting rightparen before colon - actionscript-3

I'm new to ActionScript and I'm confused about these two errors. I already have some prior coding experience from other languages.
Scene 1, Layer 'Actions', Frame 1, Line 78, Column 20 1084: Syntax error: expecting rightparen before colon.
Scene 1, Layer 'Actions', Frame 1, Line 85, Column 20 1084: Syntax error: expecting rightparen before colon.
This is my code.
function moveCharacter(evt:KeyboardEvent):void
{
if (evt.keyCode == Keyboard.RIGHT)
{
eggHead.scaleX = 1; //flip right
eggHead.x += 10;
//cycle through frames
if (eggHead.currentFrame == 9)
{
eggHead.gotoAndStop(2);
}
else
{
eggHead.gotoAndStop(eggHead.currentFrame+1);
}
}
if (evt.keyCode == Keyboard.LEFT)
{
eggHead.scaleX = -1; //flip left
eggHead.x -= 10;
//cycle through frames
if (eggHead.currentFrame == 9)
{
eggHead.gotoAndStop(2);
}
else
{
eggHead.gotoAndStop(eggHead.currentFrame+1);
}
}
}
function timing(evt:TimerEvent):void
{
timeStep += 1; //increment counter
if (run)
{ //only if run = true is shift key has been pressed
moveCharacter(evt:KeyboardEvent)
{
timeStep = 0; //reset the counter
}
}
else if (timeStep == 2)
{
moveCharacter(evt:KeyboardEvent)
{
timeStep = 0; //reset the counter
}
}
}
Lines 78 and 85 are the moveCharacter(evt:KeyboardEvent) function.
I'm not sure where the problem is, I can't see one, unless I'm blind.

The : character has a limited amount of uses in AS3 (most of them are various type declarations):
// Variable declaration.
var a:int;
// Variable declaration within a loop statement.
for (var i:int = 0; i < 10; i++)
{
// ...
}
// Ternary operator.
a = (Math.random() > 0.5)? 1: 0;
// Function declaration (both arguments and return type).
function convert(j:int, k:Number):String
{
return j + "_" + k;
}
// XML NameSpaces.
var x:XML = <soap:Envelope xmlns:soap="http://.../envelope/" />;
This is neither of them, hence the syntax error.
if (run)
{
moveCharacter(evt:KeyboardEvent)
{
timeStep = 0; //reset the counter
}
}
You should probably explain what kind of logic you wanted to code, because it is not clear what are you trying to do here.

The function moveCharacter was being called but you were typing a parameter declaration where the argument goes.
moveCharacter(evt:KeyboardEvent)
Your code doesn't have a keyboard event to pass at this spot. moveCharacter should be refactored to accept either "left" or "right" as arguments so that it doesnt require a keyboard event.
It's inherently unclear which direction the character should be moved from the time function. I assume the moveCharacter function is incomplete and missing forward and backward movement.
function moveCharacter(direction:String):void
{
direction = direction.toLowerCase();
if (direction == "right")
{
eggHead.scaleX = 1; //flip right
eggHead.x += 10;
//cycle through frames
if (eggHead.currentFrame == 9)
{
eggHead.gotoAndStop(2);
}
else
{
eggHead.gotoAndStop(eggHead.currentFrame+1);
}
}
if (direction == "left")
{
eggHead.scaleX = -1; //flip left
eggHead.x -= 10;
//cycle through frames
if (eggHead.currentFrame == 9)
{
eggHead.gotoAndStop(2);
}
else
{
eggHead.gotoAndStop(eggHead.currentFrame+1);
}
}
// TODO: Implement forward and backwards
}
function timing(evt:TimerEvent):void
{
timeStep += 1; //increment counter
if (run)
{ //only if run = true is shift key has been pressed
moveCharacter("forward");
timeStep = 0; //reset the counter
}
else if (timeStep == 2)
{
moveCharacter("forward");
timeStep = 0; //reset the counter
}
}

Related

Random movide clip without loop?

I created some MovieClips and put all of them on the stage. I'm trying to move a random MovieClip, using it only once, but at the same time I need to know which one it is because it will conflict with other tween effects. Is there an easy way to do that?
Here is what I've tried:
var biryukseklev1, ikiyukseklev1, ucyukseklev1, dortyukseklev1, besyukseklev1:int;
var assignavalue1, assignavalue2:int;
stage.addEventListener(Event.ENTER_FRAME,survivordondurlev6);
function survivordondurlev6(e:Event) {
if (biryerlessurlev1 == 0) {
biryukseklev1 = 764;//36
} else if (biryerlessurlev1 == 1) {
biryukseklev1 = 680;//120
} else if (biryerlessurlev1 == 2) {
biryukseklev1 = 596;//204
} else if (biryerlessurlev1 == 3) {
biryukseklev1 = 512;//288
} else if (biryerlessurlev1 == 4) {
biryukseklev1 = 428;//372
}
if (assignavalue1 == 0 && rabbitstatus.text.length < 2) { //Make sure to not used before
var my:Tween = new Tween(rabbit, "y", Back.easeInOut, rabbit.y, rabbit.y -biryukseklev1, 3, true);
rabbitstatus.text = "okfull";
} else if((assignavalue1 == 1 && birdstatus.text.length < 2){ //Make sure to not used before
var mys:Tween = new Tween(bird, "y", Back.easeInOut, bird.y, bird.y -biryukseklev1, 3, true);
birdstatus.text = "okfull";
}
}
If you want to keep track of which clips you've animated, then you'll have to have some way of iterating through them. The easiest list would be an Array, though how you mark them as "animated" is up to you. If you never plan on animating them again, then simply removing the ones that you've animated, and leaving the rest for later will work.
Below is example code, which you should be able to run in a new scene. You should be able to apply it to your needs with some small edits.
import fl.transitions.Tween;
import fl.transitions.easing.*;
// We'll keep track of which blocks still need to be animated by including them in this list
// Once we animate a block, we remove it from the list.
var pool:Array = [];
// Populate the stage with blocks.
for (var i:int = 0; i < 30; i++) {
var block:Sprite = createBlock();
addChild(block);
block.y = 50;
if (i > 0) { block.x = block.width * i; }
pool.push(block);
}
// Create an interactive button.
var txt:TextField = new TextField();
txt.text = "Do something";
addChild(txt);
txt.addEventListener("click", animateNext);
function createBlock():Sprite {
// Creates a single, randomly colored block.
var block:Sprite = new Sprite();
block.graphics.beginFill(random(0x000000, 0xFFFFFF));
block.graphics.drawRect(0,0,16,16);
block.graphics.endFill();
return block;
}
function random(low:Number, high:Number):Number {
// Returns a random number between the low and high numbers.
return Math.floor(Math.random() * (1+high-low)) + low;
}
function animateNext(e:Event):void {
// Do this 5 times.
for (var i:int = 0; i < 5; i++) {
// As long as we have blocks in the pool...
if (pool.length > 0) {
// Pick a random block from the pool
var index:int = random(0, pool.length-1);
// Animate it
new Tween(pool[index], "y", Back.easeInOut, pool[index].y, pool[index].y + 50, 3, true);
// Remove it from the pool so it isn't picked again
pool.splice(index, 1);
} else {
// Otherwise, break the loop.
break;
}
}
}

Pairing a draggable object to a target object in AS3

I'm currently stuck with my approach below. I'm not entirely sure if using "hitTestObject" method is appropriate in pairing the pieces to their respective place. I was able to at least match the chess piece to their respective location (that's the best I can do and I feel i'm doing it wrong) but I'm now stuck in counting how many pieces are actually in their correct places. e.g. when I move the pawn to a different tile, it will still count as one, I also want to avoid duplicate counting, example, If pawn is already in the correct location, it will just count as 1, and if it was moved, then that count will be removed. Only count the pieces that are in the correct tile.
My goal here is to be able to make all the chess pieces draggable and determine if they're in their respective location. If ALL the chess pieces are in their location, it will trace or call a function.
Thank you!
import flash.events.Event;
import flash.display.MovieClip;
import flash.events.MouseEvent;
/* Declaring an X and Y variable to be used as a reset container */
var xPos: int, yPos: int;
/* Attaching event listeners for each chess piece */
addListeners(
king, queen, bishop_1, bishop_2, knight_1, knight_2, rook_1, rook_2,
pawn_1, pawn_2, pawn_3, pawn_4, pawn_5, pawn_6, pawn_7, pawn_8);
/* Getting the original x and y postion to be used as a reset */
function getPosition(currentTarget: Object): void {
xPos = currentTarget.x;
yPos = currentTarget.y;
}
/* Function to get the suffix value of an object. example, I need to get the value 4 from "pawn_4" */
function getLastCharInString($s: String, $pos: Number): String {
return $s.substr($s.length - $pos, $s.length);
}
/* A simple function that rotates the chess piece */
function lift(object: Object, rot: Number) {
object.rotation = rot;
}
function dragObject(e: MouseEvent): void {
getPosition(e.currentTarget);
lift(e.currentTarget, -10);
getChildByName(e.currentTarget.name + "_hs").alpha = 1;
e.currentTarget.startDrag();
}
/* This variable is supposed to hold the value of each piece that is correctly placed in each tile.
The total score should be 16 as there are 16 pieces. Only correcly placed piece should be added in the total score. */
var counter:int;
function stopDragObject(e: MouseEvent): void {
var curretTarget = e.currentTarget.name;
lift(e.currentTarget, 0);
/* Hide active hotspots */
getChildByName(e.currentTarget.name + "_hs").alpha = 0;
var multiplePieceSufix = Number(getLastCharInString(curretTarget, 1));
if (multiplePieceSufix >= 1) {
/* Boolean variables that checks whether the current piece is active*/
var isPawn: Boolean = false,
isBishop: Boolean = false,
isKnight: Boolean = false,
isRook: Boolean = false,
currentTargeName;
var widthDiff = getChildByName(e.currentTarget.name + "_hs").width - getChildByName(e.currentTarget.name).width / 2;
var heightDiff = getChildByName(e.currentTarget.name + "_hs").height - getChildByName(e.currentTarget.name).height / 2;
if (curretTarget.substr(0, 4) == "pawn") {
isPawn = true;
} else if (curretTarget.substr(0, 6) == "bishop") {
isBishop = true;
} else if (curretTarget.substr(0, 6) == "knight") {
isKnight = true;
} else if (curretTarget.substr(0, 4) == "rook") {
isRook = true;
}
if (isPawn == true) {
/* there are total of 8 pieces of pawn */
for (var w = 1; w < 9; w++) {
currentTargeName = this["pawn_" + w + "_hs"];
if (e.target.hitTestObject(currentTargeName)) {
/* For some reason the chess pieces are not aligning with their "_hs" version, I already checked their registry point and it seem to be normal.
so to fix, I had to manually add some hard coded values to adjust their location. */
e.currentTarget.x = currentTargeName.x - 8;
e.currentTarget.y = currentTargeName.y + currentTargeName.height;
}
}
} else if (isBishop == true) {
for (var x = 1; x < 3; x++) {
currentTargeName = this["bishop_" + x + "_hs"];
if (e.target.hitTestObject(currentTargeName)) {
e.currentTarget.x = currentTargeName.x - 9;
e.currentTarget.y = currentTargeName.y + currentTargeName.height - 18;
}
}
} else if (isKnight == true) {
for (var y = 1; y < 3; y++) {
currentTargeName = this["knight_" + y + "_hs"];
if (e.target.hitTestObject(currentTargeName)) {
e.currentTarget.x = currentTargeName.x - 8;
e.currentTarget.y = currentTargeName.y + currentTargeName.height;
}
}
} else if (isRook == true) {
for (var z = 1; z < 3; z++) {
currentTargeName = this["rook_" + z + "_hs"];
if (e.target.hitTestObject(currentTargeName)) {
e.currentTarget.x = currentTargeName.x - 8;
e.currentTarget.y = currentTargeName.y + 62;
}
}
}
} else {
if (e.target.hitTestObject(getChildByName(e.currentTarget.name + "_hs"))) {
/* Again, I'm not sure why the pieces are not aligning as intended.
modX and modY is a holder for the adjustment value. I'm not comfortable
seeing this approach myself, but I also run out of ideas how to fix it. */
var modX: Number, modY: Number;
if (e.currentTarget.name == "king") {
modX = 11;
modY = 53;
} else {
modX = 11;
modY = 29;
}
e.currentTarget.x = getChildByName(e.currentTarget.name + "_hs").x - modX;
e.currentTarget.y = getChildByName(e.currentTarget.name + "_hs").y + getChildByName(e.currentTarget.name + "_hs").height - modY;
}
}
/* This is supposed to add to the total score or count of how many pieces are placed correctly.
Thie problem with thi scounter, as it also counts any piece that is places to any "_hs" */
counter++;
trace(counter);
e.currentTarget.stopDrag();
}
function addListeners(...objects): void {
for (var i: int = 0; i < objects.length; i++) {
objects[i].addEventListener(MouseEvent.MOUSE_DOWN, dragObject);
objects[i].addEventListener(MouseEvent.MOUSE_UP, stopDragObject);
// hide hotspots
getChildByName( objects[i].name + "_hs" ).alpha = 0;
}
}
Source: Download the FLA here
--
Updates:
I have added comments in my code to clarify what I'm trying to accomplish.
I'm planning to do board game in flash which has similar function and behaviour to this. User can drag the object to a specified tile and check wether that object belongs there or not.
After reviewing your code, your question is quite broad. I'm going pair it down to what seems to be your main concern - the score / counting correctly moved pieces.
Right now, you do the following every time an object is dragged:
counter++;
This means that the counter will increment no matter where you drag the object, and no matter how times you drag the object. (so even if the piece was already in the correct spot, if you dragged it a second time it will still increment your counter).
What you need to do, is associate a flag with each object to indicate whether it is in the correct location or not, and set that flag to the appropriate value every time that object is done dragging.
Something like this:
//don't use target, use currentTarget
if (e.currentTarget.hitTestObject(currentTargeName)) {
e.currentTarget.correct = true; //since MovieClips are dynamic, you can just make up a property on them and assign a value to it.
//to fix your alignment:
e.currentTarget.x = currentTargeName.x + ((currentTargetName.width - e.currentTarget.width) * 0.5);
e.currentTarget.y = currentTargeName.y + currentTargeName.height;
}else{
//if the hit test is false, mark it as NOT correct
e.currentTarget.correct = false;
}
Then, later to know the current count, iterate over all the pieces and check their correct value. This would be much easier if all your pieces were in an array.
var allPieces:Array = [king, queen, bishop_1, bishop_2, knight_1, knight_2, rook_1, rook_2,
pawn_1, pawn_2, pawn_3, pawn_4, pawn_5, pawn_6, pawn_7, pawn_8];
function countCorrect():Boolean {
var ctr:int = 0;
for(var i:int=0;i<allPieces.length;i++){
if(allPieces[i].correct) ctr++;
}
return ctr;
}
trace(countCorrect() + " of " allPieces.length " are correct");
As an aside, this best way to do this would be with some custom class files. That would however require a complete refactoring of your code.
Also, you probably don't want to use hitTestObject, as even if a piece is mostly over a neighbor, it will still be true as long as 1 pixel of it's bound touch 1 pixel of the tile. Better would be to do a hitTestPoint on the tile, and pass in the center point of the piece (the the middle of the piece has to be touching the tile for it to count).
//a point that is the center of the events current target (the piece)
var point:Point = new Point();
point.x = e.currentTarget.x + (e.currentTarget.width * 0.5);
point.y = e.currentTarget.y - (e.currentTarget.height * 0.5);
if (currentTargetName.hitTestPoint(point)) {

Moving objects on the stage

Let's say I have 5 objects in an array and I move all them along x-axis like this:
vx = 5;
for (i:int = 0; i < objects.length; i++)
{
objects[i].x += vx;
}
I would like to make this.
If any object from array 'objects' hit PointA, move all objects from that array to left side, for example set vx *= -1;
I can make only this:
for (i:int = 0; i < objects.length; i++)
{
// move right
objects[i].x += vx;
if (objects[i].hitTest(PointA))
{
// move left
vx *= -1;
}
}
This will change object's direction, but I need to wait all objets hit PointA.
How to change the direction of all objects in array, if any of them hit PointA?
I don't know action script but you should set a boolean outside the for loop, like bGoingRight
Check that this is true and move objects right, if its false move the objects left. When you pass the hitTest you should changed the boolean to false.
Rough Example
var bGoRight:Boolean = true;
for (i:int = 0; i < objects.length; i++)
{
if(bGoRight)
{
// move right
objects[i].x += vx;
}
else
{
// move left
vx *= -1;
}
if (objects[i].hitTest(PointA))
{
// if any object hit the point, set the flag to move left
bGoRight = false;
}
}
So you'll need to check the objects that have already hit PointA, store them, then check if the updated storage count is equivalent to your objects array. Then when that case is satisfied you can change the vx variable. This could look something like this:
//set a variable for storing collided object references
//note: if you are doing this in the IDE remove the 'private' attribute
private var _contactList:Array = [];
for (i:int = 0; i < objects.length; i++)
{
// move right
objects[i].x += vx;
if (objects[i].hitTest(PointA))
{
if( contactList.length == objects.length ) {
// move left
vx *= -1;
//clear our contact list
contactList.length = 0;
}
else if ( noContact( objects[i] ) ) {
contactList.push( objects[i] );
}
}
}
Then the function in the else if statement noContact(), again if you are doing this in the IDE you will need to remove the private attribute.
private function noContact( obj:* ):Boolean {
if ( contactList.indexOf( obj ) != -1 ) {
return false;
}
return true;
}
Another way you can do this is like this (a boolean way as stated in the other answer), but is reliant on your storage setup correct:
//set this variable for directionRight (boolean)
private var directionRight:Boolean = true;
for (i:int = 0; i < objects.length; i++)
{
// move right
objects[i].x += vx;
if (objects[i].hitTest(PointA))
{
//we are moving to the right, object[i] is the last object
if( i == objects.length-1 && directionRight ) {
// move left
directionRight = !directionRight;
vx *= -1;
}
else if ( i == 0 && !directionRight ) ) {
// move right
directionRight = !directionRight;
vx *= -1;
}
}
}

Unknown logical error

I'm assuming it's a logical error because it doesn't return any compiler or run-time errors.
my functions:
function closetest() {
tooclose=false;
for (i=0; i<10; i++) {
if (Math.abs(entry[0]-entry[i])<100) {
tooclose=true;
}
}
}
function xassignment() {
for (i=0; i<10; i++) {
entry[i+1]=entry[i];
}
do {
entry[0] = int(Math.random()*(stage.stageWidth - 30));
closetest();
} while (tooclose == false);
}
Here is where the function is called
mcMain.addEventListener(Event.ENTER_FRAME, moveChar);
function moveChar(event:Event):void {
if (gameOver == false) {
if (enemyTime < enemyLimit) {
enemyTime++;
} else {
var newEnemy = new Enemy();
xassignment();
newEnemy.y=-1*newEnemy.height;
newEnemy.x=entry[0];
addChild(newEnemy);
enemyTime=0;
}
}
}
I'm making a game that involves objects being dropped from a randomly generated x coordinate, I made these functions to make sure that objects aren't being dropped too close to each other but it doesn't appear to have any effect.
You haven't described what effect you are observing, but I noticed this:
for (i=0; i<10; i++) {
if (Math.abs(entry[0]-entry[i])<100) {
tooclose=true;
}
}
This will result in tooclose always being true, because your loop begins at 0, therefore you compare entry[0] with itself. Try starting the loop at 1 instead.
You haven't declared or changed tooclose within xassignment. You should instead return a Boolean from closetest() which will be queried. Another logical error is, you are advancing previous values by 1 in your array, while incrementing the index. So you have i=0, entry[1]=entry[0]. Then i is incremented, entry[2]=entry[1] - bam, entry[2] too starts being requal to entry[0]! And so on, so the entire array of entries now equals to what was rolled on the previous attempt, instead of storing 10 previous values. Fixed that too.
function closetest():Boolean {
for (var i:int=1; i<10; i++) {
if (Math.abs(entry[0]-entry[i])<100)
return true;
}
return false;
}
function xassignment() {
for (i=10; i>0; i--) entry[i]=entry[i-1];
do {
entry[0] = int(Math.random()*(stage.stageWidth - 30));
} while(closetest());
}
Note though, if your closetest implementation will receive a [X,100,300,500,700] array the loop will be endless, as there's no X position that will satisfy your range of 100 for absolute difference. So, fix it with the following:
function xassignment() {
for (i=10; i>0; i--) entry[i]=entry[i-1];
var loops:int=10;
do {
entry[0] = int(Math.random()*(stage.stageWidth - 30));
loops--;
} while((loops>0)&&closetest());
}
This will force an exit from that loop if we tried 10 randoms and none satisfied - the last attempt is returned.

Conditionally change the direction of a "for loop"?

Is it possible to conditionally change the direction of a for loop in ActionScript?
Example:
for(if(condition){var x = 0; x<number; x++}else{var x=number; x>0; x--}){
//do something
}
Interesting requirement. One way to keep the for is:
var start, loop_cond, inc;
if(condition)
{
start = 0;
inc = 1;
loop_cond = function(){return x < number};
}
else
{
start = number - 1;
inc = -1;
loop_cond = function(){return x >= 0};
}
for(var x = start; loop_cond(); x += inc)
{
// do something
}
We setup the start value, a function for the termination condition, and either a positive or negative increment. Then, we just call the function and use += to the do the increment or decrement.
ActionScript has the ternary operator, so you could do something like:
for (var x = cond ? 0 : number; cond ? x < number : x > 0; cond ? x++ : x--) {
}
But this is pretty ugly. :-)
You might also need/want to put some parens around pieces of that. I'm not sure about the operator precedence.
You might also consider using a higher order function. Imagine you have:
function forward (count, func) {
for (var x = 0; x < count; x++) {
func(x);
}
}
function backward (count, func) {
for (var x = count - 1; x >= 0; x--) {
func(x);
}
}
Then you could do:
(condition ? forward : backward) (number, function (x) {
// Your loop code goes here
})
You probably want a while loop instead:
var continueLooping, x;
if(condition)
{
x = 0
continueLooping = (x < number);
}
else
{
x = number;
continueLooping = (x > 0);
}
while (continueLooping)
{
// do something
if(condition)
{
x++;
continueLooping = (x < number);
}
else
{
x--;
continueLooping = (x > 0);
}
}
If you really want a for loop, you should use two of them:
function doSomething()
{
//doSomething
}
if(condition)
{
for(var x = 0; x<number; x++)
{
doSomething(x);
}
}
else
{
for(var x=number; x>0; x--})
{
doSomething(x);
}
}