Actionscript 3 Actionscript 3.0-跟踪移动物体的路径;

Actionscript 3 Actionscript 3.0-跟踪移动物体的路径;,actionscript-3,flash,Actionscript 3,Flash,我目前正在学习AS3.0。我试图设计一个简单的两体行星模拟。我需要在屏幕上显示行星的路径。所以我的问题是,一旦我在每个定时器间隔内更新了行星的x和y坐标,我如何改变舞台像素(x,y)的颜色,以显示行星的路径?是否有表单stage.x=color的一些命令 谢谢 不,没有这样的命令,但您始终可以创建一个非常简单的精灵对象,并将其添加到舞台的相应位置。比如: var dot:Sprite = new Sprite(); dot.graphics.beginFill(0xCCCCCC); dot.gr

我目前正在学习AS3.0。我试图设计一个简单的两体行星模拟。我需要在屏幕上显示行星的路径。所以我的问题是,一旦我在每个定时器间隔内更新了行星的x和y坐标,我如何改变舞台像素(x,y)的颜色,以显示行星的路径?是否有表单stage.x=color的一些命令


谢谢

不,没有这样的命令,但您始终可以创建一个非常简单的精灵对象,并将其添加到舞台的相应位置。比如:

var dot:Sprite = new Sprite();
dot.graphics.beginFill(0xCCCCCC);
dot.graphics.drawRect(-1, -1, 2, 2);
dot.graphics.endFill();

dot.x = x;
dot.y = y;
addChild(dot);

不,没有这样的命令,但您始终可以创建一个非常简单的精灵对象,并将其添加到舞台的相应位置。比如:

var dot:Sprite = new Sprite();
dot.graphics.beginFill(0xCCCCCC);
dot.graphics.drawRect(-1, -1, 2, 2);
dot.graphics.endFill();

dot.x = x;
dot.y = y;
addChild(dot);
我建议在每次更新行星时使用该方法将其渲染为像素。它的工作原理基本上类似于显示对象的“屏幕截图”,您将其作为n参数传递。如果传递对象变换,则位置/旋转/比例将可见(与从0,0绘制相反)。这样,您将只更新像素,而不是不断创建新的显示对象

下面是一个基本的示例:

import flash.display.Sprite;
import flash.events.Event;

var trails:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,true,0x00000000);//create a transparent bitmap to draw the trails into
var trailsFade:ColorTransform = new ColorTransform(1,1,1,0.025,0,0,0,1);//color transform: keep rgb the same(1,1,1), set alpha to 0.025 out of 1.0
var background:Bitmap = addChild(new Bitmap(trails,PixelSnapping.AUTO,true)) as Bitmap;//add the trails pixels/bitmap data into a Bitmap/display object at the bottom of the display list

var dot:Sprite = addChild(new Sprite()) as Sprite;
dot.graphics.lineStyle(3);
dot.graphics.drawCircle(-4, -4, 8);

addEventListener(Event.ENTER_FRAME,update);
function update(e:Event):void{
    dot.x = mouseX;
    dot.y = mouseY;
    //draw trails of the dot
    trails.draw(dot,dot.transform.concatenatedMatrix,trailsFade);//draw the dot into the bitmap data using the dot's transformation (x,y, rotation, scale)
}
请注意移动鼠标时的轨迹以及它们如何受(更新)速度的影响

下面是一个使用多个对象的较长示例:

import flash.display.*;
import flash.events.Event;
import flash.geom.ColorTransform;

var w:Number = stage.stageWidth;
var h:Number = stage.stageHeight;
var trails:BitmapData = new BitmapData(w,h,true,0x00000000);//create a transparent bitmap to draw the trails into
var trailsFade:ColorTransform = new ColorTransform(1,1,1,0.025,0,0,0,0.1);//color transform: keep rgb the same(1,1,1), set alpha to 0.025 out of 1.0
var background:Bitmap = addChild(new Bitmap(trails,PixelSnapping.AUTO,true)) as Bitmap;//add the trails pixels/bitmap data into a Bitmap/display object at the bottom of the display list
var spheres:Sprite    = addChild(new Sprite()) as Sprite;//add a container for all the spheres (planets/moons/sun/etc.)

