Raylib的贪吃蛇

news2024/11/25 22:37:31

配置Raylib库

    • 工具链
    • 主函数模板
    • Draw: 绘制网格
    • Snake: 初始化
    • Draw:绘制蛇与果
    • Input:移动
    • Logic:游戏主要逻辑
    • Draw: 游戏结束

工具链

mkdir snake
cd snake
  • CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(snake)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
find_package(raylib CONFIG REQUIRED)
add_executable(snake main.cpp)
target_link_libraries(snake PRIVATE raylib)
  • CMakePresets.json
{
  "version": 2,
  "configurePresets": [
    {
      "name": "default",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build",
      "cacheVariables": {
        "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
      }
    }
  ]
}

主函数模板

main

#include "raylib.h"

#define SNAKE_LENGTH 256
#define SQUARE_SIZE 31

typedef struct Snake {
  Vector2 position;
  Vector2 size;
  Color color;
  Vector2 speed;
} Snake;

typedef struct Fruit {
  Vector2 position;
  Vector2 size;
  Color color;
  bool active;
} Fruit;

static const int screenWidth = 800;
static const int screenHeight = 450;

static int framesCounter = 0;
static bool allowMove = false;
static bool gameOver = false;

static Snake snake[SNAKE_LENGTH];
static Vector2 snakePosition[SNAKE_LENGTH];
static Vector2 offset;
static int nTail;
static Fruit fruit;

static void InitGame(void);
static void Draw(void);
static void Input(void);
static void Logic(void);
int main(void) {
  InitWindow(screenWidth, screenHeight, "snake game with raylib");
  SetTargetFPS(60);
  InitGame();
  while (!WindowShouldClose()) {
    Draw();
    Input();
    Logic();
  }
  CloseWindow();
  return 0;
}
void InitGame(void) {
  framesCounter = 0;
  allowMove = true;
  gameOver = false;
  nTail = 1;
  offset.x = screenWidth % SQUARE_SIZE;
  offset.y = screenHeight % SQUARE_SIZE;
  // @TODO: init snake
  // @TODO: init fruit
}
// Draw game (one frame)
void Draw(void) {
  BeginDrawing();
  ClearBackground(RAYWHITE);
  if (!gameOver) {
    // @TODO: Draw grid lines
    // @TODO: Draw fruit to pick
  } else {
    // @TODO: print help message
  }
  EndDrawing();
}

void Input(void) {}
void Logic(void) {}
vcpkg new --application
vcpkg add port raylib
cmake --preset=default
cmake --build build

Draw: 绘制网格

    DrawLineV(
        Vector2{SQUARE_SIZE * 1 + offset.x / 2, offset.y / 2},
        Vector2{SQUARE_SIZE * 1 + offset.x / 2, screenHeight - offset.y / 2},
        LIGHTGRAY);
    DrawLineV(
        Vector2{offset.x / 2, SQUARE_SIZE * 2 + offset.y / 2},
        Vector2{screenWidth - offset.x / 2, SQUARE_SIZE * 2 + offset.y / 2},
        LIGHTGRAY);
    for (int i = 0; i < screenWidth / SQUARE_SIZE + 1; i++) {
      DrawLineV(
          Vector2{SQUARE_SIZE * i + offset.x / 2, offset.y / 2},
          Vector2{SQUARE_SIZE * i + offset.x / 2, screenHeight - offset.y / 2},
          LIGHTGRAY);
    }
    for (int i = 0; i < screenHeight / SQUARE_SIZE + 1; i++) {
      DrawLineV(
          Vector2{offset.x / 2, SQUARE_SIZE * i + offset.y / 2},
          Vector2{screenWidth - offset.x / 2, SQUARE_SIZE * i + offset.y / 2},
          LIGHTGRAY);
    }

