Add child + hittest? - actionscript-3

AS3 Flash -
Hey, I made a game like "Flappy Bird".
Can someone help me how to check "character" hitted a wall?
This game generate every 2.5 seconds two walls. (Wall and Wall2)
How to check that character hitted it?
function newWall():void
{
var Wall:wall = new wall();
addChildAt(Wall, 1);
Wall.x = -350 + (-80 - -350) * Math.random();
Wall.y = 805;
Wall.name = "Wall1_Object";
TweenLite.to(Wall, 10, {y:-50, ease:Linear.easeNone});
var Wall2:wall = new wall();
addChildAt(Wall2, 1);
Wall2.x = Wall.x + Wall.width + 125;
Wall2.y = 805;
Wall2.name = "Wall2_Object";
TweenLite.to(Wall2, 10, {y:-50, ease:Linear.easeNone});
}
function checkDead():void
{
if (character.hitTestObject(Wall) || character.hitTestObject(Wall2))
{
trace("You dead!");
}
}
var newWallInterval:uint = setInterval(newWall,2500);
var checkDeadInterval:uint = setInterval(checkDead,500);

If the last walls can't be hit any more when the new walls created,Try to define Wall and Wall2 outside the new newWall function.,or you need create an array to save the walls, and do a loop to check if the role hit the wall.

Related

AS3 return dropped object to initial location