var mercuryPivot:Sprite = spheres.addChild(new Sprite()) as Sprite;
var venusPivot:Sprite   = spheres.addChild(new Sprite()) as Sprite;
var earthPivot:Sprite   = spheres.addChild(new Sprite()) as Sprite;

var sun:Sprite     = spheres.addChild(getCircleSprite(69.5500 /4,0xFF9900)) as Sprite;
var mercury:Sprite = mercuryPivot.addChild(getCircleSprite(24.40 / 4,0xCECECE)) as Sprite;
var venus:Sprite   = venusPivot.addChild(getCircleSprite(60.52 / 4,0xFF2200)) as Sprite;
var earth:Sprite   = earthPivot.addChild(getCircleSprite(60.52 / 4,0x2233FE)) as Sprite;

mercury.x = 5791 / 40;
venus.x   = 10820 / 40;
earth.x   = 14960 / 40;
spheres.x = (w-spheres.width) * 0.5;
spheres.y = (h-spheres.height) * 0.5;

addEventListener(Event.ENTER_FRAME,update);
function update(e:Event):void{
    mercuryPivot.rotation += 0.5;
    venusPivot.rotation   += 0.25;
    earthPivot.rotation   += 0.12;
    //draw trails
    trails.draw(spheres,spheres.transform.concatenatedMatrix,trailsFade);
}


function getCircleSprite(radius:Number,color:int):Sprite{
    var circle:Sprite = new Sprite();
    circle.graphics.beginFill(color);
    circle.graphics.drawCircle(-radius * .5,-radius * .5,radius);//draw from centre
    circle.graphics.endFill();
    return circle;
}
注意,我们调用
trails.draw(spheres,spheres.transform.concatenatedMatrix,trailsFade)
但它可以是trails.draw(earth,earth.transform.concatenatedMatrix,trailsfead)
如果您只想绘制
地球的轨迹

在上面的例子中,我只是嵌套精灵并使用旋转属性来保持简单。你可能想用一点三角学来更新位置,因为行星可能不会有完美的圆形轨道,每次都会经过精确的位置

更新

仔细想想,如果你刚开始玩像素游戏还不习惯的话,那么使用老款可能会很方便

很容易入门:可以在flash player中显示的对象可以具有图形属性(请参见Shape/Sprite/MovieClip类)。(无论是否可以将元素嵌套到(DisplayObjectContainer)或(DisplayObject),您都可以拥有无法绘制的显示对象,但这对您来说也是另一回事)

graphics
属性Sprites and MovieClip允许您通过简单的命令以编程方式绘制,例如:设置笔划(
lineStyle()
)、填充(
beginFill()
/
endFill()
)、在不绘制的情况下移动假想的“笔”(
moveTo
)、绘制直线(
lineTo
)、圆、,一个长方形,一个圆形的长方形,等等,都在那里

因此,最小绘图程序看起来有点像这样:

import flash.events.MouseEvent;
import flash.events.Event;

var mousePressed:Boolean = false;//keep track if the mouse is pressed or not
graphics.lineStyle(1);//set the stroke to have a thickness of 1 (and the other parameters are defaults(color: black, transparency: 100% / 1.0, etc.))

stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseEventHandler);//listend for mouse down
stage.addEventListener(MouseEvent.MOUSE_UP,mouseEventHandler);//...and mouse up changes
stage.addEventListener(Event.ENTER_FRAME,update);//update continuously

function mouseEventHandler(e:MouseEvent):void{
    mousePressed = (e.type == MouseEvent.MOUSE_DOWN);
    graphics.moveTo(mouseX,mouseY);//place the graphics 'pen' at this new location
}
function update(e:Event):void{
    if(mousePressed)  graphics.lineTo(mouseX,mouseY);//if the mouse is pressed, keep drawing a line to the current mouse location   
}
或者使用鼠标移动速度影响笔划厚度和透明度的更复杂版本:

