How can I only drag obj.mc up and down - actionscript-3

Anyone help me please. I'm totally new to AS3.
I have an mc called obj.
How can I only drag it only : up and down?
Here is the code I found somewhere on the internet.
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.events.Event;
var destination:Point=new Point();
var dragging:Boolean=false;
var speed:Number=5;
var offset:Point=new Point(); // our offset
obj.addEventListener(MouseEvent.MOUSE_DOWN,startdrag);
stage.addEventListener(MouseEvent.MOUSE_UP,stopdrag);
obj.addEventListener(Event.ENTER_FRAME,followmouse);
function startdrag(e:MouseEvent):void{
offset.x=obj.mouseX*obj.scaleX; // record offset (pt obj is dragged
offset.y=obj.mouseY*obj.scaleY;
dragging=true;
}
function stopdrag(e:MouseEvent):void{
dragging=false;
}
function followmouse(e:Event):void{
if(dragging){
destination.x=mouseX;
destination.y=mouseY;
}
obj.x-=(obj.x-(destination.x-offset.x))/speed; // apply offset
obj.y-=(obj.y-(destination.y-offset.y))/speed;
}

startDrag() method
public function startDrag(lockCenter:Boolean = false, bounds:Rectangle = null):void
Check the reference before to post a question, sorry but it's clearly explained on the reference guide startDrag
This is the best way to understand the method just set the
bounds:Rectangle = null;
to a value that match the limits.
When bounds are set, you should do what you want.
I most often set the lockCenter to false, but you have to understand the basics.
Sorry I missed something, my English is really poor.
The answer of #Coder3000 is the good one in your case as you want to displace the object smoothly.
Once again, I wanted to answer too fast. :(
So to move your object up and down only, You may delete the following lines in your code :
offset.x=obj.mouseX*obj.scaleX;
destination.x=mouseX;
obj.x-=(obj.x-(destination.x-offset.x))/speed;
Because you don't want to move this object left or right

Related

AS3 best way to mass crop tiles from a tilesheet?

Okay so I'm trying to create a program that reads a map from a csv file and then draw each tile using a tilesheet. Reading in the map works fine and I could draw certain tiles depending on the value read in but only if I embedded the images. Obviously this is impractical when it comes to having >20 different tiles; embedding them all just wouldn't be smart.
This is my code for drawing the tiles from the tilesheet.
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Point;
public class Tile extends Sprite
{
[Embed(source="../bin/lib/TileSheet.png")]
private var BitmapClass:Class;
private var tileBitmap:Bitmap = new BitmapClass();
var tileSize = 25;
var tileSheetLength = 20;
var sheetColumns:int = tileBitmap.bitmapData.width / tileSize;
var pt:Point = new Point(0, 0);
var bmp:Bitmap = new Bitmap(new BitmapData(tileSize, tileSize, true, 0));
public function Tile(collide:Boolean, id:int)
{
Draw(id);
}
private function Draw(id:int):void
{
var col:int = id % sheetColumns;
var row:int = Math.floor(id / sheetColumns);
var rect:Rectangle = new Rectangle(col * tileSize, row * tileSize, tileSize, tileSize);
bmp.bitmapData.copyPixels (tileBitmap.bitmapData, rect, pt, null, null, true);
this.addChild(bmp);
}
public function Update():void
{
}
}
}
'
So what I need help with is optimising this code so that I can run it around 1,900 times rather than the 910-911 times it can handle right now before just closing without errors. If there is a better way of doing this please let me know and any constructive criticism is always appreciated!
You have a Tile class which has a BitmapClass instance. Perhaps that should be a static property (belonging to the class, not every instance) to begin with. My guess is you're using the memory for the whole tile sheet every since time you instantiate a single tile which you probably don't want to do.
Another thing I'm noticing is you're creating a new BitmapData for each tile, when in fact you probably just need the tile data (it's id/coordinates) so you can copy pixels into the final BitmapData which gets displayed on stage. Perhaps you need to a class to manage resources(embedded bitmaps) and another to manage the different Tile instance(which should hold render data and references to pixels, but shouldn't store the actual data) and copying to the main buffer.
Also, it's a good idea to use BitmapData's lock() and unlock() functions for performance when doing multiple pixel operations on an image.
Have a look at Lee Brimelow's Sprite Sheet tutorials (part 1,2 and especially 3). They're really easy to follow and useful.
Also, it might be worth having a look at the have a look at the GPU accelerated IsoHill
library.
I've used IsoHill for a project before and it's quite fast, but it's best to get comfortable with the basics first, otherwise this might seem a bit much.

can't add an event listener to a mask AS3 Flash

