Ok this has been driving me insane. My AS3 knowledge isn't the best in the world, but I'm trying to work out where I'm going wrong with all of this.
Basically, What I'm trying to do is at certain times, make visible/invisble two different MovieClips.
The weird thing is, one is responding. And the other isn't. They are both identical aside from jpeg contents and names. Is there a setting I'm missing? Both have matched MovieClip names and Instance names... but when I use the code below, HOP1 turns off/on, but HOP2 refuses to! Am i just missing some stupidly obvious preference?
I will mention, I'll have to modify the code to work with two different MovieClips, but right now I just want both files to turn off!
package {
import flash.display.MovieClip;
import flash.events.TimerEvent;
import flash.ui.Mouse;
import flash.utils.Timer;
import com.boo.CustomDate;
import com.boo.ScreensaverSimple;
public class Generic extends MovieClip {
// This is where you can set the Hour of Power time start and end time (in 24 hour format e.g. 1330 for 1:30pm)
// If there is no hour of power, simply set both numbers to 0
private var HourOfPowerStartTime:Number = 0;
private var HourOfPowerEndTime:Number = 0;
private var ss:ScreensaverSimple;
public var time_check_timer:Timer;
private var delay_add_timer:Timer;
public function Generic() {
Mouse.hide();
ss = new ScreensaverSimple;
ss.setScreensaver(screens);
HOP2.visible = false;
time_check_timer = new Timer(1000);
time_check_timer.addEventListener(TimerEvent.TIMER, checkTime);
delay_add_timer = new Timer(1,1);
delay_add_timer.addEventListener(TimerEvent.TIMER, addAllChildren);
delay_add_timer.start();
}
public function addAllChildren(evt:TimerEvent=null):void {
delay_add_timer.removeEventListener(TimerEvent.TIMER, addAllChildren);
delay_add_timer.stop();
delay_add_timer = null;
time_check_timer.start();
checkTime();
}
public function checkTime(evt:TimerEvent=null):void {
checkHOP2();
}
private function checkHOP1():void {
if(HourOfPowerStartTime == 0 && HourOfPowerEndTime == 0)
{
if(HOP2.visible == true)
{
HOP2.visible = false;
}
return;
}
var CurrentTime:Number = CustomDate.return24HourNumber();
if(CurrentTime >= HourOfPowerStartTime && CurrentTime <= HourOfPowerEndTime)
{
if(HOP2.visible == false)
{
HOP2.visible = true;
}
}
else
{
if(HOP2.visible == true)
{
HOP2.visible = false;
}
}
}
}
}
if(HOP2.visible == true)
{
HOP2.visible = false;
}
Fist thing the if condition is complete redundant here. If you think about it, those lines work exactly the same as this one alone:
HOP2.visible = false;
Also (HOP2.visible == true) would be exactly the same as (HOP2.visible) and also you can assign value of condition check directly to variable. Generally you can reduce your function to:
private function checkHOP1():void {
HOP2.visible = (HourOfPowerStartTime || HourOfPowerEndTime);
if (!HOP2.visible) return;
var CurrentTime:Number = CustomDate.return24HourNumber();
HOP2.visible = (CurrentTime >= HourOfPowerStartTime && CurrentTime <= HourOfPowerEndTime);
}
Then I see you call to checkHOP2() :
public function checkTime(evt:TimerEvent=null):void {
checkHOP2();
}
but I don't see the checkHOP2() function defined in code you gave.
Similarly I don't see form where you call your checkHOP1() function you have posted. And also I don't get why change HOP2 instance inside function named checkHOP1() . Is it suppose to be some kind of obfuscation?
Related
Here is the problem, the object is moved together with the clicked object. I want it to be moveable following the mouse pointer, but let the clicked object stays. so when an object is clicked, there will be 2 objects in the stage(the static and moving one).
I think I've figured it out by adding a new object to be moved. in function onClickHero I've tried movingHero = new heroes but it says "call to a possibly undefined method heroes". My question is there any other way how to make another clone of the clicked object since I made it in array? And why does movingHero = new heroes doesn't work?
I'm still amateur at classes. Sorry if it's messed up. Thanks for helping.
package {
import flash.display.MovieClip
import flash.events.MouseEvent
import flash.events.Event
import flash.display.Sprite
public class Hero {
private var heroesArray:Array;
private var heroContainer:Sprite = new Sprite;
private var hero1:MovieClip = new Hero1();
private var hero2:MovieClip = new Hero2();
private var moveHero:Boolean = false;
private var movingHero:MovieClip;
private var _money:Money = new Money();
private var _main:Main;
public function Hero(main:Main)
{ _main = main;
heroesArray = [hero1,hero2];
heroesArray.forEach(addHero);
}
public function addHero(heroes:MovieClip,index:int,array:Array):void
{
heroes.addEventListener(Event.ENTER_FRAME, playerMoving);
heroes.addEventListener(MouseEvent.CLICK, chooseHero);
}
public function playerMoving(e:Event):void
{
if (moveHero == true)
{
movingHero.x = _main.mouseX;
movingHero.y = _main.mouseY;
}
}
public function chooseHero(e:MouseEvent):void
{
var heroClicked:MovieClip = e.currentTarget as MovieClip;
var cost:int = _main._money.money ;
if(cost >= 10 && moveHero == false)
{
_main._money.money -= 10;
_main._money.addText(_main);
onClickHero(heroClicked);
moveHero = true;
}
}
public function onClickHero(heroes:MovieClip):void
{
movingHero = heroes;
heroContainer.addChild(movingHero);
}
public function displayHero(stage:Object):void
{
stage.addChild(heroContainer);
for (var i:int = 0; i<2;i++)
{
stage.addChild(heroesArray[i]);
heroesArray[i].x = 37;
heroesArray[i].y = 80+i*70;
heroesArray[i].width=60;
heroesArray[i].height=55;
heroesArray[i].buttonMode = true;
}
}
}
}
EDIT: I've tried to make movingHero = new Hero1(); but since I don't know which hero will be clicked so I can't just use Hero1 from library. and If I use movingHero = heroClicked I only get the value of hero1 which is a var from Hero1 movieclip. So, is there any way to call the movie clip from library the same as which hero was clicked in stage?
You seemingly want to clone an object while not knowing its type. If that object also containg game logic, it's not the best idea to say spawn new heroes of either type, this might make a mess of your code. But if not, you can get the exact class of the object given, and make an object of that class via the following code:
public function onClickHero(heroes:MovieClip):void
{
if (!heroes) {
trace('heroes is null!');
return;
}
var heroClass:Class = getDefinitionByName(getQualifiedClassName(heroes)) as Class;
movingHero = new heroClass(); // instantiate that class
heroContainer.addChild(movingHero);
// movingHero.startDrag(); if needed
}
Don't forget to clean up the movingHero once it's no longer needed.
I've set up three buttons in the first frame which are supposed to switch frames. When the program first runs, there are no errors, and i can click any of the buttons and end up where I want. However, when going back to the first frame, the buttons no longer work. The stage listener still works though. I added the "Clicked" output to check if the function was called, which it wasn't. I know I disable the buttons in the code, but only after that button is clicked, and the task is done. I should mention I don't have the code on the timeline, but on a separate document. Here is my code:
package{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.SimpleButton;
public class DocumentClass extends MovieClip
{
public var matteOppgave:Boolean = false;
public var engelskOppgave:Boolean = false;
public var flaggOppgave:Boolean = false;
public function DocumentClass()
{
stop();
btnBok.addEventListener(MouseEvent.CLICK, matte);
btnFlagg.addEventListener(MouseEvent.CLICK, flagg);
btnPc.addEventListener(MouseEvent.CLICK, engelsk);
stage.addEventListener(Event.ENTER_FRAME, sjekk);
btnBok.enabled = true;
btnPc.enabled = true;
btnFlagg.enabled = true;
function matte(evt:MouseEvent)
{
gotoAndStop(2);
frame2();
trace("Clicked");
}
function engelsk(evt:MouseEvent)
{
gotoAndStop(3);
frame3();
trace("Clicked");
}
function flagg(evt:MouseEvent)
{
gotoAndStop(4);
frame4();
trace("Clicked");
}
function sjekk(evt:Event)
{
if(matteOppgave == true && engelskOppgave == true && flaggOppgave == true)
{
gotoAndStop(5);
}
if(matteOppgave == true)
{
btnBok.alpha = 0.5;
btnBok.enabled = false;
låsEin.alpha = 0;
}
if(engelskOppgave == true)
{
btnPc.alpha = 0.5;
btnPc.enabled = false;
låsTo.alpha = 0;
}
if(flaggOppgave == true)
{
btnFlagg.alpha = 0.5;
btnFlagg.enabled = false;
låsTre.alpha = 0;
}
}
}
I got it working from a solution posted on another forum. I made the five frames i had into movieclips, and changed back and forth using addChild() and removeChild().
I'm, creating a simple drag and drop game in flash cs 5.5. There will be several movieclip on the stage suffled. What the user need to do is drag it to another movieclip and the movieclip will switch and check if it is in right place. I used the code something like this
if (evt.target.dropTarget != null && evt.target.dropTarget.parent.name == "num1" || "num2" || "num3" || ......and so on)
{
//do your thing
}
else
{
//go back to original place
}
In above code num1, num2 and so on are name of the moveiclips. There are also other movieclips on the stage. They are backgrounds. This works fine if I drag and dropped the movieclip(let say num1) on other movieclips(let say num2) as expected. But when I droped it on other movieclip(background), it shows error. I traced evt.target.dropTarget.parent.name inside the if condition and it shows the name of other movieclip(background). Why it is showing the name of the other movieclip(background) when the condition hasn't met which is the name isn't num1 or num2 or so on...? Can someone tell me if I'm doing anything wrong ? or is there another way to do this ?
Don't know if you're posting pseudo-code or not, but this won't work as a condition:
evt.target.dropTarget.parent.name == "num1" || "num2" || "num3" ||
This will always return true because it's evaluating the string "num2" as a condition. Look at the Boolean function for more information.
What you want is something like:
var par_name = evt.target.dropTarget.parent.name;
if (evt.target.dropTarget != null && par_name == "num1" || par_name=="num2" || par_name=="num3" )
or you can streamline this in many ways-- e.g.:
var valid_targets = ["num1","num2","num3"];
if ( evt.target.dropTarget != null && (valid_targets.indexOf(par_name)>=0) )
hope this simple and dummy example will be possible to explain a little bit more how to implement this logic. (of course, it's just a draft, but can be used as mockup)
Try something like:
//your package name (I just created a simple example, you should refactor and add your logic
package nu.gpeart.TheGunnersExample.components
{
import flash.geom.Rectangle;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Point;
/**
* #file DraggableItem.as
* #created Dec 18, 2013 - 9:02:52 AM
*/
public class DraggableItem extends Sprite
{
private var _item:Sprite;
private var _rightPlace:Point;
private var _dropTarget:Sprite;
private var _originalPlace:Point;
public function DraggableItem(parent:Sprite,
viewport:Rectangle,
color:uint,
rightPlace:Point,
dropTarget:Sprite)
{
_originalPlace = new Point(viewport.x, viewport.y);
_rightPlace = rightPlace;
_dropTarget = dropTarget;
_item = new Sprite();
_item.graphics.beginFill(color);
_item.graphics.drawRect(0, 0, viewport.width, viewport.height);
_item.graphics.endFill();
parent.addChild(_item);
addMouseDownListener();
}
private function addMouseDownListener():void
{
_item.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, false, 0, true);
}
private function mouseDownHandler(event:MouseEvent):void
{
_item.startDrag();
removeMouseDownListener();
addMouseUpListeners();
}
private function addMouseUpListeners():void
{
_item.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, false, 0, true);
_item.parent.stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, false, 0, true);
}
private function mouseUpHandler(event:MouseEvent):void
{
_item.stopDrag();
removeMouseUpListeners();
addMouseDownListener();
startLogic();
}
private function startLogic():void
{
if (_item.hitTestObject(_dropTarget))
{
(_item.hitTestPoint(_rightPlace.x, _rightPlace.y)) ? rightPositionLogic() : wrongPositionLogic();
}
else
{
wrongPositionLogic();
}
}
private function wrongPositionLogic():void
{
_item.x = _originalPlace.x;
_item.y = _originalPlace.y;
// go back to original place
}
private function rightPositionLogic():void
{
trace('dropped the right place');
// do your thing
}
private function removeMouseUpListeners():void
{
_item.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
_item.parent.stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
private function removeMouseDownListener():void
{
_item.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
}
}
And to use, you just need something like:
var rightPlace:Point = new Point(461, 554);
var originalPosition:Point = new Point(50, 50);
var itemWidth:Number = 50;
var itemHeight:Number = 50;
var viewport:Rectangle = new Rectangle(originalPosition.x, originalPosition.y, itemWidth, itemHeight);
var itemColor:uint = 0xf67821;
//container (the Sprite where are you adding all your objects
//dropTarget (the Sprite you want to detect the hitTest
var draggableItem:DraggableItem = new DraggableItem(container, viewport, itemColor, rightPlace, dropTarget);
Essentially, I have 6 balls, and when my showBalls() function runs, I want each ball (each are a movieclip) to run its animation and tween to the correct place. I want them to do it in order though. So 1 ball tweens, then the next, then the next and so on.
I've used a bunch of if statements because switch wouldn't work, but now it just keeps throwing me Error 1046 and telling me that "Event" was not found or not compile-time constant.
I can't see anyway around this and it's frustrating me.
Here's some code for you all. It's probably messy as hell and there'll be a much easier way to do this. But I'm pretty new to AS3 so I can't see any other way.
I have tried to find the answer on here and somebody told me to un-nest the functions. So I did. I've not had a problem with one nest but I tried two here and it didn't work. So I un-nested, but to no avail. If there is a way around this, i'd be grateful for guidance.
So yeah, first ball shown, tweens, once tween reaches final frame, it stops and the number associated with it shows. Repeat for following 6 balls.
function showNumbers()
{
var count:int = 0;
var showTimer:Timer = null;
showTimer = new Timer(3125,8);
showTimer.start();
showTimer.addEventListener(TimerEvent.TIMER, showBalls);
function showBalls(Event:TimerEvent)
{
ball1.addEventListener(Event.ENTER_FRAME, ball1stop);
ball2.addEventListener(Event.ENTER_FRAME, ball2stop);
ball3.addEventListener(Event.ENTER_FRAME, ball3stop);
ball4.addEventListener(Event.ENTER_FRAME, ball4stop);
ball5.addEventListener(Event.ENTER_FRAME, ball5stop);
ball5.addEventListener(Event.ENTER_FRAME, ball6stop);
bonusBall.addEventListener(Event.ENTER_FRAME, bonusBallstop);
function ball1stop(event:Event):void
{
if (currentFrame == stopFrame1)
{
ball1.stop();
programNumber1.text = drawnArray[0];
ball1.removeEventListener(Event.ENTER_FRAME, ball1stop);
}
}
function ball2stop(event:Event)
{
if (currentFrame == stopFrame2)
{
ball2.stop();
programNumber2.text = drawnArray[1];
ball2.removeEventListener(Event.ENTER_FRAME, ball2stop);
}
}
function ball3stop(event:Event)
{
if (currentFrame == stopFrame3)
{
ball3.stop();
programNumber3.text = drawnArray[2];
ball3.removeEventListener(Event.ENTER_FRAME, ball3stop);
}
}
function ball4stop(event:Event)
{
if (currentFrame == stopFrame4)
{
ball4.stop();
programNumber4.text = drawnArray[3];
ball4.removeEventListener(Event.ENTER_FRAME, ball4stop);
}
}
function ball5stop(event:Event)
{
if (currentFrame == stopFrame5)
{
ball5.stop();
programNumber5.text = drawnArray[4];
ball5.removeEventListener(Event.ENTER_FRAME, ball5stop);
}
}
function bonusBallstop(event:Event)
{
if (currentFrame == stopFrame7)
{
bonusBall.stop();
programBonusNumber.text = bonusArray[0];
bonusBall.removeEventListener(Event.ENTER_FRAME, bonusBallstop);
showTimer.stop();
fadeAndSort();
}
}
if (count==0)
{
ball1.visible = true;
ball1.play();
var stopFrame1:int = 75;
ball1stop();
}
else if (count==1)
{
ball2.visible = true;
ball2.addEventListener(Event.ENTER_FRAME, ball2stop);
ball2.play();
var stopFrame2:int = 75;
ball2stop();
}
else if (count==2)
{
ball3.visible = true;
ball3.addEventListener(Event.ENTER_FRAME, ball3stop);
ball3.play();
var stopFrame3:int = 75;
ball3stop();
}
else if (count==3)
{
ball4.visible = true;
ball4.addEventListener(Event.ENTER_FRAME, ball4stop);
ball4.play();
var stopFrame4:int = 75;
ball4stop();
}
else if (count==4)
{
ball5.visible = true;
ball5.addEventListener(Event.ENTER_FRAME, ball5stop);
ball5.play();
var stopFrame5:int = 75;
}
else if (count==5)
{
ball6.visible = true;
ball6.addEventListener(Event.ENTER_FRAME, ball6stop);
ball6.play();
var stopFrame6:int = 75;
ball6stop();
}
else if (count==6)
{
bonusBall.visible = true;
bonusBall.addEventListener(Event.ENTER_FRAME, bonusBallstop);
bonusBall.play();
var stopFrame7:int = 75;
bonusballstop();
}
}
count++;
mainArray[0] = userNumber1.text;
mainArray[1] = userNumber2.text;
mainArray[2] = userNumber3.text;
mainArray[3] = userNumber4.text;
mainArray[4] = userNumber5.text;
mainArray[5] = userNumber6.text;
}
I bet this is the event he has problem with:
event.ENTER_FRAME
and should be Event.ENTER_FRAME
also I've found this in your "code"
function showBalls(Event:TimerEvent)
You need to put this line at the top of your file so flash knows where to look for the Event Class
You'll also need one for Timer, TimerEvent
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
since updating to ios6, therefore having to get the beta AIR 3.5, it seems the StageOrientationEvent only fires for upsideDown and default, not rotatedRight and rotatedLeft anymore. I have read about the changes to orientation handling in ios6 but I cant seem to find a way round it for AIR AS3. Here is the code on my quick orientation testing app (just on the timeline for a quick test):
stage.autoOrients = true
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE, orientationChange);
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, orientationChanging);
function orientationChange(e:StageOrientationEvent):void{
var t:TraceOnStage = new TraceOnStage(stage ,"----------------");
t= new TraceOnStage(stage, "orientationChange before: " + e.beforeOrientation + stage.orientation);
t = new TraceOnStage(stage, "orientationChange after: " + e.afterOrientation + stage.orientation);
}
function orientationChanging(e:StageOrientationEvent):void{
var t:TraceOnStage = new TraceOnStage(stage ,"----------------");
t = new TraceOnStage(stage, "orientationChanging before: " + e.beforeOrientation + stage.orientation);
t = new TraceOnStage(stage, "orientationChanging after: " + e.afterOrientation + stage.orientation);
}
When on the iPad it only traces for upside down and default, it worked fine until ios6. I have a whole series of orientation-requiring apps about to be finalized with the client waiting then this happened! Any ideas or help would be appreciated.
Try removing the
(aspectRatio) part in your application descriptor xml - orientation change works in every direction again.
As iOS6 has disabled these events there is nothing you can do to get them from AIR.
I don't think there's any easy solution but as all the accelerometer data should still be there, you should be able to construct your own event that tells you when the rotation has changed based on the accelerometer x, y, and z.
Ok I found one way to get around this orientation with the accelerometer problem. To avoid the confusion of changing accelerometer data each time orientation is changed, I decided to try not changing the stage orientation at all, going for rotating and repositioning the root to give the same effect instead. It works well but be aware any code in your app using the localToGlobal or stage mouseX and mouseY will need a extra line of code to use the root as positioning reference. Here is the whole class I wrote. Its in its first working stage so any comments for improvements welcome!
import flash.sensors.Accelerometer;
import flash.events.AccelerometerEvent;
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.display.StageOrientation;
import flash.display.Stage;
import flash.display.DisplayObject;
import flash.utils.setInterval;
import flash.utils.clearInterval;
public class AcceleroOrientator extends EventDispatcher {
public static const ORIENTATION_CHANGE:String = "orientationChange";
public var currentOrientation:String = StageOrientation.DEFAULT
private var firstCheckOrientation:String = StageOrientation.DEFAULT;
private var theRoot:DisplayObject;
private var myConst:Number = Math.sin(Math.PI/4);
private var accl:Accelerometer;
private var inter:int;
private var inter2:int;
private var currenAcceleromResult:String;
private var checkFrequency:int = 500;
public function AcceleroOrientator(tRoot:DisplayObject) {
if (Accelerometer.isSupported) {
accl = new Accelerometer();
accl.setRequestedUpdateInterval(100);
} else {
trace("Accelerometer feature not supported!!");
}
theRoot = tRoot;
theRoot.stage.autoOrients = false;
}
public function set active(val:Boolean):void {
if (inter2){
clearInterval(inter2);
}
if (val==true) {
if (! accl.hasEventListener(AccelerometerEvent.UPDATE)){
accl.addEventListener(AccelerometerEvent.UPDATE, getAcceleromOrientation);
}
currentOrientation = currenAcceleromResult;
inter2 = setInterval(checkOrientation, checkFrequency);
} else {
if (accl.hasEventListener(AccelerometerEvent.UPDATE)){
accl.removeEventListener(AccelerometerEvent.UPDATE, getAcceleromOrientation);
}
}
}
private function checkOrientation():void {
firstCheckOrientation = currenAcceleromResult;
if (inter){
clearInterval(inter);
}
if (currentOrientation != firstCheckOrientation) {
inter = setInterval(confirmOrientation, checkFrequency/3);
}
}
private function confirmOrientation():void{
if (inter){
clearInterval(inter);
}
var secondCheckOrientation = currenAcceleromResult;
if (firstCheckOrientation == secondCheckOrientation){
currentOrientation = firstCheckOrientation;
doRootRotation();
dispatchEvent(new Event(ORIENTATION_CHANGE));
}
}
private function doRootRotation():void{
if (currentOrientation == StageOrientation.ROTATED_LEFT){
theRoot.rotation = 90;
theRoot.x = theRoot.stage.stageWidth;
theRoot.y = 0;
} else if (currentOrientation == StageOrientation.DEFAULT) {
theRoot.rotation = 0;
theRoot.x = 0;
theRoot.y = 0;
} else if (currentOrientation == StageOrientation.ROTATED_RIGHT) {
theRoot.rotation = -90;
theRoot.x = 0;
theRoot.y = theRoot.stage.stageHeight;
} else if (currentOrientation == StageOrientation.UPSIDE_DOWN) {
theRoot.rotation = 180;
theRoot.x = theRoot.stage.stageWidth;
theRoot.y = theRoot.stage.stageHeight;
}
}
private function getAcceleromOrientation(e:AccelerometerEvent):void{
if (Math.abs(e.accelerationZ) > myConst){
return;
}
if (e.accelerationX > 0 && e.accelerationY > - myConst && e.accelerationY < myConst) {
currenAcceleromResult = StageOrientation.ROTATED_LEFT;
} else if ( e.accelerationY >= myConst) {
currenAcceleromResult = StageOrientation.DEFAULT;
} else if (e.accelerationX < 0 && e.accelerationY > -myConst && e.accelerationY < myConst) {
currenAcceleromResult = StageOrientation.ROTATED_RIGHT;
} else if (e.accelerationY <= myConst) {
currenAcceleromResult = StageOrientation.UPSIDE_DOWN;
} else {
currenAcceleromResult = StageOrientation.UNKNOWN;
}
}
}