Snake: 初始化

  // @TODO: init snake
  for (int i = 0; i < SNAKE_LENGTH; i++) {
    snake[i].position = Vector2{offset.x / 2, offset.y / 2};
    snake[i].size = Vector2{SQUARE_SIZE, SQUARE_SIZE};
    snake[i].speed = Vector2{SQUARE_SIZE, 0};
    if (i == 0)
      snake[i].color = DARKBLUE;
    else
      snake[i].color = BLUE;
  }
  for (int i = 0; i < SNAKE_LENGTH; i++) {
    snakePosition[i] = Vector2{0.0f, 0.0f};
  }
  // @TODO: init fruit
  fruit.size = Vector2{SQUARE_SIZE, SQUARE_SIZE};
  fruit.color = SKYBLUE;
  fruit.active = false;
  fruit.position = Vector2{
      GetRandomValue(0, (screenWidth / SQUARE_SIZE) - 1) * SQUARE_SIZE +
          offset.x / 2,
      GetRandomValue(0, (screenHeight / SQUARE_SIZE) - 1) * SQUARE_SIZE +
          offset.y / 2};

Draw:绘制蛇与果

    // Draw snake
    for (int i = 0; i < nTail; i++)
      DrawRectangleV(snake[i].position, snake[i].size, snake[i].color);
    // Draw fruit to pick
    DrawRectangleV(fruit.position, fruit.size, fruit.color);

Input:移动

  if (!gameOver) {
    // Player control
    if (IsKeyPressed(KEY_RIGHT) && (snake[0].speed.x == 0) && allowMove) {
      snake[0].speed = Vector2{SQUARE_SIZE, 0};
      allowMove = false;
    }
    if (IsKeyPressed(KEY_LEFT) && (snake[0].speed.x == 0) && allowMove) {
      snake[0].speed = Vector2{-SQUARE_SIZE, 0};
      allowMove = false;
    }
    if (IsKeyPressed(KEY_UP) && (snake[0].speed.y == 0) && allowMove) {
      snake[0].speed = Vector2{0, -SQUARE_SIZE};
      allowMove = false;
    }
    if (IsKeyPressed(KEY_DOWN) && (snake[0].speed.y == 0) && allowMove) {
      snake[0].speed = Vector2{0, SQUARE_SIZE};
      allowMove = false;
    }
  }

Logic:游戏主要逻辑

  if (!gameOver) {
    for (int i = 0; i < nTail; i++)
      snakePosition[i] = snake[i].position;
    if ((framesCounter % 5) == 0) {
      for (int i = 0; i < nTail; i++) {
        if (i == 0) {
          snake[0].position.x += snake[0].speed.x;
          snake[0].position.y += snake[0].speed.y;
          allowMove = true;
        } else
          snake[i].position = snakePosition[i - 1];
      }
    }
    // Wall behaviour
    if (((snake[0].position.x) > (screenWidth - offset.x)) ||
        ((snake[0].position.y) > (screenHeight - offset.y)) ||
        (snake[0].position.x < 0) || (snake[0].position.y < 0)) {
      gameOver = true;
    }
    // Collision with yourself
    for (int i = 1; i < nTail; i++) {
      if ((snake[0].position.x == snake[i].position.x) &&
          (snake[0].position.y == snake[i].position.y))
        gameOver = true;
    }
    // Fruit position calculation
    if (!fruit.active) {
      fruit.active = true;
      fruit.position = Vector2{
          GetRandomValue(0, (screenWidth / SQUARE_SIZE) - 1) * SQUARE_SIZE +
              offset.x / 2,
          GetRandomValue(0, (screenHeight / SQUARE_SIZE) - 1) * SQUARE_SIZE +
              offset.y / 2};
      for (int i = 0; i < nTail; i++) {
        while ((fruit.position.x == snake[i].position.x) &&
               (fruit.position.y == snake[i].position.y)) {
          fruit.position = Vector2{
              GetRandomValue(0, (screenWidth / SQUARE_SIZE) - 1) * SQUARE_SIZE +
                  offset.x / 2,
              GetRandomValue(0, (screenHeight / SQUARE_SIZE) - 1) *
                      SQUARE_SIZE +
                  offset.y / 2};
          i = 0;
        }
      }
    }
    // Collision
    if ((snake[0].position.x < (fruit.position.x + fruit.size.x) &&
         (snake[0].position.x + snake[0].size.x) > fruit.position.x) &&
        (snake[0].position.y < (fruit.position.y + fruit.size.y) &&
         (snake[0].position.y + snake[0].size.y) > fruit.position.y)) {
      snake[nTail].position = snakePosition[nTail - 1];
      nTail += 1;
      fruit.active = false;
    }
    framesCounter++;
  } else {
    if (IsKeyPressed(KEY_ENTER)) {
      InitGame();
      gameOver = false;
    }
  }

