-- Sprite: custom sprite class for handling rendering spritesheet frames and animations Sprite = {} Sprite.__index = Sprite function Sprite:new(image, config) self = setmetatable({}, Sprite) self.image = image self.width = config and config.size and config.size[1] or 16 self.height = config and config.size and config.size[2] or 16 self.animations = config and config.animations or {} self.animationFrameDuration = config and config.fps and (config.fps / 100) or 0.15 self.animationFrameTimer = 0 self.currentAnimationName = nil self.currentAnimation = {} self.currentAnimationFrameIndex = 1 -- create quads self.quads = {} local imageWidth = self.image:getWidth() local imageHeight = self.image:getHeight() local framesPerRow = math.floor(imageWidth / self.width) local totalFrames = framesPerRow * math.floor(imageHeight / self.height) for i = 1, totalFrames do local row = math.floor((i - 1) / framesPerRow) local col = (i - 1) % framesPerRow self.quads[i] = love.graphics.newQuad(col * self.width, row * self.height, self.width, self.height, imageWidth, imageHeight) end return self end function Sprite:update(dt) if self.currentAnimation then self.animationFrameTimer = self.animationFrameTimer + dt if self.animationFrameTimer >= self.animationFrameDuration then self.animationFrameTimer = self.animationFrameTimer - self.animationFrameDuration self.currentAnimationFrameIndex = self.currentAnimationFrameIndex + 1 if self.currentAnimationFrameIndex > #self.currentAnimation then self.currentAnimationFrameIndex = 1 end end end end function Sprite:drawFrame(x, y, frame, options) if not self.image or not self.quads or not self.quads[frame or 1] then return end local angle = options and options.angle or 0 local scaleX = options and options.scale and options.scale[1] or 1 local scaleY = options and options.scale and options.scale[2] or 1 local originOffsetX = options and options.origin and options.origin[1] or 0 local originOffsetY = options and options.origin and options.origin[2] or 0 love.graphics.draw(self.image, self.quads[frame or 1], math.floor(x), math.floor(y), angle, scaleX, scaleY, originOffsetX, originOffsetY) end function Sprite:setAnimation(name) if self.currentAnimationName ~= name and self.animations[name] then self.currentAnimationName = name self.currentAnimation = self.animations[name] self.currentAnimationFrameIndex = 1 self.animationFrameTimer = 0 end end function Sprite:getAnimationFrame() return self.currentAnimation and self.currentAnimation[self.currentAnimationFrameIndex or 1] or 1 end function Sprite:drawAnimationFrame(x, y, options) local frame = self:getAnimationFrame() self:drawFrame(x, y, frame, options) end