Skip to content

Commit

Permalink
Added Particle Animation layout and some fixes to the animate module
Browse files Browse the repository at this point in the history
- Particle Animation layout added based on liquid8d's ExtendedObjects
  Advanced layout
- added support for the EndNavigation event and artwork Trigger property
  to animate module
- Fix for resource usage in the animate module's particle effect system
  • Loading branch information
mickelson committed Feb 25, 2015
1 parent 6011c21 commit 9bcf725
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 14 deletions.
Binary file added config/layouts/Particle Animation/bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
145 changes: 145 additions & 0 deletions config/layouts/Particle Animation/layout.nut
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
//
// This layout demonstrates liquid8d's extended object and animate modules
// It is a slightly modified version of the "3. ExtendedObjects Advanced" layout available at:
//
// https://github.com/liquid8d/attract-extra
//
// See modules/extended/README.md for more info
//
//we will add some user config options
class UserConfig {
</ label="Enable Debug", help="Enable/Disable debug info", options="Yes,No" />
enable_debug="No";
</ label="Enable Animations", help="Enable/Disable animations", options="Yes,No" />
enable_anims="Yes";
</ label="Enable Particles", help="Enable/Disable particle effects", options="Yes,No" />
enable_particles="Yes";
}

local config = fe.get_config();

fe.load_module("extended/extended");
fe.load_module("extended/animate");
//we can add additional animation modules, we'll try the particules module
fe.load_module("extended/animations/particles/particles.nut");
fe.load_module("extended/animations/example/example.nut");

ExtendedObjects.add_image("bg", "bg.png", 0, 0, fe.layout.width, fe.layout.height);
ExtendedObjects.get("bg").setPreserveAspectRatio(false);

//we'll attach a particles animation to our background

//uncomment others to see them
if (config.enable_particles == "Yes") ExtendedObjects.get("bg").animate({ which = "particles", preset = "sparkle" } );
//if (config.enable_particles == "Yes") ExtendedObjects.get("bg").animate({ which = "particles", preset = "snow" } );
//if (config.enable_particles == "Yes") ExtendedObjects.get("bg").animate({ which = "particles", preset = "default" } );
//if (config.enable_particles == "Yes") ExtendedObjects.get("bg").animate({ which = "particles", preset = "test" } );
//if (config.enable_particles == "Yes") ExtendedObjects.get("bg").animate({ which = "particles", preset = "cloudstoon" } );
//if (config.enable_particles == "Yes") ExtendedObjects.get("bg").animate({ which = "particles", preset = "bubbles1" } );
//if (config.enable_particles == "Yes") ExtendedObjects.get("bg").animate({ which = "particles", preset = "arc1" } );
//if (config.enable_particles == "Yes") ExtendedObjects.get("bg").animate({ which = "particles", preset = "invaders" } );
//if (config.enable_particles == "Yes") ExtendedObjects.get("bg").animate({ which = "particles", preset = "cloudstoon2" } );

//Here we'll use a custom animation
//if (config.enable_particles == "Yes") ExtendedObjects.get("bg").animate({ which = "example", when = When.Always, duration = 20000 } );

//DOESN'T WORK - haven't implemented bounding rectangles
//if (config.enable_particles == "Yes") ExtendedObjects.get("bg").animate({ which = "particles", preset = "bounce1" } );



local title = ExtendedObjects.add_text("title", "[Title]", 0, 80, fe.layout.width / 2, 60);
//property functions follow a setFunction or getFunction standard
title.setColor(220, 220, 220);
title.setCharSize(36);
//ExtendedTexts and ExtendedImages can make use of a shadow
title.setShadow(true);
title.setShadowColor(240, 240, 20);
title.setShadowAlpha(75);
title.setShadowOffset(4);

local list = ExtendedObjects.add_listbox("list", fe.layout.width / 2, 0, fe.layout.width / 2, fe.layout.height);
list.setCharSize(15);
list.setStyle(Style.Bold);
list.setColor(80, 80, 80);
list.setSelectionColor(200, 200, 200);
list.setSelectionBGColor(60, 60, 125);
list.setSelectionBGAlpha(100);
//you can set positions of objects by string names
list.setPosition("offright");

