draw line inside Moviclip in ActionScript3 - actionscript-3

I am wondering how to draw line inside movieclip[] array:
movieclip myted
line myshape
for (var i:int = 0; i < myted.numChildren-1; i++) {
if (myted.getChildAt(i).hitTestPoint(mouseX,mouseY,true)) {
//drawingLine.transform.colorTransform=pal_color;
}
}

All drawing that you do with a Graphics instance is based on basic drawing with lines and curves. Consequently, all ActionScript drawing must be performed using the same series of steps:
Define line and fill styles
Set the initial drawing position
Draw lines, curves, and shapes (optionally moving the drawing point)
If necessary, finish creating a fill
to define a line and fill styles:
var myShape:Shape = new Shape();
myShape.graphics.lineStyle(2, 0x990000, .75);
myShape.graphics.moveTo(100, 100);
myShape.graphics.lineTo(200, 200);
movieClipInstanceName.addChild(myShape);

" http://i.stack.imgur.com/ESfzi.png "
Thanks
no understand not working ?
not work raw line inside movieclip!
drawing line inside movieclip S1 .. s27 when mouse move inside teddy
////////////////
var drawingLine:MovieClip = new MovieClip();
s.addChild(drawingLine);
//2.
stage.addEventListener(MouseEvent.MOUSE_DOWN, MouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, MouseUp);
//3.
function MouseDown(event:MouseEvent):void{
drawingLine.graphics.lineStyle(3);
drawingLine.graphics.moveTo(mouseX, mouseY);
s.addEventListener(MouseEvent.MOUSE_MOVE, MouseMove);
}
//4.
function MouseMove(event:MouseEvent):void{
drawingLine.graphics.lineTo(mouseX, mouseY);
for (var i:int = 0; i < teddy.numChildren-1; i++) {
if (teddy.getChildByName("s"+i).hitTestPoint(mouseX,mouseY,true)) {
pal_color=teddy.getChildAt(i).transform.colorTransform;
pal_color.color=colors[current_color];
teddy.getChildByName("s"+i).transform.colorTransform=pal_color;
}
}
}
//5.
function MouseUp(event:MouseEvent):void{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, MouseMove);
}
public function on_teddy_click(e:MouseEvent):void {
for (var i:int = 0; i < teddy.numChildren-1; i++) {
if (teddy.getChildByName("s"+i).hitTestPoint(mouseX,mouseY,true)) {
pal_color=teddy.getChildAt(i).transform.colorTransform;
pal_color.color=colors[current_color];
teddy.getChildByName("s"+i).transform.colorTransform=pal_color;
}
}
}
/////////////////////////////////
sample 2:
not Draw line inside movieclip "S"
var drawingLine:MovieClip = new MovieClip();
s.addChild(drawingLine);
stage.addEventListener(MouseEvent.MOUSE_DOWN, MouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, MouseUp);
function MouseDown(event:MouseEvent):void{
drawingLine.graphics.lineStyle(3);
drawingLine.graphics.moveTo(mouseX, mouseY);
s.addEventListener(MouseEvent.MOUSE_MOVE, MouseMove);
}
function MouseMove(event:MouseEvent):void{
drawingLine.graphics.lineTo(mouseX, mouseY);
}
function MouseUp(event:MouseEvent):void{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, MouseMove);
}

Related

Error #2025: The supplied DisplayObject must be a child of the caller - Game Looping when after gotoAndStop

