I am trying to figure out what's the difference between pygame and SDL2 rectangle drawing. Here is my C code:
#include <SDL2/SDL.h>
const int WIDTH = 800;
const int HEIGHT = 600;
const int BOUNDARY_H[] = { 0, WIDTH };
const int BOUNDARY_V[] = { 0, HEIGHT };
typedef enum { false, true } bool;
typedef struct {
SDL_Rect rect;
SDL_Color color;
float x_velocity;
float y_velocity;
float speed;
} Cube;
void bounce(Cube *cube) {
if (cube->rect.x < BOUNDARY_H[0] || cube->rect.x + cube->rect.w > BOUNDARY_H[1])
cube->x_velocity = -cube->x_velocity;
if (cube->rect.y < BOUNDARY_V[0] || cube->rect.y + cube->rect.h > BOUNDARY_V[1])
cube->y_velocity = -cube->y_velocity;
}
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
int main(int argc, char *argv[]) {
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
Cube cube = { {0, 0, 100, 100}, {255, 0, 0, 255}, 5, 5, 5 };
SDL_Event event;
bool running = true;
while (running) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
running = false;
}
cube.rect.x += cube.x_velocity;
cube.rect.y += cube.y_velocity;
bounce(&cube);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, cube.color.r, cube.color.g, cube.color.b, cube.color.a);
SDL_RenderFillRect(renderer, &cube.rect);
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
and python code:
import math
import pygame as pg
WIDTH = 800
HEIGHT = 600
CENTER_X = WIDTH / 2
CENTER_Y = HEIGHT / 2
RED = (255, 0, 0)
BOUNDARY_H = (0, WIDTH)
BOUNDARY_V = (0, HEIGHT)
class Cube:
def __init__(self, **kwargs):
self.rect = kwargs.get('rect', pg.Rect(0, 0, 0, 0))
self.color = kwargs.get('color', (0, 0, 0, 0))
self._speed = 0
self._x_velocity = 0
self._y_velocity = 0
@property
def speed(self):
return self._speed
@speed.setter
def speed(self, x):
if math.isnan(x):
raise ValueError('Is not a number')
if x < 0:
raise ValueError('Should be positive')
self._speed = x
@property
def x_velocity(self):
return self._x_velocity
@x_velocity.setter
def x_velocity(self, x):
if math.isnan(x):
raise ValueError('Is not a number')
self._x_velocity = x
@property
def y_velocity(self):
return self._y_velocity
@y_velocity.setter
def y_velocity(self, y):
if math.isnan(y):
raise ValueError('Is not a number')
self._y_velocity = y
def bounce(rect):
if rect.rect.x < BOUNDARY_H[0] or rect.rect.x + rect.rect.w > BOUNDARY_H[1]:
rect.x_velocity = -rect.x_velocity
if rect.rect.y < BOUNDARY_V[0] or rect.rect.y + rect.rect.h > BOUNDARY_V[1]:
rect.y_velocity = -rect.y_velocity
pg.init()
screen = pg.display.set_mode((WIDTH, HEIGHT), vsync=1, flags=pg.SCALED)
rectangle = pg.Rect((0, 0, 100, 100))
rectangle = {
'rect': rectangle,
'color': RED
}
cube = Cube(**rectangle)
cube.speed = 5.0
cube.x_velocity = cube.speed
cube.y_velocity = cube.speed
clock = pg.time.Clock()
running = True
while running:
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
cube.rect.x += cube.x_velocity
cube.rect.y += cube.y_velocity
bounce(cube)
screen.fill((0, 0, 0, 0))
pg.draw.rect(screen, cube.color, cube.rect)
pg.display.flip()
clock.tick(30)
pg.quit()
When I run C SDL2 code, the rect (Cube) is moving smoothly without flickering, beside pygame does.
Build:
sudo apt install libsdl2-dev; gcc main.c -lSDL2; ./a.out
pip install pygame; python main.py
How to reduce flickering in python code? I have already tried to add flag pg.SCALED
and others. Tried to pass vsync=1
. What do I wrong?
It is something with my local python. I've tried to run some code to get it busy
n = 100000
r = n + (n - 1)
for i in range(n):
s = r - (n + i)
h = r - (s * 2)
print(' ' * s, '#' * h)
Time shows 5.01s
that is too long. On another machine, time is less and there is no image tearing with the same code. Question is closed.