所以我正试图深入研究SDL2。到目前为止,我已经构建了以下简单的程序。它所做的只是在屏幕上渲染一个矩形,并让它快速改变颜色。
game.h
#include<SDL2/SDL.h>
#include<stdbool.h>
typedef struct Game {
bool finished;
SDL_Event curevent;
SDL_Window* mainwin;
SDL_Renderer* mainren;
}Game;
Game *initGame();
void destoryGame(Game*);
void drawRect(Game*);
void handleEvents(Game*);
game.c
#include<SDL2/SDL.h>
#include<malloc.h>
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include"game.h"
Game *initGame() {
Game *game = NULL;
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(stderr,"Error: %s",SDL_GetError());
} else {
game = malloc(sizeof(Game));
game->finished = false;
game->mainwin = SDL_CreateWindow("Main Window",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
800, 640,
SDL_WINDOW_RESIZABLE);
if(game->mainwin == NULL) {
fprintf(stderr,"Error: %s",SDL_GetError());
} else {
game->mainren = SDL_CreateRenderer(game->mainwin, -1,
SDL_RENDERER_ACCELERATED);
if(game->mainren == NULL) {
fprintf(stderr,"Error: %s",SDL_GetError());
} else {
SDL_SetRenderDrawColor(game->mainren,0,0,0,0xFF);
SDL_RenderClear(game->mainren);
}
}
}
return game;
}
void destoryGame(Game *game) {
free(game);
SDL_Quit();
printf("Exiting ...n");
}
void handleEvents(Game *game) {
while(SDL_PollEvent(&(game->curevent)) != 0) {
if(game->curevent.type == SDL_QUIT) {
game->finished = true;
}
}
}
void drawRect(Game *game) {
int r, b, g, h, w;
srand(time(NULL));
r = rand() % 0xFF + 1;
b = rand() % 0xFF + 1;
g = rand() % 0xFF + 1;
SDL_GetWindowSize(game->mainwin,&h,&w);
SDL_Rect rect = {h/4,w/4,h/2,h/2};
SDL_SetRenderDrawColor(game->mainren,r,b,g,0xFF);
SDL_RenderFillRect(game->mainren, &rect);
SDL_RenderPresent(game->mainren);
}
main.c
#include"game.h"
int main() {
Game* game = initGame();
do {
handleEvents(game);
drawRect(game);
} while((game->finished != true));
destoryGame(game);
return 0;
}
我使用的是Linux系统。Ubuntu 16.04。我用编译
SRC_FILES = ./src/main.c ./src/game.c
CC_FLAGS = -Wall -Wextra -Os -g -lSDL2 -std=gnu11
CC = gcc
all:
${CC} ${SRC_FILES} -o game ${CC_FLAGS}
这个程序编译和运行都没有问题。输出看起来像这样:
http://imgur.com/U5B6hB0
我想知道为什么每种新颜色之间都会有第二次延迟?
直觉会告诉我,每次循环迭代时都会有一种新的颜色。应该是每秒数百次。也许看起来像这样:
https://youtu.be/AjbrmfjJRk0?t=6m3s
是什么原因造成了这种延误?还是我错过了对代码的理解,而它正按照它应该做的那样做?
伪随机数生成器通过对前一个值进行计算来生成可预测的数字序列。
举个简单的例子:
int lastValue;
int rand(void) {
lastValue = (lastValue * 13) / 7;
return lastValue;
}
当然,rand()
的实际实现更为复杂。
当没有以前的数字时,你必须使用默认值,如果默认值总是相同的(例如,当你启动一个程序时总是零),它总是为所有程序生成完全相同的序列。
要解决此问题,您可以设置"以前的初始编号"或种子编号。这就是srand()
的作用。
现在。。。
每次绘制矩形时都使用srand()
,并从当前时间获取种子值。如果当前时间不变,则种子是相同的,因此数字序列与上次相同。
当前时间每秒更改一次。
您正在drawRect中用对srand()
的调用重新设定随机数生成器的种子。您将提供time()
的返回值作为新种子,由于它报告自epoch开始以来的时间(以秒为单位),因此每秒只更改一次。然后调用rand()
来获得矩形颜色的随机RGB值。
因为您使用返回值time()
重新播种RNG,所以即使您的主函数经常调用drawRect()
,您也只能大约每秒看到一个新的随机颜色。你可能认为rand()
仍然应该给你一个不同的"随机"值,但这不是大多数RNG的工作方式。它们中的许多给出了给定种子值的可预测数字序列,因此被称为"伪随机数生成器"。这实际上在可测试性方面有好处。
如果您取消了对srand()
的调用,或者将其移动到drawRect()
之外(最好是移动到主游戏循环之外),您应该会看到颜色更频繁地变化。