New to AS3. Trying to do a simple mask exercise, but for some reason when I add event listener to 'myMask', the event doesn't trigger. I tried turning both 'myMask' and 'theMaskee' as sprites and movie clips, but no luck. It does trigger if I don't assign 'myMask' as a mask to 'theMaskee'. It also works if I add the listener directly to the stage, but eventually I want to put many things on the stage, and I'm afraid there will be conflict if it has to listen to the same event but perform several functions... especially if I need them one at a time. I looked through textbooks and the API and mask-related questions other people had, but I can't find anything relating to my specific situation.
(this code is written directly in the timeline)
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.sampler.NewObjectSample;
import flash.events.MouseEvent;
var temp = new backGround();
var myBG:Bitmap = new Bitmap(temp);
temp = new splashMaskee();
var theMaskee:Bitmap = new Bitmap(temp);
var myMask = new MovieClip();
myMask.graphics.beginFill(0x000000, 0);
myMask.graphics.drawRect(0, 0, 800, 600);
myMask.graphics.endFill();
myMask.cacheAsBitmap = true;
theMaskee.cacheAsBitmap = true;
theMaskee.mask = myMask;
addChild(myBG);
addChild(theMaskee);
addChild(myMask);
myMask.addEventListener(MouseEvent.CLICK, myMaskClick);
//stage.addEventListener(MouseEvent.CLICK, myMaskClick);
function myMaskClick(e:MouseEvent):void
{
trace("click");
myMask.graphics.beginFill(0x000000, 1);
myMask.graphics.drawCircle(mouseX, mouseY, 30);
}
Thank you for taking the time
You need to add the listener to theMaskee instead, not your mask.
The mask in AS3 does not implement IEventDispatcher therefore can not catch and dispatch events.
Do this:
theMaskee.addEventListener(MouseEvent.CLICK, myMaskClick);
And it should work. :)
Masks dont take any mouse/keyboard events as it is just a mask and not actually present in the display list.

Convert drawn lines into bitmapdata - Bitmap.draw() + Sprite.graphics - wont work

EDIT: The convertation / copy process it self works, I just cant figure out how to tell the bitmapdata, which part of the stage to copy - I tried to solve that problem by movie the canvas to x=0 y=0 didnt show anychanges.
The only thing that showed a change was that I did move the canvas BEFORE drawing to zero, but this is totally buggy because the part of the drawing which has negativ coordinates wont be copied since the coordinate change only affect the bitmap if you do it before you start to paint
OLDER ENTRY:
I want to convert the Sprite.graphics into bitmapData, because I have a drawTool which allowes the user to paint lines, which are located inside the Sprite.grahpics I think.
I need to convert these lines to bitmapdata, because this allows me to deform them later on, but I cant use this
Bitmapdata.draw(Sprite.graphics);
And using only the Sprite instead of Sprite.graphics doesnt show any result =\
help is needed!
Use a matrix if you want to draw only a certain portion and from an origin other than (0,0). There's plenty in the Adobe docs on this, or a good example here:
http://www.quasimondo.com/archives/000670.php
Only use graphics when drawing. The actual Sprite object contains what you want, so following your convention, simply do:
BitmapData.draw(Sprite);
Although for a literal example:
var mySprite:Sprite = new Sprite();
// add lines etc using mySprite.graphics
var myBitmapData:BitmapData = new BitmapData(mySprite.width, mySprite.height);
myBitmapData.draw(mySprite);
I think, you've not completely understand usage BitmapData.draw().
BitmapData.draw() is a All DisplayObject(Sprite, MovieClip, Shape, Text, Video...) drawing possible. because they are have a IBitmapDrawable.(more information refer a adobe document Is the best teacher.)
If you want implement Paint Board. refer a below code. very simple Paint Board. but some help you.
try copy & paste.
import flash.display.Sprite;
import flash.events.Event;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.events.MouseEvent;
var isDraw:Boolean = false;
var brush:Sprite =new Sprite();
brush.graphics.beginFill(0x0000ff);
brush.graphics.drawCircle(0,0,5);
brush.graphics.endFill();
var canvasData:BitmapData = new BitmapData(600,400, false);
var canvas:Bitmap = new Bitmap(canvasData);
addChild(canvas);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDrawStart);
stage.addEventListener(MouseEvent.MOUSE_UP, onDrawStop);
stage.addEventListener(Event.ENTER_FRAME, render);
function onDrawStart(e:MouseEvent):void
{
isDraw = true;
}
function onDrawStop(e:MouseEvent):void
{
isDraw = false;
}
function render(e:Event):void
{
if(!isDraw) return;
brush.x = mouseX;
brush.y = mouseY;
canvasData.draw(brush,brush.transform.matrix);
}

as3 calling a function in another class [duplicate]

