Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

C + Raylib:贪吃蛇游戏

Posted on 2024-11-21

介绍

蛇游戏系列的延续。这个版本使用C + Raylib,并且将会有另一个版本使用Zig + Raylib。你可能想知道为什么我要写这个贪吃蛇游戏的多个版本?我的游戏开发会话通常是在 Godot 4 中完成的,但我一直很好奇在 Raylib 中进行游戏开发时有何不同。

什么是Raylib ?

raylib 徽标

摘自网站:享受视频游戏编程的编程库;没有花哨的界面,没有可视化助手,没有 GUI 工具或编辑器……只是以纯粹的斯巴达程序员的方式编码。

要点:“纯粹的斯巴达程序员之道”。

是的,与使用 Godot 4 相比,使用 Raylib 时我确实感觉自己像一个斯巴达战士!相比之下,Godot 中的 Gamedev 简直就是在公园里散步。

注意:与ASCII Snake代码相比,您会看到一个超级相似的代码。

#1 图书馆

#include <raylib.h> #include <stdio.h> #include <stdlib.h> #include <time.h>

#2 常量、结构和全局变量

#define GRID_SIZE 25 #define SCREEN_WIDTH 800 #define SCREEN_HEIGHT 600 #define MAX_SCORE 256 typedef struct { Vector2 position; } Vec2; Vec2 head = 0; Vec2 segments[MAX_SCORE + 1]; Vec2 dir = 1; Vec2 berry; int score = 0; char score_message[32]; bool skip = false; bool is_running = true;

#3 函数声明

void game_over(); void init(); void quit_game(); void restart_game(); bool collide(Vec2 a, Vec2 b); bool collide_snake_body(Vec2 point); Vec2 spawn_berry(); void process_input(); void draw(); void update();

#4 碰撞:碰撞函数

  • 碰撞:检查两个点(a 和 b)是否具有相同的坐标。
  • collide_snake_body:检查给定点是否是蛇身体的一部分。
 bool collide(Vec2 a, Vec2 b) { return (a.position.x == b.position.x && a.position.y == b.position.y); } bool collide_snake_body(Vec2 point) { for (int i = 0; i < score; i++) { if (collide(point, segments[i])) { return true; } } return false; }

#5 产卵浆果

为新浆果生成随机位置,确保它不会与蛇的身体或头部重叠。

 Vec2 spawn_berry() { Vec2 berry = 1; while (collide(head, berry) || collide_snake_body(berry)) { berry.position.x = 1 + rand() % (GRID_SIZE - 2); berry.position.y = 1 + rand() % (GRID_SIZE - 2); } return berry; }

#6 退出并重新启动

  • quit_game:彻底退出游戏,恢复终端状态。
  • restart_game:将游戏状态重置为初始值。
 void quit_game() { CloseWindow(); } void restart_game() { head.position.x = 0; head.position.y = 0; dir.position.x = 1; dir.position.y = 0; score = 0; sprintf(score_message, "[ Score: %d ]", score); is_running = true; }

#7 初始化函数

通过设置窗口、随机数生成器和初始游戏状态来初始化游戏。

 void init() { srand(time(NULL)); InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "snake"); SetTargetFPS(8); berry = spawn_berry(); sprintf(score_message, "[ Score: %d ]", score); }

#8 运动 – process_input

处理用户输入,例如按下箭头键和按下空格/退出键。

 void process_input() { if (IsKeyPressed(KEY_LEFT)) { if (dir.position.x == 1) return; dir.position.x = -1; dir.position.y = 0; } if (IsKeyPressed(KEY_RIGHT)) { if (dir.position.x == -1) return; dir.position.x = 1; dir.position.y = 0; } if (IsKeyPressed(KEY_UP)) { if (dir.position.y == 1) return; dir.position.x = 0; dir.position.y = -1; } if (IsKeyPressed(KEY_DOWN)) { if (dir.position.y == -1) return; dir.position.x = 0; dir.position.y = 1; } if (IsKeyPressed(KEY_SPACE)) { if (!is_running) restart_game(); } if (IsKeyPressed(KEY_ESCAPE)) { is_running = false; quit_game(); } }

