Author Topic: Help me wrap my head around the Conveyor module!  (Read 9572 times)

Bgoulette

  • Sr. Member
  • ****
  • Posts: 116
  • I wrote a book.
    • View Profile
    • BlakeGoulette.com
Help me wrap my head around the Conveyor module!
« on: November 18, 2015, 01:11:19 PM »
Hi all,

I've looked through the code for the conveyor module and the SimpleArtStrip class, but I still can't wrap my brain around how to actually use it in a layout. For my purposes, a simple extension of the SimpleArtStrip and SimpleArtStripSlot classes should meet my needs, but I have no idea how to actually make a conveyor -- even the default -- show up on the screen. I don't know what else I'm doing, either, but I figure if I started there, that'd be a good place...

I just want a horizontal strip of snaps to move either left or right depending on whether the user moves up or down in the game list. I want it to take one second between transitions and stop on the next entry in the list (up or down).

Can anyone break down how to use the conveyor for a toddler? :( Thanks!

omegaman

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 880
    • View Profile
Re: Help me wrap my head around the Conveyor module!
« Reply #1 on: November 19, 2015, 05:48:06 AM »
Bgoulette-

If all you need is horizontal or vertical scrolling art then the SimpleArtStrip should be sufficient. Raygun extended on the conveyor module for this reason, to help make it easier for people who wanted a quick way to add scrolling art to their layouts. The following example of code below is configured for 1 row and 5 columns of vertical art.  The only thing you need to configure is the last line of the script. All the hard-work like the constructor is done for you. You just need to plugin the variables like the art, number of arts, the coordinates and padding for the art.

For example the last line of the script looks like this "local my_strip = SimpleArtStrip( "wheel", 5, 100, 0, fe.layout.width/4.8, fe.layout.height/1.0, 1 );" etc...   Now, you just need to change the values to suit your needs. The first value is for what are type of art you want "wheel", "snap" "flyer" yada yada. The second value is how many arts, "5" for this example. The third and fourth values are for the x, and y coordinates - position of the art. The last values are for width and the height of the art. The width and height also determines whether you art will be vertical or horizontal. This can be a little tricky at first until you get a feel for it. In this example "fe.layout.width/4.8, fe.layout.height/1.0" the art will be displayed vertically. But if I reverse it to "fe.layout.width/1.0," "fe.layout.height/4.8"the art will be displayed horizontal. Basically, in either scenario the smaller number has to be less than the bigger number if that makes sense. Because, if you change "fe.layout.width/4.8" to something like like 2.8 for example, the art will actually be bigger. The opposite of what you might think, But, anyway,  its not that hard once you get a feel for it.

You could cut and paste this code into your script right now for vertical art and just make a few tweaks.  Whew.. I usually do a terrible job of explaining things, I hope this helps... 


fe.load_module( "conveyor" );

class SimpleArtStrip extends Conveyor
{
   m_x=0; m_y=0; m_width=0; m_height=0; m_x_span=0; m_y_span=0;

   constructor( artwork_label, num_objs, x, y, width, height, pad=0 )
   {
      base.constructor();
      local my_list = [];
      for ( local i=0; i<num_objs; i++ )
         my_list.push( SimpleArtStripSlot(this,artwork_label) );
      set_slots( my_list );

      m_x=x+pad/2; m_y=y+pad/2;
      if ( width < height )
      {
         m_x_span=0;
         m_y_span=height;
         m_width=width-pad;
         m_height=height/m_objs.len()-pad;
      }
      else
      {
         m_x_span=width;
         m_y_span=0;
         m_width=width/m_objs.len()-pad;
         m_height=height-pad;
      }

      reset_progress();
   }
};


local my_strip = SimpleArtStrip( "wheel", 5,100, 0, fe.layout.width/4.8, fe.layout.height/1.0, 1 );

omegaman

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 880
    • View Profile
Re: Help me wrap my head around the Conveyor module!
« Reply #2 on: November 19, 2015, 05:52:39 AM »
Liquid8d-

Does a much better job of explaining this stuff than I do. So, if this doesn't help maybe he can break it down for you better than I did.

Bgoulette

  • Sr. Member
  • ****
  • Posts: 116
  • I wrote a book.
    • View Profile
    • BlakeGoulette.com
Re: Help me wrap my head around the Conveyor module!
« Reply #3 on: November 19, 2015, 06:22:24 AM »
Thanks, omegaman! I'll definitely give that a look. I think I was just missing which arguments to pass via the instantiating call. I'm still used to things like the "new" keyword when instantiating a class. I'll get there, thanks again for the help! :)

Bgoulette

  • Sr. Member
  • ****
  • Posts: 116
  • I wrote a book.
    • View Profile
    • BlakeGoulette.com
Re: Help me wrap my head around the Conveyor module!
« Reply #4 on: November 19, 2015, 08:47:37 AM »
Well that was easy enough! SimpleArtStrip was just what I needed, functionally...

Now to figure out another problem I created for myself. I'm going to ask it in another thread, but just in case you know, omegaman, do fe.Image instances hold a reference to their "parents" by default? Meaning, if I did something like:

Code: [Select]
local my_surface=fe.add_surface(100, 100);
local my_image=my_surface.add_image("imagepath.png");

Would the resulting my_image object know where it "lived?" Thanks!

Bgoulette

  • Sr. Member
  • ****
  • Posts: 116
  • I wrote a book.
    • View Profile
    • BlakeGoulette.com
Re: Help me wrap my head around the Conveyor module!
« Reply #5 on: November 19, 2015, 09:30:59 PM »
Okay, more conveyor questions:

If I have a conveyor (SimpleArtStrip) with 6 objects and I want the third object to represent the current game, what do I change? Right now, the "selected" item is one greater than it should be. I tried extending the class and setting selection_index to -1 (versus 0 in the conveyor module), but that didn't work. Am I fighting with the wrong variables?

And second: is there anyway to place a SimpleArtStrip on a surface? Or will it always be placed on ::fe? I've tried extending classes where I think this is happening but I'm doing it wrong because I get errors. I could work around it (and will if necessary), but I like the idea of placing it on a surface that can be manipulated independently of the whole ::fe display object.

As always, thanks for any answers!

liquid8d

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 442
    • View Profile
Re: Help me wrap my head around the Conveyor module!
« Reply #6 on: November 20, 2015, 08:26:27 AM »
Don't just change selection_index in your SimpleArtStrip because when the set_slots function is called, it automatically sets the selection index to ( slot_count / 2 ). Instead, pass the selection index when you call set_slots:

Code: [Select]
class MySimpleArtStrip extends Conveyor
{
m_x=0; m_y=0; m_width=0; m_height=0; m_x_span=0; m_y_span=0;

constructor( artwork_label, num_objs, x, y, width, height, pad=0 )
{
base.constructor();
local my_list = [];
for ( local i=0; i<num_objs; i++ )
my_list.push( SimpleArtStripSlot(this,artwork_label) );
                local new_selection_index = ( my_list.len() >= 3 ) ? 2 : my_list.len() - 1; // 3rd item, or last if less than 3
set_slots( my_list, new_selection_index );

m_x=x+pad/2; m_y=y+pad/2;
if ( width < height )
{
m_x_span=0;
m_y_span=height;
m_width=width-pad;
m_height=height/m_objs.len()-pad;
}
else
{
m_x_span=width;
m_y_span=0;
m_width=width/m_objs.len()-pad;
m_height=height-pad;
}

reset_progress();
}
}

Note the shorthand if/else set statement I used, not sure if you are familiar with that:
Code: [Select]
  local val = ( something == true ) ? true : false;
  // if something == true, set val to true, else set it to false

Bgoulette

  • Sr. Member
  • ****
  • Posts: 116
  • I wrote a book.
    • View Profile
    • BlakeGoulette.com
Re: Help me wrap my head around the Conveyor module!
« Reply #7 on: November 20, 2015, 08:36:58 AM »
Yep, the "ternary operator" :) I'll check it out. Thanks, as always for the hand-holding!

