We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I currently have a sketch that reproduces what's drawn on the screen and displays it on a LED matrix.
My idea for this sketch is to draw a layered gallery of effects (simple realtime Processing made animations), but I'm not sure of how to store these effects (each one being a little portion of code).
I need to:
I know that the animations can be stored as functions and called when necessary, ordered by "layer". And maybe each collection can be also a function that calls the needed animations.
What structure do you recommend? I'm fairly new in Processing and Java, so I don't know the best practices for this scenario. Maybe storing the animations on a separate file and importing it? (to mantain a cleaner code)
Answers
First things first: Don't bother too much about using multiple files. Processing treats different .pde files as if they were all one large file anyway, so as long as you can manage to keep everything organized in one file, that's fine.
Next, each animation is going to need, at the very least, a function. There is just no getting around this, because each animation needs to be able to do some drawing, and thus it needs to run some drawing code, and thus is needs to be in a function that draw() can call. Each animation may have other things it needs - global variables, user inputted values, data loaded from other files, etc - but let's not worry about those yet. Instead, let's write you a few animation functions now, just as place holders:
This is great, but what you really want is a collection. So what is a collection? You said it yourself - it's up to four animations that run at the same time. Since each animation has a unique function name, the easiest way to track which animations are in a collection is to just remember the four animation function names that a collection needs to call.
There's a little black magic here, in the use of the
method()
function.This is a lot better, but it's not perfect yet.
This, however, is.
Notice that all the collections are now in one large 2D array of strings. The current collection is recorded by its index, stored in the current_collection variable. the draw() function just draws each of the functions in the current collection.
You can easily add more animation functions to this. You can also easily add more collections by specifying their animation functions by name.
The only problem here is that you need to make sure that you don't mix up global variables between different animations. For example, if two different animations are using a variable called
x
, well, there's only one global x variable for them to use - so they'd share it. This could be solved by making each animation function into it's own object, but that is probably too complex unless you have animations that are sharing numerous variable names.Of course, there's still a lot to do. If any animations need resources loading, you need to make sure that happens in setup(). Plus you will need to check which collection is running if there is any sort of user input happening.
Let us know how it turns out. If you have more questions, post your complete working sketch with attempted modifications when you ask.
Wow, great! Thank you very much. It's a great start. I don't have the animations ready yet as to test throughly this method, but for as I can see, there are some things I'm struggling to understand how to implement:
method()
need to have some parameters to "configure" them for each collection, some (if not all) of the animations are present on different collections, but with different parameters (different hue or speed, for example). Can I call these functions with the parameters values included throughmethod()
?I'll do some tests, try to figure it out myself (I like learning this way), and post back when I have a code to show. But this is a great start, thank you.
1) Alas, you can't call a function with parameters using method(). Instead, you have to put the values you do want to pass into global variables that the called function then reads. Example:
2) Interesting. try it yourself.
This, to me, suggests classes. And an interface defining the common methods. And an ArrayList.
Instead of a clutch of global variables the variables would being to the class. Neater that way.
The user aspect is a bit difficult though. How is the user changing these variables? And if you have 4 different animations with 3 or 4 user tweakable variables each, that's a lot of stuff
Yeah, @koogs, I know, classes sounds like they should help here, but since each animation is doing something different to generate its image, it's not immediately obvious how you would do it.
If I were writing this in, say, Ruby, there would be no problem - each animation would just have a string that can be treated as trusted code and then simply executed. But there's no easy way to run arbitrary code like that in Processing.
Maybe a base Animation class which each specific animation inherits from? Bleh. That's still a mess.
Give it some thought? I have a few things to try.
This probably won't be any help to maurobarreca, but in JRubyArt we can simply write:-
What is more in watch mode you could edit sketch on fly and have it re-draw
Depends on the animation, I guess. My immediate thought, because he called them "effects", was that they were all filters, filtering the results of the previous operations. So, pixels in, pixels out. But, yes, could be anything.
The introspective nature of method(), however nicely it's hidden from the user, bugs me. If you're using a strongly typed language then use it, don't start passing function names around as strings.
http://Bl.ocks.org/GoSubRoutine/f9a0a94dcfee23a037b35f308b256d98
https://Forum.Processing.org/two/discussion/7147/some-simple-pulse-equations-using-trig-#Item_8
Although main Processing Mode is Java, all the other flavors are made for weakly-typed languages! ~O)
Processing isn't bound to Java at all. B-)
Processing has no obligation to please hardcore Java programmers either! :P
Sorry, maybe I don't use the correct terms because English is my second language. The idea is fairly simple: you have a series of animations, this is a simple example of one:
In this example palomaBass is nested inside a "layers" function (let's call it "scene"). Like palomaBass, there's maybe other 3 animations called inside the scene. The idea is that the user can modify r, g and b for example with a MIDI controller. All this is working now, what I'm trying to figure out is how to manage these "collections".
I need to store each scene inside another function, a "sequence" function, that calls these scenes when intended. And then I need to easily call these "sequences" when intended.
Basically I want to navigate forward and backwards from sequence to sequence, and inside each sequence, from scene to scene, that's the part I'm not sure how to solve.
(there's some talk here: https://forum.processing.org/two/discussion/26290/how-to-declare-a-variable-once-inside-a-loop but it's basically a duplicate of mauro's last post with less context.)
Yes, they're global.
t
is stores the value ofmillis()
on each draw loop, butrt
stores a value ofmillis()
when a condition is met insidepalomaBass()
. As koogs says, I asked a question outside of this thread for how to makert
stop being global and declare it insidepalomaBass()
(the problem here is that declaring it inside will 0 it out everytime the function is called on a loop, so it's modification inside the loop is useless).I will check out if I can make this all work with classes, objects and methods, it will be my first time using those resources from scratch.
Should I do something like this?:
And then call it with:
Paloma.bass(120,125,255,0);
(I'm ignoring the declaring and initiation of this object for this example)
Is this how it works?
Almost there! But I can spot you're still accessing "global" variables inside your
class
Paloma: matrixSizeX & matrixSizeY. :-\"Notice that millis() returns an
int
value. No need for along
variable to store it: L-)https://Processing.org/reference/millis_.html
B/c millis() current value increases all the time, we need to re-invoke it every time, not just once. :-B
Rather than r, g & b, why not the whole aRGB
color
as inint
variable? O:-)You can also store the desired
color
as a field member of yourclass
too, rather than keeping passing it to bass() method over & over. :ar!Much probably you're gonna need to store the coordinates for rect() as fields too. >-)
Here are some modifications I've come up w/ for your Paloma
class
: :DThank you!
Yes, it's handy for this sketch to have those global variables there. They're constant, so it's just for configuration. I prefer to have them there than having to input them every time I call an object. Having globals there is a functional problem or a style one? I'll check your other recommendations, thank you very much.
So they should follow ALL_CAPS naming convention. L-)
Also, if they're related to some class, they should be placed there. *-:)