Transparent part of sprite

BlitzMax Forums/BlitzMax Programming/Transparent part of sprite

Hi to all.
In my game scene i have a background layer, then the next layer witch contains moving sprites of smoke clouds. I want to make a radial transparency around mouse pointer -- to explore the background by mouse moving. This 'window' must be radial. Any advices?

a png with alpha mask.

smilertoo, could you please show me a simple example of how that 'alpha mask' works? Note that i have a layer of sprites, not just one sprite. Thanks for answer!

No, ive never done it.

Just create a PNG with an Alpha mask in your favourite paint program.

You should enable ALPHABLEND for it to show properly in BlitzMax. eg.
SetBlend ALPHABLEND

otherwise, you just get a solid background - where it should be transparent.

something like this ?

Strict

Graphics 800, 600, 0

SetClsColor 166, 166, 166

Type appLightCircle

  Field lightRadius:Int =100
  Field lightCirleImage:TImage
  
  Method CreateCircleLight:Timage(curLightRadius:Int =100)

    lightRadius =curLightRadius

    Local newImage:Timage =CreateImage(lightRadius *2, lightRadius *2, 1, DYNAMICIMAGE)
    Local newPixmap:TPixmap =LockImage(newImage, 0)
    ClearPixels(newPixmap)
    For Local x:Int =0 To newPixmap.width -1
      For Local y:Int =0 To newPixmap.height -1
        Local curDistance:Float =Sqr((lightRadius -y) *(lightRadius -y) +(lightRadius -x) *(lightRadius -x))
        Local curAlpha:Int =255
        If curDistance <lightRadius Then
          curAlpha :*curDistance /lightRadius
        End If
        WritePixel(newPixmap, x, y, (curAlpha Shl 24) +(0 Shl 16) +(0 Shl 8) + 0)
      Next
    Next

    UnlockImage(newImage, 0)

    lightCirleImage =newImage

  End Method

  Method Render(curX:Int, curY:Int, lightR:Int =255, lightG:Int =255, lightB:Int =255)

    SetBlend ALPHABLEND
    SetColor 0, 0, 0
    SetAlpha 1
    SetScale 1, 1 
    SetRotation 0

    DrawRect 0, 0, GraphicsWidth(), curY -lightRadius
    DrawRect 0, curY +lightRadius, GraphicsWidth(), GraphicsHeight() -curY -lightRadius
    DrawRect 0, curY -lightRadius, curX -lightRadius, 2 *lightRadius
    DrawRect curX +lightRadius, curY -lightRadius, GraphicsWidth() -curX -lightRadius, 2 *lightRadius
    SetColor lightR, lightG, lightB
    DrawImage lightCirleImage, curX -lightRadius, curY -lightRadius

  End Method

End Type


Local lightCircle:appLightCircle =New appLightCircle
lightCircle.CreateCircleLight(300)

HideMouse 

'make us some Images for the worlds scene :
'BACKGROUND
Cls
SetBlend SOLIDBLEND
SetColor 0, 0, 0
DrawRect 1, 1, 10, 3
SetColor 255, 0, 0
DrawRect 1, 4, 10, 3
SetColor 255, 255, 0
DrawRect 1, 7, 10, 3
Local backImage:TImage =CreateImage(10, 9, 1, DYNAMICIMAGE)
GrabImage backImage, 1, 1, 0

'FOREGROUND
Type appSprite

  Field x:Float
  Field y:Float
  Field vx:Float 'pixel per second
  Field vy:Float 'pixel per second 
  Field img:TImage
  Field lastUpdatet:Int

  Method CreateSprite(curX:Int =0, curY:Int, curVX:Int, curVY:Int)

    Cls
    SetColor 255, 255, 0
    DrawRect 1, 1, 110, 25
    SetColor 255, 0, 0
    DrawRect 111, 1, 110, 25
    SetColor 0, 0, 255
    DrawRect 1, 26, 110, 25
    SetColor 255, 255, 255
    DrawRect 111, 26, 110, 25
    img =CreateImage(220, 50, 1, DYNAMICIMAGE)
    GrabImage img, 1, 1, 0

    x =curX
    y =curY
    vx =curVX
    vy =curVY

  End Method

  Method Render()

    SetScale 1, 1
    If lastUpdatet =0 Then
      lastUpdatet =MilliSecs()
    Else
      Local deltaX:Float =vx *(MilliSecs() -lastUpdatet) /1000
      Local deltaY:Float =vy *(MilliSecs() -lastUpdatet) /1000
      lastUpdatet =MilliSecs()
      x :+deltaX
      y :+deltaY
      If x >GraphicsWidth() Then 
        x =0
      ElseIf x <0 Then
        x =GraphicsWidth()
      End If
      If y >GraphicsHeight() Then 
         y =0
      ElseIf y <0 Then
         y =GraphicsHeight()
      End If
    End If
    DrawImage(img, x, y)

  End Method