import flash.events.MouseEvent;
import flash.events.Event;
import flash.geom.Point;

var prevPos:Point = new Point();//previous mouse position
var currPos:Point = new Point();//current mouse position
var w:Number = stage.stageWidth;
var h:Number = stage.stageHeight;
var mousePressed:Boolean = false;//keep track if the mouse is pressed or not
graphics.lineStyle(1);//set the stroke to have a thickness of 1 (and the other parameters are defaults(color: black, transparency: 100% / 1.0, etc.))
stage.doubleClickEnabled = true;

stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseEventHandler);//listend for mouse down
stage.addEventListener(MouseEvent.MOUSE_UP,mouseEventHandler);//...and mouse up changes
stage.addEventListener(MouseEvent.DOUBLE_CLICK,function(e:MouseEvent):void{graphics.clear()});//double click to clear
stage.addEventListener(Event.ENTER_FRAME,update);//update continuously

function mouseEventHandler(e:MouseEvent):void{
    mousePressed = (e.type == MouseEvent.MOUSE_DOWN);
    graphics.moveTo(mouseX,mouseY);
}
function update(e:Event):void{
    //currPos.setTo(mouseX,mouseY);//this works for flash player 11 and above instead of setting x,y separately
    currPos.x = mouseX;
    currPos.y = mouseY;
    var mappedValue: Number = Point.distance(currPos,prevPos) / (w+h);//map the distance between points
    //prevPos.copyFrom(currPos);//this works for flash player 11 and above instead of setting x,y separately
    prevPos.x = mouseX;
    prevPos.y = mouseY;
    graphics.lineStyle(mappedValue * 100,0,1.0-(0.25+mappedValue));
    if(mousePressed)  graphics.lineTo(mouseX,mouseY);//if the mouse is pressed, keep drawing a line to the current mouse location   
}
回到行星路径的追踪,使用图形api,我前面的示例如下所示:

import flash.display.*;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.geom.Point;

var w:Number = stage.stageWidth;
var h:Number = stage.stageHeight;
var hasMoved:Boolean  = false;//has the graphics 'pen' been moved ?
var spheres:Sprite    = addChild(new Sprite()) as Sprite;//add a container for all the spheres (planets/moons/sun/etc.)

var earthPivot:Sprite = spheres.addChild(new Sprite()) as Sprite;

var sun:Sprite     = spheres.addChild(getCircleSprite(69.5500 /4,0xFF9900)) as Sprite;
var earth:Sprite   = earthPivot.addChild(getCircleSprite(60.52 / 4,0x2233FE)) as Sprite;

earth.x   = 14960 / 40;
spheres.x = (w-spheres.width) * 0.5;
spheres.y = (h-spheres.height) * 0.5;

addEventListener(Event.ENTER_FRAME,update);
function update(e:Event):void{
    earthPivot.rotation   += 0.12;
    //draw trails
    drawTrail(earth,0x0000FF);
}

function drawTrail(s:Sprite,color:int) {
    var globalPos:Point = s.localToGlobal(new Point());//convert the local position of the sprite (it might have been nested several times) to the global/stage coordinate system
    if(!hasMoved){//if the graphics 'pen' wasn't moved (is still at 0,0), this will happen only once: the 1st time you draw the mouse position
        graphics.moveTo(globalPos.x,globalPos.y);//move it to where we're about to draw first
        hasMoved = true;//and make sure we've marked that the above was done
    }
    graphics.lineStyle(1,color);
    graphics.lineTo(globalPos.x,globalPos.y);
}

function getCircleSprite(radius:Number,color:int):Sprite{
    var circle:Sprite = new Sprite();
    circle.graphics.beginFill(color);
    circle.graphics.drawCircle(-radius * .5,-radius * .5,radius);//draw from centre
    circle.graphics.endFill();
    return circle;
}

根据我的经验,如果舞台上有很多线条,使用这个旧的绘图API可能会变得很慢。我说更老是因为它现在可能已经15岁了。FlashPlayer10引入了一个更新的绘图API。你可以在报纸上读到,但我热情地推荐他

