时钟的SDL2实现

今天花了一下午时间写了一下这个程序。一开始摸不着头脑,更是走了歪路,所以浪费了很多时间。最后竟是无意间在贴吧的帖子上看见一个函数,才解决了困扰我很久的图片旋转的问题。

基本实现思路是这样:有一个表盘图片和三个指针图片,表盘图片作为背景,指针图片起始点在表盘的中央。获取系统时间,计算指针角度,重绘。监听退出事件,程序退出。

实现效果如下:
此处输入图片的描述

具体代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include "SDL2/SDL.h"
#include <stdio.h>
#include <time.h>
const int SCREEN_WIDTH = 512;
const int SCREEN_HEIGHT = 489;
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
/* print out error information */
void ShowError() {
printf("%s\n", SDL_GetError());
}
/* load image by filename */
SDL_Texture* LoadImage(char file[]) {
SDL_Surface *loadedImage = NULL;
SDL_Texture *texture = NULL;
loadedImage = SDL_LoadBMP(file);
if (loadedImage != NULL) {
texture = SDL_CreateTextureFromSurface(renderer, loadedImage);
SDL_FreeSurface(loadedImage);
}
else
ShowError();
return texture;
}
/* show the backgroud */
void ApplyBackground(SDL_Texture *tex, SDL_Renderer *rend) {
SDL_Rect pos;
SDL_QueryTexture(tex, NULL, NULL, &pos.w, &pos.h);
pos.x = pos.y = 0;
SDL_RenderCopy(renderer, tex, NULL, NULL);
}
/* show the pointers by angle */
void ApplySurface(SDL_Texture *tex, SDL_Renderer *rend, double angle) {
int x = SCREEN_WIDTH/2+7;
int y = SCREEN_HEIGHT/2;
SDL_RendererFlip flip = SDL_FLIP_HORIZONTAL | SDL_FLIP_VERTICAL;
SDL_Rect pos;
SDL_QueryTexture(tex, NULL, NULL, &pos.w, &pos.h);
pos.x = x;
pos.y = y;
SDL_Point p = {0, 0};
SDL_RenderCopyEx(renderer, tex, NULL, &pos, angle, &p, flip);
}
int main() {
if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {
ShowError();
return 1;
}
/* Initial Window */
window = SDL_CreateWindow("Clock", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (window == NULL) {
ShowError();
return 2;
}
/* Initial Renderer */
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (renderer == NULL) {
ShowError();
return 3;
}
/* load pictures */
SDL_Texture *background = NULL, *hour = NULL,
*min = NULL, *second = NULL;
background = LoadImage("background.bmp");
hour = LoadImage("hour.bmp");
min = LoadImage("min.bmp");
second = LoadImage("second.bmp");
if (background == NULL | hour == NULL | min == NULL | second == NULL) {
return 4;
}
time_t rawtime;
struct tm *timeinfo;
int quit = 0;
SDL_Event e;
/* begin to run */
while (!quit) {
time(&rawtime);
timeinfo = localtime(&rawtime);
/* get system time */
int h = timeinfo->tm_hour % 12, m = timeinfo->tm_min,
s = timeinfo->tm_sec;
/* calculate their angles */
double angle_s = s*1.0*6 - 90;
double angle_m = m*1.0*6 + angle_s/360*6 - 90;
double angle_h = h*1.0*30 + angle_m/360/2 - 90;
/* repaint */
SDL_RenderClear(renderer);
ApplyBackground(background, renderer);
ApplySurface(hour, renderer, angle_h);
ApplySurface(min, renderer, angle_m);
ApplySurface(second, renderer, angle_s);
SDL_RenderPresent(renderer);
SDL_Delay(1000);
/* way to quit */
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) // close the window
quit = 1;
if (e.type == SDL_MOUSEBUTTONDOWN) // click the mouse
quit = 1;
}
}
/* Free Memory */
SDL_DestroyTexture(background);
SDL_DestroyTexture(hour);
SDL_DestroyTexture(min);
SDL_DestroyTexture(second);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

文章目录
|