BASIC8
Not enough ratings
Understanding Sprite
By Tony Wang
Difficulty: beginner
Category: programming, graphics
   
Award
Favorite
Favorited
Unfavorite
Glossary and fundamental concepts
A sprite is a visible, movable, animatable object which contains one or more frames in a uniform size. It is often used to represent dynamic object, such as player role, NPC, enemy, or even a short period animated effect etc.

Sprite is loaded by LOAD_RESOURCE or LOAD_BLANK. The former function loads already edited sprite asset from disk, the latter loads blank for runtime accessing only.



The beginning index of sprite frame is 1, exactly the same as what you see in the sprite editor. You can assign interval for each frame respectively in the editor, and set tag as string as well.

There are state-oriented operations and stateless ones, in this guide, the term "state" means some status or condition stored in a sprite object.
Operations with states
These functions are used to manipulate the states of a sprite, read the manual for details about parameters.

PLAY(spr, b = -1, e = -1, loop = TRUE, init = FALSE): plays a range of frames of a sprite, this is state-oriented because it must be stored somewhere of whether a sprite is being played, current frame, etc. Pass frame indexes to it; you can also pass frame tags to play a range of frames, it's helpful when you'd removed or inserted a frame, and won't need to change the indexes in code.

STOP(spr): the function name explains itself.

FLIP_X(spr, f = FALSE): sets whether flipping a sprite horizontally.

FLIP_Y(spr, f = FALSE): sets whether flipping a sprite vertically.

Assuming we got the following tank sprite, (notice the blue spot):



By flipping x:

tank0 = load_resource("tank.sprite") tank1 = clone(tank0) tank1.flip_x(true) def update(delta) spr tank0, 68, 58 spr tank1, 80, 58 enddef update_with(driver(), call(update))

It becomes:



By flipping y:

tank0 = load_resource("tank.sprite") tank1 = clone(tank0) tank1.flip_y(true) def update(delta) spr tank0, 68, 58 spr tank1, 80, 58 enddef update_with(driver(), call(update))

It becomes:



By flipping x and y together:

tank0 = load_resource("tank.sprite") tank1 = clone(tank0) tank1.flip_x(true) tank1.flip_y(true) def update(delta) spr tank0, 68, 58 spr tank1, 80, 58 enddef update_with(driver(), call(update))

It becomes:



SET_FLIP_CONDITION(spr, fx, fy): sets the flipping condition of a sprite. Sprite is rendered by SPR or SSPR with x and y position. This function is used to mark it automatically flipping when a sprite moves. Read the manual for details about parameters.

Try the following code and see how it behaves, the gun barrel cannot yet flip correctly at horizon, this code only shows how it works:

tank0 = load_resource("tank.sprite") tank0.set_flip_condition(1, 1) x = 74 y = 58 v = 10 def update(delta) if btn(0) then x = x - delta * v elseif btn(1) then x = x + delta * v elseif btn(2) then y = y - delta * v elseif btn(3) then y = y + delta * v endif spr tank0, x, y enddef update_with(driver(), call(update))
Operations without states
SPR spr, x, y, r = 0: renders a sprite.

SSPR spr, sx, sy, sw, sh, x, y [, w [, h, r = 0]]: similar to the above one, but can render with only a sub area of a sprite, also can stretch to a different target area.

Try the following code to see how it rotates with parameter r:

tank0 = load_resource("tank.sprite") tank1 = clone(tank0) tank2 = clone(tank0) tank3 = clone(tank0) def update(delta) spr tank0, 56, 58 spr tank1, 68, 58, 90 spr tank2, 80, 58, 180 spr tank3, 92, 58, 270 enddef update_with(driver(), call(update))



Try the following code to make a properly rotating tank:
tank0 = load_resource("tank.sprite") x = 74 y = 58 r = 0 v = 10 def update(delta) if btn(0) then x = x - delta * v r = 270 elseif btn(1) then x = x + delta * v r = 90 elseif btn(2) then y = y - delta * v r = 0 elseif btn(3) then y = y + delta * v r = 180 endif spr tank0, x, y, r enddef update_with(driver(), call(update))