So ok Im somewhat new to flash im more of a java man myself but anyway I keep getting this error and all the solutions ive been find either don't work or they break the games collision
Here's the Code
stop();
import flash.utils.Timer;
import flash.utils.getDefinitionByName;
import flash.events.Event;
import flash.events.TimerEvent;
var playerobj:player;
var nextObject:Timer;
var objects:Array = new Array();
var score:int = 0;
const speed:Number = 9.0;
playerobj = new player();
playerobj.y = 650;
addChild(playerobj);
setNextObject();
addEventListener(Event.ENTER_FRAME, moveObjects);
function setNextObject()
{
nextObject = new Timer(1000+Math.random()*1000,1);
nextObject.addEventListener(TimerEvent.TIMER_COMPLETE,newObject);
nextObject.start();
}
function newObject(e:Event)
{
var newObject:AI;
newObject = new AI();
newObject.x = Math.random() * 480;
addChild(newObject);
objects.push(newObject);
setNextObject();
}
function moveObjects(e:Event)
{
for (var i:int=objects.length-1; i>=0; i--)
{
objects[i].y += speed;
if (objects[i].y > 800)
{
removeChild(objects[i]);
score = score + 10000;
objects.splice(i,1);
}
if (objects[i].hitTestObject(playerobj))
{
cleanUp();
}
}
playerobj.x = mouseX;
}
function cleanUp():void
{
while (this.numChildren > 0)
{
removeChildAt(0);
}
nextObject.stop();
gotoAndStop(4);
stop();
}
It must be somehow related to this problem but whenever gotoAndStop is called the game seems to loop around back into the frame not really sure why, Thanks for your help
In the cleanup function, right after declaring it, you should remove the ENTER_FRAME event listener. Also, I would stop the timer before removing childs and I would just remove the objects you added to stage dynamically. And the stop() in the cleanup function is redundant.
function cleanUp():void {
removeEventListener(Event.ENTER_FRAME, moveObjects);
nextObject.stop();
for(var i:uint = 0; i < objects.length; i++){
removeChild(objects[i]);
}
removeChild(playerObj)
gotoAndStop(4);
}
Also, it's better to keep minimal code in the timeline and move as much as you can in classes.
the error is in the cleanUp()
function moveObjects(e:Event)
{
for (var i:int=objects.length-1; i>=0; i--)
{
objects[i].y += speed;
if (objects[i].y > 800)
{
removeChild(objects[i]);
score = score + 10000;
objects.splice(i,1);
}
if (objects[i].hitTestObject(playerobj))
{
cleanUp();
}
}
//playerobj no more exists if cleanUp() is called, move this line above cleanUp();
//playerobj.x = mouseX;
//or inside cleanUp() put that line
//removeEventListener(Event.ENTER_FRAME, moveObjects);
}

As3 hittesting doesn't really work (nested)

I got a tank.
I got a hero (controllable character).
The tank has a nested movieclip which has a very thin surface area.
Yet, the thing detects a collision when it's not even touching the hero.
public class tank_sight extends MovieClip
{
private var _root:MovieClip;
public function tank_sight()
{
addEventListener(Event.ADDED, beginClass);
}
private function beginClass(event:Event):void
{
_root = MovieClip(root);
addEventListener(Event.ENTER_FRAME, loop);
}
private function loop(event:Event):void
{
if(this.hitTestObject(_root.hero.hitbox))
{
this.gotoAndStop(2);
trace("HIT");
fire();
}
else
{
this.gotoAndStop(1);
}
}
private function fire():void
{
var shell:Shell = new Shell(x, y, rotation - 180);
_root.addChild(shell);
}
}
What's wrong? I don't get it.
EDIT: Sight is rotating, so that's probably why. I tried using this code on the player class:
point = _root.tanks.barrel.sight.localToGlobal(new Point());
if(this.hitTestPoint(point.x, point.y, false))
{
trace("HIT");
}
But it doesn't work.. It never traces "HIT", unless I stand in some weird location at certain times.
hitTestObject works with nested objects also (display objects that have different parents), you should check logic of your game, and do some tests.
Simple example:
var squareHolder:Sprite = new Sprite();
var squareInner:Shape = new Shape();
var hitHolder:Sprite = new Sprite();
var hitCircle:Shape = new Shape();
hitCircle.graphics.beginFill(0x990000);
hitCircle.graphics.drawCircle(0, 0, 20);
squareInner.graphics.beginFill(0x009900);
squareInner.graphics.drawRect(0, 0, 40, 40);
addChild(squareHolder);
squareHolder.addChild(squareInner);
squareHolder.x = 200;
squareHolder.y = 100;
squareInner.x = 50;
squareInner.y = 50;
stage.addChild(hitHolder);
hitHolder.addChild(hitCircle);
hitCircle.transform.matrix = new Matrix(1, 0.5, 0.5, 1, 30, 30);
stage.addEventListener(MouseEvent.MOUSE_MOVE, function (e:MouseEvent):void {
hitHolder.x = e.stageX;
hitHolder.y = e.stageY;
if (hitCircle.hitTestObject(squareInner)) {
trace("Ding!");
}
});
Whatever you do with hitCircle (visible=false, trasparent fill, transformations) it will still work.