I am using codes from http://hub.tutsplus.com/tutorials/create-a-drag-and-drop-puzzle-in-actionscript-30--active-2920 to make a drag and drop decoration game. I am trying to make it so that when the dropped object is dragged out of target location (which is an outline of the shape in my case), it goes back to initial location... basically reversing the drag and drop. I've been messing around with really random codes and so far this line is the closest to what I want but I don't think the code is right and also it doesnt return to initial location, it just goes to the side of the stage.
so, I added the else if line to stopDragObject which got the object to be removed from target location, but it randomly goes to the side of the stage, and not initial location:
private function stopDragObject(evt:MouseEvent):void {
if (evt.target.hitTestObject(getChildByName(evt.target.name + "Target"))) {
evt.target.x = getChildByName(evt.target.name + "Target").x;
evt.target.y = getChildByName(evt.target.name + "Target").y;
} else if (evt.target.x = null) {
evt.target.x = xPos;
evt.target.y = yPos;
}
evt.target.stopDrag();
}
Solved
after reading the lesson from below, I ended up with this and it works perfectly! (not exactly the way like the lesson but at least it works...)
private function stopDragObject(evt:MouseEvent):void {
if (evt.target.hitTestObject(getChildByName(evt.target.name + "Target"))) {
evt.target.x = getChildByName(evt.target.name + "Target").x;
evt.target.y = getChildByName(evt.target.name + "Target").y;
} else {
evt.target.x = getChildByName(evt.target.name + "Int").x;
evt.target.y = getChildByName(evt.target.name + "Int").y;
}
evt.target.stopDrag();
}
I added a initial object so the object could only be either at target or initial :)
I will try to teach neither provide code.
Lets draw two rectangles:
var s1:Sprite = new Sprite()
var s2:Sprite = new Sprite()
with (s1)
{
graphics.beginFill(0xfcaaaa, .7)
graphics.drawRect(0, 0, 400, 400)
graphics.endFill()
}
with (s2)
{
graphics.beginFill(0x00aaaa, .7)
graphics.drawRect(0, 0, 30, 30)
graphics.endFill()
}
addChild(s1)
addChild(s2)
Is't that simple? You see that s1 is much bigger than s2 (dimentions: 400, 400 vs 30, 30 ) Now place s2 to the center of our big s1:
s2.x = 200;
s2.y = 200;
We will use s1 for the boundaries of s2 movings.
This code is a simplest solution for dragging our s2 rectangle (Sprite):
s2.addEventListener(MouseEvent.MOUSE_DOWN, onDown)
s2.addEventListener(MouseEvent.MOUSE_UP, onUp)
function onDown(e:MouseEvent):void
{
(e.currentTarget as Sprite).startDrag();
}
function onUp(e:MouseEvent):void
{
(e.currentTarget as Sprite).stopDrag();
}
Now, the basic solution for returning our Sprite to the starting position: hitTestObject will return true, if Sprite s2 is still located in the area of Sprite s1. More helpful functions here. Lets check it. Change onUp function this way:
function onUp(e:MouseEvent):void
{
var s:Sprite = (e.currentTarget as Sprite);
s.stopDrag();
if (!s.hitTestObject(s1))
{
s.x = 200;
s.y = 200;
}
}
You see that now s2 gets returned to the starting position if it gets dragged out from the area of s1.
Now the main part:
What to do, if you can't predict the starting position of the object? Now, when we know how to deal with already known coordinates, this is the challange. I assume that there are several implementations of this functionality exist. One of the best way is to set additional parameters e.g. startingX and startingY for the dragging object when starting drag. E.g. in our example when onDown function gets called. I guess you dealing with Sprites or MovieClips and don't have the ability to do this.
Lets go another way and use Dictionary object. Dictionary is some kind of traditional Hash Map with the ability to use objects as keys.
Hash map is kind of storage, where you can put any value mapped by a key, provided by you. In actionscript 3 we have Object as a limited implementation of Hash Map. Why use it? In two words because it's simple and fast. But with Object we can't use other Objects as keys, only strings ints numbers etc..
var sites:Object = new Object();
sites['stackoverflow'] = "http://stackoverflow.com/"
trace(sites.stackoverflow) // outputs-> http://stackoverflow.com/
With Dictionary we can use Objects as keys.
Lets create it:
var startCoordinates:Dictionary = new Dictionary();
To save coordinates, we need x and y property.
FYI: new Object() is equivalent of {}
var capitals:Object = new Object();
capitals['Italy'] = 'Rome';
is equivalent of
var capitals:Object = {Italy: 'Rome'};
To save current position we will use this code:
var s:Sprite = (e.currentTarget as Sprite);
startCoordinates[s] = { x: s.x, y: s.y };
And the whole code in our example will look like this:
var s1:Sprite = new Sprite()
var s2:Sprite = new Sprite()
addChild(s1)
addChild(s2)
with (s1)
{
graphics.beginFill(0xfcaaaa, .7)
graphics.drawRect(0, 0, 400, 400)
graphics.endFill()
}
with (s2)
{
graphics.beginFill(0x00aaaa, .7)
graphics.drawRect(0, 0, 30, 30)
graphics.endFill()
}
s2.x = 200;
s2.y = 200;
s2.addEventListener(MouseEvent.MOUSE_DOWN, onDown)
s2.addEventListener(MouseEvent.MOUSE_UP, onUp)
var startCoordinates:Dictionary = new Dictionary()
function onDown(e:MouseEvent):void
{
var s:Sprite = (e.currentTarget as Sprite);
startCoordinates[s] = { x: s.x, y: s.y };
s.startDrag();
}
function onUp(e:MouseEvent):void
{
var s:Sprite = (e.currentTarget as Sprite);
s.stopDrag();
if (!s.hitTestObject(s1))
{
s.x = startCoordinates[s].x;
s.y = startCoordinates[s].y;
}
delete startCoordinates[s];
}

Game conversion from AS2 to AS3