游戏

Draw: 游戏结束

    DrawText("PRESS [ENTER] TO PLAY AGAIN",
             GetScreenWidth() / 2 -
                 MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20) / 2,
             GetScreenHeight() / 2 - 50, 20, GRAY);

over


该例子来自raylib官方样例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1833921.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习500问——Chapter11:迁移学习(3)

文章目录 11.3 迁移学习的常用方法 11.3.1 数据分布自适应 11.3.2 边缘分布自适应 11.3.3 条件分布自适应 11.3.4 联合分布自适应 11.3.5 概率分布自适应方法优劣性比较 11.3.6 特征选择 11.3.7 统计特征对齐方法 11.3 迁移学习的常用方法 11.3.1 数据分布自适应 数据分布自适…

libdrm 2.4.107 needed because amdgpu has the highest requirement

libdrm 2.4.107 needed because amdgpu has the highest requirement 1.问题分析解决 1.问题 Message: libdrm 2.4.107 needed because amdgpu has the highest requirement Run-time dependency libdrm_intel found: YES 2.4.107 Run-time dependency libdrm_amdgpu found: Y…

深度学习500问——Chapter11:迁移学习(4)

文章目录 11.3.8 流形学习方法 11.3.9 什么是finetune 11.3.10 finetune为什么有效 11.3.11 什么是网络自适应 11.3.12 GAN在迁移学习中的应用 参考文献 11.3.8 流形学习方法 什么是流行学习&#xff1f; 流行学习自从2000年在Science上被提出来以后&#xff0c;就成为了机器…

uniapp canvas生成海报

效果 封装组件&#xff0c;父组件 ref 调用 downImgUrl()函数&#xff0c;其他根据自己需求改 <template><view><view class"bgpart"><canvas class"canvas-wrap" canvas-id"canvasID" type"2d"></canvas…

41、基于深度学习的自适应线性预测(matlab)

1、原理及流程 自适应线性预测是一种基于递归最小二乘法&#xff08;Recursive Least Squares, RLS&#xff09;的线性预测方法&#xff0c;用于自适应地估计线性系统的参数。下面是自适应线性预测的原理和流程&#xff1a; 原理&#xff1a; 自适应线性预测的核心思想是通过…

Java | Leetcode Java题解之第162题寻找峰值

题目&#xff1a; 题解&#xff1a; class Solution {public int findPeakElement(int[] nums) {int n nums.length;int left 0, right n - 1, ans -1;while (left < right) {int mid (left right) / 2;if (compare(nums, mid - 1, mid) < 0 && compare(n…

转型AI产品经理(12):“希克定律”如何应用在Chatbot产品中

信息过载&#xff0c;这个对现代人来说是很常见的问题&#xff0c;信息获取变得越来越便捷的同时&#xff0c;也导致信息过载让我们无法及时做出有效决策&#xff0c;还可能演变成选择困难症。信息过载对用户体验的设计也有着显著的负面影响&#xff0c;如果我们的产品设计让人…

HTML静态网页成品作业(HTML+CSS)——美食火锅介绍网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

笔记 | 软件工程06-2:软件设计-软件体系结构设计

