Creating Sprite Masks: Difference between revisions

From QB64 Phoenix Edition Wiki
Jump to navigation Jump to search
(Created page with "Sometimes your program may need to place a shaped sprite over background objects. To do that you cannot use the default PUT using XOR. XOR only works on black backgrounds! It distorts underlying colors. You could use the PSET option, but that places a square sprite only. To get irregularly shaped objects you need to create a "mask" of the sprite. After you have created your sprite with a BLACK background, GET the image to an Arrays|arra...")
 
No edit summary
Line 3: Line 3:
{{small|Code by: Ted Weissgerber}}
{{small|Code by: Ted Weissgerber}}
{{CodeStart}}
{{CodeStart}}
FOR xx = minX TO maxX                                  
FOR xx = minX TO maxX
     FOR yy = minY TO maxY
     FOR yy = minY TO maxY
         IF {{Cl|POINT}}(xx, yy) = 0 THEN {{Cl|PSET}} (xx, yy), 15 ELSE {{Cl|PSET}} (xx, yy), 0
         IF {{Cl|POINT}}(xx, yy) = 0 THEN {{Cl|PSET}} (xx, yy), 15 ELSE {{Cl|PSET}} (xx, yy), 0
Line 12: Line 12:




The mask routine simply changes all black portions of the sprite image to white and all other colors black. If your sprite uses black in it, you will need to assign the areas to another color attribute and change the RGB values to 0 using {{KW|OUT}} or the background will show through the final image. Color 8 could be dark enough.  
The mask routine simply changes all black portions of the sprite image to white and all other colors black. If your sprite uses black in it, you will need to assign the areas to another color attribute and change the RGB values to 0 using {{KW|OUT}} or the background will show through the final image. Color 8 could be dark enough.




GET the background at the sprite's starting position before trying to place a sprite or move it when necessary. Next we position the mask and PUT it with the [[AND]] option. Then the actual sprite is PUT over the mask as shown below:  
GET the background at the sprite's starting position before trying to place a sprite or move it when necessary. Next we position the mask and PUT it with the [[AND]] option. Then the actual sprite is PUT over the mask as shown below:




{{CodeStart}} '' ''
{{CodeStart}}
     GET (x, y)-(x + 60, y + 60), BG  ' GET BG at start position before sprite is set
     GET (x, y)-(x + 60, y + 60), BG  ' GET BG at start position before sprite is set
     PUT (x, y), Mask, {{Cl|AND}}            ' PUT mask at start position
     PUT (x, y), Mask, {{Cl|AND}}            ' PUT mask at start position
     PUT (x, y), Sprite                ' XOR will work fine on a mask '' ''
     PUT (x, y), Sprite                ' XOR will work fine on a mask
{{CodeEnd}}
{{CodeEnd}}




The two PUTs use the same coordinate so moving objects is fairly simple. All you need is a keypress reading loop. Use INP(&H60) [[Scancodes]] for diagonal moves.  
The two PUTs use the same coordinate so moving objects is fairly simple. All you need is a keypress reading loop. Use INP(&H60) [[Scancodes]] for diagonal moves.




Line 40: Line 40:
     PUT (x, y), Sprite                  ' XOR will work fine on the mask
     PUT (x, y), Sprite                  ' XOR will work fine on the mask
END IF
END IF
PX = x: PY = y '' ''
PX = x: PY = y
{{CodeEnd}}
{{CodeEnd}}


Line 50: Line 50:




''See also:''  
''See also:''


* [[INP]], [[Scancodes]](Example 3)
* [[INP]], [[Scancodes]](Example 3)
* [[GET (graphics statement)|GET]], [[PUT (graphics statement)|PUT]]  
* [[GET (graphics statement)|GET]], [[PUT (graphics statement)|PUT]]
* [[Icons and Cursors]]
* [[Icons and Cursors]]
* [[Creating Icons from Bitmaps]]
* [[Creating Icons from Bitmaps]]

Revision as of 01:23, 23 January 2023

Sometimes your program may need to place a shaped sprite over background objects. To do that you cannot use the default PUT using XOR. XOR only works on black backgrounds! It distorts underlying colors. You could use the PSET option, but that places a square sprite only. To get irregularly shaped objects you need to create a "mask" of the sprite. After you have created your sprite with a BLACK background, GET the image to an array. You can BSAVE it if you wish. Then create a mask of the sprite at the sprites current location. Use the GET box area coordinates(minX, maxX and minY, maxY) of sprite in the following routine:

Code by: Ted Weissgerber
FOR xx = minX TO maxX
    FOR yy = minY TO maxY
        IF POINT(xx, yy) = 0 THEN PSET (xx, yy), 15 ELSE PSET (xx, yy), 0
    NEXT yy
NEXT xx
GET (minX, minY)-(maxX, maxY), Mask(0)


The mask routine simply changes all black portions of the sprite image to white and all other colors black. If your sprite uses black in it, you will need to assign the areas to another color attribute and change the RGB values to 0 using Template:KW or the background will show through the final image. Color 8 could be dark enough.


GET the background at the sprite's starting position before trying to place a sprite or move it when necessary. Next we position the mask and PUT it with the AND option. Then the actual sprite is PUT over the mask as shown below:


    GET (x, y)-(x + 60, y + 60), BG   ' GET BG at start position before sprite is set
    PUT (x, y), Mask, AND             ' PUT mask at start position
    PUT (x, y), Sprite                ' XOR will work fine on a mask


The two PUTs use the same coordinate so moving objects is fairly simple. All you need is a keypress reading loop. Use INP(&H60) Scancodes for diagonal moves.


But what about the background? Once you create the background you will need to GET the sprite's box area at the starting position. You can PUT the background back to erase the sprite when moving. PX and PY are the previous x and y positions before they were changed by the user in a keypress routine:


  'user keypress or programmed coordinate changes
IF x <> PX OR y <> PY THEN               ' look for a changed coordinate value
    WAIT 936, 8                          ' vertical retrace delay
    PUT (PX, PY), BG, PSET               ' replace previous BG first
    GET (x, y)-(x + 60, y + 60), BG      ' GET BG at new position before box is set
    PUT (x, y), Mask, AND                ' PUT mask at new position
    PUT (x, y), Sprite                   ' XOR will work fine on the mask
END IF
PX = x: PY = y


In QB64 _CLEARCOLOR can also be used before using _PUTIMAGE to mask any sprite background color.


See the GET and PUT Demo to see how it works!


See also:



Navigation:
Main Page with Articles and Tutorials
Keyword Reference - Alphabetical
Keyword Reference - By usage
Report a broken link