& N$ q7 y) V6 \, s0 p#define DIR_UP 0# n$ c7 p/ D& e9 ^8 A
#define DIR_LEFT 1
) m9 @0 J a3 }+ N#define DIR_DOWN 2
# y' q A' s6 U' U6 W& y' n1 D#define DIR_RIGHT 3
, M/ B) l8 s: s$ H+ RSDL_Surface *screen;1 e! y2 ^( G. S( d
typedef struct Sprite_t {
{/ F; H* N( D int width;
2 |; ?/ B$ j, c5 @ int height;
- @+ p* I& m) L int x;* o0 _4 K; E$ H. S% e$ o& \) [
int y;
# }' Y$ X" W1 ^) ~! O# Q int ox;$ |; w. T/ r" _. |( a! e
int oy;
0 y) a- F# l! G: O int dir;
' ~1 S7 p9 i- Q9 }& Z( m* _& K5 F7 |7 a int subframe;
! B2 o7 N/ o4 ?. u% n4 C- p int speed;0 U" p7 a" H1 K9 L2 h3 ]6 u
int timer;( N! ~' B2 n1 g2 s
int moving; //use to calculate subframe5 U! B- h H9 c- C7 v* o1 S% P, _) S
SDL_Surface *image;9 w$ k9 }1 Y v; R i+ r6 G
}Sprite_t;1 }5 M- f: D1 D# `/ T/ g
typedef enum GameState {
4 |8 t* b# s. ~4 |- V GAME_RUNNING,5 m' E5 J, T& m/ E; @
GAME_OVER,
) H* F- G# ~% c: z* Y7 K}GameState;
C1 |9 d6 _! d* Evoid Init_SDL()
/ V5 M0 f$ e( Y* F- }{
* c9 r2 U1 J$ L if ( SDL_Init( SDL_INIT_VIDEO) < 0 ) {2 A5 O: q( ~. Y: ^
fprintf(stderr,"Can't init SDL: %s\n",SDL_GetError());
: O* Q$ p2 C, H* _ exit(1);
7 v( O. a" F) J: s }
5 i c! |. v" j& G! [6 x3 {* K screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);* z' i, W& @. d( u
if ( screen == NULL ) {
! R: G. x, q) `. [ fprintf(stderr, "Error: %s\n",SDL_GetError());6 t( K2 M* L X9 X) c, R
exit(1);
7 l- Z5 c% i+ | d+ k! } }7 n" v) w1 a3 X
atexit(SDL_Quit);1 S5 p9 ^: l4 G7 b1 f& u9 Q
}+ p! I# X. X! [! h! x
void DrawSprite(SDL_Surface *surface,Sprite_t *sprite) 3 j1 l1 Y+ I' ?6 `1 E( S a+ J
{/ ]2 J! f* v; L N
SDL_Rect src_rect,des_rect;- [- Y! H' Q' v9 R& d
sprite->subframe=sprite->timer/4; 9 }8 Q( @ p j6 |
src_rect.w=des_rect.w=sprite->width;' f& c* g7 |0 U& R
src_rect.h=des_rect.h=sprite->height;
$ h: ?0 s5 f3 @, ^5 m" V src_rect.x=sprite->subframe*sprite->width;: n! K$ B- `% q
src_rect.y=sprite->dir*sprite->height;. j- I1 B/ s$ T) G) Y
des_rect.x=sprite->x;, i! s4 F) P! O
des_rect.y=sprite->y;
9 |/ I! A1 ]% Q1 c1 J ? //Draw sprite to new position
2 t$ m3 \$ a6 s! k! ^ SDL_BlitSurface(sprite->image,&src_rect,surface,&des_rect);
: \% Y! w2 n2 r}
; Z' _, ?. y" U+ ]5 B7 p3 w0 @void ClearSprite(SDL_Surface *surface,Sprite_t *sprite) + }* B* |+ F* j1 p% F+ f
{( U1 `4 a3 Q# O0 r" o
SDL_Rect mask;5 ?+ `6 d3 H9 r) ?3 _% h
mask.w=sprite->width;
/ I+ [( q8 l \/ x mask.h=sprite->height;
# W3 A: Q- X" H% M mask.x=sprite->ox;- _. u# s0 q+ E# ^# Q% y% N
mask.y=sprite->oy;9 d) x) y% \4 ?( C" z. o; i
//Clear sprite from the old position% ]) }# C% g: s/ ?
SDL_FillRect(surface,&mask,SDL_MapRGB(surface->format,0,0,0));3 v c4 a1 N2 a3 L
}
: y' M7 b8 w" c: k' _$ k% ZUint32 TimeLeft() 8 Q7 n. @$ f6 M c
{
- ?' j9 X; k7 L- n: V$ E) N static Uint32 next_time=0;
. f6 w: `0 C8 j M, N Uint32 now;
* F4 S& ?6 T6 f/ a; ?+ q- @6 Y A now=SDL_GetTicks();
8 w; U6 x# g6 Q. b4 u if(next_time<=now){# h% Q( t: h+ s. \" w
next_time=now+30;
+ V' m2 m+ ]0 W( r return(0);8 m) F% `3 {6 x) h
}* B7 B/ g0 `, k% G* ^' K
return(next_time-now);' c$ ]8 d8 T, u( S* _
}
# |' o+ a, c5 u6 J2 u T m1 ^% S5 u5 u
- {" z6 C) C- H; g3 x, t+ Zint main()4 t, {$ ^% R+ t0 K' n3 a
{
6 z" `! c% h# \3 a( n- o4 W GameState game_state;1 x2 b) l9 v! q2 B9 U
Sprite_t tank;
0 O+ b. U q; s; K1 y1 w8 ? SDL_Event event;
$ E* r4 s- [4 v6 W- O# n Q Init_SDL();9 z0 L2 B; [: s* m' j- r
tank.image=IMG_Load("tank.png");9 C. o+ W+ f' M+ J" ?7 E
SDL_SetColorKey(tank.image,SDL_SRCCOLORKEY,SDL_MapRGB(tank.image->format,255,0,255));
% p* ]& y' v( q W& O0 F+ P) T tank.image=SDL_DisplayFormat(tank.image);/ P4 @" Z! ^! _+ g2 W) F; i
game_state=GAME_RUNNING;6 ?7 T! }6 j, h
tank.dir=DIR_RIGHT;
6 |- d# t, O1 D6 _1 p! e( h( v# g4 f tank.width=32;( f. H% ], A( D& C2 |5 D
tank.height=32;0 O6 ^* M! C8 o. M+ C" a# p
tank.x=300;# k- g. q" u/ k
tank.y=200;; P B5 r4 _3 z0 b. i) w6 Y
tank.ox=tank.x;
3 i1 l, K3 N1 ?+ b T# v5 d tank.oy=tank.y;0 m% m- D3 B! a6 o& F- L
tank.moving=0;
$ h/ i, u( h8 g9 M- d tank.speed=3;
! g- \6 {1 H8 _6 k2 o6 v9 ^ tank.timer=0;( w8 ?; a+ A+ i' }1 ]
while(game_state==GAME_RUNNING){
* W8 H$ z* v3 v ClearSprite(screen,&tank);
3 H8 ~! w# C2 E L- d0 R //Get Input; p0 T; q8 h; c% f' L
SDL_PollEvent(&event);
; O' |+ H8 d& o0 z% ^2 \ switch(event.type){+ w7 d4 N, c' y# `1 X1 a5 I+ `
case SDL_KEYDOWN: 1 Y1 D" A/ J* ~- r7 |/ I9 U
switch(event.key.keysym.sym){* `* F! v: d2 K9 T; B6 B
case SDLK_ESCAPE:
! R8 _6 o% K( h. p' H game_state=GAME_OVER;" \, v& {( {; d q' l( E. ?
break;
" L. t! `* E& X. x+ v- Z, { case SDLK_UP:
8 q" X, c7 |0 J! m tank.dir=DIR_UP;
7 E! @/ @4 a- R+ S3 j! ` tank.y-=tank.speed;
) ]0 F) W% I& q3 _ break;d1 b% } _! _7 E
case SDLK_DOWN:9 S! g0 O. H' w5 I6 B' B- L' G
tank.dir=DIR_DOWN;9 p+ `9 c) f7 e2 l/ y
tank.y+=tank.speed;
; e7 M& T$ O8 r4 K break;
4 \, ^3 I) l T2 }2 b4 @3 ] case SDLK_LEFT:: {4 A5 I) v8 N* ?* Z. S6 ?4 I
tank.dir=DIR_LEFT;1 T7 r! Y; w+ m0 j4 ~$ U
tank.x-=tank.speed;
7 H! J+ u% K4 h* w7 e& E# Y break;
; I. T; o5 J# ?6 ` case SDLK_RIGHT:
; W& L, e F, e/ C# r* v tank.dir=DIR_RIGHT;
3 n0 _" q/ ?1 H7 m; ^0 M tank.x+=tank.speed;
3 r3 @6 n! v6 W+ Q4 f break;) ?5 ]- i4 y9 l! m6 u5 K/ u
default:
. R* M$ E* c& r. | v7 U break;
5 A, \7 r( i# ~" S3 t }
8 [ o( a" z6 M: E. O, _ case SDL_KEYUP:
2 w/ R3 i* A4 { break;
/ y$ @9 I3 y! |" k. W% r" f default:* s: a0 w* a! Y. [# B
break;6 X. {: h9 h) ?
}2 s* E' p: |5 f5 p) k
+ f% p7 U' v% t, } DrawSprite(screen,&tank);6 Z% q+ _& |) x& d( A/ z+ x
tank.ox=tank.x;
6 O" \: o T+ y* c U; g tank.oy=tank.y; $ a/ v) K) q( ]
SDL_UpdateRect(screen,0,0,0,0);8 q; A u$ |) U/ y
SDL_Delay(TimeLeft());
$ @5 o" G" j" ^* F1 ` tank.timer++;3 W% Z) z, l7 V* h, @
tank.timer%=8;
7 i5 S S; \& m }$ P+ n. Y( @" f: r6 s4 x, g
SDL_FreeSurface(tank.image);
! {4 f. v& B) k+ h( l$ O}