基于 HAI+Flask+Ollama 的城堡探险开发实录:跨越时空的游戏重塑之旅

缘起:穿越三十年的游戏情怀浪潮 在计算机启蒙的 20 世纪 80 年代,文字冒险游戏(Text Adventure Game)以其独特的魅力,成为那个时代最受欢迎的游戏形式。玩家们通过输入指令,在纯文字的世界里展开想象的翅膀,探

基于 HAI+Flask+Ollama 的城堡探险开发实录:跨越时空的游戏重塑之旅

缘起:穿越三十年的游戏情怀浪潮

在计算机启蒙的 20 世纪 80 年代,文字冒险游戏(Text Adventure Game)以其独特的魅力,成为那个时代最受欢迎的游戏形式。玩家们通过输入指令,在纯文字的世界里展开想象的翅膀,探索神秘的领域,体验惊心动魄的冒险。如今,我们站在人工智能飞速发展的时代节点,怀揣着对经典游戏的热爱与敬意,我打算借助 HAI(Human - AI Interaction)、Flask 以及 Ollama 的强大技术组合,重现文字冒险游戏的辉煌,赋予其现代智能的全新活力。

本文将以一个引人入胜的 “古堡探险” 主题文字冒险游戏为蓝本,详细阐述如何构建一个具备智能剧情生成能力的现代文字冒险系统,带您领略一场技术与情怀交织的奇妙旅程。开发界面如下图所示:

本地极客模式 - Ollama

适合个人开发者和小型项目的轻量化选择:

零成本启动:利用闲置计算资源

数据闭环:敏感剧情永不外流

即时调试:直接查看模型推理过程

Ollama官网安装部署后启动运行即可,非常简单,这里咱们不做详述。

云端专业方案 - 腾讯云HAI

今天我们重点推荐和选择腾讯云HAI,上面自带部署好的各种主流大模型工具,比如CloudStudio,Open-webui,ChatBox等等,让你快速便捷使用Deepseek的强大功能。

当我们需要面向团队协作或商业场景时,腾讯云HAI展现出独特优势:

分钟级部署:在控制台勾选DeepSeek模型,5分钟即可获得专属API端点。

弹性算力:遇到玩家高峰时自动扩容,避免深夜更新模型时的算力闲置。

企业级护航:内置DDoS防护和API网关,让开发者专注剧情设计。

开箱即用:预置优化的模型镜像,告别CUDA版本冲突的"炼丹"烦恼。

这里我们直接使用JupyterLab中的命令行方式访问,以便部署代码到服务器上。

打开终端将Ollama deepseek模型启动,就完成了云上的第一步。

Flask 轻量级框架:后端服务的灵动核心

Python Flask 作为后端服务的基石,凭借其独特优势,成为我们的不二之选:

简洁路由配置:借助 @app.route 装饰器,能够轻松实现 RESTful API,让开发者可以快速定义和管理不同的请求路由,使后端逻辑清晰明了。

强大模板渲染:能够根据动态数据高效生成 HTML 页面,为前端展示提供丰富多样的内容,实现灵活的页面布局和数据呈现。

轻量高效运行:内存占用极小,仅约 30MB 左右,在保证高性能的同时,对硬件资源的需求较低,确保游戏在各种设备上都能稳定流畅运行。

以下是基于Flask的python代码,首先你需要安装好flask。

然后编辑一段python代码server.python

代码语言:txt复制
from flask import Flask, request, jsonify, send_from_directory
from flask_cors import CORS
import requests
import os

app = Flask(__name__, static_folder='static')  # 设置静态文件目录
CORS(app) 

OLLAMA_URL = "MyIPXX.XX.XX.XX:port/api/generate"

# 新增静态文件路由
@app.route('/<path:filename>')
def serve_static(filename):
    return send_from_directory(app.static_folder, filename)

@app.route('/')
def index():
    return send_from_directory(app.static_folder, 'index.html')

@app.route('/query', methods=['POST'])
def handle_query():
    try:
        data = request.json
        response = requests.post(
            OLLAMA_URL,
            json={
                "model": "deepseek-r1:8b",
                "prompt": data["prompt"],
                "stream": False,
                "format": "json",
                "options": {"temperature": 0.5}
            }
        )
        response.raise_for_status()
        return jsonify(response.json())
    except Exception as e:
        return jsonify({"error": str(e)}), 500

if __name__ == '__main__':
    app.run(port=5000, debug=True)

使用python执行启动刚才编写的server.py代码。就完成好了云上的flask服务器部署。

现代 Web 技术栈:简洁高效的前端呈现

接下来就是最激动人心的时刻,完成我们的前端代码。前端采用纯 HTML + CSS + JavaScript 三件套,构建出一个简洁而强大的用户交互界面,这样做的好处如下:

零第三方依赖:无需引入 React、Vue 等复杂的前端框架,减少了开发复杂度和代码冗余,使项目更加轻量化,易于维护和扩展。