End Type

Local sprites:appSprite[7]
For Local z:Int =0 To 6
  sprites[z] =New appSprite
  sprites[z].CreateSprite(Rand(100, 700), Rand(100, 500), Rand(-100, 100), Rand(-100, 100))
Next

Repeat

 Cls
 'background
 SetScale GraphicsWidth() /backImage.width, GraphicsHeight() /backImage.height
 DrawImage(backImage, 0, 0) 

 'world
 For Local z:Int =0 To 6
   sprites[z].Render()
 Next

 'lights range
 lightCircle.Render(MouseX(), MouseY())

 Flip

Until KeyHit(KEY_ESCAPE)
 


He would like a movable "window" through a layer of images. In theory, you would need a separate alpha mask applied to images on this layer. I guess this could be achieved with pixmaps, but required code would be complicated and slow.

Actually i am, Jur's right. As i see, there is no easy solution to do this.. Anyway, thanks to all!

Reading your post again I think you might something mean like this (quick hack, needs lot of optimization, but runs already nice on my Notebook - also try the alternatives of displaying the scopes circle)...if this again isn't what you are looking for then then I finally be quiet ;)

Strict

Graphics 800, 600, 0

SetClsColor 166, 166, 166



Type appSpyScope

  Field scopeRadius:Int =0
  Field scopeImage:TImage
  Field spyImage:Timage

  Field alphaValues:Int[,]
  
  Method CreateSpyScope:Timage(curScopeRadius:Int =100)

    scopeRadius =curScopeRadius
    alphaValues =New Int[2 *curScopeRadius, 2 *curScopeRadius]

    scopeImage =CreateImage(curScopeRadius *2, curScopeRadius *2, 1, DYNAMICIMAGE)
    spyImage =CreateImage(curScopeRadius *2, curScopeRadius *2, 1, DYNAMICIMAGE)

    For Local x:Int =0 To 2 *curScopeRadius -1
      For Local y:Int =0 To 2 *curScopeRadius -1
        Local curDistance:Float =Sqr((curScopeRadius -y) *(curScopeRadius -y) +(curScopeRadius -x) *(curScopeRadius -x))
        Local curAlpha:Int =0
        If curDistance <curScopeRadius Then
          curAlpha =255 -(255 *curDistance) /curScopeRadius
        End If
        alphaValues[x, y] =curAlpha 
      Next
    Next

  End Method

  Method Spy(curX:Int, curY:Int)

    Local scopePixmap:TPixmap =LockImage(scopeImage, 0)

    GrabImage(spyImage, curX -scopeRadius , curY -scopeRadius) 
    Local spyPixmap:TPixmap =LockImage(spyImage, 0)
    For Local x:Int =curX -scopeRadius To curX +scopeRadius -1
      For Local y:Int =curY -scopeRadius To curY +scopeRadius -1
        Local spyARGB:Int =ReadPixel(spyPixmap, x -curX +scopeRadius, y -curY +scopeRadius)
        Local spyRed:Int  =(spyARGB Shr 16) & $FF
        Local spyGreen:Int=(spyARGB Shr 8) & $FF
        Local spyBlue:Int =spyARGB & $FF
' ALTERNATIVES...
'        WritePixel(scopePixmap, x -curX +scopeRadius, y -curY +scopeRadius, (alphaValues[x -curX +scopeRadius, y -curY +scopeRadius] Shl 24) +(spyRed Shl 16) +(spyGreen Shl 8) +spyBlue)
'....
        If alphaValues[x -curX +scopeRadius, y -curY +scopeRadius] >0 Then
          WritePixel(scopePixmap, x -curX +scopeRadius, y -curY +scopeRadius, (255 Shl 24) +(spyRed Shl 16) +(spyGreen Shl 8) +spyBlue)
        End If  
