Firing a bullet with SDL

Pages: 12
are your bullet and dot bitmaps loading ok.

Also - in GUI the Y co-ordinates go from TOP to BOTTOM .
so to go down then it is y+ and to go up it is y-

ps did you use the entire code I gave??
Last edited on
I have managed to now get the bullet to fire upwards when I press the space bar. I still have a few problems though. The bullet is always on top of the dot. when I move the dot the bullet doesn't move with it. How could I fix this. I messed up completely whilst trying to fix the second problem but it is back to normal now. :D
The bullet is always on top of the dot. when I move the dot the bullet doesn't move with it


Well... which is it? Those sentences are contradictory.
Because you paint them that way. Your order for screen painting is:
1
2
myDot.show();  
myBullet.show1();

So the dot is drawn first, then the bullet. So the bullet will overlay the dot if they are in the same position.

The dot and the bullet are independent entities. If you want them to move at the same time, you will have to move them at the same time.
Whenever I press space the bullet moves to the left:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Bullet::Bullet()
{
    //Initialize the velocity
    xVel1 = 0;
    yVel1 = 0;
    
    x1 = 11;
    y1 = 420;
}

void Bullet::handle_input1()
{
    //If a key was pressed
    if( event.type == SDL_KEYDOWN )
    {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
                case SDLK_SPACE: yVel1 = 5;
            case SDLK_LEFT: xVel1 -= DOT_WIDTH / 3; break;
            case SDLK_RIGHT: xVel1 += DOT_WIDTH / 3; break;
        }
    }
     //If a key was released
     else if( event.type == SDL_KEYUP )
     {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
                case SDLK_SPACE: yVel1 = 5;
            case SDLK_LEFT: xVel1 += DOT_WIDTH / 3; break;
            case SDLK_RIGHT: xVel1 -= DOT_WIDTH / 3; break;
        }
    }
    }

void Bullet::move1()
{
    //Move the dot up or down
    y1 -= yVel1;
    x1 += xVel1;
}


Please help
break;
It is going up straight byut when I move left the bullet doesn't follow but stays in the same position.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void Bullet::handle_input1()
{
    //If a key was pressed
    if( event.type == SDL_KEYDOWN )
    {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
            case SDLK_SPACE: yVel1 = 5;
            case SDLK_LEFT: xVel1 -= DOT_WIDTH / 3;
            case SDLK_RIGHT: xVel1 += DOT_WIDTH / 3;
        }
    }
     //If a key was released
     else if( event.type == SDL_KEYUP )
     {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
            case SDLK_SPACE: yVel1 = 5;
            case SDLK_LEFT: xVel1 += DOT_WIDTH / 3; 
            case SDLK_RIGHT: xVel1 -= DOT_WIDTH / 3;
        }
    }
}



void Bullet::move1()
{
    //Move the dot up or down
    y1 -= yVel1;
    x1 += xVel1;
}
You shouldn't even be blitting the bullet surface if it's not firing. When the space bar is pressed, the bullets starting x coord should be whatever the dots x coord is. Make sense?
Oh Timbo1 - you really are hard work I'm sorry to say.
Do you you understand how switch and case statement work?


You are making this much harder than it needs to be.
Anyway - try this - note that the bullet is only on screen drueing the firing stage.
Return 0 mentioned this, but I hard already incorporated it.
((Notice I have removed most of your comments to make it fit in one post))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"

#include <string>

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

const int FRAMES_PER_SECOND = 15;

const int DOT_WIDTH = 25;
const int DOT_HEIGHT = 42;

const int BULLET_WIDTH = 13;
const int BULLET_HEIGHT = 31;

SDL_Surface *dot = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *bullet = NULL;

SDL_Event event;

    int x, y;
    
    int xVel1 = 0;
    int yVel1 = 3;

class Dot
{
    private:
    int xVel, yVel;
    public:
    Dot();

    void handle_input();
    void move();

    void show();
};

class Timer
{
    private:
    int startTicks;

    int pausedTicks;

    bool paused;
    bool started;

    public:
    Timer();

    void start();
    void stop();
    void pause();
    void unpause();

    int get_ticks();

    bool is_started();
    bool is_paused();
};

SDL_Surface *load_image( std::string filename )
{
    SDL_Surface* loadedImage = NULL;

    SDL_Surface* optimizedImage = NULL;

    loadedImage = IMG_Load( filename.c_str() );

    if( loadedImage != NULL )
    {
        optimizedImage = SDL_DisplayFormat( loadedImage );

        SDL_FreeSurface( loadedImage );

        if( optimizedImage != NULL )
        {
            SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) );
        }
    }

    return optimizedImage;
}

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
    SDL_Rect offset;

    offset.x = x;
    offset.y = y;

    SDL_BlitSurface( source, clip, destination, &offset );
}

bool init()
{
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
        return false;
    }

    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
    if( screen == NULL )
    {
        return false;
    }

    SDL_WM_SetCaption( "Tank Game", NULL );

    return true;
}

bool load_files()
{
    dot = load_image( "dot.bmp" );
    if( dot == NULL )
    {
        return false;
    }
     bullet = load_image( "bullet.png" );
     
     if( bullet == NULL )
     {
         return false;
     }
     

    return true;
}

