admin管理员组文章数量:1357678
So I found some old script in a Newgrounds forum that should allow me to shake the scene without having to animate the scene manually. The problem is I don't really understand how to make it work. Can anyone explain to me how this works and how I can get it to work?
var AMOUNT = 20; //adjust based on how much you want the movieclip to shake
function makeMcShake(which:MovieClip)
{
which.defaultPos = {which.x, which.y};
which.addEventListener(Event.EnterFrame, shake);
}
function stopMcShake(which:MovieClip)
{
which.removeEventListener(Event.EnterFrame, shake);
which.x = which.defaultPos.x;
which.y = which.defaultPos.y;
}
function shake(e:Event)
{
e.currentTarget.x = e.currentTarget.defaultPos.x + Math.rand() * AMOUNT - AMOUNT / 2;
e.currentTarget.y = e.currentTarget.defaultPos.y + Math.rand() * AMOUNT - AMOUNT / 2;
}
So I found some old script in a Newgrounds forum that should allow me to shake the scene without having to animate the scene manually. The problem is I don't really understand how to make it work. Can anyone explain to me how this works and how I can get it to work?
var AMOUNT = 20; //adjust based on how much you want the movieclip to shake
function makeMcShake(which:MovieClip)
{
which.defaultPos = {which.x, which.y};
which.addEventListener(Event.EnterFrame, shake);
}
function stopMcShake(which:MovieClip)
{
which.removeEventListener(Event.EnterFrame, shake);
which.x = which.defaultPos.x;
which.y = which.defaultPos.y;
}
function shake(e:Event)
{
e.currentTarget.x = e.currentTarget.defaultPos.x + Math.rand() * AMOUNT - AMOUNT / 2;
e.currentTarget.y = e.currentTarget.defaultPos.y + Math.rand() * AMOUNT - AMOUNT / 2;
}
Share
Improve this question
edited Mar 28 at 19:20
Organis
7,3462 gold badges14 silver badges15 bronze badges
asked Mar 28 at 15:29
Johnson YanJohnson Yan
114 bronze badges
3
- Ok, I formatted the script to readability, and there are problems: 1) which.defaultPos = ... line makes no sense as {a, b, c, ...} is not a valid AS3 statement. 2) The event name is wrong. It should be exactly Event.ENTER_FRAME and none other. Otherwise, the logic of it is simple: upon calling makeShake you save the initial position and then every frame shift the target to that very position with a random offset. – Organis Commented Mar 28 at 19:24
- I see. It is an old script after all, so I guess this is just outdated. Or maybe it's useable for ActionScript 2 or 1. Do you know where I can find a source where I can make a scene shake? Or the very least the Movieclip? – Johnson Yan Commented Mar 28 at 22:25
- No, it is absolutely usable, just has errors. I am going to compose a correct one now. – Organis Commented Mar 29 at 7:28
2 Answers
Reset to default 0So, while the logic of the provided code was correct, there were multiple AS3 / Flash Palyer errors that prevented it to execute.
1. Creation of the preset object. As I already mentioned, the {a, b, c, ...} record does not mean a thing, there's a meaningful record that looks pretty similar: the creation of the generic object:
var O:Object = {x: 10, y: 20, alpha: 0.5};
is essentially the same as
var O:Object = new Object;
O.x = 10;
O.y = 20;
O.alpha = 0.5;
but obviously shorter.
2. Class fields, methods, constants, they are case-sensitive and should be typed in EXACTLY as supposed, otherwise Flash Player just wouldn't understand your intent. I pretty much advise to always check things with the language reference: the Math class, the Event class.
These are wrong:
Event.EnterFrame
Math.rand()
These are correct:
Event.ENTER_FRAME
Math.random()
Now. I expect the script for the shaking was intended like the one below.
Please ⚠️ keep in mind ⚠️ that while most of the scripts I compose still work as is, it was still ages since I last used AS3 and I have no way to check it so I might just miss something.
// @param:
// which — target to shake
// power — how much you want it to shake
// count — how many times (omit if you want it to shake until stopped manually)
function shake(which:MovieClip, power:Number, count:int = -1):void
{
// Sanity check.
if (!which)
{
return;
}
// Just in case, stop it if it is already shaking.
unshake(which);
// Save the shake parameters. This creates a generic object with fields.
which.preset = {x: which.x, y: which.y, power: power, count: count};
// Subscribe to the event that fires each frame.
which.addEventListener(Event.ENTER_FRAME, onShaking);
}
function unshake(which:MovieClip):void
{
// Sanity check.
if (!which)
{
return;
}
// Unsubscribe from the event.
which.removeEventListener(Event.ENTER_FRAME, onShaking);
// Ignore if there is no preset object.
if (which.preset)
{
// Return the target to its initial position.
which.x = which.preset.x;
which.y = which.preset.y;
// Remove the shake parameters object.
which.preset = null;
}
}
function onShaking(e:Event):void
{
// Get the direct reference to the target object.
var which:MovieClip = e.currentTarget as MovieClip;
// Sanity check. If there's no parameter object — just stop it.
if (!which.preset)
{
unshake(which);
return;
}
// Check if the countdown is complete.
var count:int = which.preset.count;
if (count > 0)
{
count -= 1;
// Stop shaking if it is indeed complete.
if (count == 0)
{
unshake(which);
return;
}
which.preset.count = count;
}
// Shaking itself.
var power:Number = which.preset.power;
which.x = which.preset.x + Math.random() * power - power / 2;
which.y = which.preset.y + Math.random() * power - power / 2;
}
And so, the usage.
Since DisplayObject.root:DisplayObject won't be automatically cast to the required MovieClip (meaning that you know that your root is a MovieClip yet the compiler does not) you need to explicitly typecast it to be accepted as argument.
// Shake the root MovieClip a bit 10 times.
shake(root as MovieClip, 5, 10);
// Shake the root MovieClip a bit more for approximately 1 second.
shake(root as MovieClip, 10, stage.frameRate);
// Shake the root MovieClip a lot and indefinitely.
shake(root as MovieClip, 25);
Okay, so eventually the code that finally made a MovieClip to shake is the following.
import flash.display.MovieClip;
import flash.events.Event;
function shake(which:MovieClip, power:Number, count:int = -1):void {
if (!which) return;
unshake(which);
which.preset = {x: which.x, y: which.y, power: power, count: count};
which.addEventListener(Event.ENTER_FRAME, onShaking);
}
function unshake(which:MovieClip):void {
if (!which) return;
which.removeEventListener(Event.ENTER_FRAME, onShaking);
if (which.preset) {
which.x = which.preset.x;
which.y = which.preset.y;
which.preset = null;
}
}
function onShaking(e:Event):void {
var which:MovieClip = e.currentTarget as MovieClip;
if (!which.preset) {
unshake(which);
return;
}
var count:int = which.preset.count;
if (count > 0) {
count--;
if (count == 0) {
unshake(which);
return;
}
which.preset.count = count;
}
var power:Number = which.preset.power;
which.x = which.preset.x + Math.random() * power - power / 2;
which.y = which.preset.y + Math.random() * power - power / 2;
}
//For insertNamehere, change it to the name of the MovieClip in the properties panel
shake(insertNamehere, 10, 100);
//Thanks again Organis, you are a great help!
本文标签: actionscript 3Trying to get makeMcShake script found in Newgrounds forum to workStack Overflow
版权声明:本文标题:actionscript 3 - Trying to get makeMcShake script found in Newgrounds forum to work - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744028438a2578460.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论