我正在制作一个绘图应用程序,允许用户在画布上自由绘制,在某些坐标x,y范围内会有声音出现。我的目标是让用户以后录制和播放整个动作,并像视频一样观看。我能够使绘图笔画工作,但我有关于录制和播放部分的问题,特别是内部音频的录制。我已经搜索了很长时间,我发现这与我的概念非常相似
这是我发现由ronnie完成的一个很好的例子 http://ronnieswietek.com/piano/piano_example.swf 来源:http://ronnieswietek.com/piano/piano_example.fla
有没有办法让我把钢琴键替换为基于坐标生成声音的绘画笔画,并像示例一样录制和播放笔画和声音?
我陷入困境,想弄清楚如何做到这一点......
答案 0 :(得分:0)
如果您可以执行代码来执行绘制笔划,那么您需要做的就是为这些笔划命令的执行添加时间戳。有很多方法可以解决这个问题。我写了一个例子(仅适合你)。
您可以将其粘贴到新的Flash文档中并运行它。
/* First we'll create some variables */
var recording:Array = new Array(); // This is where we'll store all the instances of user action.
var playStart:Number = 0; // Playback will depend on whether this variable is greater than 0.
stage.addEventListener(Event.ENTER_FRAME, tic); // This will run once every frame update.
/* Next we'll create some helper functions */
function createButton(name:String, hue:uint):MovieClip {
// We'll use this to make some fancy buttons.
var box:MovieClip = new MovieClip();
var shape:Sprite = new Sprite();
shape.graphics.beginFill(hue);
shape.graphics.drawRect(0, 0, 100, 25);
box.addChild(shape);
var txt:TextField = new TextField();
txt.text = name;
txt.x = 10;
txt.y = 3;
txt.mouseEnabled = false;
box.addChild(txt);
return box;
}
function drawCircle(X:Number, Y:Number, Hue:uint = 0x000000):void {
// This creates circles on stage.
var circle:Shape = new Shape();
circle.graphics.beginFill(Hue);
circle.graphics.drawCircle(0, 0, 10);
circle.graphics.endFill();
circle.x = X;
circle.y = Y;
addChild(circle);
}
/* Now lets create some buttons; Record, Stop, and Play. And rig'em up to some actions. */
var recordBtn:MovieClip = createButton("Record", 0x10ab00);
addChild(recordBtn);
recordBtn.addEventListener("mouseUp", startRecording);
var stopRecordBtn:MovieClip = createButton("Stop", 0xe90000);
stopRecordBtn.x = 101;
addChild(stopRecordBtn);
stopRecordBtn.addEventListener("mouseUp", stopRecording);
var playBtn:MovieClip = createButton("Play", 0x0069ab);
playBtn.x = 202;
addChild(playBtn);
playBtn.addEventListener("mouseUp", playRecording);
/* In the same order, we'll create those functions */
function startRecording(e:Event):void {
// Here we'll store a timestampe of when the recording started.
recording[0] = flash.utils.getTimer();
// Register for mouseclicks on the stage; we need some kind of input to track.
stage.addEventListener("mouseUp", recordAction);
}
function stopRecording(e:Event):void {
// Conversely, we stop recording by not listening anymore.
stage.removeEventListener("mouseUp", recordAction);
}
function playRecording(e:Event):void {
// Just like recording, we keep track of when we started.
playStart = flash.utils.getTimer();
}
function recordAction(e:Event):void {
if (recording.length >= 1) {
// First, we create the timestamp, and other relavent info.
var tick:Object = {
"time":flash.utils.getTimer(),
"x":e["stageX"],
"y":e["stageY"]
}
// And store it in our numerical index
recording.push(tick);
trace("Time: " + (tick.time - recording[0]) + " Coords: " + tick.x + "," + tick.y);
// Then we do whatever action we were supposed to do (draw line, play sound, etc.). Here, we'll draw a circle at the mouse coordinates.
drawCircle(tick.x, tick.y);
}
}
function tic(e:Event):void {
if (playStart > 0) { // Assuming we've indexed a start time...
if (recording.length > 1) { // and we actually have actions to playback.
// We'll first normalize those bizzare numbers to a zero starting number.
var nextAction:Number = recording[1].time - recording[0];
var playHead:Number = flash.utils.getTimer() - playStart;
if (playHead > nextAction) {
// Now that we've matched the time, we execute the same action we did before.
drawCircle(recording[1].x, recording[1].y, 0xFFFFFF);
// ... and in this example, I'm removing that instance since we no longer need it.
recording.splice(1, 1);
}
} else {
// If the length of the recording reaches zero, we'll automatically stop playback too.
playStart = 0;
}
}
}