@@ -45,7 +45,10 @@ module SpriteModule
4545 # effects support
4646 effects:: Vector{Any} # Will hold Effect objects
4747 effectTexture:: Union{Ptr{Nothing}, Ptr{SDL2.LibSDL2.SDL_Texture}}
48+ effectSize:: Math.Vector2 # Size of effect texture (may be larger due to glow padding)
4849 needsEffectUpdate:: Bool
50+ useEffectTexture:: Bool # Toggle to enable/disable effect texture rendering
51+ interactionScale:: Float64 # Scale factor for hover/click hitbox (1.0 = full size, <1.0 = smaller)
4952
5053 function InternalSprite (
5154 parent:: JulGame.IEntity ,
@@ -89,7 +92,10 @@ module SpriteModule
8992 # Initialize effects
9093 this. effects = Any[]
9194 this. effectTexture = C_NULL
95+ this. effectSize = Math. Vector2 (0 , 0 )
9296 this. needsEffectUpdate = false
97+ this. useEffectTexture = true # Default to showing effects when applied
98+ this. interactionScale = 1.0 # Default to full-size hitbox
9399
94100 # Early returns
95101 if isCreatedInEditor
@@ -120,8 +126,8 @@ module SpriteModule
120126 update_effects (this)
121127 end
122128
123- # Use effect texture if available, otherwise use regular texture
124- texture_to_render = if ! isempty (this. effects) && this. effectTexture != C_NULL
129+ # Use effect texture if available and enabled , otherwise use regular texture
130+ texture_to_render = if this . useEffectTexture && ! isempty (this. effects) && this. effectTexture != C_NULL
125131 this. effectTexture
126132 else
127133 # Create texture if it doesn't exist
@@ -132,15 +138,14 @@ module SpriteModule
132138 this. texture
133139 end
134140
135- # Check and set color if necessary (only for regular texture, not effect texture)
136- if texture_to_render == this. texture
137- colorRefs = (Ref (UInt8 (0 )), Ref (UInt8 (0 )), Ref (UInt8 (0 )))
138- alphaRef = Ref (UInt8 (0 ))
139- SDL2. SDL_GetTextureColorMod (this. texture, colorRefs... )
140- SDL2. SDL_GetTextureAlphaMod (this. texture, alphaRef)
141- if colorRefs[1 ] != this. color[1 ] || colorRefs[2 ] != this. color[2 ] || colorRefs[3 ] != this. color[3 ] || this. color[4 ] != alphaRef
142- Component. set_color (this)
143- end
141+ # Check and set color if necessary (for both regular and effect textures)
142+ colorRefs = (Ref (UInt8 (0 )), Ref (UInt8 (0 )), Ref (UInt8 (0 )))
143+ alphaRef = Ref (UInt8 (0 ))
144+ SDL2. SDL_GetTextureColorMod (texture_to_render, colorRefs... )
145+ SDL2. SDL_GetTextureAlphaMod (texture_to_render, alphaRef)
146+ if colorRefs[1 ][] != this. color[1 ] || colorRefs[2 ][] != this. color[2 ] || colorRefs[3 ][] != this. color[3 ] || this. color[4 ] != alphaRef[]
147+ SDL2. SDL_SetTextureColorMod (texture_to_render, UInt8 (clamp (this. color[1 ], 0 , 255 )), UInt8 (clamp (this. color[2 ], 0 , 255 )), UInt8 (clamp (this. color[3 ], 0 , 255 )))
148+ SDL2. SDL_SetTextureAlphaMod (texture_to_render, UInt8 (clamp (this. color[4 ], 0 , 255 )))
144149 end
145150
146151 # Calculate camera difference
@@ -157,7 +162,10 @@ module SpriteModule
157162 # Calculate pixels per unit
158163 ppu = this. pixelsPerUnit > 0 ? this. pixelsPerUnit : JulGame. PIXELS_PER_UNIT
159164
160- # Precompute values to avoid redundant calculations
165+ # Check if using effect texture
166+ usingEffectTex = texture_to_render == this. effectTexture && this. effectSize != Math. Vector2 (0 , 0 )
167+
168+ # Always use original sprite size for positioning calculations
161169 cropWidth = srcRect == C_NULL ? this. size. x : this. crop. z
162170 cropHeight = srcRect == C_NULL ? this. size. y : this. crop. t
163171 scaleX = this. parent. transform. scale. x
@@ -179,7 +187,7 @@ module SpriteModule
179187 scaledHeight = cropHeight * scaleFactor * scaleY
180188 end
181189
182- # Compute position based on anchor
190+ # Compute position based on anchor (using original sprite dimensions)
183191 centeredX = adjustedX
184192 centeredY = adjustedY
185193
@@ -218,6 +226,19 @@ module SpriteModule
218226 centeredX -= (scaledWidth - SCALE_UNITS * scaleX)
219227 centeredY -= (scaledHeight - SCALE_UNITS * scaleY)
220228 end
229+
230+ # AFTER anchor positioning: expand render size for effect texture and offset to center it
231+ if usingEffectTex
232+ scaleFactor = this. pixelsPerUnit == 0 ? (SCALE_UNITS/ 64.0 ) : (SCALE_UNITS / ppu)
233+ effectScaledWidth = this. effectSize. x * scaleFactor * scaleX
234+ effectScaledHeight = this. effectSize. y * scaleFactor * scaleY
235+ # Offset to center the larger effect texture over the original sprite position
236+ centeredX -= (effectScaledWidth - scaledWidth) / 2
237+ centeredY -= (effectScaledHeight - scaledHeight) / 2
238+ # Use effect dimensions for rendering
239+ scaledWidth = effectScaledWidth
240+ scaledHeight = effectScaledHeight
241+ end
221242
222243 # Select float or integer precision
223244 if this. isFloatPrecision
@@ -268,7 +289,7 @@ module SpriteModule
268289
269290 # effects API
270291 function Component. apply_effects! (this:: InternalSprite , effects:: Vector )
271- this. effects = effects
292+ this. effects = Any[effect for effect in effects] # Convert to Vector{Any}
272293 this. needsEffectUpdate = true
273294 update_effects (this)
274295 return this
@@ -291,6 +312,13 @@ module SpriteModule
291312 result = JG. EffectRendererModule. apply_effects! (target, this. effects)
292313 if result isa JG. EffectsModule. SpriteTarget
293314 # Effect texture should be updated by the renderer
315+ # Query the effect texture size and store it
316+ if this. effectTexture != C_NULL
317+ w = Ref {Cint} (0 ); h = Ref {Cint} (0 )
318+ fmt = Ref {UInt32} (0 ); access = Ref {Cint} (0 )
319+ SDL2. SDL_QueryTexture (this. effectTexture, fmt, access, w, h)
320+ this. effectSize = Math. Vector2 (w[], h[])
321+ end
294322 this. needsEffectUpdate = false
295323 end
296324 catch e
@@ -405,6 +433,7 @@ module SpriteModule
405433
406434 function Component. duplicate (this:: InternalSprite , parent:: Any )
407435 newSprite = InternalSprite (parent, this. imagePath, this. crop, this. isFlipped, this. color, false ; pixelsPerUnit= this. pixelsPerUnit, position= this. position, rotation= this. rotation, layer= this. layer, center= this. center, anchor= this. anchor, offset= this. offset, isStatic= this. isStatic)
436+ newSprite. interactionScale = this. interactionScale
408437 Component. initialize (newSprite)
409438 return newSprite
410439 end
0 commit comments