Convert AS2 por AS3...please - actionscript-3

oranja.onPress = function(){
this.startDrag(true);
}
oranja.onRelease = function(){
this.stopDrag();
if(this.hitTest(this._parent.trash)){
trace("trash");
this.unloadMovie();
} else {
trace("no trash");
}
}

I think you're looking for an AS3 version of this? Something like this should work:
oranja.addEventListener( MouseEvent.MOUSE_DOWN, this._onPress );
oranja.addEventListener( MouseEvent.MOUSE_UP, this._onRelease );
// called when we mouse down on the oranja clip
private function _onPress( e:MouseEvent ):void
{
oranja.startDrag( true )
}
// called when we mouse up on the oranja clip
private function _onRelease( e:MouseEvent ):void
{
oranja.stopDrag();
if( oranja.hitTest( oranja.parent.trash ) )
{
trace( "trash" );
// remove the event listeners
oranja.removeEventListener( MouseEvent.MOUSE_DOWN, this._onPress );
oranja.removeEventListener( MouseEvent.MOUSE_UP, this._onRelease );
// remove the oranja clip
oranja.parent.removeChild( oranja );
oranja = null;
}
else
trace( "not trash" );
}
You should probably replace the oranja calls in _onPress() and _onRelease() with e.target or e.currentTarget

Related

Collision detection: TypeError: Error #1009: Cannot access a property or method of a null object reference

I'm trying to make a game but I'm stuck at this point:
in my game you are supposed to evade balls who come in from the right and disappear left. When you hit a ball you'll be redirected to another screen.
Here's the error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Evader/cleanUpObjects()
at Evader/update()
This is my code:
Evader.as (lines with the hyphens are the erroneous lines):
public class Evader extends MovieClip
{
public var penguin:Penguin;
private var objects:Array;
public function Evader()
{
initGame();
Mouse.hide();
objects = new Array();
addEventListener( Event.ENTER_FRAME, update );
//addEventListener( Event.ENTER_FRAME, hitObject );
}
private function initGame():void
{
penguin = new Penguin();
addChild( penguin );
}
private function update( event:Event ):void
{
if( Math.random() < 0.04 )
{
spawnObject();
}
//--------------------->cleanUpObjects();
}
private function cleanUpObjects():void
{
var currentObject:Object1;
for( var i:int = objects.length-1; i >= 0; i-- )
{
currentObject = objects[ i ];
//----------------------------->if( currentObject.x > stage.stageWidth )
{
removeChild( currentObject );
objects.splice( i, 1 );
}
}
}
private function spawnObject():void
{
var object1:Object1 = new Object1(penguin);
addChild( object1 );
objects.push( object1 );
}
/**
*private function hitObject(event:Event)
*{
* if (penguin.hitTestObject(object1))
* {
* Mouse.show();
* trace("geraakt!");
* removeEventListener( Event.ADDED_TO_STAGE, init );
* removeEventListener( Event.ENTER_FRAME, update );
* removeEventListener( Event.ENTER_FRAME, hitObject );
* Project.instance.switchScreen( "vierde" );
* }
}*/
}
}
Object1.as:
public class Object1 extends MovieClip
{
private var speed:Number;
private var penguin;
public function Object1(aPenguin: Penguin)
{
penguin = aPenguin;
addEventListener( Event.ADDED_TO_STAGE, init );
addEventListener( Event.ENTER_FRAME, hitObject );
}
private function init( event:Event ):void
{
removeEventListener( Event.ADDED_TO_STAGE, init );
addEventListener( Event.REMOVED_FROM_STAGE, unInit );
addEventListener( Event.ENTER_FRAME, move );
speed = -(1 + Math.random() * 2);
x = stage.stageWidth;
y = Math.random() * stage.stageHeight;
}
private function unInit( event:Event ):void
{
removeEventListener( Event.REMOVED_FROM_STAGE, unInit );
removeEventListener( Event.ENTER_FRAME, move );
}
private function move( event:Event ):void
{
this.x += speed;
}
private function hitObject(event:Event)
{
if (penguin.hitTestObject(this))
{
Mouse.show();
trace("geraakt!");
removeEventListener( Event.ADDED_TO_STAGE, init );
removeEventListener( Event.ENTER_FRAME, hitObject );
Project.instance.switchScreen( "vierde" );
}
}
}
}
The thing is, I need to have the hitTestObject function work for all the balls, so that it checks for collisions with all the appearing balls. Penguin is my character who is supposed to evade the balls.
If I comment the hitObject code in Object1.as and uncomment it at Evader.as, I don't know what to put in if (penguin.hitTestObject(???))
Using Objects doesn't work because it will give error #1067: Implicit coercion of a value of type Array to an unrelated type Function.
Could someone help me in getting it work?
Thanks in advance!
Evader is a DisplayObject, specifically type MovielCip. Each display object has a stage field, but the stage field is null until the display object (Evader) gets added to the stage display list (using addChild, eg. stage.addChild( myEvaderInstance) ).
So just from looking at the code you provided, it's possible you haven't added Evader to the display list, therefore its stage is null in the line:
if( currentObject.x > stage.stageWidth )
In which case you wouldn't want to add the event frame listener in its constructor. You'd want to add that listener after it's been added to the stage. So, here's how you can do that. In the Evador constructor:
public function Evader()
{
initGame();
Mouse.hide();
objects = new Array();
//don't update yet, we haven't been added to the display list
//addEventListener( Event.ENTER_FRAME, update );
addEventListener( Event.ADDED_TO_STAGE, onAddedToStage );
}
private function onAddedToStage( e:Event ):void {
removeEventListener( Event.ADDED_TO_STAGE, onAddedToStage );
//add the update listener!
addEventListener( Event.ENTER_FRAME, update );
}
That should do it. We wait till Evader has been added to the display list, then add the event frame listener.

