Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Codeas sprite drawer should have rotation.

edited September 2013 in General Posts: 17

I don't know if it's because of my ignorence, or is it that this is truely a problem. please fix me if I'm wrong. But I think the current sprite drawer ("sprite(texture, x, y)") is just stupid when the sprite needs rotation. Simeon suggests we draw it at 0,0 ("sprite(texture, 0,0)") then rotate it (the rotate method rotates at 0,0) then move it with translate. I think this is really stupid.
This is no biggie I understand, because we can just create a wrapper to hide this. But why not instead add another parameter to sprite(texture,x,y,angle)?

Tagged:

Comments

  • edited September 2013 Posts: 580

    What if you want to rotate the sprite around a point that's not at it's center? What if you you want a sprite to be rotated around another sprite? What if you also want to scale the sprite; should another parameter be added for that? What if you want to scale the x and y axes separately? I think you see where I'm going with this. The way that Codea handles rotation etc is a pretty common way of doing it, is very flexible, and works quite well.

    Also, sprite already has a load of parameters. Adding more would just make the interface more confusing, not less.

  • edited September 2013 Posts: 371

    Why don't you implement it yourself?? It could be a learning experience!

    local _sprite = sprite
    function sprite(s, x, y, w, h, a) -- sprite, x, y, width, height, angle
        x = x or 0
        y = y or 0
        w = w or readImage(s).width
        h = h or readImage(s).height
        a = a or 0
        pushMatrix()
            translate(x, y)
            rotate(a)
            _sprite(s, 0, 0, w, h)
        popMatrix()
    end
    

    Well, I already did :) Just add it as a dependency to any project and it should run as is

  • "What if you want to rotate the sprite around a point that's not at it's center? What if you you want a sprite to be rotated around another sprite? What if you also want to scale the sprite;..." -- toadkick

    If we need those functions you mentioned @toadkick then we would use the rotate() and scale(). But if I just needed a rotate an single image, maybe in my humble opinion it's worth adding a "angle" parameter in sprite().

  • edited September 2013 Posts: 17

    thank you @Jordan, I do understand your approach, and it is my method already. I'm just trying to suggest to Codea that it might be more convient as a optional parameter in the sprite() function. (just like the optional parameter "width" & "height")

  • edited September 2013 Posts: 580

    See, my problem isn't that we have a difference of opinion, it's that you are calling somebody's hard and well thought out work stupid. In 2 different threads. Why would anyone want to do anything for you with an attitude like that? The reason the interface shouldn't be changed is because there is nothing stopping you from doing what you want, as @Jordan has shown. Again, why complicate the interface for everyone to enable a tiny bit of convenience for one person?

  • IgnatzIgnatz Mod
    Posts: 5,396

    I agree, calling it stupid is rude, and out of place in this forum

  • I'm sorry, I couldn't think of any nicer words to explain my thoughts, I didn't mean to be rude. I'm from China so please excuse my english (Poor vocab). What I'm really trying to say is something like, ......hard? or..... incomplete.

    Please, as I also said in my thread. I know my opinon could be bad because of my ignorence, I'm not some pro game dev and I know that, so all I'm doing here is just stateting my own opinon and see if anyone can teach me something. Also I'm not here to get a moral lesson, my original opinon was not meant to be offensive to anyone. @toadkick

  • @ignatz I'm sorry to use an offensive word, my really didn't mean to be offensive when using it.

  • edited September 2013 Posts: 17

    Back to the actual topic, the sprite() function does have scalers; the width and the height parameters.

    so if it has scalers then why not have rotaters?

  • SimeonSimeon Admin Mod
    edited September 2013 Posts: 5,054

    I like the idea of adding angle to sprite, but I can't think of a good way to extend the API.

    sprite() takes the following forms:

    sprite( img )
    sprite( img, x, y )
    sprite( img, x, y, w ) -- height is computed aspect correct
    sprite( img, x, y, w, h ) -- arbitrary scale allowed

    If we were to simply stick an angle parameter to get:

    sprite( img, x, y, w, h, a ) then you would always need to specify an explicit width and height in order to also specify an angle. This means you would need to do the following:

    local w,h = spriteSize( "MySprite" )
    sprite( img, x, y, w, h, angle )

    Each time you wanted to use the angle parameter.

    It would be nice to have a form that did not require an explicit scaling. Though I am unsure if it's possible. Any ideas?

    Edit: One idea that comes to mind is to allow an advanced sprite mode that takes a table. Could be messy, however.

    sprite( img, { x=0, y=0, a=45 } )

    This would allow specifying an angle without an explicit size. We could also then allow custom texture coordinates to be specified in the table, and so on.

  • @Simeon , I thinks it's fine as is - its never been a problem (even when I was a Noob!) and could make things even more complicated i guess :-/

  • Jmv38Jmv38 Mod
    Posts: 3,295

    @simeon i agree with the general opinion expressed above (namely: it is fine the way it is), but just for the sake of discusssion, wouldnt this work? And if not, why?

    sprite( img, x, y, nil, nil, angle )
    
  • Jmv38Jmv38 Mod
    edited September 2013 Posts: 3,295

    @loolo78 i see from your replies that you have been an unfortunate victim of the 'mail magnification effect'. Things that are completly ok in oral discusssion (like 'but this is stupid!') become rude and agressive when written directly in a mail or a post. Professionnally i've learned (the hard way...) a long time ago that in mail you have to divide by 10 the amplitude of your verbal criticisms if you want them to be received the way you meant them... Some years ago we had a great manager who set the following rule: 'mail has to be limited to facts, never put emotionnal things in a mail, this is not appropriate. When you need to be emotionnal, go and tell the person directly'. Of course on this forum we are 1000 km apart so we cant tell directly... So we must remain factual!

  • Posts: 738

    While the way @loolo78's puts across the point could be done in a much more constructive manner, I agree with his/her underlying point.

    I think sprite rotation is something that would be a nice useful addition for Codea, particularly for beginners.

    The sprite function is an easier way into displaying images on the screen (than for example using meshes, which incidentally has the option for specifying a rotation) but in earlier versions of codea used to be a lot slower when lots of sprites were on the screen.

    I take @toadkick's point of writing it yourself, but there is nothing wrong with suggesting an improvement to an existing function, particularly as it could be added as an optional extra parameter which wouldn't alter any existing functionality

  • SimeonSimeon Admin Mod
    Posts: 5,054

    @Jmv38 interesting idea. So we could allow:

    sprite( name, x, y, nil, nil, a )

    and

    sprite( name, x, y, w, nil, a ) -- for auto aspect

    This looks a little unreadable to me. But it's probably the best solution.

  • edited September 2013 Posts: 580

    IMO the 'w' and 'h' parameters are already too much, and ultimately are unnecessary. I've never used them, I think the 'scale' function is a more sensible and flexible way to do it, just like I think the 'rotate' function is more sensible and flexible to rotate a sprite (vs. adding an optional 'angle' parameter).

    Allowing "nil" ameliorates the problem of how to specify multiple optional parameters, but that makes for a pretty confusing an often unreadable interface too. Passing a table with named parameters is generally the best solution, but in this case I'm not a fan because 'sprite' is a frequently called function, and adding the overhead of creating (and garbage collecting) a new table every time you want to draw a sprite seems unnecessarily wasteful. As an alternate (optional) API I suppose either one of these are okay, but in general more artificial options just generally leads to more confusion, and I honestly just don't think it's worth it to make something that is already simple to do a tiny bit simpler.

    Food for thought: would it make sense to add an angle param to 'sprite', but not to 'text', 'rect', 'ellipse', and 'line' as well?

  • SimeonSimeon Admin Mod
    Posts: 5,054

    I can see how it makes sense to add to sprite, and perhaps text — the API is not intended to be equivalent across primitives, but useful across primitives.

    Personally I use the width parameter quite a lot (though not height, as I usually want a simple aspect correct scaling).

    I also dislike the required nil arguments in order to implement angle at the end of the list.

  • edited September 2013 Posts: 580

    "I can see how it makes sense to add to sprite, and perhaps text — the API is not intended to be equivalent across primitives, but useful across primitives."

    Fair enough, and a good answer.

    I think probably the option to specify a table with named parameters is the best compromise, though I'm still dubious that it actually makes anything simpler than it already is. Being able to specify texture coordinates is intriguing though, and it's something I've wanted for awhile. If a named params table is what it takes to get that, then I'm sold :)

  • dave1707dave1707 Mod
    Posts: 7,810

    @Simeon Maybe something along these lines could work.

    existing sprite

    sprite(img,x,y,w,h)
    

    to use an angle with sprite

    sprite.angle=degrees
    sprite(img,x,y,w,h)  -- existing call using the angle  (0 default)
                      -- angle stays at degrees until another sprite.angle call
    
  • @dave1707 sprite isn't a table, though, it's a function. I suppose it could be a table or a class, with the normal sprite function as its _call, but it feels odd to me. Maybe using local i = readImage(img, angle) or local i = readImage(img) i.angle = *angle*? I have wanted width and height parameters to readImage(), though...

    I think my favorite is sprite(img, parameterTable).

  • Jmv38Jmv38 Mod
    Posts: 3,295

    I think all this becomes quite compicated, while

        pushMatrix()
            translate(x, y)
            rotate(a)
            sprite(s)
        popMatrix()
    

    is really clear, compact and fine. Isnt it?

  • @Jmv38: exactly :D

  • So we come full circle ;-) I like the way it currently works. Its flexible enough to support a range of individual ordered transforms, sometimes you will want to order them in different ways other than rotating the sprite first. Understanding this (even for noobs) is pretty important. ;-)

  • Posts: 738

    @Jmv38 it is clear, compact and fine once you have a bit of programming experience under your belt. So I am with you 100% and I too like the current way that it works.

    However, for a novice I would argue it's pretty complex. As someone starting out, I want to plonk a sprite on the screen. Great there is a command for that. When I type it, a window appears which lets me pick the image I want to put on the screen. I need to tell the function where to put it on the screen? OK so I need to give it an x and y position. Simple enough. Plus there's options to change the size - great.

    Now I want to rotate the sprite - a fairly common thing to do when you are starting out. So, I can't simply tell the sprite function how much to rotate the sprite? So, first I need to start with the pushMatrix() command and finish with the popMatrix() command. What is the purpose of these commands? Seems complex, but lets just accept them for the moment. Now what's this translate command? That's where I put the x and y position of the sprite. I thought that was set in the sprite() command? No, the sprite command should now contain the coordinates of the bottom left of the screen and the translate command will hold the x and y position and move the sprite from the bottom left to the desired position. OK. Next there is the rotate command - the command that actual rotates the sprite. Just enter the amount of rotation into the function. One more thing to note. The order of these commands matters, and the order they are executed starts from the bottom and works up (place the sprite in the bottom left, rotate it then move it to the desired position), which for someone starting out might seem counterintuitive. Changing the order of rotate and translate will give you a different result.

    I understand the advantages of the existing method, but I certainly found it confusing when I was starting out and am pretty sure other people do. So while I find it clear, compact and fine, I can also see why it is unclear, unnecessarily long and not fine for a beginner. Having said this, I can't offer a solution which keeps the existing advanced users happy as well as making it as easy as possible for beginners. I think @dave1707's suggestion for a global current rotation which any subsequent sprite call inherits is about the best so far.

  • IgnatzIgnatz Mod
    edited September 2013 Posts: 5,396

    Unless rotate becomes a property of an image, rather than a parameter of sprite, this is consistent with setRect! which has a rotation parameter

Sign In or Register to comment.