local listAnim = {
which = "property",
when = When.StartLayout,
property = "x",
delay = 750,
from = "offright",
to = "right"
}
if (config.enable_anims == "Yes") list.animate(listAnim) else list.setPosition("right");

local logo = ExtendedObjects.add_image("logo", "logo.png", 0, 0, 262, 72);
logo.setPosition("top");

local logoAnim = {
which = "translate",
when = When.StartLayout,
delay = 750,
duration = 1000,
from = "current",
to = "offtoprightx",
easing = "out",
tween = "bounce"
};
if (config.enable_anims == "Yes") logo.animate(logoAnim) else logo.setPosition("top");


local snap = ExtendedObjects.add_artwork("snap", "snap", 100, 100, 480, 360);
snap.setPosition( [ 100, (fe.layout.height / 2) - 180 ]);
snap.setShadow(false);
snap.setTrigger( Transition.EndNavigation );

//You can use some predefined animation sets (a group of animations)
// NOTE: uncommenting the following will seriously slow down the front-end's responsiveness
//if (config.enable_anims == "Yes") snap.animate_set("fade_in_out" );


local marquee = ExtendedObjects.add_artwork("marquee", "marquee", 0, 0, 500, 156);
marquee.setPosition("offleft");
marquee.setTrigger( Transition.EndNavigation );

//You can delay animations to get a step1, step2 approach
//step 1: move from offscreen left to center using the out/bounce tween
local marqueeAnim1 = {
which = "translate",
when = When.EndNavigation,
wait = false,
duration = 750,
from = "offleft",
to = "center",
easing = "out",
tween = "bounce"
};
//step 2: move from center position to bottom after a delay using the out/bounce tween
local marqueeAnim2 = {
which = "translate",
when = When.EndNavigation,
delay = 1000,
duration = 750,
from = "center",
to = "bottom",
easing = "out",
tween = "bounce"
};
if (config.enable_anims == "Yes") {
marquee.animate(marqueeAnim1);
marquee.animate(marqueeAnim2);
} else {
marquee.setPosition("bottom");
}

