Space invaders clone not moving properly

Posted by ThePlan on Game Development See other posts from Game Development or by ThePlan
Published on 2012-09-06T08:36:46Z Indexed on 2012/09/06 9:50 UTC
Read the original article Hit count: 228

Filed under:
|
|

I'm trying to make a basic space invaders clone in allegro 5, I've got my game set up, basic events and such, here is the code:

#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include "Entity.h"

// GLOBALS ==========================================
const int width = 500;
const int height = 500;
const int imgsize = 3;
bool key[5] = {false, false, false, false, false};
bool running = true;
bool draw = true;

// FUNCTIONS ========================================
void initSpaceship(Spaceship &ship);
void moveSpaceshipRight(Spaceship &ship);
void moveSpaceshipLeft(Spaceship &ship);
void initInvader(Invader &invader);
void moveInvaderRight(Invader &invader);
void moveInvaderLeft(Invader &invader);
void initBullet(Bullet &bullet);
void fireBullet();
void doCollision();
void updateInvaders();
void drawText();

enum key_t { UP, DOWN, LEFT, RIGHT, SPACE };
enum source_t { INVADER, DEFENDER };

int main(void)
{
    if(!al_init())
        { return -1; }

    Spaceship ship;
    Invader invader;
    Bullet bullet;

    al_init_image_addon();
    al_install_keyboard();
    al_init_font_addon();
    al_init_ttf_addon();

    ALLEGRO_DISPLAY *display = al_create_display(width, height);
    ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue();
    ALLEGRO_TIMER *timer = al_create_timer(1.0 / 60);
    ALLEGRO_BITMAP *images[imgsize];
    ALLEGRO_FONT *font1 = al_load_font("arial.ttf", 20, 0);

    al_register_event_source(event_queue, al_get_keyboard_event_source());
    al_register_event_source(event_queue, al_get_display_event_source(display));
    al_register_event_source(event_queue, al_get_timer_event_source(timer));

    images[0] = al_load_bitmap("defender.bmp");
    images[1] = al_load_bitmap("invader.bmp");
    images[2] = al_load_bitmap("explosion.bmp");

    al_convert_mask_to_alpha(images[0], al_map_rgb(0, 0, 0));
    al_convert_mask_to_alpha(images[1], al_map_rgb(0, 0, 0));
    al_convert_mask_to_alpha(images[2], al_map_rgb(0, 0, 0));

    initSpaceship(ship);
    initBullet(bullet);
    initInvader(invader);


    al_start_timer(timer);
    while(running)
    {
        ALLEGRO_EVENT ev;
        al_wait_for_event(event_queue, &ev);

        if(ev.type == ALLEGRO_EVENT_TIMER)
          {
              draw = true;
            if(key[RIGHT] == true)
                moveSpaceshipRight(ship);

            if(key[LEFT] == true)
                moveSpaceshipLeft(ship);
          }

        else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
            running = false;

        else if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
          {
            switch(ev.keyboard.keycode)
            {
                case ALLEGRO_KEY_ESCAPE:
                    running = false;
                    break;

                case ALLEGRO_KEY_LEFT:
                    key[LEFT] = true;
                    break;

                case ALLEGRO_KEY_RIGHT:
                    key[RIGHT] = true;
                    break;

                case ALLEGRO_KEY_SPACE:
                    key[SPACE] = true;
                    break;
            }
          }

        else if(ev.type == ALLEGRO_KEY_UP)
            {
                switch(ev.keyboard.keycode)
                {
                    case ALLEGRO_KEY_LEFT:
                        key[LEFT] = false;
                        break;

                    case ALLEGRO_KEY_RIGHT:
                        key[RIGHT] = false;
                        break;

                    case ALLEGRO_KEY_SPACE:
                        key[SPACE] = false;
                        break;
                }
            }

        if(draw && al_is_event_queue_empty(event_queue))
        {
            draw = false;

            al_draw_bitmap(images[0], ship.pos_x, ship.pos_y, 0);
            al_flip_display();
            al_clear_to_color(al_map_rgb(0, 0, 0));
        }
    }

    al_destroy_font(font1);
    al_destroy_event_queue(event_queue);
    al_destroy_timer(timer);
    for(int i = 0; i < imgsize; i++)
        al_destroy_bitmap(images[i]);
    al_destroy_display(display);
}

// FUNCTION LOGIC ======================================
void initSpaceship(Spaceship &ship)
{
    ship.lives = 3;
    ship.speed = 2;
    ship.pos_x = width / 2;
    ship.pos_y = height - 20;
}

void initInvader(Invader &invader)
{
    invader.health = 100;
    invader.count = 40;
    invader.speed = 0.5;
    invader.pos_x = 300;
    invader.pos_y = 300;
}

void initBullet(Bullet &bullet)
{
    bullet.speed = 10;
}

void moveSpaceshipRight(Spaceship &ship)
{
        ship.pos_x += ship.speed;
        if(ship.pos_x >= width)
            ship.pos_x = width-30;
}

void moveSpaceshipLeft(Spaceship &ship)
{
    ship.pos_x -= ship.speed;
    if(ship.pos_x <= 0)
        ship.pos_x = 0+30;
}

However it's not behaving the way I want it to behave, in fact the behavior for the ship movement is un-normal. Basically I specified that the ship only moves when the right/left key is down, however the ship is moving constantly to the direction of the key pressed, it never stops although it should only move while my key is down. Even more weird behavior, when I press the opposite key the ship completely stops no matter what else I press.

What's wrong with the code? Why does the ship move constantly even after I specified it only moves when a key is down?

© Game Development or respective owner

Related posts about c++

Related posts about behavior