AS3 BitmapData Collision - actionscript-3

I am having a problem with BitmapData Collision detection, my class is not detecting any collision at all
BitmapCollision.as
package com.ipromoweb.demoapp
{
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
/**
* ...
* #author Me
*/
public class BitmapCollision {
private var collides:Boolean = false;
public function check(obj1:DisplayObjectContainer, obj2:DisplayObjectContainer):Boolean {
// obj1
var obj1Rect:Rectangle = obj1.getBounds(obj1);
var obj1Offset:Matrix = obj1.transform.matrix;
obj1Offset.tx = obj1.x - obj1Rect.x;
obj1Offset.ty = obj1.y - obj1Rect.y;
var obj1ClipBmpData:BitmapData = new BitmapData(obj1Rect.width, obj1Rect.height, true, 0);
obj1ClipBmpData.draw(obj1, obj1Offset);
// obj2
var obj2Rect:Rectangle = obj2.getBounds(obj2);
var obj2Offset:Matrix = obj2.transform.matrix;
obj2Offset.tx = obj2.x - obj2Rect.x;
obj2Offset.ty = obj2.y - obj2Rect.y;
var obj2ClipBmpData:BitmapData = new BitmapData(obj2Rect.width, obj2Rect.height, true, 0);
obj2ClipBmpData.draw(obj2, obj2Offset);
var rLoc:Point = new Point(obj2Rect.x, obj2Rect.y);
var bLoc:Point = new Point(obj1Rect.x, obj1Rect.y);
if (obj1ClipBmpData.hitTest(bLoc, 255, obj2ClipBmpData, rLoc, 255)) {
trace("hit");
collides = true;
}else {
collides = false;
}
obj1ClipBmpData.dispose();
obj2ClipBmpData.dispose();
return collides;
}
}
}
And i am calling checkCollision function on a ENTER_FRAME event, the hitTestObject is firing well but the bitmapData Collision is not firing at all.
private function checkCollision():void {
for (var i:int = 0; i < parent.numChildren; i++) {
if (Object(parent.getChildAt(i)).constructor == '[class CollisionTest]') {
if (this.hitTestObject(parent.getChildAt(i))) {
trace('colliding');
if ( _collision.check(Sprite(this),Sprite(parent.getChildAt(i))) ) {
trace('>>>>>>>>>>> perfect hit');
}
}
}
}
}
Any help on this would be greatly appreciated.

I discarded the previous method of BitmapData Collision that i was trying to implement and downloaded a free library called CDK:
https://code.google.com/p/collisiondetectionkit/
it solved all my problems.

Related

How to add 2 volume sliders to my mp3 players in as3

Easy people. Im currently trying to add 2 volume sliders to my existing project. I have two turntables, deck1 & deck2 but i need to be able to control the volume of each deck individually.
Im relatively new to actionscript 3 so im struggling abit. Can anyone help me please, here is my code..
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.display.Graphics;
import flash.events.Event;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import flash.text.TextField;
//variables
var mySound:Sound;
var myChannel:SoundChannel;
var nowPlaying:Boolean = false;
var nowPaused:Boolean = false;
var p:uint = 0;
var songfile:String;
var songtitle:String;
deck1_btn.addEventListener(MouseEvent.CLICK, deck1_data);
deck2_btn.addEventListener(MouseEvent.CLICK, deck2_data);
//song3_btn.addEventListener(MouseEvent.CLICK, song3_data);
stop_btn.addEventListener(MouseEvent.CLICK, stopSound);
stop2_btn.addEventListener(MouseEvent.CLICK, stopSound);
pause_btn.addEventListener(MouseEvent.CLICK, pauseSound);
function deck1_data(myEvent:MouseEvent):void {
songfile = "audio/desire.mp3";
songtitle = "Skeptical - Desire";
playSound(null);
}
function deck2_data(myEvent:MouseEvent):void {
songfile = "audio/tundra.mp3";
songtitle = "Skeptical - Tundra";
playSound(null);
}
//function song3_data(myEvent:MouseEvent):void {
songfile = "audio/always_be_mine.mp3";
songtitle = "Skeptical - Always Be Mine";
playSound(null);
function stopSound(myEvent:MouseEvent):void {
if (nowPlaying) {
myChannel.stop();
p = 0;
nowPlaying = false;
nowPaused = false;
}
}
function playSound(myEvent:Event):void {
mySound = new Sound;
mySound.load(new URLRequest(songfile));
title_txt.text = songtitle;
if (isPlaying) {
myChannel.stop();
myChannel = mySound.play(0);
} else {
myChannel = mySound.play(0);
nowPlaying = true;
}
}
function pauseSound(myEvent:MouseEvent):void {
if (isPlaying) {
p = Math.floor(myChannel.position);
myChannel.stop();
nowPlaying = false;
nowPaused = true;
} else if (nowPaused) {
myChannel = mySound.play(p);
nowPlaying = true;
nowPaused = false;
}
}
title_txt.text = "";
For controlling volume you will need SoundTransform. Create sliders, and store volumes as numbers. And when you start deck sound, apply soundTransform with deck volume value:
myChannel = mySound.play(0, 0, new SoundTransform(myDeck1Volume));
//or
//myChannel = mySound.play(0, 0, new SoundTransform(myDeck2Volume));
As for sliders. You could use Slider component