I have an example of very simple shooter. But it on AS2. Here the source:
speed = 4;
depth = 0;
nose = 50;
_root.onMouseMove = function() {
updateAfterEvent();
xdiff = _root._xmouse-spaceShip._x;
ydiff = _root._ymouse-spaceShip._y;
angle = Math.atan2(ydiff, xdiff);
angle = angle*180/Math.PI;
spaceShip._rotation = angle;
};
_root.onMouseDown = function() {
angle = spaceShip._rotation;
angle = angle*Math.PI/180;
++depth;
name = "projectile"+depth;
_root.attachMovie("projectile", name, depth);
//projectile - it is bullet
_root[name]._x = spaceShip._x+nose*Math.cos(angle);
_root[name]._y = spaceShip._y+nose*Math.sin(angle);
_root[name].xmov = speed*Math.cos(angle);
_root[name].ymov = speed*Math.sin(angle);
_root[name].onEnterFrame = function() {
this._x += this.xmov;
this._y += this.ymov;
};
};
I want to do the same, but in as3.
I tried to convert. Here is what I have: PS - I'm newbie, please, don't get angry of the code below :)
var nose=55;
var angle;
var acc=1;
Mouse.hide();
stage.addEventListener(MouseEvent.MOUSE_MOVE, cursor);
function cursor(e:MouseEvent):void {
cross.x=mouseX;
cross.y=mouseY;
}
stage.addEventListener(Event.ENTER_FRAME, rotation2);
function rotation2(event:Event):void {
var xdiff=mouseX-spaceShip.x;
var ydiff=mouseY-spaceShip.y;
angle=Math.atan2(ydiff,xdiff);
angle=angle*180/Math.PI;
spaceShip.rotation=angle;
}
stage.addEventListener(MouseEvent.CLICK, shoot);
function shoot(event:MouseEvent):void {
angle = spaceShip.rotation;
angle = angle*Math.PI/180;
bullet.x=spaceShip.x+nose*Math.cos(angle);
bullet.y=spaceShip.y+nose*Math.sin(angle);
var xmov=acc*Math.cos(angle);
var ymov=acc*Math.sin(angle);
stage.addEventListener(Event.ENTER_FRAME, action);
function action(event:Event):void {
bullet.x+=xmov;
bullet.y+=xmov;
}
}
bullet appears, but only once, and did not move on the right path.
how to do that would be a lot of bullets, as in the example above?
attachMovie() is not the same as addChild().
MovieClip.attachMovie() creates a new symbol and add it to the MovieClip
DisplayObjectContainer.addChild() adds the specified DisplayObject to the container
Instead of calling (in AS2):
_root.attachMovie("projectile", name, depth);
You should use something like this (in AS3):
var proj:DisplayObject = new projectile();
proj.name = "projectile" + depth;
stage.addChild(proj);
Please note that there is no depth in AS3.
You could trick this by using addChildAt().
Thanks for the fast replying. I solve the problem this way:
I added this:
var bullet1:Bullet = new Bullet ();
addChild (bullet1);
And changed all "bullet" below on "bullet1".
Program is working now correctly.

"Error#2025 The supplied DisplayObject must be a child of the caller." upon trying to removeChild();

