Reputation: 1
I do school project on basis of Atari Breakout. I do it in c++ using ALLEGRO 5 library. I don't know how to avoid one problem. When I compile my program i have flickering image on my program and the ball is going too slow. I was trying to change FPS but it still doesn't work properly.
Main loop is collecting informations about position of mouse (paddle), position of ball and bricks left. Than it should print it smoothly on the screen. Do you have any ideas, what i did wrong?
Here is my code:
#include <allegro5/allegro.h>
#include <allegro5\allegro_native_dialog.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#define BRICKS_HORIZONTALLY 10
#define BRICKS_VERTICALLY 5
#define BRICK_WIDTH 102
#define BRICK_HEIGHT 50
#define BRICK_GAP 2
#define PADDLE_WIDTH 100
#define PADDLE_HEIGHT 20
#define PADDLE_POSITION_Y (768-50)
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
struct ball_typ {
int xv, yv;
int x, y;
};
int playerPaddleEdgeX;
ball_typ ball;
int bricks[BRICKS_VERTICALLY][BRICKS_HORIZONTALLY];
void makeScreenBlack() { //clead screen to black
al_clear_to_color(al_map_rgb(0, 0, 0));
al_flip_display();
}
void resetBricks() {
for (int i = 0; i<BRICKS_VERTICALLY; i++) {
for (int ii = 0; ii<BRICKS_HORIZONTALLY; ii++) {
bricks[i][ii] = 1;
}
}
}
int numberOfBricksRemaining() {
int numberOfBricksRemaining;
numberOfBricksRemaining = 0;
for (int i = 0; i<BRICKS_VERTICALLY; i++) {
for (int ii = 0; ii<BRICKS_HORIZONTALLY; ii++) {
if (bricks[i][ii] != 0) {
numberOfBricksRemaining++;
}
}
}
return numberOfBricksRemaining;
}
void drawingThings() {
makeScreenBlack();
// draw the bricks
for (int i = 0; i<BRICKS_VERTICALLY; i++) {
for (int ii = 0; ii<BRICKS_HORIZONTALLY; ii++) {
if (bricks[i][ii] != 0) {
al_draw_filled_rectangle(ii*BRICK_WIDTH, i*BRICK_HEIGHT,(ii + 1)*BRICK_WIDTH - BRICK_GAP, (i + 1)*BRICK_HEIGHT - BRICK_GAP, al_map_rgb(255, 0, 0));
}
}
}
// draw the ball
al_draw_filled_circle(ball.x, ball.y, 8, al_map_rgb(255, 255, 255));
// draw the player
al_draw_filled_rectangle(playerPaddleEdgeX, PADDLE_POSITION_Y,playerPaddleEdgeX + PADDLE_WIDTH, PADDLE_POSITION_Y + PADDLE_HEIGHT, al_map_rgb(255, 255, 255));
ALLEGRO_FONT *font = al_create_builtin_font();
al_draw_textf(font, al_map_rgb(0, 0, 0), 10, 10, 0, "Player Position (playerPaddleEdgeX is %i)", playerPaddleEdgeX);
al_draw_textf(font, al_map_rgb(0, 0, 0), 10, 20, 0, "ball (x,y) position is (%i, %i)", ball.x, ball.y);
}
void resetBall() {
ball.x = 1024 / 2;
ball.y = 768 / 2;
ball.xv = 4;
ball.yv = 2;
}
int doesOverlap(int objectX, int objectY,
int areaLeft, int areaTop,
int areaRight, int areaBottom) {
if (ball.x > areaLeft &&
ball.x < areaRight &&
ball.y > areaTop &&
ball.y < areaBottom) {
return 1; // 1 here means yes
}
return 0; // 0 here means no
}
void moveBall() {
// update the ball's position for the next frame
ball.x += ball.xv;
ball.y += ball.yv;
// if the ball is overlapping the rectangle
if (ball.yv > 0) { // only if the ball is moving down
if (doesOverlap(ball.x, ball.y,
playerPaddleEdgeX + (PADDLE_WIDTH*0.0),
PADDLE_POSITION_Y,
playerPaddleEdgeX + (PADDLE_WIDTH*0.25),
PADDLE_POSITION_Y + PADDLE_HEIGHT) == 1) {
ball.xv = -5;
ball.yv = -3;
}
if (doesOverlap(ball.x, ball.y,
playerPaddleEdgeX + (PADDLE_WIDTH*0.25),
PADDLE_POSITION_Y,
playerPaddleEdgeX + (PADDLE_WIDTH*0.5),
PADDLE_POSITION_Y + PADDLE_HEIGHT) == 1) {
ball.xv = -3;
ball.yv = -5;
}
if (doesOverlap(ball.x, ball.y,
playerPaddleEdgeX + (PADDLE_WIDTH*0.5),
PADDLE_POSITION_Y,
playerPaddleEdgeX + (PADDLE_WIDTH*0.75),
PADDLE_POSITION_Y + PADDLE_HEIGHT) == 1) {
ball.xv = 3;
ball.yv = -5;
}
if (doesOverlap(ball.x, ball.y,
playerPaddleEdgeX + (PADDLE_WIDTH*0.75),
PADDLE_POSITION_Y,
playerPaddleEdgeX + (PADDLE_WIDTH*1.0),
PADDLE_POSITION_Y + PADDLE_HEIGHT) == 1) {
ball.xv = 5;
ball.yv = -3;
}
}
for (int i = 0; i<BRICKS_VERTICALLY; i++) {
for (int ii = 0; ii<BRICKS_HORIZONTALLY; ii++) {
if (bricks[i][ii] != 0) { // is the brick still here?
if (doesOverlap(ball.x, ball.y,
ii*BRICK_WIDTH, i*BRICK_HEIGHT,
(ii + 1)*BRICK_WIDTH - BRICK_GAP,
(i + 1)*BRICK_HEIGHT - BRICK_GAP) == 1) {
// reverse ball's vertical direction
ball.yv = -ball.yv;
bricks[i][ii] = 0; // erase the brick
}
}
}
}
// bounce off edges of screen
if (ball.x > 1024) {
ball.xv = -ball.xv;
}
if (ball.x < 0) {
ball.xv = -ball.xv;
}
if (ball.y < 0) {
ball.yv = -ball.yv;
}
// but reset ball if it goes off bottom of screen
if (ball.y > 768) {
// lose!
ALLEGRO_MOUSE_STATE state;
al_get_mouse_state(&state);
if (state.buttons & 1) { //reappear ball
resetBall();
}
}
}
void updatePaddlePosition() {
// for now, put the player's paddle where the mouse is
int pos_x = 1024 / 2;
ALLEGRO_MOUSE_STATE state;
al_get_mouse_state(&state);
pos_x = state.x;
playerPaddleEdgeX = pos_x;
}
void gameSetup() {
resetBricks();
resetBall();
// start with the ball off the bottom of the screen
ball.y = 768 + 50;
}
int main() {
ALLEGRO_TIMER * timer = NULL;
int FPS = 60;
al_init(); // allegro initializing
al_init_font_addon();
al_init_primitives_addon();
if (!al_init()){ //check
al_show_native_message_box(NULL, NULL, NULL,
"failed to initialize allegro!", NULL, NULL);
return -1;
}
timer = al_create_timer(1.0 / FPS);
al_install_keyboard();
al_install_mouse();
event_queue = al_create_event_queue();
al_register_event_source(event_queue, al_get_mouse_event_source());
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_set_new_window_position(20, 30);
display = al_create_display(1024, 768);
if (!display){ //check
al_show_native_message_box(NULL, NULL, NULL,
"failed to initialize display!", NULL, NULL);
return -1;
}
makeScreenBlack();
updatePaddlePosition();
gameSetup();
ALLEGRO_KEYBOARD_STATE key;
al_start_timer(timer);
while (al_key_down(&key, ALLEGRO_KEY_ESCAPE)){
updatePaddlePosition();
moveBall();
if (numberOfBricksRemaining() == 0) {
resetBricks();
}
drawingThings();
al_flip_display();
al_rest(0.01);
}
al_destroy_display(display);
return 0;
}
Upvotes: 0
Views: 751
Reputation: 340
You're calling al_flip_display
twice. You should remove the call to al_flip_display
in makeScreenBlack()
and keep the other one.
Upvotes: 2