Text displays on mouse release in as3

Ok, I have a question about drag/drop, hittest and some text.
I have two objects, one of them is draggable. I want to display some text, when colission is detected, but only when mouse is UP (mouse is released).
How to do that?
This is part of the code that handles collision:
this.addEventListener( Event.ENTER_FRAME, handleCollision)
function handleCollision( e:Event ):void
{
if(zuto.hitTestObject(tabla) && crveno.hitTestObject(tabla))
{
tekst.text = "GAME OVER"
} else {
tekst.text = ""
}
}
Should check if the mouse is down or not:
var mouseDown:Boolean;
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(MouseEvent.MOUSE_Up, onMouseUp);
function onMouseDown(e:MouseEvent):void {
mouseDown = true;
}
function onMouseUp(e:MouseEvent):void {
mouseDown = false;
}
function handleCollision( e:Event ):void {
if (mouseDown) { // mouse is still down, stop collision check
return;
}
// ..rest of your code here
}

click tap or touch begin and drag an object on the same time as3

i am creating a buttons bar that can be dragged however when i lift my finger after dragging the buttons the button is getting pushed, i would like to cancel the click/tap when dragging the buttons any suggestions?
Thank you
You'll either need to remove/add your listeners as necessary, or have a property on your buttons. Something like:
public class DragButton extends Sprite
{
public var isDragging:Boolean = false;
public function DragButton()
{
// add our listeners
this.addEventListener( MouseEvent.MOUSE_DOWN, this._onMouseDown );
this.addEventListener( MouseEvent.MOUSE_UP, this._onMouseUp );
this.addEventListener( MouseEvent.CLICK, this._onMouseClick );
}
private function _onMouseDown( e:MouseEvent ):void
{
// add our move listener for dragging
this.addEventListener( MouseEvent.MOUSE_MOVE, this._onMouseMove );
}
private function _onMouseUp( e:MouseEvent ):void
{
// remove our dragging listener
this.removeEventListener( MouseEvent.MOUSE_MOVE, this._onMouseMove );
}
private function _onMouseMove( e:MouseEvent ):void
{
// drag us
this.x = e.stageX;
this.y = e.stageY;
this.isDragging = true;
}
private function _onMouseClick( e:MouseEvent ):void
{
// if we're dragging, ignore
if( this.isDragging )
{
this.isDragging = false;
return;
}
// do our click stuff
}
}

