C++ SDL2 / Scrolling Collision Issue - c++

As the title suggests, I am trying to implement collision with scrolling.
The code here isn't the tidiest and it doesn't make use of object-oriented programming. But this code is a prototype for collision in a game I am making so I can reuse in that game.
Anyway, when I wrote this code and implemented no scrolling, the collision worked fine. However, when I implemented scrolling, suddenly, one pixel of the rectangle that represent the player gets stuck in the rectangles I've used to test the collision.
Here's the code.
Main.cpp:
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
#include "SDL_ttf.h"
using namespace std;
int main(int argc, char *argv[]) {
SDL_Init(SDL_INIT_EVERYTHING);
IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG);
Mix_Init(MIX_INIT_MP3);
Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 640);
TTF_Init();
SDL_Window *Window = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1000, 600, SDL_WINDOW_SHOWN);
SDL_Renderer *Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
bool quit = false;
SDL_Event Event;
SDL_Rect Box;
Box.w = 25;
Box.h = 25;
Box.x = 500 - int(Box.w / 2);
Box.y = 300 - int(Box.h / 2);
int CAMERA_X = 0;
int CAMERA_Y = 0;
int xVel = 0;
int yVel = 0;
SDL_Rect RECTS[3];
RECTS[0].x = 50;
RECTS[0].y = 50;
RECTS[0].w = 50;
RECTS[0].h = 100;
RECTS[1].x = 150;
RECTS[1].y = 50;
RECTS[1].w = 50;
RECTS[1].h = 100;
RECTS[2].x = 250;
RECTS[2].y = 50;
RECTS[2].w = 50;
RECTS[2].h = 100;
SDL_Rect CAM_RECTS[3];
CAM_RECTS[0].x = 50;
CAM_RECTS[0].y = 50;
CAM_RECTS[0].w = 50;
CAM_RECTS[0].h = 100;
CAM_RECTS[1].x = 150;
CAM_RECTS[1].y = 50;
CAM_RECTS[1].w = 50;
CAM_RECTS[1].h = 100;
CAM_RECTS[2].x = 250;
CAM_RECTS[2].y = 50;
CAM_RECTS[2].w = 50;
CAM_RECTS[2].h = 100;
const Uint8 *Input = NULL;
while (!quit) {
Input = SDL_GetKeyboardState(NULL);
while (SDL_PollEvent(&Event)) {
if (Event.type == SDL_QUIT) {
quit = true;
}
}
if (Input[SDL_SCANCODE_RIGHT]) {
xVel = -7;
} else if (Input[SDL_SCANCODE_LEFT]) {
xVel = 7;
} else {
xVel = 0;
}
if (Input[SDL_SCANCODE_UP]) {
yVel = 7;
} else if (Input[SDL_SCANCODE_DOWN]) {
yVel = -7;
} else {
yVel = 0;
}
for (unsigned int i = 0; i < 3; i++) {
CAM_RECTS[i].x = RECTS[i].x + CAMERA_X;
CAM_RECTS[i].y = RECTS[i].y + CAMERA_Y;
}
CAMERA_X += xVel;
for (unsigned int i = 0; i < 3; i++) {
if (Box.x <= CAM_RECTS[i].x + CAM_RECTS[i].w && Box.x + Box.w >= CAM_RECTS[i].x && Box.y <= CAM_RECTS[i].y + CAM_RECTS[i].h && Box.y + Box.h >= CAM_RECTS[i].y) {
if (Box.x <= CAM_RECTS[i].x + CAM_RECTS[i].w && Box.x + Box.w >= CAM_RECTS[i].x) {
CAMERA_X += -xVel;
}
}
}
CAMERA_Y += yVel;
for (unsigned int i = 0; i < 3; i++) {
if (Box.x <= CAM_RECTS[i].x + CAM_RECTS[i].w && Box.x + Box.w >= CAM_RECTS[i].x && Box.y <= CAM_RECTS[i].y + CAM_RECTS[i].h && Box.y + Box.h >= CAM_RECTS[i].y) {
if (Box.y <= CAM_RECTS[i].y + CAM_RECTS[i].h && Box.y + Box.h >= CAM_RECTS[i].y) {
CAMERA_Y += -yVel;
}
}
}
SDL_SetRenderDrawColor(Renderer, 0, 0, 0, 255);
SDL_RenderClear(Renderer);
SDL_SetRenderDrawColor(Renderer, 255, 255, 255, 255);
SDL_RenderFillRect(Renderer, &Box);
SDL_SetRenderDrawColor(Renderer, 255, 255, 255, 255);
for (unsigned int i = 0; i < 3; i++) {
SDL_RenderFillRect(Renderer, &CAM_RECTS[i]);
}
SDL_RenderPresent(Renderer);
}
Input = NULL;
SDL_DestroyRenderer(Renderer);
SDL_DestroyWindow(Window);
TTF_Quit();
Mix_CloseAudio();
Mix_Quit();
IMG_Quit();
SDL_Quit();
return 0;
}
Please help.
Thank you very much :)