Draw over a movieclip

I have a paint application. I want to put a layer(movieclip with a square) and I want to draw over it.
Until now I cant paint but when I'm trying to add movieclip child, I cant draw over that movieclip. Which is the way to make something like this?
This is my code:
import flash.display.Sprite;
var myThick=10;
var currentColor = 0X000000;
var myCanvas:Sprite;
init();
function init():void {
drawCanvas();
var clearSwatch:Sprite = new Sprite();
clearSwatch.graphics.beginFill(0xFFFFFF);
clearSwatch.graphics.lineStyle(2, 0x000000);
clearSwatch.graphics.drawCircle(30, 370, 20);
clearSwatch.graphics.endFill();
addChild(clearSwatch);
clearSwatch.buttonMode = true;
clearSwatch.addEventListener(MouseEvent.CLICK, clearCanvas);//clear
}
function drawCanvas():void {
myCanvas = new Sprite();
myCanvas.graphics.beginFill(0xF0F0F0);
myCanvas.graphics.drawRect(60, 20, stage.stageWidth-80, stage.stageHeight+40);
myCanvas.graphics.endFill();
myCanvas.graphics.lineStyle(myThick, currentColor);
addChild(myCanvas);
myCanvas.addEventListener(MouseEvent.MOUSE_DOWN, startDraw);
//stage.addEventListener(MouseEvent.MOUSE_UP, stopDraw);
myCanvas.buttonMode = true;
}
function startDraw(event:MouseEvent):void {
myCanvas.graphics.moveTo(event.localX, event.localY);
myCanvas.addEventListener(MouseEvent.MOUSE_MOVE, paintLine);
}
function stopDraw(event:MouseEvent):void {
myCanvas.removeEventListener(MouseEvent.MOUSE_MOVE, paintLine);
}
function paintLine(event:MouseEvent):void {
myCanvas.graphics.lineTo(event.localX, event.localY);
event.updateAfterEvent();
}
function clearCanvas(event:MouseEvent):void {
myCanvas.graphics.clear();
drawCanvas();
}
How can I make it work?
thank you!
Add both listeners to stage, along with mouse move listener, but use graphics commands over myCanvas.
stage.addEventListener(MouseEvent.MOUSE_DOWN, startDraw);
function startDraw(event:MouseEvent):void {
myCanvas.graphics.moveTo(event.localX, event.localY);
myCanvas.addEventListener(MouseEvent.MOUSE_MOVE, paintLine);
}
Etc.

Collision is not working properly as3

var i:Number;
for (i=0;i<6;i++)
{
var brick:Sprite=new Sprite();
brick.graphics.beginFill(0x02589E);
brick.graphics.drawRect(0,0,70,7);
brick.graphics.endFill();
brick.y=10;
brick.x=12+(80*i);
addChild(brick);
}
addEventListener(Event.ENTER_FRAME,destroy);
var ball:Sprite=new Sprite();
ball.graphics.beginFill(0xff0000);
ball.graphics.drawCircle(0,0,7);
ball.graphics.endFill();
ball.x=200;
ball.y=230;
addChild(ball);
.......some code for ball moving.......
function destroy(e:Event):void
{
if(ball.hitTestObject(brick)){
removeChild(brick);
}
}
When the ball collide with the brick,only the last brick remove.But I want to remove all the brick separately if the ball collide with the brick.
Currently, brick is referring to the last instance created in your for loop. What you need to do is store these objects in an array, loop through that array, and check for a collision between each individual brick within that array.
It might look something like this:
// Define the array.
var bricks:Array = [];
// Create bricks.
for(var i:int = 0; i < 6; i++)
{
var brick:Sprite = new Sprite();
brick.y = 10;
brick.x = 12 + (80 * i);
brick.graphics.beginFill(0x02589E);
brick.graphics.drawRect(0, 0, 70, 7);
brick.graphics.endFill();
addChild(brick);
bricks.push(brick);
}
And then your collision checking code:
function destroy(e:Event):void
{
for each(var brick:Sprite in bricks)
{
if(ball.hitTestObject(brick))
{
removeChild(brick);
}
}
}
Here brick only refers to a single object. Add all your bricks to an array and then loop through them in your destroy function.