#9 游戏结束状态

显示游戏结束屏幕以及重新启动和退出选项。

 void game_over() { int gameOverWidth = MeasureText("Game Over", 30); int gameOverX = (SCREEN_WIDTH - gameOverWidth) / 2; DrawText("GAME OVER", gameOverX - 20, SCREEN_HEIGHT/2 - 20, 36, RED); int restartWidth = MeasureText("[SPACE] to restart, [ESC] to quit", 20); int restartX = (SCREEN_WIDTH - restartWidth) / 2; DrawText("[SPACE] to restart, [ESC] to quit", restartX + 5, SCREEN_HEIGHT/2 + 50, 20, ORANGE); }

#10 更新游戏状态

通过移动蛇、检查碰撞和更新分数来更新游戏状态。

 void update() { for (int i = score; i > 0; i--) { segments[i] = segments[i - 1]; } segments[0] = head; head.position.x += dir.position.x; head.position.y += dir.position.y; if (collide_snake_body(head) || head.position.x < 0 || head.position.y < 0 \ || head.position.x >= GRID_SIZE || head.position.y >= GRID_SIZE) { is_running = false; } if (collide(head, berry)) { if (score < MAX_SCORE) { score += 1; sprintf(score_message, "[ Score: %d ]", score); } else { printf("You Win!"); } berry = spawn_berry(); } }

#11 绘图功能

渲染游戏屏幕,包括蛇、浆果、得分和游戏结束屏幕(如果适用)。

 void draw() { BeginDrawing(); ClearBackground(BLACK); DrawRectangle(berry.position.x * SCREEN_WIDTH / GRID_SIZE, berry.position.y * SCREEN_HEIGHT / GRID_SIZE, SCREEN_WIDTH / GRID_SIZE, SCREEN_HEIGHT / GRID_SIZE, BLUE); for (int i = 0; i < score; i++) { DrawRectangle(segments[i].position.x * SCREEN_WIDTH / GRID_SIZE, segments[i].position.y * SCREEN_HEIGHT / GRID_SIZE, SCREEN_WIDTH / GRID_SIZE, SCREEN_HEIGHT / GRID_SIZE, GREEN); } DrawRectangle(head.position.x * SCREEN_WIDTH / GRID_SIZE, head.position.y * SCREEN_HEIGHT / GRID_SIZE, SCREEN_WIDTH / GRID_SIZE, SCREEN_HEIGHT / GRID_SIZE, YELLOW); DrawRectangleLines(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE); int score_text = MeasureText("[ Score: {} ]", 24); int score_x = (SCREEN_WIDTH - score_text) / 2; DrawText(score_message, score_x, 10, 24, WHITE); int lang_text = MeasureText("C + Raylib", 24); int lang_x = (SCREEN_WIDTH - lang_text) / 2; DrawText("C + Raylib", lang_x, SCREEN_HEIGHT - 60, 24, WHITE); if (!is_running) { game_over(); } EndDrawing(); }

#12 主要

初始化游戏并运行游戏循环。

 int main(void) { init(); while (!WindowShouldClose()) { process_input(); if (skip) { skip = false; continue; } if (is_running) { update(); } draw(); } quit_game(); return 0; }

结果

cRL-蛇

原文: https://hwisnu.bearblog.dev/c-raylib-snake-game/

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Bits about Money
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Elad Gil
  • Ellie Huxtable
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • Henrique Dias
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Lou Plummer
  • Luke Wroblewski
  • Matt Stoller
  • Mert Bulan
  • Mostly metrics
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Small Good Things
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2025 搞英语 → 看世界 | Design: Newspaperly WordPress Theme