'....
'         If alphaValues[x -curX +scopeRadius, y -curY +scopeRadius] >0 Then
'           WritePixel(scopePixmap, x -curX +scopeRadius, y -curY +scopeRadius, (155 Shl 24) +(spyRed Shl 16) +(spyGreen Shl 8) +spyBlue)
'         End If
      Next
    Next
    UnlockImage(spyImage, 0)
    UnlockImage(scopeImage, 0) 
 
  End Method

  Method Render(curX:Int, curY:Int, lightR:Int =255, lightG:Int =255, lightB:Int =255)

    SetBlend ALPHABLEND
    SetColor lightR, lightG, lightB
    SetAlpha 1
    SetScale 1, 1 
    SetRotation 0

    DrawImage scopeImage, curX -scopeRadius, curY -scopeRadius

  End Method

End Type

Local scope:appSpyScope =New appSpyScope
scope.CreateSpyScope(100)

HideMouse 

'make us some Images for the worlds scene :

'NEAR BACKGROUND
Cls
SetBlend SOLIDBLEND
SetColor 0, 0, 0
DrawRect 1, 1, 10, 3
SetColor 255, 0, 0
DrawRect 1, 4, 10, 3
SetColor 255, 255, 0
DrawRect 1, 7, 10, 3
Local backImage:TImage =CreateImage(10, 9, 1, DYNAMICIMAGE)
GrabImage backImage, 1, 1, 0

'FOREGROUND
Type appSprite

  Field x:Float
  Field y:Float
  Field vx:Float 'pixel per second
  Field vy:Float 'pixel per second 
  Field img:TImage
  Field lastUpdatet:Int

  Method CreateSprite(curX:Int =0, curY:Int, curVX:Int, curVY:Int)

    Cls
    SetColor 255, 255, 0
    DrawRect 1, 1, 110, 25
    SetColor 255, 0, 0
    DrawRect 111, 1, 110, 25
    SetColor 0, 0, 255
    DrawRect 1, 26, 110, 25
    SetColor 255, 255, 255
    DrawRect 111, 26, 110, 25
    img =CreateImage(220, 50, 1, DYNAMICIMAGE)
    GrabImage img, 1, 1, 0

    x =curX
    y =curY
    vx =curVX
    vy =curVY

  End Method

  Method Render()

    SetScale 1, 1
    If lastUpdatet =0 Then
      lastUpdatet =MilliSecs()
    Else
      Local deltaX:Float =vx *(MilliSecs() -lastUpdatet) /1000
      Local deltaY:Float =vy *(MilliSecs() -lastUpdatet) /1000
      lastUpdatet =MilliSecs()
      x :+deltaX
      y :+deltaY
      If x >GraphicsWidth() And vx >0 Then 
        x =-img.Width
      ElseIf x <0 And vx <0 Then
        x =GraphicsWidth() +img.Width
      End If
      If y >GraphicsHeight() And vy >0 Then 
         y =img.Height
      ElseIf y <0 And vy <0 Then
         y =GraphicsHeight() +img.Height
      End If
    End If
    DrawImage(img, x, y)

  End Method

End Type


Local sprites:appSprite[7]
For Local z:Int =0 To 6
  sprites[z] =New appSprite
  sprites[z].CreateSprite(Rand(100, 700), Rand(100, 500), Rand(-100, 100), Rand(-100, 100))
Next

Local spritesFAR:appSprite[7]
For Local z:Int =0 To 6
  spritesFAR[z] =New appSprite
  spritesFAR[z].CreateSprite(Rand(100, 700), Rand(100, 500), Rand(-100, 100), Rand(-100, 100))
Next


Repeat

 Cls
 
 ' FAR background
 SetColor 255, 0, 0
 DrawRect 0, 0, GraphicsWidth() /3, GraphicsHeight()
 SetColor 255, 255, 255
 DrawRect GraphicsWidth() /3 +1, 0, GraphicsWidth() /3, GraphicsHeight()
 SetColor 0, 0, 255
 DrawRect 2 *GraphicsWidth() /3 +1, 0, GraphicsWidth() /3, GraphicsHeight()
 SetColor 255, 255, 255

 ' FAR foreground
 For Local z:Int =0 To 6
   spritesFAR[z].Render()
 Next

 scope.Spy(MouseX(), MouseY())

 'NEAR background
 SetScale GraphicsWidth() /backImage.width, GraphicsHeight() /backImage.height
 DrawImage(backImage, 0, 0) 

' scope.Render(MouseX(), MouseY())

 'NEAR world
 For Local z:Int =0 To 6
   sprites[z].Render()
 Next

 scope.Render(MouseX(), MouseY())

 Flip

Until KeyHit(KEY_ESCAPE)



Yes!! It is what i was looking for! Thanks, xMicky.