UPDATE: OK I am about ready to give up on Pacakages and classes. No answers coming. Not sure what to do. I tried to make the question easier and made a new post but I was down voted for it. as3 calling a function in another class
I am TOTALLY NEW to using PACKAGES and CLASSES. I am finally converting over from the timeline after having so many issues. Please be patient with my lack of knowledge. I need to know how to call a function in the child swf file I loaded from code in the maintime in the parent swf.
There are 2 swf files. Main.swf and pConent.swf
1. Main.swf has code in the timeline of the first frame.
2. pConent.swf is loading a PACKAGE CLASS as file.
QUESTIONS
I am trying to call a function in it from its parent Main.swf. How do I do this?
Here is sections of the code from both. Thanks
Main.swf CODE /// is an AIR for Andrid swf
function LoadContent()
{
TheContent.load(new URLRequest( "pContent.swf"));
TheContent.contentLoaderInfo.addEventListener(Event.COMPLETE, LoadContentTWO);
function LoadContentTWO(e:Event)
{
Content = TheContent.content as MovieClip;
pContent = Content as Object;
addChild(TheContent);
var OSS:String = "device";
trace(pContent); //// comes out as: [object pContent]
pContent.GetOnlineStatus(OSS); ///// HOW DO I GET THIS TO CALL FUNCTION
}
}
A SECTION OF THE "CLASS" in pContent.swf I am trying to call
public function GetOnlineStatus(OS:String)
{
if(OS=="online")
trace("inside ONLINE" );
}
if(OS=="device")
{
trace("inside DEVICE" );
}
}
THE ERROR I AM GETTING
TypeError: Error #1006: GetOnlineStatus is not a function.
UPDATE: I decided to post the FULL PACKAGE ( my first) to see if I am doing it right.
package
{
import flash.display.MovieClip;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
import flash.display.*;
import flash.media.Sound;
import flash.system.*;
import flash.media.SoundChannel;
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class pContent extends MovieClip
{
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
var ScreenY = flash.system.Capabilities.screenResolutionY;
var ScreenX = flash.system.Capabilities.screenResolutionX;
var swf:String;
var daSounds:String;
var images:String;
var videos:String;
var OnlineStatus:Boolean;
//++++++++++++++++++++++++
//++++++++++++++++++++++++
public function pContent()
{
BG.addEventListener(MouseEvent.CLICK, mouseHandlerdown);
}
//++++++++++++++++++++++++
//++++++++++++++++++++++++
//-------- * FUNCTIONS * --------
//-------------------------------
public function mouseHandlerdown(event:MouseEvent):void
{
alpha = .3; // testing
}
public function GetOnlineStatus(OS:String)
{
if(OS=="online")
{
OnlineStatus = true;
Security.allowDomain("*");
trace("inside THE PATH " + ThePath.text);
daSounds = "http://mycontactcorner.com/upload/files/";
swf = "http://mycontactcorner.com/upload/files/";
trace("inside THE DEVICE ONLINE" );
OnlineStatus = false;
swf = "";
daSounds = "content/sounds/";
//LoadMenu();
LoadStage();
LoadBeau();
}
if(OS=="device")
{
trace("inside THE DEVICE ONLINE" );
}
}
//------ * END FUNCTIONS * -----
//------------------------------
}// END FUNCTION pContent
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
}//// END PACKAGE
Don't be disappointed, but I won't have a "real" answer to your question, and I am really not going to work through all of your code to solve it, either. It is your own task to learn how to do this, and unless people here are very, very hungry for reputation, no one will do it for you - we will only help you to find the right way.
Your problem is not "packages and classes", so please do not give up on them. They will help you a great deal, once you've started to understand them. Your problem is, that you are not facing a single problem, but actually at least two (and quite substantial ones, I might add):
You need to go back to learn about the basics of object oriented programming in ActionScript. You won't have much luck getting answers to questions like this, otherwise. And believe me, I don't mean that in a patronizing way - it is simply a complicated matter, and it is hard to communicate complicated issues, both when you don't know the terms to express them, or when your counterpart doesn't understand them. Think of it like a high school math problem: You won't ever find a solution to your trigonometry question (or get a decent answer), unless you learn some basic algebra first.
You also have a problem related to loading, application domains, and the Flash Player security model - which are all far more complicated than what you should aim at when trying out OOP stuff. This can be a major obstacle, and unless you want to frustrate yourself, you should try to avoid it, until your program actually runs.
So this here is my advice: Always try to solve one problem at a time. Do not work yourself into such complex scenarios as the one you are in right now, but take step by step, until you've reached a level where you are confident with what you are doing.
Your first issue should be to understand what's going on with classes and objects. Everything else will come later. You should try to isolate your problem in the pContent.swf and get that to work first - or better yet, put everything you need for your program into a single file. Convert to using classes. Then, once you know how to work with those, start learning about more advanced OO, decoupling your code using interfaces, type casting and loading binaries at runtime.
//makes contact with classs but comes out as: [object pContent]
its because you said
pContent = Content as Object;
I am not sure why you are doing this extra step
Change it to this
Content = TheContent.content as MovieClip;
// pContent = Content as Object; //NO NEED OF THIS
addChild(Content); // just in case this gives error change it as addChild(Content as Object);
var OSS:String = "device";
trace(Content); //now see the difference
Content.GetOnlineStatus(OSS); // it calls now
Also, give the link where you posted that scary question :P if it has rest of the code
Sorry if this does not sound like an answer, but I'm going to write a couple of doubts that I have reading your code that can possibly lead to the solution:
Why are you casting it to MovieClip? If you cast it as MovieClip, the compiler it is going to tell you that the method "GetOnlineStatus" doesn't exist, because MovieClip class doesn't have it! I think you have to cast it as pContent
Why are you trying to casting TheContent.content? What is "content"? I had a look to your previous post and I cannot see anything called "content"?
If I ignore my second doubt (TheContent.content issue), I would change the code like this:
Content = TheContent.content as pContent; // your class it's called pContent
addChild(Content);
Content.GetOnlineStatus(OSS); // it calls now
Also, keep in mind that generally it's a good pratice to capitalize name of classes and not variables.
Let me know!
private function GetOnlineStatus
Try making this a public function instead. When it's private it can't be accessed outside the scope of the class that owns it.
I believe that in order to make this work, content property of the Loader. You have to create a reference to the loaded SWF as the class you are trying to call. This class has to be included in the main SWF's project. Then you can call the functions of that particular class in the child.
function LoadContent()
{
TheContent.load(new URLRequest( "pContent.swf"));
TheContent.contentLoaderInfo.addEventListener(Event.COMPLETE, LoadContentTWO);
}
function LoadContentTWO(e:Event)
{
var pContent:GetOnlineStatus = GetOnlineStatus(e.target.content);
addChild(e.target.content); //Assuming that "TheContent was
// declared as var TheContent:Loader , you'd be adding the loader to the stage when I think you actually wanted // to add the content.
var OSS:String = "device";
trace(pContent); //// comes out as: [object pContent]
pContent.GetOnlineStatus(OSS); ///// HOW DO I GET THIS TO CALL FUNCTION
// This should work now. If not, try to loading a function that is not the class' main function. Because I think you might get an "unable to call static function error". I'm a begginner too though, so sorry if I'm wrong. Example: pContent.GetOnlineStatusFunction(OSS);
}
This answer assumes that the pContent.swf contains a class file that looks like this:
package {
public class GetOnlineStatus {
public function GetOnlineStatus (OSS:String) {
//Do your GetOnlineStatus Logic. This is the main function.
}
/*public function GetOnlineStatusFunction (OSS:String) {
//Example non-main function
} */
}
}
Source: http://www.scottgmorgan.com/accessing-document-class-of-externally-loaded-swf-with-as3/