回到像素:没那么难。您可以使用BitmapData类操纵像素,并使用位图实例,以便可以在舞台上添加这些像素。下面是一个最小的绘图程序:

var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false,0xFFFFFF);//setup pixels
addChild(new Bitmap(canvas));//add them to the stage
addEventListener(Event.ENTER_FRAME,update);//setup continuous updates
function update(e:Event):void{
    canvas.setPixel(int(mouseX),int(mouseY),0x990000);//pretty easy, right ?
}
要制作trippy图案,当然,玩一玩:

var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false,0xFFFFFF);//setup pixels
addChild(new Bitmap(canvas));//add them to the stage
addEventListener(Event.ENTER_FRAME,update);//setup continuous updates
function update(e:Event):void{
    canvas.lock();//when updating multiple pixels or making multiple pixel operations
    canvas.perlinNoise(mouseX,mouseY,mouseX/stage.stageWidth * 8,getTimer(),false,true);
    canvas.unlock();//when you're done changing pixels, commit the changes
}
那么,回到trails示例:

var w:Number = stage.stageWidth;
var h:Number = stage.stageHeight;
var canvas:BitmapData = new BitmapData(w,h,false,0xFFFFFF);
addChild(new Bitmap(canvas));
var spheres:Sprite    = addChild(new Sprite()) as Sprite;//add a container for all the spheres (planets/moons/sun/etc.)

var earthPivot:Sprite = spheres.addChild(new Sprite()) as Sprite;

var sun:Sprite     = spheres.addChild(getCircleSprite(69.5500 /4,0xFF9900)) as Sprite;
var earth:Sprite   = earthPivot.addChild(getCircleSprite(60.52 / 4,0x2233FE)) as Sprite;

earth.x   = 14960 / 40;
spheres.x = (w-spheres.width) * 0.5;
spheres.y = (h-spheres.height) * 0.5;

addEventListener(Event.ENTER_FRAME,update);
function update(e:Event):void{
    earthPivot.rotation   += 0.12;
    //draw trails
    drawTrail(earth,0x0000FF,canvas);
}

function drawTrail(s:Sprite,color:int,image:BitmapData) {
    var globalPos:Point = s.localToGlobal(new Point());//convert the local position of the sprite (it might have been nested several times) to the global/stage coordinate system
    image.setPixel(int(globalPos.x),int(globalPos.y),color);//colour a pixel at a set position
}

function getCircleSprite(radius:Number,color:int):Sprite{
    var circle:Sprite = new Sprite();
    circle.graphics.beginFill(color);
    circle.graphics.drawCircle(-radius * .5,-radius * .5,radius);//draw from centre
    circle.graphics.endFill();
    return circle;
}
看起来是这样的:

虽然不确定它是否是你想要的,但像素使用起来很有趣,而且速度也很快。 通过一点数学,你也可以做一些

此外,为了获得在actionscript中绘制的灵感,您可以看看Erik Natzke、Joshua Davis等。我建议您在每次更新行星时使用该方法将其渲染为像素。它的工作原理基本上类似于显示对象的“屏幕截图”,您将其作为n参数传递。如果传递对象变换,则位置/旋转/比例将可见(与从0,0绘制相反)。这样,您将只更新像素,而不是不断创建新的显示对象

下面是一个基本的示例:

import flash.display.Sprite;
import flash.events.Event;

var trails:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,true,0x00000000);//create a transparent bitmap to draw the trails into
var trailsFade:ColorTransform = new ColorTransform(1,1,1,0.025,0,0,0,1);//color transform: keep rgb the same(1,1,1), set alpha to 0.025 out of 1.0
var background:Bitmap = addChild(new Bitmap(trails,PixelSnapping.AUTO,true)) as Bitmap;//add the trails pixels/bitmap data into a Bitmap/display object at the bottom of the display list

var dot:Sprite = addChild(new Sprite()) as Sprite;
dot.graphics.lineStyle(3);
dot.graphics.drawCircle(-4, -4, 8);

