英文:
Received error while trying to add font for Snake Game (C Language)
问题
我正在尝试将字体添加到我的程序中(该程序与字体文件位于同一文件夹中),以显示我的分数和"游戏结束"屏幕上的文字。但似乎它不起作用。我尝试了谷歌搜索解决方案,但只得到了一些人说字体位置错误/尝试另一种字体的回答。对于第一个问题,我确认字体位置是正确的,对于第二个问题,它也不起作用。有没有办法解决这个问题?错误信息
//加载字体到程序中
TTF_Font* font = TTF_OpenFont("arial.ttf", 24);
//如果有错误,打印错误消息
if (font == NULL) {
printf("无法加载字体!错误信息:%s\n", TTF_GetError());
return false;
}
你的程序中已经尝试加载字体文件 "arial.ttf",但可能出现了问题。请确保以下几点:
-
字体文件位置正确:字体文件 "arial.ttf" 应该与你的程序位于同一文件夹中,或者你可以使用绝对文件路径来指定字体文件的位置。
-
TTF 初始化:确保 SDL_ttf 库已经正确初始化。你在代码中使用了
TTF_Init
函数来初始化 SDL_ttf,但请确保没有其他地方出现了问题。 -
字体文件存在:检查字体文件 "arial.ttf" 是否存在于指定的位置,且没有损坏。
如果你仍然遇到问题,请验证这些方面,以确保字体加载的正确性。
英文:
So i am trying to add a font into my program (which is located in the same folder with the program) to display my score and the words for the Game Over screen. But it seems that it is not working. I tried to google for solutions, and all i got is people saying that the font location is wrong / try another font. For the first one, i am confirm the font location is correct and for the second, it does not work also. Is there any way to solve this problem? error
#include <stdio.h>
#include <stdbool.h>
#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <time.h>
//use const int so that the value cannot be changed.
const int WINDOW_WIDTH = 640;
const int WINDOW_HEIGHT = 480;
const int GRID_SIZE = 20;
const int GAME_SPEED = 150;
//array set to 100, indicate the maximu length for the snake is 100 only.
int snakeX[100], snakeY[100];
// Assigning variables.
int snakeLength;
int fruitX, fruitY;
int score;
int direction;
int gameOver;
TTF_Font* font = NULL;
//game window create by SDL
SDL_Window* window = NULL;
//this pointer indicates the rendere associated with the game window.
SDL_Renderer* renderer = NULL;
//error checking
bool init() {
//Obtaining the error by using the SDL_GetError()
//Check if SDL initialization with video support was succesful. If there is error then print message.
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
return false;
}
//This will create a window with the words Snake Game, but if failed will print the error message.
window = SDL_CreateWindow("Snake Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
if (window == NULL) {
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
return false;
}
//Will create renderer that associates with the game window, but if failed will print the error message.
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
printf("Renderer could not be created! SDL_Error: %s\n", SDL_GetError());
return false;
}
//load the font into the program
TTF_Font* font = TTF_OpenFont("arial.ttf",24);
//print message if there is any error
if(font == NULL){
printf("Failed to load the font!: %s\n",TTF_GetError());
return false;
}
return true;
}
//cleaning up and close the SDL resources when game finished. It destroys the renderer and windwow after that quit the program.
void close() {
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
TTF_Quit();
}
//capture the keyboard input
void handleInput() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
//check any quitting game event, for example closing window, if yes then game over.
if (event.type == SDL_QUIT) {
gameOver = true;
}
//check which key has been input.
else if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym) {
case SDLK_UP:
case SDLK_w:
if (direction != 2)
direction = 0;
break;
case SDLK_DOWN:
case SDLK_s:
if (direction != 0)
direction = 2;
break;
case SDLK_LEFT:
case SDLK_a:
if (direction != 1)
direction = 3;
break;
case SDLK_RIGHT:
case SDLK_d:
if (direction != 3)
direction = 1;
break;
}
}
}
}
//generate the fruit position randomly
void generateFruit() {
fruitX = rand() % (WINDOW_WIDTH / GRID_SIZE);
fruitY = rand() % (WINDOW_HEIGHT / GRID_SIZE);
}
//move the snake
void moveSnake() {
for (int i = snakeLength; i > 0; --i) {
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
switch (direction) {
case 0: // Up
snakeY[0] -= 1;
break;
case 1: // Right
snakeX[0] += 1;
break;
case 2: // Down
snakeY[0] += 1;
break;
case 3: // Left
snakeX[0] -= 1;
break;
}
//check if the snake hit the boudary of the window, if yes then game over.
if (snakeX[0] < 0 || snakeX[0] >= WINDOW_WIDTH / GRID_SIZE || snakeY[0] < 0 || snakeY[0] >= WINDOW_HEIGHT / GRID_SIZE) {
gameOver=true;
}
//check collion between head and body, if yes then game over.
for (int i = 1; i < snakeLength; ++i) {
if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
gameOver=true;
}
}
//check if the snake's head collide with the fruit, if yes the score will increase.
if (snakeX[0] == fruitX && snakeY[0] == fruitY) {
score += 1;
snakeLength++;
generateFruit();
}
}
void renderScore(){
SDL_Color textColor = {255,255,255};
char scoreText[20];
sprintf(scoreText, "Score: %d", score);
SDL_Surface* surface = TTF_RenderText_Solid(font, scoreText, textColor);
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
int textWidth = surface->w;
int textHeight = surface->h;
SDL_Rect textRect = {10, 10, textWidth, textHeight};
SDL_RenderCopy(renderer, texture, NULL, &textRect);
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
}
//render everything, the snake, the fruit, the score
void render() {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
for (int i = 0; i < snakeLength; ++i) {
SDL_Rect rect = { snakeX[i] * GRID_SIZE, snakeY[i] * GRID_SIZE, GRID_SIZE, GRID_SIZE };
SDL_RenderFillRect(renderer, &rect);
}
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_Rect fruitRect = { fruitX * GRID_SIZE, fruitY * GRID_SIZE, GRID_SIZE, GRID_SIZE };
SDL_RenderFillRect(renderer, &fruitRect);
renderScore();
SDL_RenderPresent(renderer);
}
//render the score
//Game over screen
void showGameOver(){
bool quit=false;
SDL_Event event;
while (!quit){
//render the game over screen
SDL_SetRenderDrawColor(renderer, 255,255,255,255);
SDL_RenderClear(renderer);
//render the Game Over text
SDL_Color textColor = {0, 0, 255};
SDL_Surface* surface = TTF_RenderText_Solid(font, "Game Over!", textColor);
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
int textWidth = surface->w;
int textHeight = surface->h;
SDL_Rect textRect = {(WINDOW_WIDTH - WINDOW_HEIGHT) / 2, (WINDOW_HEIGHT - WINDOW_WIDTH) / 2, textWidth, textHeight};
SDL_RenderCopy(renderer, texture, NULL, &textRect);
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
// Render the option in the game over screen
surface = TTF_RenderText_Solid(font, "Press ESC to quit the game or press R to restart", textColor);
texture = SDL_CreateTextureFromSurface(renderer, surface);
textWidth = surface->w;
textHeight = surface->h;
SDL_Rect textRect1 = {(WINDOW_WIDTH - WINDOW_HEIGHT) / 2, (WINDOW_HEIGHT - WINDOW_WIDTH) / 2 + 30, textWidth, textHeight};
SDL_RenderCopy(renderer, texture, NULL, &textRect);
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
SDL_RenderPresent(renderer);
//Handle the input for choosing options in game over screen
while(SDL_PollEvent(&event)){
if(event.type == SDL_QUIT){
quit = true;
gameOver=true;
}
else if(event.type == SDL_KEYDOWN){
if(event.key.keysym.sym == SDLK_ESCAPE){
quit=true;
gameOver=true;
}
}
else if (event.key.keysym.sym == SDLK_r){
quit=true;
}
}
}
}
//everything is here
int main(int argc, char* argv[]) {
srand(time(NULL));
//initialize the SDl library and create the game window, if failed, will exit the program and return to 1 which indicating an error.
if (!init()) {
return 1;
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
//generate the initial fruit position
generateFruit();
//generate the initial position of the snake
snakeX[0] = WINDOW_WIDTH / (2 * GRID_SIZE);
snakeY[0] = WINDOW_HEIGHT / (2 * GRID_SIZE);
//initial length
snakeLength = 1;
direction = -1;
gameOver = false;
score = 0;
renderScore();
//records the current time
Uint32 lastTime = SDL_GetTicks();
//loop the game
Uint32 currentTime = 0;
while (!gameOver) {
currentTime = SDL_GetTicks();
Uint32 deltaTime = currentTime - lastTime;
handleInput();
if (deltaTime >= GAME_SPEED) {
handleInput();
moveSnake();
render();
lastTime = currentTime;
}
}
//show the game over screen
showGameOver();
//close the SDL resources before exit the program
close();
return 0;
}
答案1
得分: 2
错误 Library not initialized
是因为库未初始化。初始化它并检查结果。
if (TTF_Init() < 0) {
// 错误处理代码
}
然后你可以加载字体。
TTF_Font* font = TTF_OpenFont("arial.ttf",24);
英文:
The error Library not initialized
is because the library is not initialized. Initialize it and check the result.
if (TTF_Init() < 0) {
// Error handling code
}
Then you can load the font.
TTF_Font* font = TTF_OpenFont("arial.ttf",24);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论