用C语言写一个贪吃蛇游戏程序
由于贪吃蛇游戏涉及到图形界面的显示等操作,需要使用相关的图形库,如SDL、OpenGL等。以下是一个使用SDL库实现的简单贪吃蛇游戏程序。
#include <SDL2/SDL.h>
#include <stdlib.h>
#include <time.h>
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define BLOCK_SIZE 20
typedef struct {
int x;
int y;
} Point;
typedef enum {
DIR_UP,
DIR_DOWN,
DIR_LEFT,
DIR_RIGHT
} Direction;
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Texture *block_texture = NULL;
int map[SCREEN_HEIGHT / BLOCK_SIZE][SCREEN_WIDTH / BLOCK_SIZE];
int score = 0;
Point snake[SCREEN_WIDTH * SCREEN_HEIGHT];
int snake_length = 3;
Direction snake_dir = DIR_RIGHT;
Point food;
void init() {
srand(time(NULL));
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("Snake", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
block_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, BLOCK_SIZE, BLOCK_SIZE);
SDL_SetRenderTarget(renderer, block_texture);
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderDrawLine(renderer, BLOCK_SIZE / 2, 0, BLOCK_SIZE / 2, BLOCK_SIZE);
SDL_RenderDrawLine(renderer, BLOCK_SIZE / 2, BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE / 2);
SDL_RenderDrawLine(renderer, BLOCK_SIZE, BLOCK_SIZE / 2, BLOCK_SIZE / 2, BLOCK_SIZE / 2);
SDL_SetRenderTarget(renderer, NULL);
for (int i = 0; i < snake_length; i++) {
snake[i].x = SCREEN_WIDTH / 2 - BLOCK_SIZE * (snake_length - i);
snake[i].y = SCREEN_HEIGHT / 2;
map[snake[i].y / BLOCK_SIZE][snake[i].x / BLOCK_SIZE] = 1;
}
food.x = rand() % (SCREEN_WIDTH / BLOCK_SIZE) * BLOCK_SIZE;
food.y = rand() % (SCREEN_HEIGHT / BLOCK_SIZE) * BLOCK_SIZE;
}
void quit() {
SDL_DestroyTexture(block_texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
void draw_block(int x, int y) {
SDL_Rect rect = {x, y, BLOCK_SIZE, BLOCK_SIZE};
SDL_RenderCopy(renderer, block_texture, NULL, &rect);
}
void draw_map() {
for (int i = 0; i < SCREEN_HEIGHT / BLOCK_SIZE; i++) {
for (int j = 0; j < SCREEN_WIDTH / BLOCK_SIZE; j++) {
if (map[i][j] == 1) {
draw_block(j * BLOCK_SIZE, i * BLOCK_SIZE);
}
}
}
}
void draw_snake() {
SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF);
for (int i = 0; i < snake_length; i++) {
draw_block(snake[i].x, snake[i].y);
}
}
void draw_food() {
SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF);
draw_block(food.x, food.y);
}
void move_snake() {
Point head = snake[0];
switch (snake_dir) {
case DIR_UP:
head.y -= BLOCK_SIZE;
break;
case DIR_DOWN:
head.y += BLOCK_SIZE;
break;
case DIR_LEFT:
head.x -= BLOCK_SIZE;
break;
case DIR_RIGHT:
head.x += BLOCK_SIZE;
break;
}
if (head.x < 0 || head.x >= SCREEN_WIDTH || head.y < 0 || head.y >= SCREEN_HEIGHT || map[head.y / BLOCK_SIZE][head.x / BLOCK_SIZE] == 1) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Game Over", "You Lose!", window);
quit();
exit(0);
}
snake_length++;
for (int i = snake_length - 1; i > 0; i--) {
snake[i] = snake[i - 1];
}
snake[0] = head;
map[head.y / BLOCK_SIZE][head.x / BLOCK_SIZE] = 1;
if (head.x == food.x && head.y == food.y) {
score++;
food.x = rand() % (SCREEN_WIDTH / BLOCK_SIZE) * BLOCK_SIZE;
food.y = rand() % (SCREEN_HEIGHT / BLOCK_SIZE) * BLOCK_SIZE;
} else {
map[snake[snake_length - 1].y / BLOCK_SIZE][snake[snake_length - 1].x / BLOCK_SIZE] = 0;
}
}
void handle_event(SDL_Event *event) {
switch (event->type) {
case SDL_QUIT:
quit();
exit(0);
break;
case SDL_KEYDOWN:
switch (event->key.keysym.sym) {
case SDLK_UP:
if (snake_dir != DIR_DOWN) {
snake_dir = DIR_UP;
}
break;
case SDLK_DOWN:
if (snake_dir != DIR_UP) {
snake_dir = DIR_DOWN;
}
break;
case SDLK_LEFT:
if (snake_dir != DIR_RIGHT) {
snake_dir = DIR_LEFT;
}
break;
case SDLK_RIGHT:
if (snake_dir != DIR_LEFT) {
snake_dir = DIR_RIGHT;
}
break;
}
break;
}
}
int main(int argc, char *argv[]) {
init();
SDL_Event event;
while (1) {
while (SDL_PollEvent(&event)) {
handle_event(&event);
}
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(renderer);
draw_map();
draw_snake();
draw_food();
move_snake();
SDL_RenderPresent(renderer);
SDL_Delay(100);
}
return 0;
}
``
原文地址: https://www.cveoy.top/t/topic/erCu 著作权归作者所有。请勿转载和采集!