1 软件体系结构的概念 1.1 软件体系结构的设计元素 1.2 不同的抽象层次 1.3 软件体系结构的不同视图 1.3.1 软件体系结构的逻辑视图&#xff1a;包图 1.3.2 软件体系结构的逻辑视图&#xff1a;构件图 1.3.3 软件体系结构的开发视图 1.3.4 软件体系结构的部署视图 1.3.4.1 描述…

UV胶带和UV胶水的应用场景有哪些不同吗?

UV胶带和UV胶水的应用场景有哪些不同吗? UV胶带和UV胶水的应用场景确实存在不同之处&#xff0c;以下是详细的比较和归纳&#xff1a; 一&#xff1a;按使用场景来看&#xff1a; UV胶带的应用场景&#xff1a; 包装行业&#xff1a;UV胶带在包装行业中常用于食品包装、药…

About Apple Pay

本文翻译整理自&#xff1a;About Apple Pay &#xff08;更新时间&#xff1a;2017-03-16&#xff09; https://developer.apple.com/library/archive/ApplePay_Guide/index.html#//apple_ref/doc/uid/TP40014764 文章目录 一、关于 Apple Pay1、使用 Apple Pay2、测试 Apple …

Kaggle比赛:成人人口收入分类

拿到数据首先查看数据信息和描述 import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 加载数据&#xff08;保留原路径&#xff0c;但在实际应用中建议使用相对路径或环境变量&#xff09; data pd.read_csv(r"C:\Users\11794\Desk…

【机器学习300问】121、RNN是如何生成文本的?

当RNN模型训练好后&#xff0c;如何让他生成一个句子&#xff1f;其实就是一个RNN前向传播的过程。通常遵循以下的步骤。 &#xff08;1&#xff09;初始化 文本生成可以什么都不给&#xff0c;让他生成一首诗。首先&#xff0c;你需要确定采样的起始点。这可以是一个特殊的开…

深度学习:从理论到应用的全面解析

引言 深度学习作为人工智能&#xff08;AI&#xff09;的核心技术之一&#xff0c;在过去的十年中取得了显著的进展&#xff0c;并在许多领域中展示了其强大的应用潜力。本文将从理论基础出发&#xff0c;探讨深度学习的最新进展及其在各领域的应用&#xff0c;旨在为读者提供全…

外网怎么访问内网?

当我们需要在外网环境下访问内网资源时&#xff0c;常常会面临一些困扰。通过使用一些相关的技术与工具&#xff0c;我们可以轻松地实现这一目标。本文将介绍如何通过【天联】组网产品&#xff0c;解决外网访问内网的问题。 【天联】组网是一款由北京金万维科技有限公司自主研…

事务所管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;客户管理&#xff0c;评论管理&#xff0c;基础数据管理&#xff0c;公告信息管理 客户账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;律师管理&#xff0…

示例:WPF中绑定枚举到ComboBox想显示成中文或自定义名称如何实现

一、目的&#xff1a;在开发过程中绑定的枚举不想显示成英文字段怎么办&#xff0c;这里通过TypeConverter的方式来实现绑定的枚举从定义的特性中读取 二、实现 首先定义如下枚举 [TypeConverter(typeof(DisplayEnumConverter))]public enum MyEnum{[Display(Name "无&q…

C++ -- 红黑树的基本操作

目录 摘要 基本规则 基本操作 利用Graphviz 库 总结 摘要 红黑树是一种自平衡的二叉搜索树&#xff0c;它在插入和删除节点时&#xff0c;通过颜色和旋转操作保持树的平衡&#xff0c;确保插入、删除和查找的时间复杂度都是 (O(log n))。红黑树的每个节点都有一个颜色属性…

CentOS 7 安装MySQL以及常见问题解决

访问网站&#xff1a;http://repo.mysql.com 找到适配CentOS 7版本的MySQL 的YUM仓库包rpm文件&#xff0c;如下图 下载后&#xff0c;找到安装包的位置 空白处右键&#xff0c;选择在终端打开 查看当前目录下文件 # 安装MySQL 5.7的YUM仓库包rpm -ivh mysql57-community-rele…