特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接0 W% ^% v5 u8 [% |
第25章 Sprites 6 i7 a5 X. Z' q) J
本期教程主要是跟大家讲解sprite的显示,这里讲的sprite跟第23章讲的游标是类似的,只是这里的游标是可以任意跑动的,可以根据程序设置跑动的路径。 25. 1 介绍 25. 2 模拟器上演示sprite例子 25. 3总结 25.1 介绍 emWin sprite作为一种纯粹的软件解决方案实现。使用emWin sprite不需要额外的硬件。它们可以显示、移动和删除,而不影响当前可见的图形项目。 存储器要求 每个sprite都需要一个存储器区,用于保存sprite后面的显示数据,以便在移动或删除sprite时能恢复背景显示。另外需要一个存储区,用作颜色缓存。颜色缓存的大小取决于sprite图像中使用的颜色数量。因此,sprite需要的全部字节数可以按以下等式计算: SizeOfSpriteObject (~30 bytes) +(XSize * YSize + NumberOfBitmapColors) *REQUIRED_BYTES_PER_PIXEL Sprite的最大数目 emWin并不限制同时可见的sprite的数量。具体取决于可用存储器的大小。 性能 需要注意的是,绘制sprite比绘制简单的位图需要耗费更多计算资源,因为需要处理背景数据以及与其他sprite的交叉点。 叠置顺序 叠置顺序是对有重叠的二维对象 (此处为sprite)的排序。当两个sprite重叠时,它们的叠置顺序决定了哪个sprite位于另一个sprite的上方。最后创建的sprite位于最上面。 25.2 模拟器上演示sprite例子 模拟器中有一个例子专门做了sprite的演示,这个例子位置在: " i9 U+ E3 B1 m" Q
此DEMO的实际代码如下: - /*********************************************************************# |2 e- |3 Q7 w4 B) J9 S9 s
- *
( D; x" ?) u+ S) n4 @ - * Dolphin bitmap arrays
2 `. c$ I [. @* c - */
0 O, u6 y. w6 _' h4 z# q D, D - GUI_CONST_STORAGE GUI_BITMAP * _apImages_0[] = {(1)$ `; d' y9 `1 ~7 n0 C$ n# M6 h& G% F- j
- &bmDolphin_00,
% y/ t( _( \) ~2 I. x7 M - &bmDolphin_01,
3 t! x3 i" n) ~/ ?* C* g ~ n+ @ - &bmDolphin_02,/ P6 H; }. Q2 _# S4 N
- &bmDolphin_03,
) Z& @, B0 W7 d. c0 a- t2 x - &bmDolphin_04,
4 \, {# x! v1 c0 ?9 j) N% N - };3 ~/ `/ O3 x* t& @% S
- 4 ^( {" y, z4 e. R6 l- [
- GUI_CONST_STORAGE GUI_BITMAP * _apImages_1[] = { (2)/ K) p5 g1 k* y4 _( Q8 s) A
- &bmDolphin_10,
/ l$ T z! ?& J8 s5 k& V/ O - &bmDolphin_11,
# ~0 i5 D1 ?7 i& J - &bmDolphin_12,
, O. {( G5 w6 K - &bmDolphin_13,1 j, _7 {" A7 h. C) r
- &bmDolphin_14,
) r) J) i4 L9 Z* f - };" J" [; {3 \. A% g
-
- z3 u1 u0 e+ ?- J% } - /*********************************************************************9 |% V$ ]. M4 v
- *0 z8 d2 w% O) F
- * Sprite array
+ `, t. e! q% n1 ] - */
- C/ k1 ` {. e w - static SPRITE _aSprite[] = {
& d6 r; d0 G5 n - { -90, 20, 10, 3, GUI_COUNTOF(_apImages_1), _apImages_1},1 n2 H7 `& r/ h: H# G
- { 290, 150, -8, -2, GUI_COUNTOF(_apImages_0), _apImages_0},8 N% D. U5 {0 Y3 D3 v. S7 }
- };% M Y8 I% E: [8 H# T& G
-
: A+ C6 ]2 S- X/ c% z# t' K - /*********************************************************************4 a4 T, y/ ~& B" i. c
- *
+ ^) ~6 O, Y+ V - * Static code% c2 k E( C) G$ P
- *
& ^5 ^0 M* S: e2 E - **********************************************************************: g3 J6 q! w/ ~* a# u9 j. }
- */4 `. K+ a: b/ F" `5 a, B9 Q; a" p" R
- /*********************************************************************
7 o, d( p1 F0 }3 T5 x - *
& a3 N( q) D0 y* U - * _MoveSprite3 [( c0 o) q5 Q4 G+ ] z7 {: K' k
- */' K" N/ D q' t! k% _ `
- static void _MoveSprite(SPRITE * pSprite) {$ l$ u7 G+ ^. g: G# N" o7 s5 k
- //
' c8 g9 s5 Y' O& b - // Set new index
8 _6 S1 i1 Y4 q6 [ - //
* n( R- j: X# n9 z$ ~) n6 f, m - pSprite->Index += 1;
4 X; a! D. S( S - if (pSprite->Index >= pSprite->NumImages) { (3)! J+ N1 x q8 B2 X# W, ?
- pSprite->Index = 0;4 h( _. z7 H( N) Y/ b" o9 L
- }
3 O {5 R5 Y5 n* E' a5 ]& N- o6 ~ - //7 \# d2 h5 M* F5 J
- // Adjust X-position
7 G3 d$ C* ]6 x, v - //) L( G e$ J% X
- pSprite->xPos += pSprite->dx;(4)5 `1 E, R: T( v$ ~
- if (pSprite->xPos > 320) {
6 R$ ^: l! s7 \) ^* i - pSprite->xPos = -1L * pSprite->apImages[pSprite->Index]->XSize;
( E7 [0 t& M" _( s/ O% X/ P - }: }6 Q( T" D1 r2 s' u
- if (pSprite->xPos < -1L * pSprite->apImages[pSprite->Index]->XSize) {9 S% s$ W+ R, k0 q2 F( i( d
- pSprite->xPos = 320;
+ \: I5 D) M5 Y - }
, f' t: J/ x% i* t - //; t$ C3 J9 u6 V
- // Adjust Y-position
8 @4 Y" `6 w! P# H9 B6 Q - //' Z' N5 d& K9 C# A0 k8 G
- pSprite->yPos += pSprite->dy; (5)1 |3 K+ }5 F; z0 u3 O5 ?9 Q: o7 a
- if (pSprite->yPos < 0) {
/ L% W. E- S6 n" }& { a - pSprite->dy = -pSprite->dy;$ r8 y- G5 m9 h- d2 l% S8 o
- }
6 t! G% F0 {# k {* I h - if (pSprite->yPos > (240 - pSprite->apImages[pSprite->Index]->YSize)) {4 x* q2 E1 E' j ]1 |3 r- T
- pSprite->dy = -1 * pSprite->dy;5 F ] j$ F% P) Y6 E: O5 r A9 D
- }
7 |; f7 e$ k- | - //
; J; y0 L f' P3 X% z( i - // Change sprite
5 d$ y4 T; G- T - //(6)5 S/ ^: m, ~9 S% r0 E
- GUI_SPRITE_SetBitmapAndPosition(pSprite->hSprite, pSprite->apImages[pSprite->Index], pSprite->xPos, pSprite->yPos);
$ L4 Z" d6 d+ m8 B; u- B; A - }5 c6 M4 n' s4 |" O/ P9 i
-
4 g5 ^& \% m6 h - /*********************************************************************9 K6 A" `8 z/ J
- *+ H7 x3 Z4 u* V4 y! ?
- * _ShowSprites. m. _) C0 ]- b* f& ^1 T# H
- */7 z; t. U8 A" o# u; M3 A7 `. a
- static void _ShowSprites(void) {# r; _- D* K# k4 s
- unsigned i;
# P) A( }4 v' ?& _/ O. f3 Z. P8 v -
3 I+ ~" J: s4 `5 Z% p8 s1 V - //+ A5 D# D T, v6 X& s4 M/ Q
- // Create the sprites5 c- P6 ?0 `. W4 x1 J( v6 q; l
- //. W( f% L* g# b% D( [6 `
- for (i = 0; i < GUI_COUNTOF(_aSprite); i++) { (7). ^9 n' c3 d* h n2 @
- _aSprite[i].hSprite = GUI_SPRITE_Create(_aSprite[i].apImages[0], _aSprite[i].xPos, _aSprite[i].yPos);
/ v7 l# K! U3 |; f! u- L& R; o) p - }
- q X u( |7 Z5 n5 d9 h& e - //
# C: B) `" ~% y. v7 A- G1 O) r3 S - // Move them forever...
b; B1 @+ f" U# i- } - //
# s) Y4 K4 K$ H - while (1) {( S8 B6 u( j2 N( W
- for (i = 0; i < GUI_COUNTOF(_aSprite); i++) {
1 s/ P' U1 L( |, u+ [ - _MoveSprite(&_aSprite[i]);: M9 e0 Z4 _1 z! @; x; a4 A: u! ?7 M
- GUI_Delay(100);$ S! u2 n3 L! f
- }
$ _5 Y5 Q8 a9 {6 p" I5 y) u - }& M7 g6 i% V" l: b2 G$ s, J
- }) q( G, h4 g/ ^, l# n
-
" c) i2 ^. N( g+ Z! m' V* m - /*********************************************************************
9 [: g& |+ k/ {( f5 G, { \ - *
% {! v3 R' S" z1 x; N5 _ - * _DrawBackground
2 f% @3 P# C8 K# C( j+ \ - */
/ l4 ?# e9 C) l$ M/ R$ v - static void _DrawBackground(void) {
5 _/ u! _6 l/ j. X# { - GUI_DrawGradientV(0, 0, 319, 239, 0xffffff, 0xff0000); // Draw background gradient% @3 K1 J+ Q* V- U2 i& p
- GUI_SetTextMode(GUI_TM_TRANS);0 c4 U! W" Z8 W
- GUI_SetFont(&GUI_Font24B_ASCII);8 s9 E# X3 o# t. n1 J& E
- GUI_SetColor(GUI_BLACK);
. g4 B+ O8 L' x9 Z: r* Q, v - GUI_DispStringHCenterAt("Showing sprites...", 160, 20); // Draw sample text5 N4 h- X% i( J4 ?
- GUI_DrawBitmap(&bmSeggerLogoLarge, 60, 80); // Draw company logo$ ~2 U- k7 E; D; E9 ~3 G
- }" E- w( k" `* n: O" ?3 [
- ( _& K( e# l/ Y `
- /*********************************************************************( C3 X+ w9 z3 S7 h' a1 ?, c! c( w
- *
Y* d: n3 [8 G) e7 L' W - * Public code
& s/ i/ h7 i5 f6 Q* B* K - *
" h3 a' Q0 l& M! w, H/ j) M8 F, b - **********************************************************************
, S4 c& ~, k+ s; y - */" Q+ Q9 L4 t/ \: J$ c$ @2 s ^
- /*********************************************************************$ ^) m7 o" W: L% }% f2 r7 O9 A( X
- *
$ o8 [; M( x+ ?1 {8 B7 Z# R! v - * MainTask8 g: M$ ^6 `6 k3 F. p# B* |
- */
- w- A( b" z( n1 Q/ L! F - void MainTask(void) {6 m* n% r5 Y6 G& M @ _
- GUI_Init(); // Initialize emWin
1 u/ P" G4 ~2 j7 f% f - _DrawBackground(); // Draw background+ q; ?+ k/ m- g1 R7 h9 ^( }
- _ShowSprites(); // Show sprites6 ~# I9 |; Y% j( H5 d, X1 x+ r
- }
复制代码1. 这里面的5个位图是用于sprite显示的,通过这5张图的切换实现动态效果。Sprite对位图的要求如下: n 不得压缩。 n 必须透明。 n 应是基于调色板的位置,为1、2、4或8bpp。 这个要求跟前面讲的游标是一样的。 2. 和上面讲的一样。 3. 实现5幅sprite图的切换。 4. 调整sprite显示的X轴位置。 5. 调整sprite显示的Y轴位置。 6. 显示sprite。 7. 创建sprite。 实际显示效果如下: 1 g c) |6 s X7 t; W9 k2 E t
25.3 总结 本期教程有一个问题还没有解决,就是如何生成这种8bpp还带透明的图片数据,这个问题有待解决。
& U$ U" E) ^8 P" b r6 x. F+ ?$ L, U2 C |