- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
好吧,我不确定那是为了代码审查还是为了这个网站,但它有问题,所以我想我来对地方了。我正在尝试使用 C 和 SDL 创建游戏。这是代码(下面的解释):
//Includes
#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <SDL2_gfxPrimitives.h>
//Create some global variables(is there some other way to do that?)
SDL_Window *screen;
SDL_Renderer *renderer;
SDL_Texture *tardis;
SDL_Surface *tardis_surface;
SDL_Texture *gallifrey;
SDL_Surface *gallifrey_surface;
SDL_Surface *pillar_surface;
SDL_Rect tardis_dest;
//Some variables I want to keep throughout the game
float speed = 0;
int pillars = 0;
int pause = 0;
//Those two could change in the future
int WIDTH = 640;
int HEIGHT = 480;
//Define a struct to express the pillars in a better way
typedef struct{
SDL_Rect pillar_up;
SDL_Rect pillar_down;
SDL_Texture *pillar_texture;
}pillar;
//OK, that might be silly, but I create a list of pointers so
//that I can keep track of them afterwards. Is that bad?
pillar *list_dest[4];
//Generate a pillar
void create_pillar(int pillars_no, int xpos)
{
//Generate random height
int height = rand() % 200;
if(height < 50)
height += 50;
pillar pillar_dest;
//Set the coordinates for the upper pillar
pillar_dest.pillar_up.x = xpos;
pillar_dest.pillar_up.y = 0;
pillar_dest.pillar_up.w = 70;
pillar_dest.pillar_up.h = HEIGHT - (height + 180);
//Set the coordinates for the pillar on the ground
pillar_dest.pillar_down.x = xpos;
pillar_dest.pillar_down.y = HEIGHT - height;
pillar_dest.pillar_down.w = 70;
pillar_dest.pillar_down.h = 200;
//Set the pillar texture
pillar_dest.pillar_texture = SDL_CreateTextureFromSurface(
renderer, pillar_surface);
//Allocate space for the pillar and save the address
//in the list_dest
pillar *pillar_destp = malloc(sizeof(pillar_dest));
*pillar_destp = pillar_dest;
list_dest[pillars_no % 3] = pillar_destp;
}
//Check if the Tardis collides with a pillar
int check_collision(SDL_Rect A, SDL_Rect B)
{
//The sides of the rectangles
int leftA, leftB;
int rightA, rightB;
int topA, topB;
int bottomA, bottomB;
//Calculate the sides of rect A
leftA = A.x;
rightA = A.x + A.w;
topA = A.y;
bottomA = A.y + A.h;
//Calculate the sides of rect B
leftB = B.x;
rightB = B.x + B.w;
topB = B.y;
bottomB = B.y + B.h;
//If any of the sides from A are outside of B
if(bottomA < topB)
{
return 0;
}
if(topA > bottomB)
{
return 0;
}
if(rightA < leftB)
{
return 0;
}
if(leftA > rightB)
{
return 0;
}
//Else
return 1;
}
//Render the pillars(shitty function name, whatever...)
void draw_ground()
{
//I always create 3 pillars, no more
if(pillars < 3)
{
create_pillar(pillars, WIDTH + pillars * 240);
pillars += 1;
}
else
{
int i;
for(i = 0; i < 3; i++)
{
//Free the previous pillars
pillar *current_pillar;
current_pillar = list_dest[i];
if(current_pillar->pillar_up.x < -70)
{
free(current_pillar->pillar_texture);
free(current_pillar);
create_pillar(pillars, WIDTH);
pillars += 1;
}
else
{
//Check if the Tardis has collided with a pillar and
//display a "game over" message.
if(check_collision(current_pillar->pillar_up, tardis_dest) ||
check_collision(current_pillar->pillar_down, tardis_dest))
{
SDL_Rect target;
target.x = (WIDTH / 2) - 100;
target.y = (HEIGHT / 2) - 50;
target.w = 200;
target.h = 100;
TTF_Font *font;
font = TTF_OpenFont("DALEK.ttf", 40);
SDL_Surface *text;
SDL_Color text_color = {255, 255, 0};
text = TTF_RenderText_Solid(font,
"GAME OVER",
text_color);
SDL_Texture *game_over;
game_over = SDL_CreateTextureFromSurface(renderer, text);
SDL_RenderCopy(renderer, game_over, NULL, &target);
pause = 1;
int j;
for(j = 0; j < 3; j++)
{
free(list_dest[j]);
}
pillars = 0;
break;
}
//Render the pillars
double angle = 180.0;
current_pillar->pillar_up.x -= 10;
current_pillar->pillar_down.x -= 10;
SDL_RenderCopyEx(renderer, current_pillar->pillar_texture,
NULL, ¤t_pillar->pillar_up, angle = 0.0,
NULL, SDL_FLIP_VERTICAL);
SDL_RenderCopy(renderer, current_pillar->pillar_texture,
NULL, ¤t_pillar->pillar_down);
}
}
}
}
//Render the pillar counter
void draw_counter()
{
SDL_Rect counter;
counter.x = WIDTH - 50;
counter.y = 10;
counter.w = 40;
counter.h = 50;
TTF_Font *font;
font = TTF_OpenFont("DALEK.ttf", 40);
SDL_Surface *count;
SDL_Color text_color = {0, 255, 255};
char count_text[3];
if(pillars >= 3)
sprintf(count_text, "%d", pillars - 3);
else
sprintf(count_text, "%d", pillars);
count = TTF_RenderText_Solid(font,
count_text,
text_color);
SDL_Texture *pillar_counter;
pillar_counter = SDL_CreateTextureFromSurface(renderer, count);
SDL_RenderCopy(renderer, pillar_counter, NULL, &counter);
//This is the last function of the game loop, so I suppose it's a good
//place for the SDL_RenderPresent
SDL_RenderPresent(renderer);
}
//Load the images used in the game
void load_images()
{
tardis_surface = IMG_Load("files/tardis.bmp");
gallifrey_surface = IMG_Load("files/gallifrey.bmp");
pillar_surface = IMG_Load("files/pipe.bmp");
}
//Create the background and the Tardis in it's initial place
void create_sprites()
{
//Create area for the TARDIS
tardis_dest.x=50;
tardis_dest.y=100;
tardis_dest.w=50;
tardis_dest.h=80;
//Color key the TARDIS and create texture
Uint32 colorkey = SDL_MapRGB(tardis_surface->format,0,0,0);
//SDL_DisplayFormat(tardis_surface);
SDL_SetColorKey(tardis_surface, SDL_SRCCOLORKEY, colorkey); // That doesn't work!!!!!
//Why? Any ideas?
tardis = SDL_CreateTextureFromSurface(renderer, tardis_surface);
//Create texture for the Gallifreyan background
gallifrey = SDL_CreateTextureFromSurface(renderer, gallifrey_surface);
//Clear the renderer
SDL_RenderClear(renderer);
//Add textures to renderer
SDL_RenderCopy(renderer, gallifrey, NULL, NULL);
SDL_RenderCopy(renderer, tardis, NULL, &tardis_dest);
//Update renderer
//SDL_RenderPresent(renderer);
}
//Update the Tardis' position
void update_sprites(float time)
{
speed += time * 28;
if(tardis_dest.y > 460)
{
tardis_dest.y = 460;
speed = 0;
}
else if(tardis_dest.y < 0)
{
tardis_dest.y = 0;
speed = 0;
}
else
{
tardis_dest.y += speed;
SDL_RenderCopy(renderer, gallifrey, NULL, NULL);
SDL_RenderCopy(renderer, tardis, NULL, &tardis_dest);
//SDL_RenderPresent(renderer);
}
}
//Change the speed when clicked
void ignite()
{
if(speed > 0)
speed = -10;
else
speed -= 10;
}
//The main function
int main(int argc, char *argv[])
{
SDL_Event ev;
int active = 1;
if(SDL_Init(SDL_INIT_EVERYTHING) != 0)
fprintf(stderr, "Could not initialize SDL. SDL Error: %s\n", SDL_GetError());
else
printf("SDL initialized.\n");
if(TTF_Init() == 0)
fprintf(stderr, "TTF initialized.\n");
else
fprintf(stderr, "Could not initialize TTF.\n");
//Open main window
screen = SDL_CreateWindow
(
"First Game", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
WIDTH,
HEIGHT,
SDL_WINDOW_SHOWN
);
if(!screen)
fprintf(stderr, "Could not set video mode: SDL Error: %s\n", SDL_GetError());
renderer = SDL_CreateRenderer(screen, 0, SDL_RENDERER_ACCELERATED);
//Draw the environment
load_images();
create_sprites();
//Set time
Uint32 current_time, old_time;
float time_passed;
current_time = SDL_GetTicks();
while(active)
{
//Update time
old_time = current_time;
current_time = SDL_GetTicks();
time_passed = (current_time - old_time) / 1000.0f;
//Handle Events
while(SDL_PollEvent(&ev))
{
if(ev.type == SDL_QUIT)
active = 0;
if(ev.type == SDL_MOUSEBUTTONDOWN)
{
if(pause)
{
pause = 0;
}
else
ignite();
}
}
if(pause)
continue;
update_sprites(time_passed);
draw_ground();
draw_counter();
SDL_Delay(40);
}
//Exit
SDL_FreeSurface(tardis_surface);
SDL_FreeSurface(gallifrey_surface);
SDL_Quit();
printf("SDL terminated. Have a nice day...\n");
return 0;
}
读起来不错吧?它可能有很多缺陷,因为这是我第一次尝试游戏编程,但我的主要问题是玩了一段时间后我遇到了段错误。使用 gdb,我发现是以下命令导致了问题:
count = TTF_RenderText_Solid(font,
count_text,
text_color);
位于 draw_counter() 函数的第 214 行(中间某处)。问题是:为什么?我想这与我正在做的内存分配有关(我还在学习 C,这是一个非常棘手的部分,来自 Python)。如果有人可以提供一些有用的信息?谢谢顺便说一句,请不要用通常的“不要使用 C,学习 C++ 或 Java”甚至“只使用 Unity”来回应,我想学习 C,并可能在此过程中学习一些游戏编程。
最佳答案
肯定是不断调用font = TTF_OpenFont("DALEK.ttf", 40);
,过了一段时间就失败了。
SDL 为每个打开的字体分配内存,有时您会用完。 (也许文件保持打开状态并且您的系统用完了文件句柄。)您需要关闭字体句柄:添加
TTF_CloseFont( font );
在打开它的例程结束时。或者,只打开字体一次(在您的 main
中)例程并将它们的句柄保存在全局变量中。
顺便说一句,我还注意到你对表面的处理也很自由。使用类似的函数 SDL_FreeSurface
当你完成一个时,再次防止只使用一次资源但仍然分配它们。 (这是针对 SDL 1.0 的,我已经习惯了。查看 SDL 2 文档。)
关于c - SDL2 : getting segmentation fault with TTF_RenderText after some time?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27785880/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!