addEventListener(Event.ENTER_FRAME,update);
function update(e:Event):void{
    dot.x = mouseX;
    dot.y = mouseY;
    //draw trails of the dot
    trails.draw(dot,dot.transform.concatenatedMatrix,trailsFade);//draw the dot into the bitmap data using the dot's transformation (x,y, rotation, scale)
}
请注意移动鼠标时的轨迹以及它们如何受(更新)速度的影响

下面是一个使用多个对象的较长示例:

import flash.display.*;
import flash.events.Event;
import flash.geom.ColorTransform;

var w:Number = stage.stageWidth;
var h:Number = stage.stageHeight;
var trails:BitmapData = new BitmapData(w,h,true,0x00000000);//create a transparent bitmap to draw the trails into
var trailsFade:ColorTransform = new ColorTransform(1,1,1,0.025,0,0,0,0.1);//color transform: keep rgb the same(1,1,1), set alpha to 0.025 out of 1.0
var background:Bitmap = addChild(new Bitmap(trails,PixelSnapping.AUTO,true)) as Bitmap;//add the trails pixels/bitmap data into a Bitmap/display object at the bottom of the display list
var spheres:Sprite    = addChild(new Sprite()) as Sprite;//add a container for all the spheres (planets/moons/sun/etc.)

var mercuryPivot:Sprite = spheres.addChild(new Sprite()) as Sprite;
var venusPivot:Sprite   = spheres.addChild(new Sprite()) as Sprite;
var earthPivot:Sprite   = spheres.addChild(new Sprite()) as Sprite;

var sun:Sprite     = spheres.addChild(getCircleSprite(69.5500 /4,0xFF9900)) as Sprite;
var mercury:Sprite = mercuryPivot.addChild(getCircleSprite(24.40 / 4,0xCECECE)) as Sprite;
var venus:Sprite   = venusPivot.addChild(getCircleSprite(60.52 / 4,0xFF2200)) as Sprite;
var earth:Sprite   = earthPivot.addChild(getCircleSprite(60.52 / 4,0x2233FE)) as Sprite;

mercury.x = 5791 / 40;
venus.x   = 10820 / 40;
earth.x   = 14960 / 40;
spheres.x = (w-spheres.width) * 0.5;
spheres.y = (h-spheres.height) * 0.5;

addEventListener(Event.ENTER_FRAME,update);
function update(e:Event):void{
    mercuryPivot.rotation += 0.5;
    venusPivot.rotation   += 0.25;
    earthPivot.rotation   += 0.12;
    //draw trails
    trails.draw(spheres,spheres.transform.concatenatedMatrix,trailsFade);
}


function getCircleSprite(radius:Number,color:int):Sprite{
    var circle:Sprite = new Sprite();
    circle.graphics.beginFill(color);
    circle.graphics.drawCircle(-radius * .5,-radius * .5,radius);//draw from centre
    circle.graphics.endFill();
    return circle;
}
注意,我们调用
trails.draw(spheres,spheres.transform.concatenatedMatrix,trailsFade)
但它可以是trails.draw(earth,earth.transform.concatenatedMatrix,trailsfead)
如果您只想绘制
地球的轨迹

在上面的例子中,我只是嵌套精灵并使用旋转属性来保持简单。你可能想用一点三角学来更新位置,因为行星可能不会有完美的圆形轨道,每次都会经过精确的位置

更新

仔细想想,如果你刚开始玩像素游戏还不习惯的话,那么使用老款可能会很方便

很容易入门:可以在flash player中显示的对象可以具有图形属性(请参见Shape/Sprite/MovieClip类)。(无论是否可以将元素嵌套到(DisplayObjectContainer)或(DisplayObject),您都可以拥有无法绘制的显示对象,但这对您来说也是另一回事)

graphics
属性Sprites and MovieClip允许您通过简单的命令以编程方式绘制,例如:设置笔划(
lineStyle()
)、填充(
beginFill()
/
endFill()
),移动假想的“笔”