AS3 to get children in Gestureworks TouchSprite working - actionscript-3

Recently just trying around with the Gestureworks multitouch.
Here I have some problem about button inside a TouchSprite, below is my code:
package
{
import com.gestureworks.core.GestureWorks;
import com.gestureworks.core.TouchSprite;
import com.gestureworks.events.GWGestureEvent;
import com.gestureworks.events.GWTouchEvent;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Stage;
import flash.events.Event;
import flash.display.Sprite;
import flash.net.URLRequest;
import flash.events.MouseEvent;
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
public class Main extends GestureWorks
{
private var myDisplay:TouchSprite;
public function Main():void
{
super();
key = "xxx";
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
}
override protected function gestureworksInit():void
{
myDisplay = new TouchSprite();
myDisplay.gestureReleaseInertia = true;
myDisplay.gestureEvents = true;
myDisplay.disableNativeTransform = false;
myDisplay.disableAffineTransform = false;
myDisplay.mouseChildren = true;
myDisplay.gestureList = {"n-drag":true,"n-scale":true};
myDisplay.addChild(boliviaMap);
myDisplay.addChild(mapPink);
addChild(myDisplay);
myDisplay.addEventListener(GWGestureEvent.DRAG, gestureDragHandler);
myDisplay.addEventListener(GWGestureEvent.SWIPE, gestureSwipeHandler);
mapPink.addEventListener(TouchEvent.TOUCH_TAP, tapPink);
}
private function tapPink(e:TouchEvent):void
{
trace("PINK");
indicatorTxt.text = "PINK";
}
private function gestureDragHandler(event:GWGestureEvent):void
{
trace("g drag: ", event.value.dx, event.value.dy);
event.target.$x += event.value.dx;
event.target.$y += event.value.dy;
indicatorTxt.text = "g drag: " + event.value.dx + " " + event.value.dy;
}
}
}
apparently the myDisplay.mouseChildren = true; will make myDisplay not able to drag or scale anymore.