It maybe appropriate to use rotation for object moves all directions around; and use flipping for object moves either horizontally or vertically.
Getting, setting pixels
These functions are used to get and set pixels of sprite. They apply to sprites from both disk assets or dynamic. Read the manual for details:

  • SGET spr, i, x, y
  • SGET spr, i, what
  • SSET spr, i, x, y, v
  • SSET spr, i, what, v
Automatic sorting
SET_ORDERBY(drv, rule ...): sets ordering rules of graphics commands; defaults to "nil" without calling this function. rule ... can be one or more in "nil", "map", "spr", "all"; "all" is shortcut to "spr" and "map", I'll only explain "spr" in this guide.

Sometimes we need to specify rendering orders of multiple objects, it is possible to simply achieve this modifying few lines of code. After calling the above function with a "spr" argument, BASIC8 will automatically sort all sprites according to their y positions. Try the following code:

set_orderby(driver(), "spr") tank0 = load_resource("tank.sprite") tank1 = clone(tank0) x = 60 y = 59 r = 0 v = 10 def update(delta) if btn(0) then x = x - delta * v r = 270 elseif btn(1) then x = x + delta * v r = 90 elseif btn(2) then y = y - delta * v r = 0 elseif btn(3) then y = y + delta * v r = 180 endif spr tank0, x, y, r spr tank1, 74, 58 enddef update_with(driver(), call(update))

Move your tank around to see how it sorts.

STEP_ON(y): creates a "step on" non-referenced value, which represents for aligning a sprite's bottom edge to y. Normal position arguments passed to SPR and SSPR denote for the top-left coner of a sprite, use this functions to denote for the bottom edge at y-axis. For example, try following code:

set_orderby(driver(), "spr") tank0 = load_resource("tank.sprite") tank1 = clone(tank0) tank2 = clone(tank0) x = 60 y = 59 r = 0 v = 10 def update(delta) if btn(0) then x = x - delta * v r = 270 elseif btn(1) then x = x + delta * v r = 90 elseif btn(2) then y = y - delta * v r = 0 elseif btn(3) then y = y + delta * v r = 180 endif spr tank0, x, y, r spr tank1, 74, 58 spr tank1, 86, step_on(58) enddef update_with(driver(), call(update))
8 Comments
Heptagram 31 May, 2018 @ 2:00am 
thx, i ajusted the colors to mach the color codes used in BASIC8, and now the images render just fine
Tony Wang  [author] 30 May, 2018 @ 9:08pm 
Each disk uses a set of 16-color palette, the generic algorithm quantizes images into those colors by picking the most similar one for each source pixel. It's not intended to produce 100% accurate result with a lossy mapping algorithm. But to make a better result, you could adjust the palette for expected colors before importing that image. PS: palette can be adjusted in any sprite, tiles, quantized editor.
Heptagram 30 May, 2018 @ 5:37am 
PS: could you fix the quantized image converter for small images in the next update?
because when i use blender to render (coulored) 32x32 pictures for a sprite, and convert it to quantized format, the coulors turn to grey and dark blue. (dispite all formats i tryed, with or without point to point filtering)


Tony Wang  [author] 30 May, 2018 @ 5:16am 
And you can also specify a range of frames to play by begin, end indices.
Tony Wang  [author] 30 May, 2018 @ 4:40am 
Ah, sorry for my misunderstanding. The guides are supplements to the manual and examples, so I didn't cover all obvious information to keep this short.
Heptagram 30 May, 2018 @ 3:13am 
@Tony Wang, Sorry, im new to BASIC8, in this tutorial, they dont explain how to make animated sprites, but after looking into the sourcecode of Infinity Fighter, i finaley found out how to request tagged frames in a sprite, and animate them.

Thanks enyway.
Tony Wang  [author] 29 May, 2018 @ 7:58pm 
@AlexBosch1232, by editing different frames in the timeline
Heptagram 29 May, 2018 @ 6:10am 
how do you make an animated sprite?