Ok, I changed answer, now it should work without jittering.
It's definitely not the best solution, but it would depends on wider concepion of your program.
int sign(int x)
{
return (x > 0) - (x < 0);
}
/* Movement values are updated by referenced arguments.*/
void check_collisions(SDL_Rect* obj_rects, unsigned num_of_obj,
SDL_Rect obstacle, int& horizontal_move, int& vertical_move)
{
for (unsigned int i = 0; i < num_of_obj; i++)
{
int obj_new_x = obj_rects[i].x + horizontal_move;
// Horizontal collision
if (obj_new_x < (obstacle.x + obstacle.w)
&& (obj_new_x + obj_rects[i].w) > obstacle.x
&& obj_rects[i].y < (obstacle.y + obstacle.h)
&& (obj_rects[i].h + obj_rects[i].y) > obstacle.y)
{
// Calculate maximal possible horizontal movement.
if (sign(horizontal_move) == 1)
horizontal_move = obstacle.x - (obj_rects[i].x + obj_rects[i].w);
else if (sign(horizontal_move) == -1)
horizontal_move = (obstacle.x + obstacle.w) - obj_rects[i].x;
}
int obj_new_y = obj_rects[i].y + vertical_move;
// Vertical collision
if (obj_rects[i].x < (obstacle.x + obstacle.w)
&& (obj_rects[i].x + obj_rects[i].w) > obstacle.x
&& obj_new_y < (obstacle.y + obstacle.h)
&& (obj_new_y + obj_rects[i].h) > obstacle.y)
{
if (sign(vertical_move) == 1)
vertical_move = obstacle.y - (obj_rects[i].y + obj_rects[i].h);
else if (sign(vertical_move) == -1)
vertical_move = (obstacle.y + obstacle.h) - obj_rects[i].y;
}
}
}
int cam_velocity = 5;
...
while (!quit) {
...
if (Input[SDL_SCANCODE_RIGHT])
{
x_movement = cam_velocity;
}
else if (Input[SDL_SCANCODE_LEFT])
{
x_movement = -cam_velocity;
}
if (Input[SDL_SCANCODE_UP])
{
y_movement = -cam_velocity;
}
else if (Input[SDL_SCANCODE_DOWN])
{
y_movement = cam_velocity;
}
check_collisions(CAM_RECTS, 3, Box, x_movement, y_movement);
CAMERA_X += x_movement;
CAMERA_Y += y_movement;
for (unsigned int i = 0; i < 3; i++) {
CAM_RECTS[i].x = RECTS[i].x + CAMERA_X;
CAM_RECTS[i].y = RECTS[i].y + CAMERA_Y;
}
...

Related

How to add a game over function in this Doodle Jump game in sfml?

How to add a game over? If you are not familiar with the Doodle Jump game, it is where a character will need to bounce off a platform to progress. But if the player doesnt land on the platform, the game is over.
But in my case, even if I dont land on a platform, the game still continues.
`
#include <SFML/Graphics.hpp>
#include <time.h>
using namespace sf;
struct point
{
int x, y;
};
int main()
{
srand(time(0));
RenderWindow app(VideoMode(400, 533), "Doodle Game!");
app.setFramerateLimit(60);
Texture t1, t2, t3;
t1.loadFromFile("C:/Users/Dani/Documents/GAMES SFML/16_Games/02 Doodle Jump/images/background.png");
t2.loadFromFile("C:/Users/Dani/Documents/GAMES SFML/16_Games/02 Doodle Jump/images/platform.png");
t3.loadFromFile("C:/Users/Dani/Documents/GAMES SFML/16_Games/02 Doodle Jump/images/mark.png");
Sprite sBackground(t1), sPlat(t2), sPers(t3);
point plat[20];
for (int i = 0; i < 10; i++)
{
plat[i].x = rand() % 400;
plat[i].y = rand() % 533;
}
int x = 100, y = 100, h = 200;
float dx = 0, dy = 0;
while (app.isOpen())
{
Event e;
while (app.pollEvent(e))
{
if (e.type == Event::Closed)
app.close();
}
if (Keyboard::isKeyPressed(Keyboard::Right)) x += 3;
if (Keyboard::isKeyPressed(Keyboard::Left)) x -= 3;
dy += 0.2;
y += dy;
if (y > 500) dy = -10;
if (y < h)
for (int i = 0; i < 10; i++)
{
y = h;
plat[i].y = plat[i].y - dy;
if (plat[i].y > 533) { plat[i].y = 0; plat[i].x = rand() % 400; }
}
for (int i = 0; i < 10; i++)
if ((x + 50 > plat[i].x) && (x + 20 < plat[i].x + 68)
&& (y + 70 > plat[i].y) && (y + 70 < plat[i].y + 14) && (dy > 0)) dy = -10;
sPers.setPosition(x, y);
app.draw(sBackground);
app.draw(sPers);
for (int i = 0; i < 10; i++)
{
sPlat.setPosition(plat[i].x, plat[i].y);
app.draw(sPlat);
}
app.display();
}
return 0;
}
`
Thank you, all of your answers will be appreciated.

Creating an X amount of rectangles which are not intersecting each other on a specified screen size

I managed with some help to know how when two rectangles are intersecting each other, from there it should be easy to make what i just said in the title but ...
So, short story of what i just did below:
Created a for loop from 1 to Number_of_Obstacles
In that for an random obstacle (rectangle/square) is created and it will be checked if it is overlaped with all other obstacles created from 0 to the loop contor (or in other words every obstacle stored in the vector)
Again, the doOverLap function works. Tested it with a square which i made a controller and other random rectangle created on the screen. It outputs in chat when i'm overlaping it and trust me, i overlaped it from all angles.
Here is a picture with the overlaping issue: https://imgur.com/a/ZzorOcD
bool doOverlap(A a, B b)
{
if (a.x1 > b.x2 || b.x1 > a.x2)
return false;
if (a.y1 > b.y2 || b.y1 > a.y2)
return false;
return true;
}
struct Obstacles {
int X, Y;
void Create_Random_Obstacles(Obstacles Obj[], int Numar_Obstacole)
{
srand(time(NULL));
A Rectangle_1;
B Rectangle_2;
/* To avoid rendering outside of the screen */
int X_Axis = X_RESOLUTION - 40;
int Y_Axis = Y_RESOLUTION - 40;
int obstacolX = rand() % X_Axis + 1;
int obstacolY = rand() % Y_Axis + 1;
Obj[0].X = obstacolX;
Obj[0].Y = obstacolY;
for (int i = 1; i < Numar_Obstacole; i++)
{
obstacolX = rand() % X_Axis + 1;
obstacolY = rand() % Y_Axis + 1;
Rectangle_1.x1 = obstacolX;
Rectangle_1.x2 = obstacolX + 40;
Rectangle_1.y1 = obstacolY;
Rectangle_1.y2 = obstacolY + 40;
for (int j = 0; j < i; j++) {
Rectangle_2.x1 = Obj[j].X;
Rectangle_2.x2 = Obj[j].X + 40;
Rectangle_2.y1 = Obj[j].Y;
Rectangle_2.y2 = Obj[j].Y + 40;
if (doOverlap(Rectangle_1, Rectangle_2))
{
std::cout << "Overlap\n";
}
else
{
Obj[i].X = obstacolX;
Obj[i].Y = obstacolY;
}
}
}
}
void Render(SDL_Renderer* renderer, Obstacles Obj[], int Numar_Obstacole) {
for (int i = 0; i < Numar_Obstacole; i++)
{
SDL_Rect r{ Obj[i].X, Obj[i].Y, 40, 40 };
SDL_SetRenderDrawColor(renderer, 255, 160, 15, 255);
SDL_RenderFillRect(renderer, &r);
}
}
};
Restart selection when collision occurs, something like:
bool Has_Overlap(const Obstacles& obj, const Obstacles* Objs, int Size)
{
B Rectangle_2;
Rectangle_2.x1 = obs.X;
Rectangle_2.x2 = obs.X + 40;
Rectangle_2.y1 = obs.Y;
Rectangle_2.y2 = obs.Y + 40;
for (int i = 0; i != Size; ++i) {
A Rectangle_1;
Rectangle_1.x1 = Obs[i].X;
Rectangle_1.x2 = Obs[i].X + 40;
Rectangle_1.y1 = Obs[i].Y;
Rectangle_1.y2 = Obs[i].Y + 40;
if (doOverlap(Rectangle_1, Rectangle_2)) {
return true;
}
}
return false;
}
void Create_Random_Obstacles(Obstacles* Objs, int Size)
{
/* To avoid rendering outside of the screen */
const int X_Axis = X_RESOLUTION - 40;
const int Y_Axis = Y_RESOLUTION - 40;
for (int i = 0; i < Size; i++)
{
do {
Objs[i].X = rand() % X_Axis + 1;
Objs[i].Y = rand() % Y_Axis + 1;
} while (Has_Overlap(Objs[i], Objs, i));
}
}

SDL 2.0 Menu Function

I'm currently trying to write a menu function for one of my projects. I'm remaking pac-man and I'd like to be able to modularize the main menu, calling it when I want it to appear. I'm thinking an SDL_surface and a TTF font are all I need as parameters for this particular function.
I ran into trouble when I used SDL functions only available in SDL 1.2 as opposed to 2.0. I would like this code to be as reusable as possible. How would you guys approach this problem? I have some sample code below, though not all of it is my own. I'd like to get something like this working:
int showmenu(SDL_Surface* screen, TTF_Font* font)
{
Uint32 time;
int x, y;
const int NUMMENU = 2;
const char* labels[NUMMENU] = {"Continue","Exit"};
SDL_Surface* menus[NUMMENU];
bool selected[NUMMENU] = {0,0};
SDL_Color color[2] = {{255,255,255},{255,0,0}};
menus[0] = TTF_RenderText_Solid(font,labels[0],color[0]);
menus[1] = TTF_RenderText_Solid(font,labels[1],color[0]);
SDL_Rect pos[NUMMENU];
pos[0].x = screen->clip_rect.w/2 - menus[0]->clip_rect.w/2;
pos[0].y = screen->clip_rect.h/2 - menus[0]->clip_rect.h;
pos[1].x = screen->clip_rect.w/2 - menus[0]->clip_rect.w/2;
pos[1].y = screen->clip_rect.h/2 + menus[0]->clip_rect.h;
SDL_FillRect(screen,&screen>clip_rect,SDL_MapRGB(screen>format,0x00,0x00,0x00));
SDL_Event event;
while(1)
{
time = SDL_GetTicks();
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
SDL_FreeSurface(menus[0]);
SDL_FreeSurface(menus[1]);
return 1;
case SDL_MOUSEMOTION:
x = event.motion.x;
y = event.motion.y;
for(int i = 0; i < NUMMENU; i += 1)
{
if(x >= pos[i].x && x <= pos[i].x + pos[i].w &&
y >= pos[i].y && y <= pos[i].y + pos[i].h)
{
if(!selected[i])
{
selected[i] = 1;
SDL_FreeSurface(menus[i]);
menus[i] = TTF_RenderText_Solid(font,labels[i],color[1]);
}
}
else
{
if(selected[i])
{
selected[i] = 0;
SDL_FreeSurface(menus[i]);
menus[i] = TTF_RenderText_Solid(font,labels[i],color[0]);
}
}
}
break;
case SDL_MOUSEBUTTONDOWN:
x = event.button.x;
y = event.button.y;
for(int i = 0; i < NUMMENU; i += 1)
{
if(x >= pos[i].x && x <= pos[i].x + pos[i].w &&
y >= pos[i].y && y <= pos[i].y + pos[i].h)
{
SDL_FreeSurface(menus[0]);
SDL_FreeSurface(menus[1]);
return i;
}
}
break;
case SDL_KEYDOWN:
if(event.key.keysym.sym == SDLK_ESCAPE)
{
SDL_FreeSurface(menus[0]);
SDL_FreeSurface(menus[1]);
return 0;
}
}
}
for(int i = 0; i < NUMMENU; i += 1)
{
SDL_BlitSurface(menus[i],NULL,screen,&pos[i]);
}
}
}