Typewriter effect with AS3

I'm trying to create a typewriter effect with AS3.
I read tutorials the hole day, but can't find, what I'm looking for....
Perhaps you can help me. - please
That's what I want:
- a typewriter text effect
- the speed can be set
- no import from an external .as file
- no import from an external .txt file (the text should be defined with a variable)
- if the textfield is full of text, it should be "scroll" down....it should jump down one line, so that theres a new empty line, where the typewriter could write....
could you actionscript gurus help me?
I always worked with as2 and it's very hard for me to get a solution in as3.. :(
thanks a lot!
Ok that sounds simple what you have is good.
firtst create the textfield that will display the final text. What you did next is adding all charackters at once, but what you want is adding each charackter after a time.
try something like:
import flash.events.TimerEvent;
import flash.text.TextField;
import flash.utils.Timer;
// the textfield guess you will add this on timeline instead of coding it...
var myTextField:TextField = new TextField();
// this is the text that should be displayed tywriterstyle
var typewriterText:String ="Hello World Typewriter";
// Charackter count and timer for timedelay between each upcoming charackter
var counter:int = 0;
var delayTimer: Timer = new Timer(300);
// starts Timer
delayTimer.addEventListener(TimerEvent.TIMER, addCharackter);
delayTimer.start();
private function addCharackter( E:Event = null ):void{
// get a single Charackter out of the String
var charackterToAdd:String = typewriterText.charAt(counter);
// add the charackter to the Textfield
myTextField.text.append(charackterToAdd);
counter++;
// if you reached the end of the String stop Timer
if(counter == typewriterText.length){
delayTimer.stop();
}
}
For text animation you can use flupie.
I think it's a better way to do.
See also this and this.
If you are a watch&learn guy this would be much convenient to you.