Actionscript 3: Error #1009: Cannot access a property or method of a null object reference. (parent)

This is a bit difficult to explain, but I will try.
In my Main() class, let's say I have the main movieclip (bg_image) being created, and also some lines that create an instance of another class. (look at the code below)
var route = Route(Airport.return_Route);
This route instance, is then purposed to dynamically add sprite-childs to the main background from the Main() class.
I have tried to to this with the following line:
new_flight = new Flight(coordinates)
Main.bg_image.addChild(new_flight);
This seem to work pretty fine. Let's switch focus to the new_flight instance. At the Flight class, this line trace(this.parent) would return "[object Image]".I would consider this successful so far since my intention is to add the new_flight as child to bg_image, which I guess is an "object image".
The problem, however, occurs when trying to delete the "new_flight"-instance. Obviously the ideal way of doing this would be through bg_image with removeChild.
But, when my script reaches this line: Main.bg_image.removeChild(this), my script stops and returns ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller., at that line. I have also tried replacing Main.bg_image.removeChild(this) with this.parent.removeChild(this), with no luck.
I think the solution may be to use some sort of "EventDispatching"-method. But I haven't fully understood this concept yet...
The code follows. Please help. I have no idea how to make this work...
Main class:
package
{
import flash.display.MovieClip;
import flash.utils.Dictionary;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.text.TextField;
import fl.controls.Button;
import flash.display.DisplayObject;
import Airport;
public class Main extends Sprite
{
// ------------------------
// Buttons
public var create_new_route;
public var confirm_new_route;
// images
public static var bg_image:MovieClip;
public var airport:MovieClip;
//-------------------------------
public var routeArray:Array;
public static var airportDict:Dictionary = new Dictionary();
public static var collectedAirportArray:Array = new Array();
public function Main()
{
addEventListener(Event.ADDED_TO_STAGE, init);
create_new_route = new Button();
create_new_route.label = "Create new route";
create_new_route.x = 220;
create_new_route.y = 580;
this.addChild(create_new_route)
create_new_route.addEventListener(MouseEvent.CLICK, new_route)
confirm_new_route = new Button();
confirm_new_route.label = "Confirm route";
confirm_new_route.x = 220;
confirm_new_route.y = 610;
this.addChild(confirm_new_route)
confirm_new_route.addEventListener(MouseEvent.CLICK, confirm_route)
}
public function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
bg_image = new Image();
addChild(bg_image);
S_USA["x"] = 180.7;
S_USA["y"] = 149.9;
S_USA["bynavn"] = "New York";
S_Norway["x"] = 423.7;
S_Norway["y"] = 76.4;
S_Norway["bynavn"] = "Oslo";
S_South_Africa["x"] = -26;
S_South_Africa["y"] = 146;
S_South_Africa["bynavn"] = "Cape Town";
S_Brazil["x"] = 226;
S_Brazil["y"] = 431.95;
S_Brazil["bynavn"] = "Rio de Janeiro";
S_France["x"] = 459.1;
S_France["y"] = 403.9;
S_France["bynavn"] = "Paris";
S_China["x"] = 716.2;
S_China["y"] = 143.3;
S_China["bynavn"] = "Beijing";
S_Australia["x"] = 809.35;
S_Australia["y"] = 414.95;
S_Australia["bynavn"] = "Sydney";
// ----------------------------------------------------
airportDict["USA"] = S_USA;
airportDict["Norway"] = S_Norway;
airportDict["South Africa"] = S_South_Africa;
airportDict["Brazil"] = S_Brazil;
airportDict["France"] = S_France;
airportDict["China"] = S_China;
airportDict["Australia"] = S_Australia;
for (var k:Object in airportDict)
{
var value = airportDict[k];
var key = k;
startList.addItem({label:key, data:key});
sluttList.addItem({label:key, data:key});
var airport:Airport = new Airport(key,airportDict[key]["bynavn"]);
airport.koordinater(airportDict[key]["x"], airportDict[key]["y"]);
collectedAirportArray.push(airport);
airport.scaleY = minScale;
airport.scaleX = minScale;
bg_image.addChild(airport);
}
// --------------------------------------------
// --------------------------------------------
// -----------------------------------------------
}
private function new_route(evt:MouseEvent):void
{
Airport.ROUTING = true;
}
public function confirm_route(evt:MouseEvent):void
{
Airport.ROUTING = false;
trace(Airport.return_ROUTE);
var route = new Route(Airport.return_ROUTE); // ***
this.addChild(route); // **
Airport.return_ROUTE = new Array();
}
}
}
Airport class:
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.SimpleButton;
import flash.display.Stage;
import flash.text.TextField;
import flash.text.TextFormat;
import flashx.textLayout.formats.Float;
public class Airport extends MovieClip
{
public static var ROUTING = false;
public static var return_ROUTE:Array = new Array();
//-----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
protected var navn:String;
protected var bynavn:String;
// ----------------------------------------------------------------------------
public function Airport(navninput, bynavninput)
{
this.bynavn = bynavninput;
this.navn = navninput;
this.addEventListener(MouseEvent.CLICK, clickHandler);
this.addEventListener(MouseEvent.MOUSE_OVER, hoverHandler);
}
public function zoomHandler():void
{
trace("testing complete");
}
public function koordinater(xc, yc)
{
this.x = (xc);
this.y = (yc);
}
private function clickHandler(evt:MouseEvent):void
{
trace(ROUTING)
if (ROUTING == true)
{
return_ROUTE.push([this.x, this.y])
}
}
private function hoverHandler(evt:MouseEvent):void
{
if (ROUTING == true)
{
this.alpha = 60;
this.width = 2*this.width;
this.height = 2*this.height;
this.addEventListener(MouseEvent.MOUSE_OUT, awayHandler);
}
}
private function awayHandler(evt:MouseEvent):void
{
this.width = 13;
this.height = 13;
}
}
}
Route class
package
{
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.display.MovieClip;
import Main;
public class Route
{
public var income:Number;
public var routePoints:Array;
private var routeTimer:Timer;
private var new_flight:Flight;
public function Route(route_array:Array)
{
this.routePoints = route_array
routeTimer = new Timer(2000);// 2 second
routeTimer.addEventListener(TimerEvent.TIMER, route_function);
routeTimer.start();
}
private function route_function(event:TimerEvent):void
{
for (var counter:uint = 0; counter < routePoints.length - 1; counter ++)
{
trace("Coords: ", routePoints[counter][0],routePoints[counter][1],routePoints[counter + 1][0],routePoints[counter + 1][1]);
new_flight = new Flight(routePoints[counter][0],routePoints[counter][1],routePoints[counter + 1][0],routePoints[counter + 1][1]);
Main.bg_image.addChild(new_flight);
var checkTimer:Timer = new Timer(15);// 1 second
checkTimer.addEventListener(TimerEvent.TIMER, check_function);
checkTimer.start();
function check_function(event:TimerEvent):void
{
if (new_flight.finished = true)
{
checkTimer.stop();
}
}
}
}
}
}
Flight class
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.SimpleButton;
import flash.display.Stage;
import flash.events.TimerEvent;
import flash.utils.Timer;
import fl.controls.Button;
import flash.display.DisplayObject;
public class Flight extends MovieClip
{
public static var speed:uint = 1
public var finished:Boolean = false;
protected var absvector:Number;
protected var vector:Array;
protected var myTimer:Timer;
//protected var parentContainer:MovieClip;
protected var utgangspunkt_x;
protected var utgangspunkt_y;
protected var destinasjon_x;
protected var destinasjon_y;
protected var vector_x;
protected var vector_y;
public function Flight(utgangspunkt_x, utgangspunkt_y, destinasjon_x, destinasjon_y):void
{
addEventListener(Event.ADDED_TO_STAGE, init);
this.utgangspunkt_x = utgangspunkt_x;
this.utgangspunkt_y = utgangspunkt_y;
this.x = utgangspunkt_x;
this.y = utgangspunkt_y;
this.destinasjon_x = destinasjon_x + 10;
this.destinasjon_y = destinasjon_y + 10;
this.vector_x = Math.abs(this.destinasjon_x-this.utgangspunkt_x);
this.vector_y = Math.abs(this.destinasjon_y-this.utgangspunkt_y);
this.height = 20;
this.width = 20;
}
public function init(evt:Event):void
{
trace(this.parent)
if (utgangspunkt_x < destinasjon_x)
{
this.rotation = -(Math.atan((utgangspunkt_y-destinasjon_y)/(destinasjon_x-utgangspunkt_x)))/(Math.PI)*180;
}
else
{
this.rotation = 180-(Math.atan((utgangspunkt_y-destinasjon_y)/(destinasjon_x-utgangspunkt_x)))/(Math.PI)*180;
}
absvector = Math.sqrt(Math.pow((destinasjon_x - utgangspunkt_x),2) + Math.pow((utgangspunkt_y - destinasjon_y),2));
vector = [(destinasjon_x - utgangspunkt_x) / absvector,(utgangspunkt_y - destinasjon_y) / absvector];
stage.addEventListener(Event.ENTER_FRAME, movement)
}
private function movement(evt:Event):void
{
if (this.vector_x > this.vector_y)
{
if (destinasjon_x>utgangspunkt_x)
{
if (this.x < destinasjon_x)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
finished = true
Main.bg_image.removeChild(this)
}
}
else if (destinasjon_x<utgangspunkt_x)
{
if (this.x > destinasjon_x)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
finished = true
Main.bg_image.removeChild(this)
}
}
}
else
{
if (destinasjon_y>utgangspunkt_y)
{
if (this.y < destinasjon_y)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
finished = true
Main.bg_image.removeChild(this)
}
}
else if (destinasjon_y<utgangspunkt_y)
{
if (this.y > destinasjon_y)
{
this.x += speed*vector[0];
this.y -= speed*vector[1];
}
else
{
finished = true
Main.bg_image.removeChild(this)
}
}
}
}
}
}
I am confused what your asking and what your trying to do, but I will give it my best shot.
this.addchild(new_class2)
This line adds your object to the display list. Adding another object to the display is done the same way you added the first. Flash adds objects in the sequentially, so the objects you want in the back need to be declared and added first.
This is probably what you want:
var new_flight:Flight = new Flight();
this.addchild(new_flight);
Also you forgot your type declaration for Class2:
var new_class2:Class2 = new Class2();
Try replacing:
Main.bg_image.addChild(new_flight);
with
Main(this.parent).bg_image.addChild(new_flight);
... assuming the 'main' class you refer to is infact named 'Main' and it has a named instance called 'bg_image'
Please leave a comment if it works, I can explain in more detail what is actually happening here.
Why you are adding new_flight to bg_image?
Anyway, if you are adding new_flight to bg_image, then you have bg_image already declared as public static (which I do not recommend),
Try removing the flight in your Flight class it-self like so,
Main.bg_image.removeChild(this) // *
You can also use Event Dispatching instead of declaring bg_image as static.
If you want to remove flight then dispatch event from Flight class to Route class and there you again dispatch event to main class.
And, inside main class capture this event and access the MovieClip.