startDrag - stop diagonal movement

Is there a way to have a MovieClip with startDrag, but to force only horizontal and vertical (i.e. not diagonal) movement?
Here is my solution. It tracks the mouseX and mouseY on click and compares it to last position. Finds out which direction the mouse is mainly moving then moves the object there. You may want to add some extra logic to lock the object to the nearest 10th unit or whatever unit size you want to form a snap grid for use in games or organized placement of the object.
Update: I went ahead and added a snapNearest function to help control the movement.
import flash.events.MouseEvent;
import flash.events.Event;
dragObj.addEventListener(MouseEvent.MOUSE_DOWN, dragIt);
var curX:Number = 0;
var curY:Number = 0;
var oldX:Number = 0;
var oldY:Number = 0;
var gridUnit:Number = 25;
function dragIt(e:MouseEvent):void
{
// set x,y on down
oldX = mouseX;
oldY = mouseY;
// add mouse up listener so you know when it is released
stage.addEventListener(MouseEvent.MOUSE_UP, dropIt);
stage.addEventListener(Event.ENTER_FRAME, moveIt);
trace("Start Drag")
}
function moveIt(e:Event):void
{
// figure out what the main drag direction is and move the object.
curX = mouseX;
curY = mouseY;
// figure out which is the larger number and subtract the smaller to get diff
var xDiff:Number = curX > oldX ? curX - oldX : oldX - curX;
var yDiff:Number = curY > oldY ? curY - oldY : oldY - curY;
if(xDiff > yDiff) {
dragObj.x = snapNearest(mouseX, gridUnit);
}else{
dragObj.y = snapNearest(mouseY, gridUnit);
}
oldX = mouseX;
oldY = mouseY;
}
function dropIt(e:MouseEvent):void
{
//remove mouse up event
stage.removeEventListener(MouseEvent.MOUSE_UP, dropIt);
stage.removeEventListener(Event.ENTER_FRAME, moveIt);
trace("Stop Drag")
}
// snap to grid
function snapNearest(n:Number, units:Number):Number
{
var num:Number = n/units ;
num = Math.round(num);
num *= units;
return num;
}
yes. there are a few options.
A. you can choose to use the startDrag() function and supply it's 2nd parameter with a bounds rectangle for your draggable object. something like;
dragSprite.startDrag(false, new Rectangle(0, 0, 20, stage.stageHeight));
B. you can set your draggable object to listen for mouse events, moving it according to the mouse movements. something like:
dragSprite.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownEventHandler);
function mouseDownEventHandler(evt:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
}
function mouseMoveEventHandler(evt:MouseEvent):void
{
//only move dragSprite horizontally
//dragSprite.y = evt.stageY;
dragSprite.x = evt.stageX;
}
function mouseUpEventHandler(evt:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
}
You could use a modifier key, for instance normal behavior would be horizontal & press down the shift key to move vertically.
function mouseMoveEventHandler(evt:MouseEvent):void
{
if(!evt.shiftKey)
dragSprite.x = evt.stageX;
else
dragSprite.y = evt.stageY;
}
You can only constrain to one axis or the other (using a constraint rectangle) But diagonal movement would be possible in the method you propose, unless you also define some other limits... for example a grid.