//The debugger adds debug text ontop of every object, helpful for... debugging
if (config.enable_debug == "Yes") {
local debug = ExtendedObjects.debugger();
debug.setVisible(true);
}
Binary file added config/layouts/Particle Animation/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions config/modules/extended/animate.nut
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ When <- {
ToGame = 4,
FromGame = 5,
ToNewList = 6,
EndNavigation = 7,
OnDemand = 100,
Always = 101
}
Expand Down Expand Up @@ -118,6 +119,8 @@ class Animate {
return "FromGame";
case 6:
return "ToNewList";
case 7:
return "EndNavigation";
case 100:
return "OnDemand";
case 101:
Expand Down
48 changes: 35 additions & 13 deletions config/modules/extended/animations/particles/particles.nut
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class ParticlesAnimation extends ExtendedAnimation {
resources = null;
emitter = null;
particles = null;
dead_parts = null;
elapsed = 0;
current = 0;
timePerParticle = 0;
Expand Down Expand Up @@ -111,6 +112,7 @@ class ParticlesAnimation extends ExtendedAnimation {

//setup particles
particles = [];
dead_parts = [];

//used for debugging
if (debug) setupDebug(config);
Expand Down Expand Up @@ -148,9 +150,20 @@ class ParticlesAnimation extends ExtendedAnimation {
}

function create(ttime) {
local resource = randomResource();
local p = Particle(ttime, resource, emitter, config);
particles.append(p);
if ( dead_parts.len() > 0 )
{
// recycle our dead parts
particles.append( dead_parts[0] );
particles[ particles.len()-1 ].visible( true );
particles[ particles.len()-1 ].setup( ttime, emitter, config );
dead_parts.remove( 0 );
}
else
{
local resource = randomResource();
local p = Particle(ttime, resource, emitter, config);
particles.append(p);
}
}

function frame(obj, ttime) {
Expand All @@ -166,19 +179,17 @@ class ParticlesAnimation extends ExtendedAnimation {
}

local msg = "";
for (local i = 0; i < particles.len(); i++) {
for (local i = particles.len()-1; i >= 0; i--) {
//update
particles[i].update(ttime);

//kill dead ones
if (particles[i].isDead()) {
particles[i].visible(false);
//particles.remove(i);
dead_parts.push( particles[i] );
particles.remove(i);
//fe.obj[#].remove
}
//give us some debug info
if (i > particles.len() - 4) {
msg += "p" + i + " " + particles[i].toString();
}
}
//if (particles.len() >= 1) ExtendedDebugger.notice(particles[0].toString());
//ExtendedDebugger.notice("time: " + current + " elapsed: " + elapsed + " particles: " + particles.len() + " ppm: " + emitter.ppm + " (" + timePerParticle + "mspp)" + "\n" + msg);
Expand Down Expand Up @@ -213,6 +224,7 @@ class ParticlesAnimation extends ExtendedAnimation {
class Particle {
createdAt = 0;
resource = null;
parent_resource=null;
x = 0;
y = 0;
w = 0;
Expand Down Expand Up @@ -243,10 +255,19 @@ class Particle {
currentAccel = 0; //store the current acceleration
currentGravity = 0; //store the gravity
currentSpeed = 0; //store the current speed
constructor(createdAt, resource, emitter, config) {
this.createdAt = createdAt;
this.resource = config.layer.add_clone(resource);

constructor(createdAt, resource_param, emitter, config) {
this.resource = config.layer.add_clone(resource_param);
this.parent_resource = resource_param;
setup( createdAt, emitter, config );
}

function setup( createdAt, emitter, config ) {

this.resource.width = this.parent_resource.width;
this.resource.height = this.parent_resource.height;

this.createdAt = createdAt;
this.x = this.startx = ParticlesAnimation.random(emitter.x, emitter.x + emitter.width);
this.y = this.starty = ParticlesAnimation.random(emitter.y, emitter.y + emitter.height);
this.w = resource.width;
Expand All @@ -271,7 +292,8 @@ class Particle {

function update(ttime) {
ttime = ttime - createdAt;
lifespan = lifetime - (ttime - createdAt);
// lifespan = lifetime - (ttime - createdAt);
lifespan = lifetime - ttime;

//the ttime/ numbers below are adjustments to attempt to match the speed of HyperTheme
if (movement) {
Expand Down
4 changes: 3 additions & 1 deletion config/modules/extended/extended.nut
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ ExtendedObjects <- {
}

const OFFSCREEN = 20;
TRANSITIONS <- ["StartLayout", "EndLayout", "ToNewSelection", "FromOldSelection", "ToGame", "FromGame", "ToNewList"];
TRANSITIONS <- ["StartLayout", "EndLayout", "ToNewSelection", "FromOldSelection", "ToGame", "FromGame", "ToNewList", "EndNavigation" ];

POSITIONS <- {
centerX = function() { return fe.layout.width / 2; },
Expand Down Expand Up @@ -268,6 +268,7 @@ class ExtendedImage extends ShadowedObject {
function getVideoDuration() { return object.video_duration; }
function getVideoTime() { return object.video_time; }
function getFilename() { return object.file_name; }
function getTrigger() { return object.trigger; }

function setMovieEnabled(e) { object.movie_enabled = shadow.movie_enabled = e; }
function setPinch(x, y) { setPinchX(x); setPinchY(y); }
Expand All @@ -283,6 +284,7 @@ class ExtendedImage extends ShadowedObject {
function setVideoFlags(f) { object.video_flags = shadow.video_flags = f; }
function setVideoPlaying(p) { object.video_playing = shadow.video_playing = p; }
function setFilename(f) { object.file_name = shadow.file_name = f; }
function setTrigger(t) { object.trigger = shadow.trigger = t; }
function swap(i) { print("swapped\n"); object.swap(i.object); }
}

Expand Down

0 comments on commit 9bcf725

Please sign in to comment.