I'm creating a simple iPhone game (but the class I'm in is requiring me to use Flash...), and I'm having a major issue as I'm trying to remove objects from the game.
The game is somewhat of a dynamic time-wasting bubblewrap game where there are infinite "refreshes" of the stage. Once the user pops all the bubbles, more randomly generate. (When the array is empty, call the setup() again.)
For now, I have one of each five different colored bubble graphics pulled from the library by code and placed on the stage randomly. However, I don't like the overlap, so I've given each bubble a small square hitspace so when they're placed randomly and overlap significantly they pop themselves. For some reason when I'm trying to remove the bubbles it gives me
Error#2025 The supplied DisplayObject must be a child of the caller.
I've tried adding stage to addChild and removeChild, but I get the same error.
import flash.events.*;
import flash.display.*;
var bubbles:Array = new Array();
var b:BlueBubble = new BlueBubble();
var b2:GreenBubble = new GreenBubble();
var b3:PinkBubble = new PinkBubble();
var b4:PurpleBubble = new PurpleBubble();
var b5:YellowBubble = new YellowBubble();
// values to be tweaked later
var bNum:uint = 1;
var maxSize:uint = 100;
var minSize:uint = 1;
var range:uint = maxSize - minSize;
var tooBig:uint = 100;
function init():void {
setup();
stage.addEventListener(Event.ENTER_FRAME, onEveryFrame);
}
function setup():void {
for (var i:uint=0; i<bNum; i++) {
// blue
b.width = Math.ceil(Math.random() * range) + minSize;
b.height = b.width;
b.x = Math.random()*(stage.stageWidth - b.width);
b.y = Math.random()*(stage.stageHeight - b.height);
bubbles.push(b);
stage.addChild(b);
// green
b2.width = Math.ceil(Math.random() * range) + minSize;
b2.height = b2.width;
b2.x = Math.random()*(stage.stageWidth - b2.width);
b2.y = Math.random()*(stage.stageHeight - b2.height);
bubbles.push(b2);
stage.addChild(b2);
// pink
b3.width = Math.ceil(Math.random() * range) + minSize;
b3.height = b3.width;
b3.x = Math.random()*(stage.stageWidth - b3.width);
b3.y = Math.random()*(stage.stageHeight - b3.height);
bubbles.push(b3);
stage.addChild(b3);
// purple
b4.width = Math.ceil(Math.random() * range) + minSize;
b4.height = b4.width;
b4.x = Math.random()*(stage.stageWidth - b4.width);
b4.y = Math.random()*(stage.stageHeight - b4.height);
bubbles.push(b4);
stage.addChild(b4);
// yellow
b5.width = Math.ceil(Math.random() * range) + minSize;
b5.height = b5.width;
b5.x = Math.random()*(stage.stageWidth - b5.width);
b5.y = Math.random()*(stage.stageHeight - b5.height);
bubbles.push(b5);
stage.addChild(b5);
//add event listeners for bubbles later
}
}
function onEveryFrame(e:Event) {
for (var i:uint=0; i<bubbles.length; i++) {
bubbles[i].width++;
bubbles[i].height++;
if (bubbles[i].height >= tooBig && bubbles[i].width >= tooBig) {
bubbles[i].height = tooBig;
bubbles[i].width = tooBig;
}
// Blue hit testing
if (b2.hitGreen.hitTestObject(b.hitBlue)) {
removeChild(b);
}
if (b3.hitPink.hitTestObject(b.hitBlue)) {
removeChild(b);
}
if (b4.hitPurple.hitTestObject(b.hitBlue)) {
removeChild(b);
}
if (b5.hitYellow.hitTestObject(b.hitBlue)) {
removeChild(b);
}
// Other hit testing...
}
}
init();
You are adding b, b2, b3, etc to the stage, but removing them from whatever object is executing this code. Try changing
stage.addChild(b);
to
addChild(b);
Additionally, it is a good idea to check that an object is a child before removing it. Try changing
if (...)
removeChild(b);
to
if (contains(b) && ...)
removeChild(b);
The best way to solve this is:
mc.parent.removeChild(mc);
Basically, the removeChild function needs to be called from whatever display object that your soon to be removed object is in.

augmented reality flartoolkit rotation