void clean_up()
{
    SDL_FreeSurface( dot );
    SDL_FreeSurface(bullet);

    //Quit SDL
    SDL_Quit();
}

Dot::Dot()
{
    x = 1;
    y = 420;

    xVel = 0;
    yVel = 0;
}

void Dot::handle_input()
{
    if( event.type == SDL_KEYDOWN )
    {
        switch( event.key.keysym.sym )
        {
            case SDLK_LEFT: xVel -= DOT_WIDTH / 3; break;
            case SDLK_RIGHT: xVel += DOT_WIDTH / 3; break;
        }
    }
    else if( event.type == SDL_KEYUP )
    {
        switch( event.key.keysym.sym )
        {
            case SDLK_LEFT: xVel += DOT_WIDTH / 3; break;
            case SDLK_RIGHT: xVel -= DOT_WIDTH / 3; break;
        }
    }
}

void Dot::move()
{
    x += xVel;

    if( ( x < 0 ) || ( x + DOT_WIDTH > SCREEN_WIDTH ) )
    {
        x -= xVel;
    }

    y += yVel;

    if( ( y < 0 ) || ( y + DOT_HEIGHT > SCREEN_HEIGHT ) )
    {
        y -= yVel;
    }
}

void Dot::show()
{
    apply_surface( x, y, dot, screen );
}

Timer::Timer()
{
    startTicks = 0;
    pausedTicks = 0;
    paused = false;
    started = false;
}

void Timer::start()
{
    started = true;

    paused = false;

    startTicks = SDL_GetTicks();
}

void Timer::stop()
{
    started = false;

    paused = false;
}

void Timer::pause()
{
    if( ( started == true ) && ( paused == false ) )
    {
        paused = true;

        pausedTicks = SDL_GetTicks() - startTicks;
    }
}

void Timer::unpause()
{
    if( paused == true )
    {
        paused = false;

        startTicks = SDL_GetTicks() - pausedTicks;

        pausedTicks = 0;
    }
}

int Timer::get_ticks()
{
    if( started == true )
    {
        if( paused == true )
        {
            return pausedTicks;
        }
        else
        {
            return SDL_GetTicks() - startTicks;
        }
    }

    return 0;
}

bool Timer::is_started()
{
    return started;
}

bool Timer::is_paused()
{
    return paused;
}

class Bullet
{
    private:
    //The X and Y offsets of the bullet
    int x1, y1;

    //The velocity of the bullet
    int xVel1, yVel1;

    public:
    Bullet();

    //Takes key presses and adjusts the bullet's velocity
    void handle_input1();

    //Moves the bullet
    void move1();

    //Shows the bullet on the screen
    void show1();

    bool isFired;
};

Bullet::Bullet()
{
    //Initialize the position and velocity
  x1 = 20;
  y1 = 400;
    xVel1 = 0;
    yVel1 = 3;

    isFired = false;
}

void Bullet::handle_input1()
{
    if( event.type == SDL_KEYDOWN )
    {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
          case SDLK_SPACE: 
            if (isFired)
            {
               yVel1 = BULLET_HEIGHT / 3;
            }


              
            else //first firing
            {
              //move the bullet to the position of the dot
              x1=x;
              y1=y;
              yVel1 = 3;
              isFired = true;
            }
          break;

          default:
            break;


              
        }
    }
    //If a key was released
    else if( event.type == SDL_KEYUP )
    {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
            case SDLK_SPACE: 
              if (isFired)
              {
                yVel1 = 3;
              }
                break;
            default:
              break;

        }
    }
}

void Bullet::move1()
{
    //Only move Move the bullet if fired
      if (isFired)
      {
        y1 -= yVel1;
      }
}

void Bullet::show1()
{
  //Only show the bullet if fired and it is onscreen
  if (isFired && y1+BULLET_HEIGHT >0)
  {
    apply_surface( x1, y1, bullet, screen );
  }
  else
  {
    isFired = false;
  }


}



int main( int argc, char* args[] )
{
  
  
    bool quit = false;

    Dot myDot;
    Bullet myBullet;

    Timer fps;

    if( init() == false )
    {
        return 1;
    }

    if( load_files() == false )
    {
        return 1;
    }

   
        while( quit == false )
    {
        fps.start();

        while( SDL_PollEvent( &event ) )
        {
            //Handle events for the dot and bullet
            myDot.handle_input();
            myBullet.handle_input1();

            //If the user has Xed out the window
            if( event.type == SDL_QUIT )
            {
                //Quit the program
                quit = true;
            }
        }

           //Fill the screen green
        SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0x7F, 0xFF, 0x00 ) );

        myDot.show();
        myBullet.show1();
      
        //Move the dot and bullet
        myDot.move();
        myBullet.move1();



        //Update the screen
        if( SDL_Flip( screen ) == -1 )
        {
            return 1;
        }

        //Cap the frame rate
        if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND )
        {
            SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );
        }
    }

    //Clean up
    clean_up();
    
    return 0;
}
Last edited on
Topic archived. No new replies allowed.
Pages: 12