ActionScript 3: Zoom functions - drag does not show

I've included a zoom functionality similar to the one explained at this website: http://www.flashandmath.com/howtos/zoom/
Even though it does indeed work in terms of the possibility of moving the image on my stage, the drag-animation is not present, meaning there will be no "movement" of my image, just a sudden change in position.
The problem followed my attempt to change the concept from timeline-based to class-based.
Here is my Main class:
package
{
import flash.display.MovieClip;
import flash.utils.Dictionary;
import flash.display.Shape;
import fl.transitions.Fly;
import fl.motion.MatrixTransformer;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.ui.Mouse;
public class Main extends Sprite
{
public static var scale:Number = 1;
private var _rootMC:MovieClip;
// ------------------------------
public var bg_image:Sprite;
public var spImage:Sprite;
public var mat:Matrix;
public var mcIn:MovieClip;
public var mcOut:MovieClip;
public var boardWidth:int = 980;
public var boardHeight:int = 661;
public var boardMask:Shape;
public var externalCenter:Point;
public var internalCenter:Point;
public static var scaleFactor:Number = 0.8;
public static var minScale:Number = 0.25;
public static var maxScale:Number = 10.0;
//-------------------------------
public function Main(rootMC:MovieClip)
{
_rootMC = rootMC;
bg_image = new image();
this.graphics.beginFill(0xB6DCF4);
this.graphics.drawRect(0,0,boardWidth,boardHeight);
this.graphics.endFill();
spImage = new Sprite();
this.addChild(spImage);
boardMask = new Shape();
boardMask.graphics.beginFill(0xDDDDDD);
boardMask.graphics.drawRect(0,0,boardWidth,boardHeight);
boardMask.graphics.endFill();
boardMask.x = 0;
boardMask.y = 0;
this.addChild(boardMask);
spImage.mask = boardMask;
minScale = boardWidth / bg_image.width;
mcIn = new InCursorClip();
mcOut = new OutCursorClip();
bg_image.addChild(mcIn);
bg_image.addChild(mcOut);
bg_image.scaleX = minScale;
bg_image.scaleY = minScale;
spImage.addChild(bg_image);
spImage.addChild(mcIn);
spImage.addChild(mcOut);
spImage.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
_rootMC.stage.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
spImage.addEventListener(MouseEvent.CLICK, zoom);
_rootMC.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandler);
_rootMC.stage.addEventListener(KeyboardEvent.KEY_UP, keyHandler);
}
private function startDragging(mev:MouseEvent):void
{
spImage.startDrag();
}
private function stopDragging(mev:MouseEvent):void
{
spImage.stopDrag();
}
private function zoom(mev:MouseEvent):void
{
if ((!mev.shiftKey)&&(!mev.ctrlKey))
{
return;
}
if ((mev.shiftKey)&&(mev.ctrlKey))
{
return;
}
externalCenter = new Point(spImage.mouseX,spImage.mouseY);
internalCenter = new Point(bg_image.mouseX,bg_image.mouseY);
if (mev.shiftKey)
{
bg_image.scaleX = Math.max(scaleFactor*bg_image.scaleX, minScale);
bg_image.scaleY = Math.max(scaleFactor*bg_image.scaleY, minScale);
}
if (mev.ctrlKey)
{
bg_image.scaleX = Math.min(1/scaleFactor*bg_image.scaleX, maxScale);
bg_image.scaleY = Math.min(1/scaleFactor*bg_image.scaleY, maxScale);
}
mat = this.transform.matrix.clone();
MatrixTransformer.matchInternalPointWithExternal(mat,internalCenter,externalCenter);
bg_image.transform.matrix = mat;
}
private function keyHandler(ke:KeyboardEvent):void
{
mcIn.x = spImage.mouseX;
mcIn.y = spImage.mouseY;
mcOut.x = spImage.mouseX;
mcOut.y = spImage.mouseY;
mcIn.visible = ke.ctrlKey;
mcOut.visible = ke.shiftKey;
if (ke.ctrlKey || ke.shiftKey)
{
Mouse.hide();
}
else
{
Mouse.show();
}
}
}
}
Here is my image class:
package {
import fl.motion.MatrixTransformer;
import flash.display.MovieClip;
import flash.utils.Dictionary;
import flash.display.Shape;
import fl.transitions.Fly;
import fl.motion.MatrixTransformer;
import flash.events.MouseEvent;
public class image extends MovieClip
{
public function image()
{
this.width = 980
this.height = 500
this.y = 0
this.x = 0
}
}
I know this is a lot of code, but I am really stuck :(
On your MOUSE_DOWN handler, you need to start listening to the MOUSE_MOVE event.
On your MOUSE_UP handler, you need to stop listening to the MOUSE_MOVE event.
Not sure if you are already doing this.
In your MOUSE_MOVE event handler, you need to update the x / y positions of the image, in a similar way to what you are probably doing on the MOUSE_UP handler.

as3 hitTestPoint detecting alpha

I am trying to make maze where the user draws with mouse and if they hit the wall it erases the line they just drew. I have a png file with alpha that creates the walls of the maze.
I need the user to draw on the alpha but when they hit a non alpha it will trigger an action and erase the line.
Here is the line I am having issues with:
if (myshape.hitTestPoint(theBall.x,theBall.y, true))
Here is the full code:
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.JointStyle;
import flash.display.LineScaleMode;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.*;
public class MazeClass extends Sprite
{
//Are we drawing or not?
private var drawing:Boolean;
public var myshape:Shape;
public var alreadyDrawn:Shape;
public var theBall:Ball = new Ball();
//alreadyDrawn = new Shape();
public function MazeClass()
{
if (stage)
{
myshape = new Shape();
myshape.graphics.lineStyle(12,0x000000);
addChild(myshape);
drawing = false;//to start with
stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing);
stage.addEventListener(MouseEvent.MOUSE_MOVE, draw);
stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawing);
//stage.addEventListener(Event.ENTER_FRAME, checkIt);
addChild(theBall);
}
}
public function startDrawing(event:MouseEvent):void
{
myshape.graphics.moveTo( mouseX, mouseY);
drawing = true;
}
public function draw(event:MouseEvent)
{
if (drawing)
{
//checkIt();
myshape.graphics.lineTo(mouseX,mouseY);
if (myshape.hitTestPoint(theBall.x,theBall.y, true))
{
trace("Hit A WALL!");
myshape.graphics.clear();
myshape.graphics.lineStyle(12, 0xFFFFFF);
myshape.graphics.moveTo(mouseX,mouseY);
}
}
}
public function stopDrawing(event:MouseEvent)
{
drawing = false;
}
}
}
Another option is to test the colour of the map bitmapdata pixel that corresponds to the "player's position" (the end of the drawn line, in this case):
var testPixel:uint = _myBitmapData.getPixel(xPosition, yPosition);
Or you can use .getPixel32 which includes alpha in the returned uint.
I FOUND A WORKING SOLUTION:
I found a working solution thanks to fsbmain. Thank you. I am posting my full code in hopes that this can help someone else.
In the end I had to use another movieClip rather than the mouse, but this worked for me. Now instead of drawing anywhere in the maze they have to drag a little character named Beau thru the maze. This works better for me.
It would be nice to know how to also detect if the mouse or the actual line I am drawing hit the wall as well. Maybe someone can make a suggestion. Nevertheless, thanks for helping me get this far.
The short and essential code to make my movieClip detect the alpha can be found here. It really is very short compared to other complicated options I found. Here is the link: http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.JointStyle;
import flash.display.LineScaleMode;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.*;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.desktop.NativeApplication;
import flash.system.Capabilities;
import flash.display.*;
import flash.geom.*;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Matrix;
public class MazeClass extends Sprite
{
//Are we drawing or not?
private var drawing:Boolean;
public var myshape:Shape;
public var alreadyDrawn:Shape;
public var theMap:*;
public var swiper:Swiper = new Swiper();
public var Beau:littleBeau = new littleBeau();
//alreadyDrawn = new Shape();
public var currentGalleryItem:Number = 1;
public var totalGalleryItems:Number = 4;
public var redClipBmpData:BitmapData;
public var blueClipBmpData:BitmapData;
public var redRect:Rectangle;
public var blueRect:Rectangle;
public function MazeClass()
{
if (stage)
{
theMap = new MapOne();
myshape = new Shape();
myshape.graphics.lineStyle(33,0x0aa6df);
addChild(myshape);
drawing = false;//to start with
stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing);
stage.addEventListener(MouseEvent.MOUSE_MOVE, draw);
stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawing);
//stage.addEventListener(Event.ENTER_FRAME, checkIt);
stage.addEventListener(KeyboardEvent.KEY_UP, fl_OptionsMenuHandler);
Multitouch.inputMode = MultitouchInputMode.GESTURE;
addChild(theMap);
//theMap.height = stage.stageHeight - 200;
theMap.theStart.alpha = 0;
theMap.theFinish.alpha = 0;
addChild(swiper);
swiper.y = stage.stageHeight - swiper.height;
swiper.addEventListener(TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrame);
addChild(Beau);
Beau.x = theMap.theStart.x;
Beau.y = theMap.theStart.y - swiper.height;
Beau.addEventListener(MouseEvent.MOUSE_DOWN, BeauStartDrag);
Beau.addEventListener(MouseEvent.MOUSE_UP, BeauStopDrag);
redRect = theMap.getBounds(this);
redClipBmpData = new BitmapData(redRect.width,redRect.height,true,0);
redClipBmpData.draw(theMap);
blueRect = Beau.getBounds(this);
blueClipBmpData = new BitmapData(blueRect.width,blueRect.height,true,0);
blueClipBmpData.draw(Beau);
//blueClipBmpData.x = theMap.theStart.x;
//blueClipBmpData.y = theMap.theStart.y - swiper.height;
stage.addEventListener(Event.ENTER_FRAME, enterFrame);
}
}
public function enterFrame(e:Event):void
{
//Beau.x = mouseX;
//Beau.y = mouseY;
if (redClipBmpData.hitTest(new Point(theMap.x, theMap.y),
255,
blueClipBmpData,
new Point(Beau.x, Beau.y),
255
))
{
trace("hit");
clearAll();
//redClip.filters = [new GlowFilter()];
}
else
{
trace("No Hit");
}
}
public function BeauStartDrag(event:MouseEvent):void
{
Beau.startDrag();
drawing = true;
}
public function BeauStopDrag(event:MouseEvent):void
{
drawing = false;
Beau.stopDrag();
}
public function startDrawing(event:MouseEvent):void
{
myshape.graphics.moveTo( mouseX, mouseY);
}
//drawing = true;
public function draw(event:MouseEvent)
{
if (drawing)
{
//checkIt();
myshape.graphics.lineTo(mouseX,mouseY);
}
}
public function stopDrawing(event:MouseEvent)
{
//drawing = false;
}
public function fl_OptionsMenuHandler(event:KeyboardEvent):void
{
if ((event.keyCode == 95) || (event.keyCode == Keyboard.MENU))
{
NativeApplication.nativeApplication.exit(0);
}
}
public function clearAll()
{
myshape.graphics.clear();
myshape.graphics.lineStyle(12, 0x0aa6df);
myshape.graphics.moveTo(mouseX,mouseY);
Beau.x = theMap.theStart.x;
Beau.y = theMap.theStart.y - swiper.height;
drawing = false;
Beau.stopDrag();
}
public function fl_SwipeToGoToNextPreviousFrame(event:TransformGestureEvent):void
{
if (event.offsetX == 1)
{
if (currentGalleryItem > 1)
{
currentGalleryItem--;
trace("swipe Right");
clearAll();
removeChild(theMap);
theMap = new MapOne();
addChild(theMap);
theMap.height = stage.stageHeight - 200;
theMap.theStart.alpha = 0;
theMap.theFinish.alpha = 0;
addChild(Beau);
Beau.x = theMap.theStart.x;
Beau.y = theMap.theStart.y - swiper.height;
}
}
else if (event.offsetX == -1)
{
if (currentGalleryItem < totalGalleryItems)
{
currentGalleryItem++;
trace("swipe Left");
clearAll();
removeChild(theMap);
theMap = new MapTwo();
addChild(theMap);
theMap.height = stage.stageHeight - 200;
theMap.theStart.alpha = 0;
theMap.theFinish.alpha = 0;
addChild(Beau);
Beau.x = theMap.theStart.x;
Beau.y = theMap.theStart.y - swiper.height;
}
}
}
}
}