Before adding your bigMap button set the mouseChildren property of myDisplay to true:
myDisplay.mouseChildren = true;
This should pass mouseEvents to objects inside.
Also, depending on the effect you want (I'm assuming this is for a multi-touch screen of somesort), I'd suggest you should probably use a TouchEvent.TOUCH_TAP on bigMap instead of MouseEvent.CLICK(MouseEvents arent multi-touch and won't be responsive if there is some kind of touch on another part of the screen at the same time).
Edit:
Assuming boliviaMap and mapPink aren't TouchMovieClips or TouchSprites then do something like this:
myDisplay.graphics.beginFill(0x555555, 1);
myDisplay.graphics.drawRect(0,0,500,500);
myDisplay.graphics.endFill();
Then add your child assuming boliviaMap and mapPink are less than 500x500px:
myDisplay.addChild(boliviaMap);
myDisplay.addChild(mapPink);
Edit 2- A working example(for me anyways) combining TouchEvents with GWEvents:
package {
import flash.display.MovieClip;
import com.gestureworks.core.GestureWorks;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import com.gestureworks.core.TouchSprite;
import flash.display.Sprite;
import flash.events.TouchEvent;
public class Main extends GestureWorks {
public function Main() {
super();
key = "INSERT YOUR GW KEY HERE";
Multitouch.inputMode=MultitouchInputMode.TOUCH_POINT;
}
override protected function gestureworksInit():void
{
trace("GestureWorks has initialized");
var myTouchSprite:TouchSprite = new TouchSprite();
myTouchSprite.graphics.beginFill(0x555555,1);
myTouchSprite.graphics.drawRect(0,0,100,100);
myTouchSprite.graphics.endFill();
myTouchSprite.gestureReleaseInertia = false;
myTouchSprite.gestureEvents = true;
myTouchSprite.disableNativeTransform = false;
myTouchSprite.disableAffineTransform = false;
myTouchSprite.gestureList = {"n-drag":true, "n-rotate":true};
myTouchSprite.mouseChildren = true;
var myTappableSprite:Sprite = new Sprite();
myTappableSprite.graphics.beginFill(0xAD3059,1);
myTappableSprite.graphics.drawRect(30,30,40,40);
myTappableSprite.graphics.endFill();
myTappableSprite.addEventListener(TouchEvent.TOUCH_TAP, tappedThis);
//myTouchSprite.addChild(myTappableSprite);
myTouchSprite.addChild(myTappableSprite);
addChild(myTouchSprite);
}
public function tappedThis(event:TouchEvent){
trace("You tapped this");
}
}
}
I should also add that this will only work on a screen/device that triggers TouchEvents(if you're clicking myTappableSprite with a mouse it won't trigger the event).

Related

as3 preloader stop loaded swf from caching?

sorry if this has been answered elsewhere but I can't find anything matching.
I have two swfs; a preloader (let's call it A) and some content (B). A loads B and adds it as a child. Everything is working beautifully (you can even see it here).
There's just one little problem I'm having. Normally when loading, say an image, into flash using the URLLoader Class, I add + "?" + new Date().getTime() to the URLRequest to force flash to load the latest version of the target, in other words to stop it using a cached version. Now, when I try to do this to the Loader that adds B to A, it can't find the URL (#2035 URL not found). So my question is: is what I'm trying to do possible, or should I take another approach to stopping B from caching?
Here's the preloader code:
package
{
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.ProgressEvent;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.ErrorEvent;
import flash.net.URLLoader;
import flash.text.TextField;
public class claude_loader extends MovieClip
{
public var main_movie:Loader = new Loader();
public var rss_loader:URLLoader;
private var perc_text:TextField = new TextField();
public function claude_loader()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
with (perc_text)
{
x = this.stage.stageWidth / 2;
y = this.stage.stageHeight / 2;
}
addChild(perc_text);
main_movie.load(new URLRequest("claudia_summers.swf"+ "?" + new Date().getTime()));
main_movie.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, load_progress);
main_movie.contentLoaderInfo.addEventListener(Event.COMPLETE,on_complete);
}
public function load_progress(e:ProgressEvent):void
{
var perc:Number = Math.round((e.bytesLoaded/e.bytesTotal)*100);
perc_text.text = "Loading " + perc + "%";
if (e.bytesLoaded == e.bytesTotal)
{
perc_text.text = "Loading done";
}
}
public function on_complete(e:Event):void
{
rss_loader = new URLLoader(new URLRequest("http://news.sulsc.org/feed"));
rss_loader.addEventListener(Event.COMPLETE,rss_complete);
perc_text.text = "Loading RSS";
}
public function rss_complete(e:Event):void
{
MovieClip(main_movie.content).rss_xml = XML(e.target.data);
addChild(main_movie);
}
}
}
Not sure how/why, but adding String() around new Date().getTime() and giving main_movie an IOErrorEvent listener resolves the issue. I think I have a bug somewhere, as this surely should have worked without these additions, no? Anyway thanks for all your help!
Working code:
package
{
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.ProgressEvent;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.ErrorEvent;
import flash.net.URLLoader;
import flash.text.TextField;
import flash.events.IOErrorEvent;
public class claude_loader extends MovieClip
{
public var main_movie:Loader = new Loader();
public var rss_loader:URLLoader;
private var perc_text:TextField = new TextField();
public function claude_loader()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
with (perc_text)
{
x = this.stage.stageWidth / 2;
y = this.stage.stageHeight / 2;
textColor = 0xFFFFFF;
}
addChild(perc_text);
main_movie.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,catch_error);
main_movie.load(new URLRequest("claudia_summers.swf" + "?" + String(new Date().getTime())));
function catch_error(e:IOErrorEvent):void
{
main_movie.load(new URLRequest("claudia_summers.swf"));
perc_text.text = "Failed non-cache load"
}
main_movie.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, load_progress);
main_movie.contentLoaderInfo.addEventListener(Event.COMPLETE,on_complete);
}
public function load_progress(e:ProgressEvent):void
{
var perc:Number = Math.round((e.bytesLoaded/e.bytesTotal)*100);
perc_text.text = "Loading " + perc + "%";
if (e.bytesLoaded == e.bytesTotal)
{
perc_text.text = "Loading done";
}
}
public function on_complete(e:Event):void
{
rss_loader = new URLLoader(new URLRequest("http://news.sulsc.org/feed"));
rss_loader.addEventListener(Event.COMPLETE,rss_complete);
perc_text.text = "Loading RSS";
}
public function rss_complete(e:Event):void
{
MovieClip(main_movie.content).rss_xml = XML(e.target.data);
addChild(main_movie);
}
}
}