Edit: I mean that in a positive way, though after re-reading it, it sounds petulant. That's not what I intended at all! I sincerely mean thank you for being patient enough to respond to my questions!

Bgoulette

  • Sr. Member
  • ****
  • Posts: 116
  • I wrote a book.
    • View Profile
    • BlakeGoulette.com
Re: Help me wrap my head around the Conveyor module!
« Reply #8 on: November 20, 2015, 11:12:02 AM »
That did the trick!

Of course, another issue that I'm not sure how to address (shocked, right?! ;) )

I've extended ConveyorSlot like so:

Code: [Select]
class SimpleThumbStripSlot extends ConveyorSlot
{
m_p=null;
constructor(parent, name)
{
m_p=parent;
base.constructor(FillArtwork(name, 0, 0, THUMB_WIDTH, THUMB_HEIGHT));
// base.constructor(::fe.add_artwork(name));
}

function on_progress(progress, var)
{
m_obj.width = m_p.m_width;
m_obj.height = m_p.m_height;
m_obj.x = m_p.m_x + progress * m_p.m_x_span;
m_obj.y = m_p.m_y + progress * m_p.m_y_span;
}
};

(Yes, that looks suspiciously like SimpleArtStripSlot...because that's what I stole it from!) However, while it uses my FillArtwork class, every object in the strip is the same (selected) thumbnail! If I comment out my line and replace it with the original, it works, so there's something in my FillArtwork class, I'm guessing, that's not responding to the index setting methods... Mostly thinking out loud here... so it's on the art object that I probably need to be setting the index, which is inherent when using ::fe.add_artwork()... so I'll have to access the FillArtwork's art property instead...

Am I on the right track? :) Thanks!

