How do I randomize an NPC object sprite color palettes onDraw while rotating? (solved)

Post here for help and support regarding LunaLua and SMBX2's libraries and features.

Moderator: Userbase Moderators

cato
Volcano Lotus
Volcano Lotus
Posts: 564
Joined: Thu Aug 24, 2017 3:06 am
Flair: Koishi enjoyer
Contact:

How do I randomize an NPC object sprite color palettes onDraw while rotating? (solved)

Postby cato » Sun Aug 07, 2022 10:16 am

Currently, I have the horizontal sprite sheet of an NPC object (1 frame) with the others being the same but different color palettes next to the original one. In my custom NPC Lua file, I can't seem to have it randomize the starting color and rotate simultaneously.

I have tried once or twice just randomizing the color (without the rotation) in the onDraw function. I used a random value to determine where the image should source from (in terms of pixels). However, either the NPCs were stuck with one color at a time or the NPC is flashing like a Disco shell.

I did get the rotation to work (thanks to SetaYoshi's wormhole) in terms of creating a sprite. The problem is that I can't try the same with the color randomization. When I override the sprite sheet, it stretches to the object's size (32x32) instead of sourcing the sprite from a particular position. Besides that, I am unable to come up with where I should put my randomizer in (especially the sourceX part), as well as some other details between the sprite initialization and the onDraw function. Putting the parts in either places don't do anything.

Here is the NPC Lua code in question:
Spoiler: show

Code: Select all

local npcManager = require("npcManager")
local npcutils = require("npcs/npcutils")
local rng = require("rng")

-- Settings
-- Harmtypes

local iniNPC = function(v)
	local config = NPC.config[v.id]
	if not v.data.ini then
	  	v.data.ini = true
		v.data.sprite = Sprite.box{
			x = v.x,
			y = v.y,
			width = 32,
			height = 32,
			texture = Graphics.sprites.npc[v.id].img,
			rotation = 0,
			align = Sprite.align.CENTRE,
			frames = npcutils.getTotalFramesByFramestyle(v)
		}
	end
end

function myNPC.onTickEndNPC(v)
	iniNPC(v)
	v.data.sprite:rotate(12 * v.direction)

        -- NPC behaviors
end

function myNPC.onDrawNPC(v)
	if v:mem(0x12A, FIELD_WORD) <= 0 then
        return end

	local config = NPC.config[v.id]
	local p = -45

	if config.foreground then	p = -15	end
	v.data.sprite.x = v.x + v.width*0.5 + config.gfxoffsetx
	v.data.sprite.y = v.y + v.height*0.5 + config.gfxoffsety
	v.data.sprite:draw{priority = p - 0.1, sceneCoords = true, frame = v.animationFrame + 1}

	npcutils.hideNPC(v)
end

return myNPC;
And the lines/parts I probably needed to add:
Spoiler: show

Code: Select all

local smallballs = Graphics.loadImageResolved("smallballs.png")
Graphics.sprites.npc[752].img = Graphics.loadImage("smallballs.png")
local state = rng.randomInt(0, 7)
sourceX = 32 * state

Many thanks to someone who can help. And I am definitely keeping this useful stuff for future uses.
Last edited by cato on Tue Aug 09, 2022 1:40 pm, edited 1 time in total.

deice
Rocky Wrench
Rocky Wrench
Posts: 638
Joined: Fri Jul 23, 2021 7:35 am

Re: How do I randomize an NPC object sprite color palettes onDraw while rotating?

Postby deice » Sun Aug 07, 2022 4:34 pm

i'd say your biggest issue is the fact that the sprite sheet is horizontal. if you rotate it 90 degrees in an image editor, you could use the following simple solution:

1. load "smallballs"

Code: Select all

local smallballs = Graphics.loadImageResolved("smallballs.png")
(at the start of the file)

2. replace your current "iniNPC" with:

Code: Select all

local iniNPC = function(v)
	local config = NPC.config[v.id]
	if not v.data.ini then
	  	v.data.ini = true
		v.data.color = rng.randomInt(0, 7)
		v.data.sprite = Sprite.box{
			x = v.x,
			y = v.y,
			width = 32,
			height = 32,
			texture = smallballs,
			rotation = 0,
			align = Sprite.align.CENTRE,
			frames = 8
		}
	end
end
3. then in onDrawNPC, replace the draw call with:

Code: Select all

v.data.sprite:draw{priority = p - 0.1, sceneCoords = true, frame = v.data.color}
this is assuming you intend to keep it a 1-frame thing. if each color has to be animated as well, i recommend just using separate images at that point. also, i'm pretty sure you can move the iniNPC() and rotate() calls into onTick instead of onTickEnd

cato
Volcano Lotus
Volcano Lotus
Posts: 564
Joined: Thu Aug 24, 2017 3:06 am
Flair: Koishi enjoyer
Contact:

Re: How do I randomize an NPC object sprite color palettes onDraw while rotating?

Postby cato » Tue Aug 09, 2022 1:33 pm

deice wrote:
Sun Aug 07, 2022 4:34 pm
I added a line

Code: Select all

if v.data.sprite then...end
then right at the Draw function to avoid the error "attempt to index a sprite". It would seem to be a simpler solution to source from a particular frame instead of a particular pixel position.

Nonetheless, thank you for helping, alongside with Marioman2007 who tried with me (and failed) on Discord. Now, I am going to the same thing for another NPC, and hopefully it works when I do it myself.


Return to “LunaLua Help”

Who is online

Users browsing this forum: No registered users and 1 guest

SMWCentralTalkhausMario Fan Games GalaxyKafukaMarioWikiSMBXEquipoEstelari