响应式布局设计:能够自动适配各种移动设备和不同屏幕尺寸,无论玩家是在手机、平板还是电脑上进行游戏,都能获得最佳的视觉体验。

即时交互体验:玩家在操作过程中,页面能够即时响应,无需等待整个页面重新加载,极大提升了交互的流畅性和用户体验。

实现代码index.html示例如下:

代码语言:txt复制
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>文字冒险游戏</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        #story-container {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            margin-bottom: 20px;
            min-height: 150px;
        }
        .options-container {
            display: grid;
            gap: 10px;
        }
        button {
            padding: 12px 20px;
            background: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background 0.3s;
        }
        button:hover {
            background: #45a049;
        }
        button:disabled {
            background: #cccccc;
            cursor: not-allowed;
        }
        .loading {
            position: relative;
            opacity: 0.7;
        }
        .loading::after {
            content: " ";
            display: inline-block;
            width: 20px;
            height: 20px;
            border: 3px solid rgba(0,0,0,0.3);
            border-radius: 50%;
            border-top-color: #fff;
            animation: spin 1s ease-in-out infinite;
            margin-left: 10px;
        }
        @keyframes spin {
            to { transform: rotate(360deg); }
        }
    </style>
</head>
<body>
    <h1>文字冒险游戏</h1>
    <div id="story-container">
        <p>游戏正在初始化...</p>
    </div>
    <div class="options-container" id="options-container">
        <button disabled>加载中...</button>
    </div>
<script>
let storyHistory = [];
async function loadGame() {
    try {
        const initResponse = await fetch('/query', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({ selection: "开始游戏" })
        });
        
        const data = await initResponse.json();
        if (data.error) throw new Error(data.error);
        
        updateGameUI(data);
    } catch (error) {
        alert(`初始化失败: ${error.message}`);
    }
}
async function selectOption(option) {
    const buttons = document.querySelectorAll('button');
    buttons.forEach(btn => btn.disabled = true);
    try {
        const response = await fetch('/query', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({ selection: option })
        });
        const data = await response.json();
        if (data.error) throw new Error(data.error);
        
        storyHistory.push(option);
        updateGameUI(data);
    } catch (error) {
        alert(`请求失败: ${error.message}`);
    } finally {
        buttons.forEach(btn => btn.disabled = false);
    }
}
function updateGameUI(data) {
    const storyDiv = document.getElementById('story-container');
    const optionsContainer = document.getElementById('options-container');
    
    // 更新剧情
    storyDiv.innerHTML = `<p>${data.story}</p>`;
    
    // 生成新选项
    optionsContainer.innerHTML = data.options.map(opt => `
        <button onclick="selectOption('${opt}')">${opt}</button>
    `).join('');
}
// 启动游戏
loadGame();
</script>
</body>
</html>

这样我们的主游戏前后端引擎就已经基本实现了。直接通过浏览器在本地访问你在云上的IP:port/static/index.html即可。

上下文维护机制:记忆的延续

为了让 AI 能够更好地理解玩家的行为和游戏的发展脉络,维护最近 3 次交互历史作为模型输入:

通过这种方式,AI 可以根据之前的选择和结果,生成更加连贯、合理的剧情,使游戏的叙事更加流畅自然,仿佛玩家真的置身于一个有记忆的游戏世界中。

这种精心设计的提示词结构,既能激发 AI 的创作灵感,又能让生成的内容符合游戏的需求和玩家的期望,为游戏的丰富性和趣味性提供了有力保障。

结语:云端的城堡与现实的桥梁

在腾讯云HAI的加持下,实现了堪比中型游戏工作室的运营效率——最初我们只是怀旧的极客,想用代码复刻儿时的文字冒险感动。而当腾讯云HAI加入技术栈后,这个项目意外成为了传统游戏开发与云原生AI的碰撞实验——本地环境保留着车库创业的灵活热血,云端平台赋予它稳健成长的商业基因。

或许这就是现代开发者独有的浪漫:左手在Ollama的日志里调试着骑士与恶龙的对话分支,右手通过HAI控制台观察着全球玩家在数字城堡留下的足迹。当北京时间的开发者熄灯离开工位时,西雅图的玩家正通过HAI美国节点的模型,开启他们的东方奇幻之旅——这何尝不是另一种意义上的"文字冒险"呢?

发布者:admin,转转请注明出处:http://www.yc00.com/web/1748201468a4746850.html

相关推荐

  • 基于 HAI+Flask+Ollama 的城堡探险开发实录:跨越时空的游戏重塑之旅

    缘起:穿越三十年的游戏情怀浪潮 在计算机启蒙的 20 世纪 80 年代,文字冒险游戏(Text Adventure Game)以其独特的魅力,成为那个时代最受欢迎的游戏形式。玩家们通过输入指令,在纯文字的世界里展开想象的翅膀,探

    4小时前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信