Flickering screen ALLEGRO 5

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;
}
You're calling al_flip_display twice. You should remove the call to al_flip_display in makeScreenBlack() and keep the other one.

SDL_Rect not visible

I have multiple SDL_Rects creating a snake that is supposed to stay in a specific area. Sometimes when the "snake" reaches the boundaries a part disappears.
void Snake::update(SDL_Surface *screen, int level)
{
old_pos.first = snake_rect[0];
if(x_axis)
snake_rect[0].x += snake_speed * level * direction_multiplier;
else if(!x_axis)
snake_rect[0].y += snake_speed * level * direction_multiplier;
for(unsigned int i = 1; i < snake_rect.size(); ++i)
{
old_pos.second = snake_rect[i];
snake_rect[i] = old_pos.first;
old_pos.first = old_pos.second;
}
boundariesCheck(screen);
/// Making the enemy move randomly
if(rand() % 100 < 10)
{
if(x_axis)
{
x_axis = false;
direction.second = rand() % 2;
if(direction.second)
direction_multiplier = 1;
else if(!direction.second)
direction_multiplier = -1;
}
else if(!x_axis)
{
x_axis = true;
direction.first = rand() % 2;
if(direction.first)
direction_multiplier = 1;
else if(!direction.first)
direction_multiplier = -1;
}
}
}
void Snake::draw(SDL_Surface *screen)
{
for(unsigned int i = 1; i < snake_rect.size(); ++i)
{
SDL_FillRect(screen, &snake_rect[i], 0xFF0000);
}
SDL_FillRect(screen, &snake_rect[0], 0xFF5500);
}