looping custom cursor opacity falling in infinite loop

I am trying to make my custom cursor glow slowly by changing its opacity. The problem is that the only way I can see it working is by making a while, which creates an infinite loop. Is there a way to proceed so my cursor changes from 0 opacity to 1 opacity and go up and down. Here is my code at the moment... I'm trying to find another way to proceed, but I really don't see any other way.
public var Alpha:Number = 1;
public var sense:String = "down";
private function thisMouseOver(e:MouseEvent):void{
Mouse.hide();
//draws the cursor
drawCursor();
//Animates cursor
if(!this.animationStarted)
{
this.animationStarted = true;
animateCursor();
}
}
private function animateCursor():void{
while(this.animationStarted)
{
if(this.Alpha==1)
{
this.sense = "down";
}
else if(this.Alpha == 0)
{
this.sense = "up";
}
if(this.sense == "up")
this.Alpha += 0.1;
else
this.Alpha -= 0.1;
this.graphics.beginFill(0x333333);
this.graphics.drawRect(0,0,25,25);
this.graphics.endFill();
drawCursor();
}
}
private function drawCursor():void{
this.graphics.beginFill(0x00BFFF,this.Alpha);
//top left
this.graphics.drawRect(0,0,6,2);
//bottom left
this.graphics.drawRect(0,23,6,2);
//left top
this.graphics.drawRect(0,0,2,6);
//left bottom
this.graphics.drawRect(0,19,2,6);
//top righ
this.graphics.drawRect(19,0,6,2);
//right top
this.graphics.drawRect(23,0,2,6);
//bottom right
this.graphics.drawRect(19,23,6,2);
//right bottom
this.graphics.drawRect(23,19,2,6);
this.graphics.endFill();
}
The best way is to use tweener, my favorite is GTween:
private function test():void
{
var shape:Shape = new Shape();
addChild(shape);
shape.graphics.beginFill(0xFF0000, 1);
shape.graphics.drawCircle(100, 100, 50);
shape.graphics.endFill();
var tween:GTween = new GTween(shape, 1, {alpha:0}, {reflect:true, repeatCount:2});
tween.nextTween = tween;
}
Use tween.paused = true/false to play()/stop() the tween.
There is another variant without tweener (but I recommend to use tween because code is more clear, readable and it's less resources cost) that is more like your, but instead of while loop use EnterFrame event approach - remove while loop from animateCursor() method, add Event.ENTER_FRAME listener in the point of animateCursor(); call:
if(!this.animationStarted)
{
this.animationStarted = true;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame():void
{
animateCursor();
}
One way to avoid your problem with the infinite loop is to put your animateCursor code inside an ENTER_FRAME event handler.
Here's how it can look: http://www.swfcabin.com/open/1360303185
( Your custom cursor shape looks awesome ; )
Here's your code remade in MiniBuilder ( functions are arranged alphabetically ):
package com.glowingcursor {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.ui.*;
public class Application extends Sprite {
private var cursor:Sprite;
private var cursorOffset:Point;
private var sense:Boolean;
public function
Application() {
addEventListener( Event.ADDED_TO_STAGE, onAdded );
}
private function
animateCursor( e:Event ):void {
if ( cursor.alpha >= 1 ) sense = false;
else if ( cursor.alpha <= 0.2 ) sense = true;
if( sense ) cursor.alpha += 0.08;
else cursor.alpha -= 0.08;
}
private function
hideCursor( e:MouseEvent ):void {
Mouse.show();
removeChild( cursor );
removeEventListener( Event.ENTER_FRAME, moveCursor );
removeEventListener( Event.ENTER_FRAME, animateCursor );
}
private function
initCursor():void {
cursor = new Sprite();
cursor.graphics.beginFill( 0xff0000 );
cursor.graphics.drawRect( 0, 0, 6, 2 ); // top left
cursor.graphics.drawRect( 0, 23, 6, 2 ); // bottom left
cursor.graphics.drawRect( 0, 0, 2, 6 ); // left top
cursor.graphics.drawRect( 0, 19, 2, 6 ); // left bottom
cursor.graphics.drawRect( 19, 0, 6, 2 ); // top right
cursor.graphics.drawRect( 23, 0, 2, 6 ); // right top
cursor.graphics.drawRect( 19, 23, 6, 2 ); // bottom right
cursor.graphics.drawRect( 23, 19, 2, 6 ); // right bottom
cursor.graphics.endFill();
// So InteractiveObjects react to the custom cursor properly
cursor.mouseEnabled = false;
// For cursor centering
cursorOffset = new Point( cursor.width / 2, cursor.height / 2 );
}
private function
moveCursor( e:Event ):void {
cursor.x = mouseX - cursorOffset.x;
cursor.y = mouseY - cursorOffset.y;
}
private function
onAdded( e:Event ):void {
initCursor();
showCursor();
}
private function
showCursor():void {
Mouse.hide();
addChild( cursor );
addEventListener( Event.ENTER_FRAME, moveCursor );
addEventListener( Event.ENTER_FRAME, animateCursor );
}
}
}
You can put your code from the animateCursor inside a different method, and use a Timer to call that method. This way you can control how "fast" the cursor blinks and when.
Timer timer = new Timer( 25, 0 );
private function animateCursor():void
{
timer.addEventListener( TimerEvent.TIMER, timerHandler );
timer.start()
}
private function timerListener( e:TimerEvent ):void
{
if(this.Alpha==1)
{
this.sense = "down";
}
else if(this.Alpha == 0)
{
this.sense = "up";
}
if(this.sense == "up")
this.Alpha += 0.1;
else
this.Alpha -= 0.1;
this.graphics.beginFill(0x333333);
this.graphics.drawRect(0,0,25,25);
this.graphics.endFill();
drawCursor();
}
also it's a good idea to change your alpha conditions from this.Alpha == 0 to this.Alpha <= 0 as you may choose to change the amount by which you modify the alpha to values that don't always add up to 0 or 1.

Flash AS3 hit test go to next frame

I have a object that can be dragged into another object. I have set up a hit test for the collision. When the collision occurs I would like to progress to the next frame however, I have to click on the draggable object for it to do so. I would like it to move to the next frame right away without clicking. Is there anyway to fix this?
I mean after I have dragged the objected to create the collision I need to click on the object again to progress to the next frame. I do not want to have to click on the object again I want it to go to the next frame as the collision occurs.
This is my code
bottle.buttonMode = true;
bottle.addEventListener(MouseEvent.MOUSE_DOWN, drag);
bottle.addEventListener(MouseEvent.MOUSE_UP, drop);
function collision():void{
if(bottle.hitTestObject(hit)){
nextFrame();
}
}
function drag(e:MouseEvent):void{
bottle.startDrag();
collision();
}
function drop(e:MouseEvent):void{
bottle.stopDrag();
}
You should be checking for collisions after the drop, not at the start of the drag:
function collision():void{
if(bottle.hitTestObject(hit)){
nextFrame();
}
}
function drag(e:MouseEvent):void{
bottle.startDrag();
}
function drop(e:MouseEvent):void{
bottle.stopDrag();
collision();
}
Change collision() into an event listener and attach it to bottle.
Try this one ( adapted from Gary Rosenzweig ) :
bottle.buttonMode = true;
bottle.addEventListener( MouseEvent.MOUSE_DOWN, startBottleDrag );
stage.addEventListener( MouseEvent.MOUSE_UP, stopBottleDrag );
function collision():void {
if( bottle.hitTestObject( hit ) ) {
stopBottleDrag();
nextFrame();
}
}
// to keep bottle location as it is when clicked
var clickOffset:Point = null;
function startBottleDrag( e:MouseEvent ) {
clickOffset = new Point( e.localX, e.localY );
bottle.addEventListener( Event.ENTER_FRAME, dragBottle );
}
function stopBottleDrag( e:MouseEvent = null ) {
clickOffset = null;
bottle.removeEventListener( Event.ENTER_FRAME, dragBottle );
}
function dragBottle( e:Event ) {
bottle.x = mouseX - clickOffset.x;
bottle.y = mouseY - clickOffset.y;
collision();
}