Multitouch as3 problems

I have a little problem with multitouch in as3.
Recently started a project in connection with my student practice.
This is to be a small game for android.
Are used to control two virtual joysticks and that's the problem with them.
As long as I use one of them or the other separately all works very well. However, when I try to use two at the same time, one of them is blocked and the object which moves begin to move in a random way and I can not control it.
Here is my code:
joystick.as:
package com.controls {
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.display.Sprite;
import flash.events.Event;
import flash.display.MovieClip;
import flash.geom.Rectangle;
import com.controls.JoystickKnob;
import com.Hero;
import com.Fire;
import com.greensock.*;
import com.greensock.easing.*;
public class Joystick extends MovieClip {
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
private var my_x:Number;
private var my_y:Number;
private var knob:JoystickKnob;
private var hero:Hero;
private var fire:Fire;
private var knob_tween:TweenLite;
public function Joystick(margin_left, margin_bottom, hero_mc) {
var circle:Sprite = new Sprite();
circle.graphics.beginFill(0x696969);
circle.graphics.drawCircle(50, 50, 60);
circle.graphics.endFill();
addChild(circle);
my_x = margin_left;
my_y = margin_bottom;
hero = hero_mc;
if (stage) {
init();
} else {
addEventListener(Event.ADDED_TO_STAGE,init);
}
}
private function init(e:Event = null):void {
if (hasEventListener(Event.ADDED_TO_STAGE)) {
removeEventListener(Event.ADDED_TO_STAGE,init);
}
this.x = my_x + this.width / 2;
this.y = stage.stageHeight - my_y - this.height / 2;
knob = new JoystickKnob();
knob.x = 0;
knob.y = 0;
knob.origin_x = 0;
knob.origin_y = 0;
addChild(knob);
this.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin, true);
knob.addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove, true);
stage.addEventListener(TouchEvent.TOUCH_END, onTouchEnd, true);
knob.buttonMode = true;
}
private function onTouchBegin(event:TouchEvent):void {
knob.x = this.mouseX;
knob.y = this.mouseY;
onTouchMove(null);
}
private function onTouchMove(event:TouchEvent):void {
if (knob_tween) {
knob_tween.kill();
}
this.addEventListener(Event.ENTER_FRAME, knobMoved);
knob.startDrag(false, new Rectangle( - this.width /2, - this.height /2, this.width, this.height));
}
private function knobMoved(event:Event):void {
// LEFT OR RIGHT
if (knob.x > 15) {
hero.move_right = true;
hero.move_left = false;
} else if (knob.x < -15) {
hero.move_right = false;
hero.move_left = true;
} else {
hero.move_right = false;
hero.move_left = false;
}
// UP OR DOWN
if (knob.y > 15) {
hero.move_down = true;
hero.move_up = false;
} else if (knob.y < -15) {
hero.move_down = false;
hero.move_up = true;
} else {
hero.move_down = false;
hero.move_up = false;
}
}
private function onTouchEnd(event:TouchEvent):void {
knob.stopDrag();
hero.move_left = false;
hero.move_up = false;
hero.move_right = false;
hero.move_down = false;
if (this.hasEventListener(Event.ENTER_FRAME)) {
this.removeEventListener(Event.ENTER_FRAME, knobMoved);
}
mover();
}
private function mover():void {
knob_tween = new TweenLite(knob, 0.5, {x: knob.origin_x, y:knob.origin_y, ease:Bounce.easeOut});
}
}
}
joystickKnob.as:
package com.controls {
import flash.display.Sprite;
import flash.display.MovieClip;
public class JoystickKnob extends MovieClip {
private var _origin_x:Number;
private var _origin_y:Number;
private var knob:Class;
public function JoystickKnob() {
var circle:Sprite = new Sprite();
circle.graphics.beginFill(0x32CD32);
circle.graphics.drawCircle(50, 50, 35);
circle.graphics.endFill();
addChild(circle);
}
public function get origin_x():Number {
return _origin_x;
}
public function set origin_x(o_x:Number):void {
_origin_x = o_x;
}
public function get origin_y():Number {
return _origin_x;
}
public function set origin_y(o_y:Number):void {
_origin_y = o_y;
}
}
}
Second joystick code looks the same, except that it is stored in files joystick2.as, joystickKnob2.as.
This is the main class of my program:
package com {
import flash.events.TouchEvent;
import flash.display.MovieClip;
import flash.events.MouseEvent;
import com.controls.Joystick;
import com.controls.Joystick2;
import com.Hero;
import com.Fire;
public class MyApp extends MovieClip {
private var joystick:Joystick;
private var hero:Hero;
private var joystick2:Joystick2;
private var fire:Fire;
public function MyApp() {
hero = new Hero();
hero.x = stage.stageWidth/1.7;
hero.y = stage.stageHeight/1.7;
addChild(hero);
fire = new Fire();
fire.x = stage.stageWidth/1.7;
fire.y = stage.stageHeight/1.7;
addChild(fire);
joystick = new Joystick(-350, 100, hero);
addChild(joystick);
joystick2 = new Joystick2(600, 100, fire);
addChild(joystick2);
}
}
}
When using the two joysticks at the same time, the problem also occurs with the knob graphics - instead move in a specific area, one of them almost always moves to the other end of the screen, near the area of the second joystick.
Has anyone of you already encountered such a problem and knows how to remedy it?
Best regards and thank you in advance for your help
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT; does not support multiple fingers as written in de documentation:
For user interaction with multiple points of contact (such as several fingers moving across a touch screen at the same time) use the related GestureEvent, PressAndTapGestureEvent, and TransformGestureEvent classes. And, use the properties and methods of these classes to construct event handlers that respond to the user touching the device.
so you want Multitouch.inputMode = MultitouchInputMode.GESTURE;
This post shows up when searching for info on touch_point so I want to make sure it's correct.
TOUCH_POINT does support multiple touch points. Each touch is unique and given a unique id. You can have 100s of simultaneous touches.
TOUCH_POINT is what you use if you want to code your own touch handlers. GESTURE is TOUCH_POINTs handled for you. GESTURE decides if the touchpoints are swiping, tapping, etc. TOUCH_POINT is like a mouse event - the raw event.