How do I scale a sprite in place at its current position?

I’m trying to make a game for my daughter and teach her how to program. We want to be able to make a sprite bigger and smaller via a Scale parameter slider.

We’ve made a new class for the character, called SuperKittyGirl, and successfully linked the Scale parameter to make the sprite bigger, but as the sprite grows in size, its position changes by moving up and to the right from its current position instead of simply growing bigger from its current position. I want the sprite to grow bigger around the central point of the sprite.

I’ve looked around and it seems the scale operation is scaling the whole view instead of just the sprite. I’ve tried to wrap my head around how I could use translate to fix the issue without success. (and I bet I’ll run into issues when I want to rotate the sprite around a central anchor point)

Can someone give me some pointers on how to accomplish this? Code for the SuperKittyGirl class is below. Thanks!

-Michael


-- SuperKittyGirl class

SuperKittyGirl = class()

function SuperKittyGirl:init(x, y)
    -- you can accept and set parameters here
    self.x = x
    self.y = y
    --self.position.x = x
    --self.position.y = y
    self.speed = 20
    self.image = readImage("Planet Cute:Character Cat Girl")
    self.halfwidth = self.image.width / 2
    self.halfheight = self.image.height / 2
end

function SuperKittyGirl:draw(cx, cy)
    pushMatrix()
    --translate(self.x, self.y)
    scale(Scale, Scale)
    sprite(self.image, self.x, self.y)
    popMatrix()
    -- Codea does not automatically call this method

    -- normalize accelerometer measurement
    gx = Gravity.x - cx
    gy = Gravity.y - cy
    if math.abs(gx) < 0.01 then
        gx = 0.0
    else
        gx = gx - 0.01
    end
    if math.abs(gy) < 0.01 then
        gy = 0.0
    else
        gy = gy - 0.01
    end
    
    self.x = self.x + (gx * self.speed)
    self.y = self.y + (gy * self.speed)
    
    if (self.x + self.halfwidth) > WIDTH then
        self.x = WIDTH - self.halfwidth
    end
    if (self.x) < 0 + self.halfwidth then
           self.x = self.halfwidth
    end
    if (self.y) > HEIGHT then
           self.y = HEIGHT
    end
    if (self.y) < 0 then
           self.y = 0
    end
end

function SuperKittyGirl:touched(touch)
    -- Codea does not automatically call this method
    
end


It seems that you had everything almost in place. This:


    pushMatrix()
    sprite(self.image, self.x, self.y)
    popMatrix()

is equal to this:


    pushMatrix()
    translate(self.x, self.y)
    sprite(self.image, 0, 0)
    popMatrix()

Instead of telling the sprite where it has to draw itself, translate the matrix and draw the sprite at 0, 0. It’s the same. It seems that you already played with translate, but not enough. Now you can scale the view:


    pushMatrix()
    translate(self.x, self.y)
    scale(Scale, Scale)
    sprite(self.image, 0, 0)
    popMatrix()

All transformations add up, so if you scale and then transform, the latter will be scaled as well. If leave the correct placement of rotation as a homework for you.

Excellent, it occurred to me after I submitted that I might be able to move the sprite to 0,0 and scale from there, but I hadn’t gotten a chance to test that yet. Thank you, this works marvelously! This also gives me the answer I need on how to keep a rotate centered as well! :slight_smile: