【愚公系列】《AIGC辅助软件开发》034-AI辅助开发跑酷游戏:代码实现

举报
愚公搬代码 发表于 2024/10/31 16:17:11 2024/10/31
【摘要】 标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主等。博客内容.NET、...
标题 详情
作者简介 愚公搬代码
头衔 华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。
近期荣誉 2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主等。
博客内容 .NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
欢迎 👍点赞、✍评论、⭐收藏

🚀前言

在跑酷游戏的开发过程中,代码实现是将创意转化为可玩产品的核心环节。然而,随着游戏复杂度的增加,开发者常常面临挑战:如何编写高效、可维护的代码,如何快速响应玩家的反馈,以及如何在不同平台上保持游戏的流畅性。幸运的是,人工智能的迅猛发展为这一领域带来了新的机遇,AI正逐渐成为开发者的重要助手。

本文将探讨AI如何辅助跑酷游戏的代码实现,从自动化代码生成到智能调试,再到性能优化,AI的应用为开发流程带来了显著提升。我们将分享一些具体的工具和技术,帮助开发者提高编码效率,减少错误,并优化游戏性能。无论你是初学者,还是希望提升开发技能的资深开发者,这篇文章都将为你提供实用的见解与灵感。让我们一起探索AI在跑酷游戏代码实现中的应用,推动游戏开发迈向新的高度!

🚀一、代码实现

🔎1.代码辅助工具选型

目前,基于 ChatGPT 的代码辅助工具主要有以下几种:

  1. ChatGPT 网站:虽然可以直接使用,但片段式的对话并不适合项目层面的代码辅助。

  2. 编程插件:借助 ChatGPT 的 API 打造的一些编程插件,例如正则表达式生成器和 SQL 生成工具,主要用于解决单点问题并提高效率。

  3. Copilot:Copilot 是一个基于代码上下文的提示工具,提供了出色的提示和补全功能。它能够猜测我想写的内容并生成代码,表现得像一个非常智能的代码补全工具,体验非常棒。然而,在这个项目中,我希望 AI 能提供全局的代码操控能力,而不仅仅是局部的补全,目前 Copilot 还无法满足我的需求。

最终,我选择使用 Cursor 客户端,这是一个仍在成长中的 DDE,我看重它的以下几个能力:

  1. 整个模块文件的代码生成。

  2. 代码片段的局部优化能力。
    在这里插入图片描述

  3. 代码增量的 diff 能力,例如让我 AI 帮我生成一个销毁的方法。
    在这里插入图片描述

  4. 集成了 ChatGPT 的对话应用,相当于我有了一个秘书。
    在这里插入图片描述

🔎2.模块功能编写

接下来我会展示背景滚动模块的编写过程,举一反三,其他模块的编写过程大致相同。为了避免重复,我将只展示背景滚动模块的编写过程。

用Cocos Creator写一个背景模块,要实现背景的无限滚动。

在Cocos Creator中实现背景的无限滚动,可以通过创建两个背景图片,并不断地在它们之间切换位置,模拟出背景无限滚动的效果。以下是一个简单的实现步骤和代码示例:

1. 创建一个新项目,或者在现有项目中创建一个新的场景。
2. 导入背景图片资源到项目中。
3. 创建一个节点作为背景的父节点,并添加两个子节点用来放置背景图片。
4. 编写脚本来控制背景的滚动。

### 步骤详解

#### 1. 创建背景节点

在场景编辑器中,创建一个名为 `Background` 的节点。然后在 `Background` 节点下创建两个子节点,分别命名为 `Bg1` 和 `Bg2`。将背景图片资源拖动到 `Bg1` 和 `Bg2` 节点上。

#### 2. 编写脚本

在项目的 `assets` 目录中创建一个新的脚本文件,例如命名为 `BackgroundScroll.js`,然后编写以下代码:

```javascript
// BackgroundScroll.js
cc.Class({
    extends: cc.Component,

    properties: {
        bg1: cc.Node,
        bg2: cc.Node,
        scrollSpeed: 100, // 滚动速度,可以根据需要调整
    },

    onLoad () {
        // 获取背景图片高度
        this.bgHeight = this.bg1.height;

        // 设置初始位置
        this.bg1.y = 0;
        this.bg2.y = this.bgHeight;
    },

    update (dt) {
        // 计算滚动距离
        let distance = this.scrollSpeed * dt;

        // 移动背景
        this.bg1.y -= distance;
        this.bg2.y -= distance;

        // 检查并重置位置
        if (this.bg1.y <= -this.bgHeight) {
            this.bg1.y = this.bg2.y + this.bgHeight;
        }
        if (this.bg2.y <= -this.bgHeight) {
            this.bg2.y = this.bg1.y + this.bgHeight;
        }
    }
});
```javascript

#### 3. 绑定脚本

将 `BackgroundScroll.js` 脚本挂载到 `Background` 节点上,并在属性检查器中将 `Bg1` 和 `Bg2` 分别拖动到脚本的 `bg1` 和 `bg2` 属性中。

#### 4. 调整参数

根据需要调整 `scrollSpeed` 参数和背景图片的高度,确保滚动效果平滑。

### 运行项目

保存所有修改,运行项目,应该可以看到背景图片在垂直方向上不断滚动。如果需要实现水平滚动,只需调整脚本中的 `y` 坐标为 `x` 坐标即可。

这个基本实现可以根据需求进一步优化和扩展,比如添加更多的背景图层,实现不同的滚动速度等。

在这里插入图片描述

用装饰器和 TypeScript 实现。

在 TypeScript 中,使用装饰器来实现背景无限滚动的逻辑可以增强代码的结构化和可复用性。这里,我们使用装饰器来为背景滚动逻辑提供一个灵活的解决方案。

### 实现步骤

1. 创建一个背景滚动模块,它可以通过装饰器来管理多个背景节点的无限滚动。
2. 使用 TypeScript 编写脚本,通过装饰器封装滚动逻辑。

### TypeScript 装饰器实现无限背景滚动

首先,确保项目已经支持 TypeScript。如果还没有设置,请在 `tsconfig.json` 中确保 `experimentalDecorators` 选项被设置为 `true`。

#### 1. 创建滚动装饰器

首先,我们定义一个装饰器,它将控制节点的滚动逻辑。

```typescript
function ScrollDecorator(scrollSpeed: number) {
    return function (target: any) {
        target.prototype.scrollSpeed = scrollSpeed;

        target.prototype.updateScroll = function (dt: number) {
            const distance = this.scrollSpeed * dt;

            this.bg1.y -= distance;
            this.bg2.y -= distance;

            if (this.bg1.y <= -this.bgHeight) {
                this.bg1.y = this.bg2.y + this.bgHeight;
            }
            if (this.bg2.y <= -this.bgHeight) {
                this.bg2.y = this.bg1.y + this.bgHeight;
            }
        };

        target.prototype.initScroll = function () {
            this.bgHeight = this.bg1.height;
            this.bg1.y = 0;
            this.bg2.y = this.bgHeight;
        };
    };
}
```typescript

#### 2. 创建背景滚动组件

接下来,我们创建一个类 `BackgroundScroll`,并使用上面定义的装饰器来装饰这个类。

```typescript
@ScrollDecorator(100) // 设置滚动速度为100,可以根据需要调整
class BackgroundScroll extends cc.Component {
    public bg1: cc.Node;
    public bg2: cc.Node;
    public scrollSpeed: number;
    public bgHeight: number;

    onLoad() {
        this.initScroll();
    }

    update(dt: number) {
        this.updateScroll(dt);
    }
}
```typescript

#### 3. 使用场景中的背景节点

在 Cocos Creator 场景编辑器中,创建一个 `Background` 节点,将其子节点命名为 `Bg1` 和 `Bg2`。然后创建一个新的 TypeScript 脚本,并将其绑定到 `Background` 节点上。

确保在属性检查器中,将 `Bg1` 和 `Bg2` 节点拖到 `BackgroundScroll` 脚本的对应属性上。

```typescript
const { ccclass, property } = cc._decorator;

@ccclass
export default class BackgroundScrollComponent extends cc.Component {
    @property(cc.Node)
    public bg1: cc.Node = null;

    @property(cc.Node)
    public bg2: cc.Node = null;

    private scrollInstance: BackgroundScroll;

    onLoad() {
        this.scrollInstance = new BackgroundScroll();
        this.scrollInstance.bg1 = this.bg1;
        this.scrollInstance.bg2 = this.bg2;
        this.scrollInstance.onLoad();
    }

    update(dt: number) {
        this.scrollInstance.update(dt);
    }
}
```typescript

### 运行项目

在场景中运行项目后,背景节点将会按照我们设置的滚动速度无限滚动。通过装饰器的封装,滚动逻辑被更好地分离出来,便于在项目中复用。

### 优化和扩展

1. **装饰器参数化**:你可以使用装饰器来控制不同背景的滚动速度,例如前景、背景可以不同速率滚动。
2. **添加水平滚动**:如果你想要实现水平滚动,只需调整 `y` 坐标的滚动逻辑为 `x` 坐标。
3. **动态调整**:你可以在游戏运行过程中动态调整滚动速度

在这里插入图片描述

如果我想要用一个Sprite节点,可以实现背景图无限滚动吗?

是的,你可以用一个 `Sprite` 节点实现背景图的无限滚动。使用一个 `Sprite` 节点的方案将更加简洁,同时可以通过移动 `Sprite` 的纹理(`SpriteFrame`)的 UV 坐标来实现滚动效果,这样无需创建多个节点。

在 Cocos Creator 和 TypeScript 中,你可以通过调整 `Sprite` 的 `uvOffset` 或者直接移动节点的位置来实现这个效果。

### 实现方案

我们可以通过直接移动 `Sprite` 的纹理坐标 (`uvOffset`) 来模拟背景的滚动效果。

### 实现步骤

#### 1. 创建背景节点

在场景编辑器中,创建一个 `Sprite` 节点,命名为 `Background`,并为该节点设置一个背景图片。

#### 2. 编写 TypeScript 脚本

创建一个 TypeScript 脚本文件,命名为 `BackgroundScrollUV.ts`,并编写以下代码:

```typescript
const { ccclass, property } = cc._decorator;

@ccclass
export default class BackgroundScrollUV extends cc.Component {
    @property(cc.Float)
    public scrollSpeed: number = 0.1; // 背景滚动的速度

    private material: cc.Material = null;
    private offset: number = 0;

    onLoad() {
        // 获取 Sprite 的材质
        const sprite = this.node.getComponent(cc.Sprite);
        this.material = sprite.getMaterial(0);
    }

    update(dt: number) {
        // 计算纹理偏移
        this.offset += this.scrollSpeed * dt;

        // 设置 UV 偏移,假设在y轴方向滚动
        this.material.setProperty('offset', new cc.Vec2(0, this.offset));
    }
}
```typescript

#### 3. 绑定材质

为了使这个脚本生效,你需要为 `Sprite` 节点绑定一个自定义材质,且这个材质支持 `UV` 的偏移操作。

##### 创建自定义材质

1. 在项目的 `assets` 目录中右键选择 **Create → Effect**,创建一个新的 Effect 文件,命名为 `ScrollEffect.effect`。
2. 打开 `ScrollEffect.effect` 文件,写入以下内容:

```glsl
CCProgram sprite-uv {
    // 开启 uv 操作
    properties: {
        offset: { value: vec2(0.0, 0.0) }
    }
    pass {
        // Cocos 内置 Sprite 着色器的基础
        vert: vs: {
            // 内置的 sprite 顶点着色器
            source: spritedefault.vert
        }
        frag: fs: {
            precision highp float;
            varying vec2 v_uv0;
            uniform sampler2D texture;
            uniform vec2 offset;

            void main () {
                // 计算新的 UV 坐标
                vec2 uv = v_uv0 + offset;
                gl_FragColor = texture2D(texture, uv);
            }
        }
    }
}
```glsl

3. 保存 `ScrollEffect.effect` 文件。
4. 在 `assets` 目录中右键选择 **Create → Material**,创建一个新的 `Material` 文件,命名为 `ScrollMaterial.mtl`。
5. 打开 `ScrollMaterial.mtl`,并将刚刚创建的 `ScrollEffect` 绑定为材质的效果(Effect)。
6. 将 `ScrollMaterial` 拖到 `Sprite` 节点的材质上,替换默认材质。

#### 4. 设置滚动参数

将 `BackgroundScrollUV.ts` 脚本挂载到 `Sprite` 节点上,并在属性检查器中调整 `scrollSpeed` 的值(例如 `0.1`)。

### 运行项目

当项目运行时,你应该可以看到背景图片在 `y` 轴方向上持续滚动,且不会出现断裂,因为滚动逻辑是通过 `UV` 的偏移来模拟的。

### 优化和扩展

1. **方向控制**:你可以通过更改 `UV` 偏移方向来控制背景的滚动方向。如果需要实现水平滚动,只需将 `this.offset` 设置为 `x` 方向的偏移(`new cc.Vec2(this.offset, 0)`)。
   
2. **滚动加速**:可以动态调整 `scrollSpeed` 实现加速效果。

3. **多层滚动**:可以为不同的背景层设置不同的滚动速度,模拟出更丰富的滚动效果,如前景、中景和远景。

在这里插入图片描述

但是这样用户就会看到背景图不是无缝衔接的。

你提到的问题是背景图在滚动过程中可能出现断裂或不连续的问题。这通常是因为背景图本身不是无缝的纹理,或者在滚动时没有正确处理其衔接部分。要解决这个问题,确保背景图能够在滚动过程中无缝衔接,可以考虑以下几种方法:

### 解决方案1:使用无缝衔接的纹理

确保你使用的背景图片本身是无缝拼接的纹理。如果背景图在左右或上下两侧衔接部分存在明显断层,滚动时就会看起来不连续。你可以使用图像编辑工具(如 Photoshop 或 GIMP)对背景图进行编辑,使它们在边缘无缝衔接。

**如何制作无缝纹理:**
1. 打开你的背景图,在图像编辑工具中使用“平铺”功能,检查两侧的衔接是否连续。
2. 如果发现断层,可以通过模糊、复制或调整边缘部分来使图像两侧无缝连接。

### 解决方案2:双图拼接法(通过节点位置滚动实现)

如果你不能使用无缝的背景图,或者为了保持滚动更加简单,你可以使用 **双图拼接法**。该方法使用两个相同的背景图片,然后不断地在背景图之间进行切换,保持滚动过程的无缝效果。

### 实现步骤

1. 使用两个 `Sprite` 节点分别作为 `Bg1` 和 `Bg2`,这两个节点会摆放在一起,当第一个背景图移出屏幕时,立即将它移动到第二个背景图的后面,实现无缝滚动。

#### TypeScript 实现:

```typescript
const { ccclass, property } = cc._decorator;

@ccclass
export default class BackgroundScroll extends cc.Component {
    @property(cc.Node)
    public bg1: cc.Node = null;

    @property(cc.Node)
    public bg2: cc.Node = null;

    @property(cc.Float)
    public scrollSpeed: number = 100; // 滚动速度

    private bgWidth: number = 0; // 背景宽度

    onLoad() {
        // 获取背景图片的宽度(假设背景的两个图片宽度相同)
        this.bgWidth = this.bg1.width;

        // 初始化两个背景的位置
        this.bg1.x = 0;
        this.bg2.x = this.bgWidth;
    }

    update(dt: number) {
        // 计算滚动的距离
        let distance = this.scrollSpeed * dt;

        // 移动两个背景
        this.bg1.x -= distance;
        this.bg2.x -= distance;

        // 检查第一个背景是否已经移出屏幕,如果是,则将它移动到第二个背景的后面
        if (this.bg1.x <= -this.bgWidth) {
            this.bg1.x = this.bg2.x + this.bgWidth;
        }

        // 同样检查第二个背景
        if (this.bg2.x <= -this.bgWidth) {
            this.bg2.x = this.bg1.x + this.bgWidth;
        }
    }
}
```typescript

#### 说明:
1. `bg1` 和 `bg2` 是两个相同的背景图片节点,分别放置在场景中。
2. 当背景图片向左滚动时,如果一个背景图完全离开了屏幕,就将它移动到另一个背景图的后面,这样就实现了无缝滚动的效果。

#### 绑定节点:

1. 在 Cocos Creator 中,创建 `Bg1` 和 `Bg2` 两个节点,并为它们分别设置相同的背景图片。
2. 将上面编写的 `BackgroundScroll` 脚本绑定到场景的根节点,或者单独的控制器节点上。
3. 在属性检查器中,将 `Bg1` 和 `Bg2` 节点拖动到脚本的对应属性中。

### 解决方案3:使用 TilingSprite(自动纹理平铺)

如果你的项目使用了带有自动平铺功能的纹理,你可以使用 `TilingSprite` 或者其他支持纹理平铺的功能来实现无缝滚动。

#### 代码示例:

```typescript
const { ccclass, property } = cc._decorator;

@ccclass
export default class BackgroundScrollTiling extends cc.Component {
    @property(cc.Sprite)
    public bgSprite: cc.Sprite = null;

    @property(cc.Float)
    public scrollSpeed: number = 0.1;

    private offset: number = 0;

    update(dt: number) {
        // 更新偏移量,模拟UV坐标移动
        this.offset += this.scrollSpeed * dt;
        this.bgSprite.getMaterial(0).setProperty('offset', new cc.Vec2(this.offset, 0));
    }
}
```typescript

#### 注意:

- 该方法依赖于你的 `Sprite` 节点的材质支持 `UV` 平铺,因此你可能需要确保材质文件配置支持这种效果。
- 这可以用于一些无缝平铺的背景图像,但是如果图像不是专门设计成平铺纹理,那么还是需要对图像进行无缝处理。

### 总结

1. **无缝纹理**:确保背景图本身是无缝的,避免在滚动中出现视觉断层。
2. **双图拼接法**:通过两个 `Sprite` 交替滚动,模拟出无缝的效果。
3. **UV 滚动**:直接操作 `UV` 坐标滚动,适合有平铺效果的背景。

根据你项目的实际需求,选择适合的方式来实现无缝背景滚动效果。

在这里插入图片描述
后续提问就不做详细截图了,过程如下:

你还是没理解我的意思,会报错“child already added.It can't be added again”。
父节点和子节点需要设置 widget吗?。
能讲得更具体一点吗?我如何做才能确保背景滚动在不同屏幕宽高比的设备上兼容?

🚀二、结论

在这次项目实践中,Cursor 向我展示了项目级别 AI 代码工程的潜力,包括以下几方面:

  1. 模块代码从零到一的生成能力。
  2. 局部代码的补全和优化能力。
  3. Bug 修复能力。
  4. 代码注释能力。
  5. 代码讲解能力。
  6. 上下文理解能力。
  7. 增量代码可视化能力。
  8. 游戏编辑器中的 U 模块搭建步骤提供。

Cursor IDE 是深度定制的,整体交互流畅,操作便捷高效,使用后整个研发流程非常顺畅。

当然,它仍存在一些不足之处,例如代码串联、调试和项目全局把控能力等,这些还需要程序员进行补充。作为一个编程 IDE,Cursor 在插件系统和研发流程等方面与成熟的 IDE 工具相比还有不小的距离。然而,这些问题并不是最重要的,随着版本的迭代,这些能力将会逐步完善。目前,我只需进行一些代码评审工作,就能完成整个项目的代码研发,这种研发模式真的是颠覆性的。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。