2016-05-25 8 views
0

私はAtari Breakoutに基づいて学校プロジェクトを行っています。私はC++でALLEGRO 5ライブラリを使用しています。私は1つの問題を避ける方法を知らない。私のプログラムをコンパイルすると私のプログラムでイメージがちらつき、ボールの動きが遅すぎます。私はFPSを変更しようとしていましたが、それでも正しく動作しません。ちらつき画面ALLEGRO 5

メインループは、マウス(パドル)の位置、ボールとレンガの位置についての情報を収集しています。それは画面上にスムーズに印刷する必要があります。あなたは何かアイデアを持っていますか?

#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

一般的には、シングルバッファディスプレイモデルを使用することで、画面がちらつく場合があります(つまり、画面に表示しているメモリと同じチャンクを更新しています)。私はAllegroに慣れていないので、https://wiki.allegro.cc/index.php?title=Double_bufferingを参照します。 – Aumnayan

+0

@Aumnayan私は自分のコードでダブルバッファリング(私は思う)しました。ループはすべての要素を描画しており、最終的に画面を更新しています。 –

+0

問題です。それはちょうど底にあります。あなたはタイマーを持っていますが、実際にはそれを使ってフレームレートやゲームループのタイミングを制御していません。あなたがやっていることは、キーボードのアップデートを受け取り、それを使ってゲームをアップデートすることです。ボタンを押さなかったときにゲームが動きますか? – rlam12

答えて

2

あなたが二回al_flip_displayを呼んでいる:

は、ここに私のコードです。 al_flip_displayへのコールをmakeScreenBlack()に削除し、もう一方のコールは保持してください。

+0

別の方法を使用して問題は既に解決されています。ありがとう –

関連する問題