AS3 Preloader not updating screen

I've been struggling with a Flash preloader. I just want it to update the text on the screen with the current percentage. Now it basically works as the trace outputs the correct percentages, but it won't update the textfield I have on the screen. Once the trace gets to 100% however, the code does output "100" on the screen, but not until it's all loaded. I don't have the Flash IDE and am just using pure Actionscript with FlashDevelop. Here's my code:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.display.Loader;
import flash.events.ProgressEvent;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.display.Loader;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldType;
public class Main extends Sprite
{
public var myLoader:Loader = new Loader();
public var image:String = "tmp/Avengers-poster.jpg";
private var Title:TextField;
private var txt:String;
private var Form:TextField;
public function Main():void {
textbox("This is the title","box",100,100,200,30);
myLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgressStatus);
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderReady);
var fileRequest:URLRequest = new URLRequest(image);
myLoader.load(fileRequest);
}
public function onProgressStatus(e:ProgressEvent):void {
// this is where progress will be monitored
var perc:int = Math.ceil((e.bytesLoaded/e.bytesTotal)*100);
txt = perc.toString();
Title.text = txt;
addChild (Title);
trace(perc);
}
public function onLoaderReady(e:Event):void {
// the image is now loaded, so let's add it to the display tree!
addChild(myLoader);
}
private function textbox (title_str:String,form_name:String,x:int,y:int,width:int,height:int):void {
Title = new TextField ();
Title.text = title_str;
Title.selectable = false;
Title.setTextFormat (new TextFormat ("Arial", 12, 0x777777, true));
txt = ".";
Title.x = x;
Title.y = y;
addChild (Title);
}
}
}
Thanks for your help.
Darryl
This will work. Don't recreate the TextField on each status. You only need to addChild once and update the reference to it.
package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
public class Main extends Sprite
{
public var myLoader:Loader = new Loader();
public var image:String = "http://apod.nasa.gov/apod/image/0605/titan5km_huygens_big.jpg";
private var Title:TextField;
private var Form:TextField;
public function Main():void {
createTextField("This is the title","box",100,100,200,30);
myLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgressStatus);
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderReady);
var fileRequest:URLRequest = new URLRequest(image);
myLoader.load(fileRequest);
}
public function onProgressStatus(e:ProgressEvent):void {
// this is where progress will be monitored
var perc:int = Math.ceil((e.bytesLoaded/e.bytesTotal)*100);
Title.text = perc.toString();
}
public function onLoaderReady(e:Event):void {
// the image is now loaded, so let's add it to the display tree!
addChild(myLoader);
}
private function createTextField (title_str:String,form_name:String,x:int,y:int,width:int,height:int):void {
Title = new TextField();
Title.text = title_str;
Title.selectable = false;
Title.setTextFormat (new TextFormat ("Arial", 12, 0x777777, true));
Title.text = ".";
Title.x = x;
Title.y = y;
addChild (Title);
}
}
}

Implementing stageWebView in GestureWorks TouchSprite

