2016-05-25 11 views
0

Ich mache Schulprojekt auf Basis von Atari Breakout. Ich mache es in C++ mit ALLEGRO 5-Bibliothek. Ich weiß nicht, wie ich ein Problem vermeiden kann. Wenn ich mein Programm kompiliere habe ich flackerndes Bild auf meinem Programm und der Ball geht zu langsam. Ich habe versucht, FPS zu ändern, aber es funktioniert immer noch nicht richtig.Flackernde Bildschirm ALLEGRO 5

Main Loop sammelt Informationen über die Position der Maus (Paddel), Position der Kugel und Steine ​​links. Dann sollte es glatt auf dem Bildschirm gedruckt werden. Hast du irgendwelche Ideen, was ich falsch gemacht habe?

Hier ist mein 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; 
} 
+0

Im Allgemeinen werden flackernde Bildschirme durch Verwendung eines Einzelpuffer-Anzeigemodells gekürzt (dh, Sie aktualisieren denselben Speicherbereich, den Sie auf dem Bildschirm anzeigen). Ich kenne kein Allegro, daher werde ich Sie auf https://wiki.allegro.cc/index.php?title=Double_buffering verweisen. – Aumnayan

+0

@Aumnayan Ich habe in meinem Code doppelt gepuffert (glaube ich). Loop zeichnet jedes Element und am Ende wird der Bildschirm aktualisiert –

+0

Ich bin dein Problem. Es ist ganz unten. Sie haben einen Timer, aber Sie verwenden ihn nicht, um die Bildfrequenz oder das Timing Ihrer Spielschleife zu steuern. Was Sie tun, ist die Tastatur Updates erhalten und damit Ihr Spiel zu aktualisieren. Bewegt sich das Spiel, wenn Sie keine Taste drücken? – rlam12

Antwort

2

Sie al_flip_display zweimal aufrufen. Sie sollten den Anruf zu al_flip_display in makeScreenBlack() entfernen und den anderen behalten.

+0

Problem bereits gelöst, indem man eine andere Methode verwendet. Vielen Dank –

Verwandte Themen