Линии, нарисованные на этапе, отображаются на следующем и предыдущем кадрах

#actionscript-3

Вопрос:

Я использую код для сопоставления объектов путем рисования линий, код работает хорошо, но нарисованные линии появляются на следующем и предыдущем кадрах при нажатии кнопок «Следующий» и «предыдущий».

`

 import flash.events.MouseEvent;
import flash.display.Shape;
import flash.geom.Point;

var p1:Point = new Point();
var p2:Point = new Point();


stage.addEventListener(MouseEvent.MOUSE_DOWN, setP1);
function setP1(e:MouseEvent):void {
    p1.x=mouseX;
    p1.y=mouseY;
    
    stage.addEventListener(MouseEvent.MOUSE_MOVE, draw);
    s=new Shape();
    stage.addChild(s);
}

var s:Shape;

function draw(e:MouseEvent):void {
    s.graphics.clear();
    s.graphics.lineStyle(4,0xff0000, 1);
    s.graphics.moveTo(p1.x, p1.y);
    p2.setTo(mouseX, mouseY);
    s.graphics.lineTo(p2.x, p2.y)
}

stage.addEventListener(MouseEvent.MOUSE_UP, end);
function end(e:MouseEvent):void {
    
    stage.removeEventListener(MouseEvent.MOUSE_MOVE, draw);
    if (MC_1.hitTestPoint(p1.x,p1.y) amp;amp; MC_1_1.hitTestPoint(p2.x, p2.y))
        
    {
        
    }
    else {
        s.graphics.clear();
    }
}
 

`

Комментарии:

1. Это ожидаемый результат. Рисунок не привязан к текущему кадру, он привязан ко всему объекту. Если вы хотите, чтобы рисунки исчезли при перемещении в другой кадр, вызовите graphics.clear(); с помощью gotoAndStop/gotoAndPlay/nextFrame/prevFrame .

2. Я добавляю graphics.clear(); но тот же результат, строка все еще появляется, и появляется следующая ошибка TypeError: Ошибка #1009: Не удается получить доступ к свойству или методу ссылки на нулевой объект. в Unit5_fla::Линия обслуживания/конец()

Ответ №1:

Хорошо, я немного подумал об этом и выяснил, что вы

  • прикрепите фигуру s непосредственно к сцене, а не к текущему контексту
  • не утруждайте себя тем, чтобы следить за ними

Я немного улучшил ваш сценарий, чтобы в нем сохранялось все, что вы создаете (я не знаю, работаете ли вы с несколькими строками, так что на всякий случай), и есть метод очистки (), который вы должны вызвать, чтобы отменить буквально все, что делает остальная часть сценария.

 import flash.events.MouseEvent;
import flash.display.Shape;
import flash.geom.Point;

var P1:Point = new Point;
var P2:Point = new Point;

// A list of Shapes that will probably stockpile here.
var Slist:Array = new Array;

// The Shape to work with.
var S:Shape;

// Subscribe to the event to start drawing.
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);

function onDown(e:MouseEvent):void
{
    // Subscribe to the relevant events.
    stage.addEventListener(MouseEvent.MOUSE_MOVE, onDraw);
    stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
    
    // Create an object for drawing.
    S = new Shape;
    Slist.push(S);
    stage.addChild(s);
    
    P1.x = S.mouseX;
    P1.y = S.mouseY;
    
    // First draw.
    onDraw(e);
}

// Draw the line every time the mouse moves.
function onDraw(e:MouseEvent):void
{
    // Memorize the endpoint coordinates.
    P2.x = S.mouseX;
    P2.y = S.mouseY;
    
    // Drawing routine.
    S.graphics.clear();
    S.graphics.lineStyle(4,0xff0000, 1);
    S.graphics.moveTo(P1.x, P1.y);
    S.graphics.lineTo(P2.x, P2.y);
}

// End the drawing process.
function onUp(e:MouseEvent):void
{
    stage.removeEventListener(MouseEvent.MOUSE_MOVE, onUp);
    stage.removeEventListener(MouseEvent.MOUSE_MOVE, onDraw);
    
    // Last draw,
    onDraw(e);
    
    // Convert Points to stage coordinates. I know they are identical in
    // the present setup, but it is not the reason to ignore the operation.
    var GP1:Point = S.localToGlobal(P1);
    var GP2:Point = S.localToGlobal(P2);
    
    var aHit1:Boolean = MC_1.hitTestPoint(GP1.x, GP1.y);
    var aHit2:Boolean = MC_1_1.hitTestPoint(GP2.x, GP2.y);

    if (aHit1 amp;amp; aHit2)
    {
        // Whatever you need to do here.
    }
    else
    {
        // Erase the unneeded Shape.
        stage.removeChild(S);
        
        var anIndex:int = Slist.indexOf(S);
        if (anIndex > -1) Slist.splice(anIndex, 1);
        
        S.graphics.clear();
        S = null;
    }
}

// Call this at the same time you go to another frame.
function cleanUp():void
{
    // Clean the stockpiled objects if any.
    while (Slist.length)
    {
        S = Slist.pop();
        if (!S) continue;
        if (!(S is Shape)) continue;
        
        S.graphics.clear();
        
        if (!S.parent) continue;
        S.parent.removeChild(S);
    }
    
    // Destroy all the relevant objects.
    S = null;
    P1 = null;
    P2 = null;
    Slist = null;
    
    // Finally, unsubscribe from DOWN handler (and the rest just in case).
    stage.removeEventListener(MouseEvent.MOUSE_MOVE, onUp);
    stage.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);        
    stage.removeEventListener(MouseEvent.MOUSE_MOVE, onDraw);
}
 

Комментарии:

1. Большое спасибо @Organis это работает!, Я только создаю mc, называю его (холст) и заменяю его этапом (canvas.addEventListener(MouseEvent……….)