I am attempting to create a component in a GestureWorks AIR application that renders a stageWebView in a touchsprite container. Given the stageWebView is not a display object is this possible?
Below is the code:
package view
{
import com.gestureworks.core.GestureWorks;
import com.gestureworks.core.TouchSprite;
import com.gestureworks.events.GWGestureEvent;
import com.modestmaps.Map;
import com.modestmaps.events.MapEvent;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.geom.Rectangle;
import flash.media.StageWebView;
import flash.net.URLLoader;
import flash.net.URLRequest;
public class webView extends TouchSprite
{
private var urlAddress:String = "http://google.com";
public var stageWebView:StageWebView = new StageWebView();
private var ts:TouchSprite;
public function webView()
{
super();
init();
}
private function init():void
{
ts = new TouchSprite();
ts.width = 500;
ts.height = 500;
ts.x = 200;
ts.y = 100;
ts.rotation = 45;
ts.scaleX = 0.5;
ts.scaleY = 0.5;
ts.gestureEvents = true;
ts.disableAffineTransform = false;
ts.gestureList = { "n-drag":true, "n-scale":true, "n-rotate":true };
ts.addEventListener(GWGestureEvent.DRAG, gestureDragHandler);
ts.addEventListener(GWGestureEvent.ROTATE, gestureRotateHandler);
ts.addEventListener(GWGestureEvent.SCALE, gestureScaleHandler);
if(StageWebView.isSupported == true)
{
stageWebView.stage = this.stage;
stageWebView.viewPort = new Rectangle(0,0, 500, 500);
//stageWebView.addEventListener(LocationChangeEvent.LOCATION_CHANGE, locationChangedHandler);
//stage.scaleMode = StageScaleMode.EXACT_FIT;
//this.stage.addEventListener(Event.RESIZE, resizeEvent);
getURL();
}
else
{
urlAddress = "StageWebView not supported";
}
ts.addChild(stageWebView as DisplayObject);
addChild(ts);
}
protected function getURL():void
{
stageWebView.loadURL(urlAddress);
//stageWebView.addEventListener(Event.COMPLETE,handleLoad);
}
No. Since StageWebView is not a display object, you can't add it to another object to be managed automatically.
You can manage it manually from the sprite--when the sprite is displayed, show the web view, when the sprite is resized, resize the web view, etc.
If your web view is covering up the entire TouchSprite once it's rendered, I'm fairly certain that your sprite won't receive gesture events--those would be handled by the native component.

1046: Type was not found or was not a compile-time constant:Button

package
{
import flash.display.MovieClip;
import flash.display.NativeWindow;
import flash.display.NativeWindowInitOptions;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.SimpleButton;
public class PencereyiGizle extends MovieClip
{
public var natWindow:NativeWindow=new NativeWindow(
new NativeWindowInitOptions());
public var pencereyiAc_Btn:Button;
public function PencereyiGizle(fro:Button)
{
pencereAc_Btn = fro;
//Pencere ekleniyor
natWindow.width = 500;
natWindow.height = 400;
natWindow.activate();
natWindow.addEventListener(Event.CLOSING,pencereyiSakla);
pencereyiAc_Btn.label = "Pencereyi Ac";
pencereyiAc_Btn.addEventListener(MouseEvent.MOUSE_DOWN,pencereyiAktifEt);
}
//pencerenin kapanmasını engelleyip pencereyi gizliyoruz.;
private function pencereyiSakla(e:Event):void
{
e.preventDefault();
natWindow.visible = false;
}
//gizlenen pencereyi tekrar aktif hale getiriyoruz
private function pencereyiAktifEt(e:MouseEvent):void
{
natWindow.activate();
}
}
}
IN AIR;
import PencereyiGizle;
var firat:PencereyiGizle= new PencereyiGizle();
addChild(firat);
and then, i get that problem "1046: Type was not found or was not a compile-time constant:Button. "
Based on what is in your imports, I think you want to use the SimpleButton class and not the Button class. (Which is a flash component)
Either that or you are missing this import
import fl.controls.Button;
Here is an artilce from adobe on the button component.
http://www.adobe.com/devnet/flash/quickstart/button_component_as3.html

How to update children in actionscript?

For starters let me just say that I am very new to action script and also that I'm not using adobe creative suite, I am using notepad with flex as a compiler. I have two classes, a main class and a class called OBJECT_square.
Here is the MAIN class:
package
{
import flash.display.*; import mx.core.*;
import flash.events.*; import mx.collections.*;
import flash.geom.*; import mx.controls.*;
import flash.text.*; import mx.events.*;
import mx.styles.*;
import mx.containers.*;
public class MAIN extends Sprite
{
public var APPLICATION:Application = Application(Application.application);
public var keyDownText:TextField = new TextField();
public function MAIN()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN,KEY_DOWN);
addEventListener(Event.ENTER_FRAME,STEP);
this.addChild(new OBJECT_square().CREATE(10,100,1));
this.addChild(new OBJECT_square().CREATE(10,200,1));
}
public function STEP():void {}
public function DRAW():void {}
public function KEY_DOWN(event:KeyboardEvent):void
{
keyDownText.text = "Key code: " + event.keyCode;
this.addChild(keyDownText);
}
}
}
Here is the OBJECT_square class:
package
{
import flash.display.*;
import flash.events.*;
public class OBJECT_square extends Sprite
{
public var X:int = 0;
public var Y:int = 0;
public var DEPTH:int = 0;
public var SPRITE:Sprite = new Sprite();
public function CREATE(X:int,Y:int,DEPTH:int):Sprite
{
addEventListener(KeyboardEvent.KEY_DOWN,KEY_DOWN);
this.DEPTH = DEPTH;
this.X = X;
this.Y = Y;
DRAW();
return SPRITE;
}
public function KEY_DOWN(event:KeyboardEvent):void
{
if (event.keyCode == 39) {X += 1; DRAW();}
}
public function DRAW():void
{
SPRITE.graphics.beginFill(0xFF0000,1);
SPRITE.graphics.drawRect(X - 10,Y - 10,20,20);
SPRITE.graphics.endFill();
}
}
}
Now my problem is this. Simply put I would like the square that OBJECT_square draws to move right when I press the right arrow key. Right now I can only get it to be drawn once (though I am actually creating two separate squares in two different spots). Now the thing I need to know is if I have used the keyboard event correctly in OBJECT_square. I used keyboard event in the main class as well to display the last key I pressed but I'm not sure how to use it in a class other than the main one. Also I'm not sure how to 'update' the square so that it is redrawn when it moves, that is remove its old self from the display list and reinsert its new self. The whole kinda point to the code is that the square be 'self-sufficient', ie contains all the code needed to draw it and move it rather than relying on any other class. I basically want it so that once another class has made a square the square is capable of doing everything else on its own.
You don't need to keep manually redrawing the square. Sprites have x and y properties that you can change and will automatically be moved. There is also no reason to be creating a sprite inside a class that is already extending sprite. There are a couple of other weird things you are doing so a fixed up version of your class would look something like:
package
{
import flash.display.*;
import flash.events.*;
public class ObjectSquare extends Sprite
{
public function ObjectSquare (x:int,y:int):void
{
graphics.beginFill(0xFF0000,1);
graphics.drawRect(x,y,30,30);
graphics.endFill();
addEventListener(KeyboardEvent.KEY_DOWN,KEY_DOWN);
}
public function KEY_DOWN(event:KeyboardEvent):void
{
if (event.keyCode == 39)
{
x += 1;
}
}
}
}
package
{
import flash.display.*; import mx.core.*;
import flash.events.*; import mx.collections.*;
import flash.geom.*; import mx.controls.*;
import flash.text.*; import mx.events.*;
import mx.styles.*;
import mx.containers.*;
//rename your class to Main. Should not be all caps
public class Main extends Sprite
{
public var APPLICATION:Application = Application(Application.application);
public var keyDownText:TextField = new TextField();
public function Main()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyPress);
addChild(new ObjectSquare(10,100));
addChild(new ObjectSquare(10,200));
}
public function onKeyPress(event:KeyboardEvent):void
{
keyDownText.text = "Key code: " + event.keyCode;
this.addChild(keyDownText);
}
}
}
You would probably be better off creating a class to handle all your keyboard inputs and then change the relevant objects.