Spherical forums

Sphere Development => Sphere Support => Script Support => Topic started by: Rhuan on December 27, 2016, 08:41:03 pm

Title: Drawing behind and in front...
Post by: Rhuan on December 27, 2016, 08:41:03 pm
Background - I've decided to start making an SRPG in Sphere (there is a 90+% chance I'll never finish it but hey...)

I'd like to have what I call a "spinning ring" as a selection cursor. This is an ellipse rolling up and down on its side - obviously I'd do this in some kind of render script but to show what this ought to look like here's some example code that simply draws the ring:
Code: (javascript) [Select]
function draw_ring(x, y, a, b)
  var ring_s = CreateSurface(2*a + 5,2*b + 5,transparent);
  for(var i = 0, t_x = 0, t_y = 0; i < 200; ++i)
    t_x = a * Math.cos(i*Math.PI/100) + a;
    t_y = b * Math.sin(i*Math.PI/100) + b;
    ring_s.setPixel(t_x, t_y, red);
    ring_s.setPixel(t_x + 1, t_y, red);
    ring_s.setPixel(t_x, t_y + 1, red);
    ring_s.setPixel(t_x - 1, t_y, red);
    ring_s.setPixel(t_x, t_y -1, red);
  var ring = ring_s.createImage();
  for(i = 0; i < 800; ++ i)
   ring.transformBlit(x                                        ,//X1
                      y + b *         Math.cos(i * Math.PI/100),//Y1
                      x + a                                    ,//X2
                      y + b *         Math.sin(i * Math.PI/100),//Y2
                      x + a                                    ,//X3
                      y + b / 2 - b * Math.cos(i * Math.PI/100),//Y3
                      x                                        ,//X4
                      y + b / 2 - b * Math.sin(i * Math.PI/100)); //Y4

Note: I do not expect any part of the above to be final except perhaps the image creation at the top - but this does show what the spinning ring should look like. (note I probably should change this to use the ellipse functions rather than the loop of points though I couldn't immediately see how to do a multi-thickness outlined ellipse particularly not in minisphere which seems to have not implemented the ellipse functions)

Now the problem:
1. from looking at that code (or trying it out) you'll soon see that sometimes the front of the ring is at the top and sometimes the back is at the top.
2. Imagine you have a sprite and this ring is around their feet - you want the front to show in front of them and the back not to. The only ways I can currently think of to do this are to have two seperate images, one for the back half which is drawn before the sprite and one for the front half which is drawn after the sprite - this seems a tad painful

Does anyone have any suggestions of ways to make this better?
Title: Re: Drawing behind and in front...
Post by: Fat Cerberus on December 28, 2016, 02:35:37 am
I didn't realize Sphere 1.x had ellipse-drawing functions, thanks for pointing those out.  I'll add them posthaste :-[  That said, minisphere does have the prim module:

Code: (javascript) [Select]

// note: one can also require() to a local variable - the module is cached
//       and will only be evaluated once.
global.prim = require('prim');

// IMPORTANT: Sphere v2 Color required, CreateColor() won't work here!
prim.lineEllipse(screen, 100, 100, 20, 10, Color.Chartreuse);

Unfortunately there's no support to change the outline thickness yet :(

I recommend studying both of these files to get acquainted with the new way of doing things:

But anyway, to get to the point, I don't think you can do what you want in a single drawing operation.  If you want half of an image in front and half in back of a sprite, then you have to split the rendering into steps like you suggest.  There's no way around that.
Title: Re: Drawing behind and in front...
Post by: Rhuan on December 28, 2016, 06:21:03 am
Maybe it's because I've never worked in C# or perhaps for some other reason; but to me the sphere v2 api seems incredibly complex and hard to understand.

I understand procedural code and I understand the idea of a class with properties including methods that you can make an instance of. I don't really understand many other programming concepts as I've never used them or read any tutorials on them.
Title: Re: Drawing behind and in front...
Post by: Fat Cerberus on December 28, 2016, 06:45:24 am
The core Sphere v2 API is still pretty classical in that regard.  miniRT on the other hand is implemented as modules, and I think what trips people up with require() is the extra level of indirection.  Basically when you say require(whatever) that's the same as Sphere v1 RequireScript(), with the difference being that the functions defined in the script are loaded into a variable rather than just tossing them into the global scope.  There's no real magic to it, it's just better organized.
Title: Re: Drawing behind and in front...
Post by: Rhuan on December 28, 2016, 07:07:17 am
I'm happy with the way require works the things I don't understand are various of the specific modules that seem quite important.

Notably I don't understand how from and dispatch are meant to work - maybe if someone wrote an example game with them that I could pick apart I'd get it for now I'm happy with my largely procedural code...
Title: Re: Drawing behind and in front...
Post by: Fat Cerberus on December 28, 2016, 10:23:14 am
Dispatch at least is easy - say you call Dispatch.onUpdate() and pass it a function.  Now that function gets called every frame.  Or if you call Dispatch.later(60, func), then func() gets called 60 frames from now.  Sphere 1.x has this too, with its update and render scripts, the only difference is that you pass it source code (like eval) instead of a function.