Edit: Heck yeah! I tweaked the following in my FillArtwork module (which borrows extensively from liquid8d's superior version):

Code: [Select]
function _set(idx, val)
{
::print ("idx: "+idx+"; val: "+val+"\n");
if (idx!="index_offset")
{
parent[idx]=val;
}
else {
art[idx]=val;
}
return val;
}

There's probably a "more better" way to handle it, but I don't know, and this works for now: when attempting to set the index_offset property, pass it to the art object as opposed to leaving it with the parent.

Edit 2: Now I'm noticing that as I advance the conveyor (SimpleArtStrip variant), the last item (a FillArtwork instance) updates at the end of the transition. Where would I look to force the update to take place before the transition begins? Or is that even possible? I ask because the update needs to run, but running at the end of the transition causes a visual hiccup as the fill is reapplied. Thanks!
« Last Edit: November 20, 2015, 03:02:45 PM by Bgoulette »

Bgoulette

  • Sr. Member
  • ****
  • Posts: 116
  • I wrote a book.
    • View Profile
    • BlakeGoulette.com
Re: Help me wrap my head around the Conveyor module!
« Reply #9 on: November 27, 2015, 07:53:01 AM »
I had the (modified) conveyor working, with animation and all, but when I tried to use the same classes in another layout (that scrolls the conveyor vertically rather than horizontally), the animation broke! :( Any suggestions on where to look to fix it? Here are my extended classes:

Code: [Select]
// Extend ConveyorSlot to use FillArtwork instances:
class SimpleThumbsStripSlot extends ConveyorSlot
{
m_p=null;
constructor(parent, name)
{
m_p=parent;
base.constructor(FillArtwork(name, 0, 0, THUMB_WIDTH, THUMB_HEIGHT, ::fe, Vid.ImagesOnly));
}

function on_progress(progress, var)
{
m_obj.width = m_p.m_width;
m_obj.height = m_p.m_height;
m_obj.x = m_p.m_x + progress * m_p.m_x_span;
m_obj.y = m_p.m_y + progress * m_p.m_y_span;
}
};

// Extends Conveyor to hold SimpleThumbStripSlot instances:
class SimpleThumbsStrip extends Conveyor
{
transition_ms=100;

m_x=0; m_y=0; m_width=0; m_height=0; m_x_span=0; m_y_span=0;

constructor (name, num_objs, x, y, w, h, p=0)
{
base.constructor();

local my_list=[];
for(local i=0; i<num_objs; i++)
{
my_list.push(SimpleThumbsStripSlot(this, name));
}

local new_selection_index=(my_list.len()>=5) ? 4 : my_list.len()-1;

set_slots( my_list, new_selection_index );

m_x=x+p/2; m_y=y+p/2;
if (w < h)
{
m_x_span=0;
m_y_span=h;
m_width=w-p;
m_height=(h/m_objs.len())-p;
}
else
{
m_x_span=w;
m_y_span=0;
m_width=(w/m_objs.len())-p;
m_height=h-p;
}

reset_progress();

::fe.add_transition_callback(this, "on_transition");
::fe.add_signal_handler(this, "on_signal")
}

function on_transition(ttype, var, ttime)
{
switch (ttype)
{
case Transition.FromOldSelection:
case Transition.ToNewSelection:
case Transition.ToNewList:
case Transition.StartLayout:
break;
}

return false;
}

function on_signal(signal)
{
// ::print ("signal: "+signal+"\n");
switch (signal)
{
case "up":
transition_swap_point=0.8;
break;

case "down":
transition_swap_point=0.2;
break;
}

return false;
}
};

Here's what the "new" layout looks like (wip):


Bgoulette

  • Sr. Member
  • ****
  • Posts: 116
  • I wrote a book.
    • View Profile
    • BlakeGoulette.com
Re: Help me wrap my head around the Conveyor module!
« Reply #10 on: November 30, 2015, 07:26:53 AM »
I realized what I did wrong: I created new on_transition and on_signal handlers that overrode the originals. After renaming my functions, the animation works again. Woo!

raygun

  • Administrator
  • Sr. Member
  • *****
  • Posts: 393
    • View Profile
Re: Help me wrap my head around the Conveyor module!
« Reply #11 on: December 03, 2015, 11:28:08 PM »
Edit 2: Now I'm noticing that as I advance the conveyor (SimpleArtStrip variant), the last item (a FillArtwork instance) updates at the end of the transition. Where would I look to force the update to take place before the transition begins? Or is that even possible? I ask because the update needs to run, but running at the end of the transition causes a visual hiccup as the fill is reapplied. Thanks!

Hi Bgoulette, not sure if you sorted this out, but there is a "transition_swap_point" member variable in the Conveyor object that controls when the update takes place during the transition.  Setting this value to 0 has it at the beginning, 1 is at the end, 0.5 is in the middle... default value is 0.5
hope that helps.