I'm trying to do some augmented reality projects with flartoolkit . I can now put simple 3d objects on my marker and it works fine , but I wanna give my project some events that the user can interact with . I'm trying to trace the rotation of the marker. there's a container:DisplayObject3D which my application uses to add the 3d objects , I traced this :"trace(container.rotationZ)" but it's just returning 0 . I studied another AR application's source code and it was using the rotation of it's container object without problem .and I think I should mention that I'm using the exercise file of seb lee delisle papervision3d course from lynda.com . anyone has any experience with flartoolkit? the main functions of my my code is as below:
public function AR_AlchemyBase()
{
super(640,480, false);
cameraParams = FLARParam.getDefaultParam(WIDTH * 0.5, HEIGHT * 0.5);
marker = new FLARCode(16, 16);
marker.loadARPattFromFile(new MarkerPattern());
init();
}
public function init():void
{
video = new Video(WIDTH, HEIGHT);
webCam = Camera.getCamera();
webCam.setMode(WIDTH, HEIGHT, 30);
video.attachCamera(webCam);
video.smoothing = true;
camBitmapData = new BitmapData(WIDTH *0.5, HEIGHT * 0.5,false, 0x000000);
camBitmap = new Bitmap(camBitmapData);
camBitmap.scaleX = camBitmap.scaleY = 2;
addChildAt(camBitmap,0);
raster = new FLARRgbRaster(WIDTH *0.5, HEIGHT * 0.5);
detector = new FLARSingleMarkerDetector(cameraParams, marker, 80);
result = new FLARTransMatResult();
viewport.x = -4;
_camera = new FLARCamera3D(cameraParams);
container = new FLARMarkerNode();
scene.addChild(container);
addSceneObjects();
stage.addEventListener(Event.ENTER_FRAME, enterFrame);
}
//the function to put our objects in
public function addSceneObjects() : void
{
var wmat:WireframeMaterial = new WireframeMaterial(0xff0000, 1, 2);
wmat.doubleSided = true;
var plane : Plane = new Plane(wmat, 80, 80);
container.addChild(plane);
var light:PointLight3D = new PointLight3D();
light.x = 1000;
light.y = 1000;
light.z = -1000;
var fmat:FlatShadeMaterial = new FlatShadeMaterial(light, 0xff22aa, 0x0);
var cube : Cube = new Cube(new MaterialsList({all: fmat}), 40, 40, 40);
cube.z = -20;
container.addChild(cube);
}
public function enterFrame(e:Event):void
{
var scaleMatrix:Matrix = new Matrix();
scaleMatrix.scale(0.5, 0.5);
camBitmapData.draw(video, scaleMatrix);
raster.setBitmapData(camBitmapData);
counter++;
if(counter == 3) counter = 0;
var imageFound : Boolean = false
currentThreshold = threshold+ (((counter%3)-1)*thresholdVariance);
currentThreshold = (currentThreshold>255) ? 255 : (currentThreshold<0) ? 0 : currentThreshold;
imageFound = (detector.detectMarkerLite(raster, currentThreshold) && detector.getConfidence() > 0.5) ;
if(imageFound)
{
detector.getTransformMatrix(result);
container.setTransformMatrix(result);
container.visible = true;
threshold = currentThreshold;
thresholdVariance = 0;
if(onImageFound!=null) onImageFound();
}
else
{
if(counter==2) thresholdVariance +=2;
if(thresholdVariance>128 ) thresholdVariance = 1;
if(onImageLost!=null) onImageLost();
}
singleRender();
}
I might not be able to help with the main problem but If you want users to interact with the models you need to set their materials to be interactive, otherwise they don't receive mouse events. Regarding the rotation...I might be missing something but it's the instances inside the container thar you're applying the rotation to, not the the container itself?
This helped me with getting a simple PV3D example running:
PV3D Tutorial for basic interactivity

How to set dynamic locations in an Image using actionscript3.0?

I want to set different locations in an Image, and when I mouse over the location it needs to shows something('box' or 'x' nd 'y' position of the location). How can i achieve this.?
Hope, you want to set some locations in the stage and u want to store something.
If that, your coding is good. here after u can achieve that by using amf-php for back end purpose. php will help u store values in the database. refer google to know about amf-php.
good luck.
not sure wht you are looking for, may be something like that
http://www.oscartrelles.com/archives/dynamic_movieclip_registration_with_as3
Not registration point...
var msgBox:messageBox;//package
var loc:Array = new Array();
for(var i:uint = 0;i<20;i++)
{
for(var j:uint = 0;j<14;j++)
{
spr = new Sprite();
spr.graphics.beginFill(0xaaaaaa,.1);
spr.graphics.drawCircle(0,0,10);
spr.graphics.endFill();
addChild(spr);
loc.push(spr);
spr.x = 30 + i * spr.width * 1.3;
spr.y = 30 + j * spr.height * 1.3;
}
}
for(i=0; i<loc.length;i++)
{
loc[i].name = "unknown "+i;
loc[i].buttonMode = true;
loc[i].addEventListener(MouseEvent.MOUSE_OVER, mouseOverAction);
loc[i].addEventListener(MouseEvent.MOUSE_OUT, mouseOutAction);
}
function mouseOverAction (e:MouseEvent):void
{
msgBox = new messageBox(100,20,6,0xFFFFFF);
addChild(msgBox);
cur_loc_name = new TextField();
cur_loc_name.text = e.target.name;
msgBox.addChild(cur_loc_name);
cur_loc_name.x = 5;
cur_loc_name.y = 1;
msgBox.x = mouseX + 20;
msgBox.y = mouseY + 26;
}
function mouseOutAction (e:MouseEvent):void
{
removeChild(msgBox);
}
Run this code. It will fill the stage with 280 sprites, and each sprite can have diff instance name..
I wants to do this using pixels...or any other way to do?