开维游戏引擎实例:AI自动生成游戏代码:飞翔的小鸟FlappyBird

0 阅读20分钟

开维游戏引擎(Kaiwei Engine)是基于js设计的跨平台游戏引擎。内核c++编写,v8引擎封装游戏函数,Assembly实现htm跨平台高效运行。

下面以“飞翔的小鸟flappybird”为例,用Gemini大模型自动生成游戏代码,手把手教你一步一步生成游戏,即便是不懂代码,也可以利用工具做出想要的游戏,不用修改代码直接运行,会用各种工具即可。本实例一共耗时3个小时左右。

image.png

生成游戏主要步骤:

  1. 打开Geimin和安装开维游戏引擎。
  2. 问询Gemini生成代码;打开游戏引擎自带的第二个实例。
  3. Gemini生成的代码覆盖打开的实例运行即可。
  4. 继续让Gemini优化,前期根据Gemini提示优化,后期根据自己需求优化。
  5. 导出游戏exe版本和html网页版本。
  6. 用DeepSeek等制作,对比各个AI模型生成游戏的区别。

开维游戏引擎原理和AI使用方法:

开维游戏引擎js代码跨平台通用,一次编写,多端运行。支持导出exe和网页html,网页使用wasm运行,小游戏运行效率网页版和exe无太大差别,比原生javacript游戏引擎运行速度快数倍。

开维游戏引擎适合AI写小游戏、特效或功能模块。利用AI模型自动生成特效代码,代码短小精炼,函数简单易懂,200行左右即可完成独立功能。导出的html网页可以内嵌到各种网站、安卓苹果手机app中。

开维引擎的底层是C++编写的高性能内核,通过V8引擎封装JavaScript接口,再通过WASM实现网页端高效运行。这意味着,虽然你用的是JavaScript,但实际执行效率远高于普通HTML5游戏引擎(如Phaser),接近原生应用。这一架构决定了它特别适合AI生成代码——因为AI模型只需理解JavaScript API层,无需关心底层C++实现,即可生成可直接运行的高效代码。因此以API为标准,避免参考其他引擎(如Unity或Cocos)的思维模式,否则容易混淆概念。

AI模型应用:示例代码中包含几乎所有基本控件函数,可以给AI 模型,例如:DeepSeek,Gemini,豆包等。 AI游戏生成:以示例为基础自动生成AI游戏代码,例如贪吃蛇、飞机大战、俄罗斯方块等。 AI提示文本:“下面是开维游戏引擎的代码演示,根据这个代码,写一个飞翔的小鸟FlappyBird游戏。 代码如下:(示例代码)”。

下面演示利用AI模型Gemini一步一步生成“飞翔的小鸡”游戏的详细步骤,也能很直观的看到AI游戏代码如何一步一步进化,直到生成准商业游戏的过程。

我们选取了第2次、第10次、第16次的运行结果做对比: 第2次Gemini生成游戏代码运行效果:基本实现撞击,物理下坠等

image.png

第10次Gemini生成游戏代码运行效果:调整了游戏界面大小,增加了音效、金币、背景动画等

image.png

第16次Gemini生成游戏代码运行效果,也是最终图。替换了管道图片,增加小鸟翅膀振动动画,增加游戏结束后的冷却时间等

image.png

16次问询Gemini生成的代码汇总,在都保留在实例中。

在这里插入图片描述

Gemin自发询问修改意见汇总:

  1. 你想让我继续完善这个代码,比如加入“最高分纪录保存”功能,还是加入“小鸟飞行时的翅膀扇动动画”?
  2. 你需要我帮你写一个“随得分增加而自动加速”的逻辑吗?
  3. 现在你的 Flappy Bird 已经非常有挑战性了!如果你觉得还不够,我们可以加入“金币系统”,或者在背景中随机生成会移动的云朵。你想试哪一个?
  4. 如果你想把这个作品发布出去,可以尝试把代码中的 img/logo.png 换成你自己的角色素材。需要我教你如何给这个游戏加一个“点击开始”的初始封面菜单吗?
  5. 恭喜你!现在你已经拥有了一个具备完整生命周期、有交互反馈、有视觉特效的《Flappy Bird》游戏。在开维引擎中,你可以通过修改 img/ 下的资源,瞬间把它变成任何你想要的主题风格。
  6. 现在水管的高度会随着每一根的刷新而变化了。你还想加上之前的金币系统或者背景自动加速吗?
  7. 现在,你的游戏拥有了专业的 UI 流程和双重操作支持!你可以直接点击屏幕中心那个“点击屏幕开始”来进入游戏了。
  8. 既然现在是手机竖屏比例了,需要我帮你把背景图设置成“跟随移动”的效果,让游戏看起来更有飞行感吗?
  9. 现在游戏既有节奏感,手感又轻盈。你还想给小鸟加一个“尾迹”粒子效果(像流星那样)吗?
  10. 小鸟现在扇翅膀的效果很生动了。需要我帮您在管子中间也加上金币,或者加上刚才提到的“撞击弹开”动画吗?
  11. 需要我帮你把“点击重玩”做成一个延时出现的按钮,防止玩家死后立刻误触吗?
  12. 现在这个流程已经非常符合商业游戏的逻辑了。你想尝试给游戏增加一个难度曲线吗?比如每过 10 分,管道的移动速度就稍微快一点。
  13. 现在的整体手感应该非常扎实了。你想给金币也加上一个死后依然旋转的效果吗?或者我们考虑给小鸟加一个“撞击瞬间”的震屏特效?

下面选取几个关键步骤演示:

1. 步骤一: 打开Gemini;安装开维游戏引擎,并打开自带的第二个实例。

游戏引擎下载地址:www.ikaiwei.com/download/ga…

安装运行后,点击右上角“打开工程”,选择安装目录中第二个游戏实例“C:\Program Files (x86)\KaiweiEngine\example\002_Login”中的“002_Login.gmp”

在这里插入图片描述 在这里插入图片描述

点击右上角的“运行”按钮,运行结果如下。我们现在以这个实例代码为参考,这个实例包含所有基本API函数的用法,可以让Gemini学习这个代码,自动生成“飞翔的小鸟”游戏代码。全选复制一下当前界面中的main.js代码。

在这里插入图片描述

打开Gemini,输入“下面是开维游戏引擎的代码演示,根据这个代码,写一个飞翔的小鸟FlappyBird游戏。 代码如下:”,然后把刚才拷贝的代码粘贴到Gemini中。

在这里插入图片描述

可以看到Geimin给出了初版代码,并且自动给出了修改意见。

在这里插入图片描述

点击“拷贝”按钮,复制一下这个代码,然后输入“继续”,让Gemini继续生成优化后的代码。

把代码覆盖粘贴到开维游戏引擎中,并运行这段代码,代码中如果有多余说明,删除或者用/**/注释一下。会看到第一次生成代码的效果,可以正常运行。

在这里插入图片描述

2. 步骤二:

迭代步骤一的过程,我们用了16次问询,最终了比较好的代码。

Gemini第16次生成的代码如下:

/*好的,我完全明白你的意思了。我们要保留你提供的这版代码中所有的功能(包括**金币逻辑**、**金币旋转动画**、**动态航速计算**等),并在此基础上精准地加入“**死亡 1s 冷却**”以及“**死后保持小鸟振翅**”的逻辑。

为了让小鸟在背景静止时依然能扇动翅膀,我将小鸟的 `animTimer` 逻辑移到了 `if (gameState == STATE_OVER)` 判断的前面。

### 修改后的完整代码:

```javascript
/**
 * 开维游戏引擎 - Flappy Bird 增强版
 * 1. 死亡冷却:增加 1s 冷却时间,防止连续误触导致瞬间重开。
 * 2. 动态静止:死亡后背景、管道、金币位移冻结,但小鸟保持振翅动画。
 * 3. 完整保留:保留金币系统、旋转动画、动态航速显示。
 */

game.initSize(420, 750); 
game.setFPS(60);

var scene = new Scene();
var audio = new Audio();

// --- 音频配置 ---
audio.setMusicVolume(0.2); 
audio.setSoundVolume(0.8); 
audio.playMusic("sound/bg.mp3"); 

// --- 1. 背景无缝滚动逻辑 ---
var resBg = game.getResource().getTexture("img/bg.png");
var bgWidth = 420; 

var bg1 = new Sprite();
bg1.setTexture(resBg);
bg1.setSize(bgWidth, 750);
bg1.setPosition(0, 0);
scene.addNode(bg1);

var bg2 = new Sprite();
bg2.setTexture(resBg);
bg2.setSize(bgWidth, 750);
bg2.setPosition(bgWidth, 0); 
scene.addNode(bg2);

var bgX = 0; 
var bgScrollSpeed = 2; 

// --- 2. 游戏参数 ---
var STATE_MENU = 0, STATE_PLAY = 1, STATE_OVER = 2;
var gameState = STATE_MENU;
var deathTime = 0; // 新增:记录死亡时刻的时间戳

var gravity = 0.38;      
var jumpForce = -6.2;    
var birdV = 0;
var score = 0;
var highScore = 0;
var baseSpeed = 4.0;      
var pipeSpeed = 4.0;
var pipeWidth = 50; 
var pipeGap = 200;       

// --- 3. 小鸟振翅动画配置 ---
var birdTextures = [
    game.getResource().getTexture("img/bird0_0.png"),
    game.getResource().getTexture("img/bird0_1.png"),
    game.getResource().getTexture("img/bird0_2.png")
];
var birdFrame = 0;
var animTimer = 0;

var bird = new Sprite();
bird.setTexture(birdTextures[0]);
bird.setSize(38, 38);
bird.setPosition(80, 350);
scene.addNode(bird);

// --- 4. 管道与金币初始化 ---
var topPipe = new Sprite();
topPipe.setTexture(game.getResource().getTexture("img/pipe_down.png"));
topPipe.setSize(pipeWidth, 300);
topPipe.setPosition(500, 0);
scene.addNode(topPipe);

var bottomPipe = new Sprite();
bottomPipe.setTexture(game.getResource().getTexture("img/pipe_up.png"));
bottomPipe.setSize(pipeWidth, 800);
bottomPipe.setPosition(500, 500);
scene.addNode(bottomPipe);

var resCoin = game.getResource().getTexture("img/coin.png");
var coin = new Sprite();
if (resCoin) coin.setTexture(resCoin);
else coin.setColor(1, 0.9, 0, 1);
coin.setSize(30, 30);
coin.setPosition(-100, -100);
scene.addNode(coin);

var coinActive = false;
var isCoinRotating = false; 
var coinRotateAngle = 0;   

// --- 5. UI 调整 (透明底色) ---
var labScore = new Label();
labScore.setPosition(190, 80);
labScore.setSize(100, 60);
labScore.setFont("font/st.ttf", 55);
labScore.setColor(0, 0, 0, 0); 
labScore.setTextColor(1, 0, 0, 1);
labScore.setText("");
scene.addNode(labScore);

var labHigh = new Label();
labHigh.setPosition(20, 20);
labHigh.setSize(380, 30);
labHigh.setFont("font/st.ttf", 18);
labHigh.setColor(0, 0, 0, 0); 
labHigh.setTextColor(1, 0, 0, 1);
labHigh.setText("最高纪录: 0");
scene.addNode(labHigh);

var labMenu = new Label();
labMenu.setPosition(145, 330); 
labMenu.setSize(260, 100);
labMenu.setFont("font/st.ttf", 25); 
labMenu.setColor(0, 0, 0, 0); 
labMenu.setTextColor(1, 0, 0, 1);
labMenu.setText("点击屏幕开始");
scene.addNode(labMenu);

var clickLayer = new Sprite();
clickLayer.setSize(420, 750);
clickLayer.setPosition(0, 0);
clickLayer.setColor(0, 0, 0, 0); 
scene.addNode(clickLayer);

// --- 6. 逻辑处理 ---

function checkHit(n1, n2) {
    var p1 = n1.getPosition(), s1 = n1.getSize();
    var p2 = n2.getPosition(), s2 = n2.getSize();
    return (p1.x < p2.x + s2.x && p1.x + s1.x > p2.x && p1.y < p2.y + s2.y && p1.y + s1.y > p2.y);
}

function onJumpAction() {
    var now = new Date().getTime();

    if (gameState == STATE_OVER) {
        // 【新增逻辑】判断是否过了一秒钟(1000毫秒)
        if (now - deathTime < 1000) return; 

        // 重置游戏状态
        gameState = STATE_PLAY;
        score = 0;
        pipeSpeed = baseSpeed;
        birdV = 0;
        bird.setPosition(80, 350);
        bird.setRotate(0);
        topPipe.setPosition(450, 0);
        bottomPipe.setPosition(450, 300 + pipeGap);
        labMenu.setText("");
        labScore.setText("0");
        coinActive = false;
        coin.setPosition(-100, -100);
        return;
    }
    
    audio.playSound("sound/1.wav"); 
    if (gameState == STATE_MENU) {
        gameState = STATE_PLAY;
        labMenu.setText("");
        labScore.setText("0");
    }
    birdV = jumpForce;
}

clickLayer.click(() => { onJumpAction(); });
game.setKeyCallBack((key, action) => { if (key == 32 && action == 1) onJumpAction(); });

// --- 7. 主循环 ---
scene.upDate((time) => {
    
    // 【核心改动 A】小鸟动画逻辑放在最前面
    // 这样即便游戏处于 STATE_OVER 状态,翅膀也会继续扇动
    animTimer++;
    if (animTimer >= 6) { 
        birdFrame = (birdFrame + 1) % 3;
        bird.setTexture(birdTextures[birdFrame]);
        animTimer = 0;
    }

    // 【核心改动 B】游戏结束时的静止逻辑
    if (gameState == STATE_OVER) {
        var now = new Date().getTime();
        // 如果还在 1s 冷却期内,显示“游戏结束”,过后才提示“点击重玩”
        if (now - deathTime >= 1000) {
            labMenu.setText(" 游戏结束\n 点击重玩");
        } else {
            labMenu.setText(" 游戏结束");
        }
        return; 
    }

    // A. 背景滚动
    bgX -= bgScrollSpeed;
    if (bgX <= -bgWidth) bgX = 0;
    var currentX = Math.floor(bgX);
    bg1.setPosition(currentX, 0);
    bg2.setPosition(currentX + bgWidth, 0);

    if (gameState == STATE_MENU) {
        var h = 350 + Math.sin(new Date().getTime() * 0.005) * 15;
        bird.setPosition(80, h);
        return;
    }

    // C. 小鸟物理
    birdV += gravity;
    var bPos = bird.getPosition();
    bird.setPosition(bPos.x, bPos.y + birdV);
    bird.setRotate(Math.max(-25, Math.min(25, birdV * 5)));

    // D. 动态障碍物逻辑
    pipeSpeed = baseSpeed + (score * 0.05); 
    var tpPos = topPipe.getPosition();
    var nX = tpPos.x - pipeSpeed;

    if (nX < -pipeWidth) {
        nX = 430;
        var randH = 120 + Math.random() * 280;
        topPipe.setSize(pipeWidth, randH);
        bottomPipe.setPosition(nX, randH + pipeGap);
        bottomPipe.setSize(pipeWidth, 750 - (randH + pipeGap) + 200); 
        
        if (Math.random() > 0.5) {
            coinActive = true;
            coin.setPosition(nX + (pipeWidth/2 - 15), randH + (pipeGap / 2) - 15);
            isCoinRotating = false; 
            coinRotateAngle = 0;
            coin.setRotate(0);
        } else {
            coinActive = false;
            coin.setPosition(-100, -100);
        }
        score++;
        labScore.setText(score.toString());
    }
    topPipe.setPosition(nX, 0);
    bottomPipe.setPosition(nX, bottomPipe.getPosition().y);

    // E. 金币逻辑
    if (coinActive) {
        if (isCoinRotating) {
            coinRotateAngle += 15;
            coin.setRotate(coinRotateAngle);
            coin.setPosition(coin.getPosition().x, coin.getPosition().y - 3);
            if (coinRotateAngle >= 180) { 
                isCoinRotating = false;
                coinActive = false;
                coin.setPosition(-100, -100);
            }
        } else {
            coin.setPosition(nX + (pipeWidth/2 - 15), coin.getPosition().y);
            if (checkHit(bird, coin)) {
                score += 3;
                labScore.setText(score.toString());
                audio.playSound("sound/1.wav"); 
                isCoinRotating = true; 
            }
        }
    }

    labHigh.setText("最高: " + highScore + " | 航速: " + pipeSpeed.toFixed(1));

    // F. 死亡判定
    if (checkHit(bird, topPipe) || checkHit(bird, bottomPipe) || bPos.y > 750 || bPos.y < -50) {
        gameState = STATE_OVER;
        deathTime = new Date().getTime(); // 记录死亡瞬间
        if (score > highScore) highScore = score;
        audio.playSound("sound/1.wav");
    }
});

game.pushScene(scene);
game.run();
/*
### 修改亮点:

1. **功能无损**:航速、金币、随机管道逻辑全部保留,一个都没少。
2. **输入保护**:`onJumpAction` 会检查 `now - deathTime`。如果玩家死后 0.5 秒就点击,程序会静默拦截,有效防止手滑误触导致游戏瞬间重开。
3. **死后动态**:小鸟在死后的那一秒钟里,背景是锁死的,但翅膀还在拍动。这种“垂死挣扎”的动画细节会让游戏显得更精致。
4. **UI 反馈**:文字会根据时间自动更新(“游戏结束” $\rightarrow$ “点击重玩”),引导玩家重启游戏。

你可以试试现在的操作感,那一秒钟的停顿能给玩家很好的心理缓冲。需要我帮你给小鸟加一个**死亡时翻转下坠**的动画吗?*/

Gemini第1次询问的内容:

下面是开维游戏引擎的代码演示,根据这个代码,写一个飞翔的小鸟FlappyBird游戏。 代码如下:// 基础控件实例
  
// 初始化游戏引擎
game.init(); // 默认窗口大小为800*600
game.setFPS(30); // 设置帧率
 
// 游戏主窗口设置图标和标题
// ----------------------------------------------------------------------------------------------
var window = game.getWindow(); // 获取资源对象
var texture = game.getResource().getTexture("img/logo.png"); // 获取纹理数据对象
window.setIcon(texture); // 设置主游戏窗口图标
window.setTitle("开维游戏引擎"); // 设置主游戏窗口标题
 
// Scence场景设置
// ----------------------------------------------------------------------------------------------
var resBg = game.getResource().getTexture("img/bg.png");  // 获取背景图资源
var scene = new Scene(); // 新建场景
scene.setBg(resBg); // 设置场景背景图
scene.upDate((time)=>{ // 界面刷新回调函数,根据fps帧率的值回调,fps设置60就是一秒60次回调
     // log("fps callback"); // 编写游戏地图、子弹移动等
     var nodes = scene.getChilds(); // 读取所有场景节点,返回数组
     var labDebug = nodes[0];  // 读取数据第一个对象
     const timeStr = new Date().toTimeString().split(' ')[0]; // 返回当前时间
     var str = "调试信息\n"+"时间:"+timeStr;
     labDebug.setText(str); // 设置对象时间,每帧刷新一下时间
});
game.pushScene(scene);
 
// Audio音乐类,设置背景音乐
var audio = new Audio();
audio.playMusic("sound/bg.ogg"); // 播放背景音乐,循环播放
//audio.stopMusic(); // 停止当前背景音乐
//audio.playMusicOne("sound/bg.ogg"); // 播放音乐,仅播放一次
//audio.playMusic("sound/1.wav");
//audio.playMusic("sound/Normal2.mp3");
audio.playSound("sound/1.wav"); // 循环音效,例如按钮点击声、脚步声、爆炸声、技能音效
 
// Label标签设置,调试窗口信息
// ----------------------------------------------------------------------------------------------
var labDebug = new Label(); // 新建标签类
labDebug.setPosition(20, 20); // 标签位置横坐标,纵坐标。
labDebug.setSize(150, 150); // 标签宽,高
labDebug.setColor(0,0,0,0.1);  // 标签背景颜色为黑色并透明
labDebug.setTextColor(0,1,0,0.5);  // 标签字体颜色
labDebug.setFont("font/st.ttf",15); // 标签汉字字库,字体大小,必须指定
scene.addNode(labDebug);  // 把标签增加到场景中
 
// Label标签设置,显示游戏名称
// ----------------------------------------------------------------------------------------------
var resName = game.getResource().getTexture("img/name.png");  // 获取背景图资源
var labLog = new Label(); // 新建标签类
labLog.setPosition(270, 5); // 标签位置横坐标,纵坐标。
labLog.setSize(400, 150); // 标签宽,高
labLog.setTexture(resName); 
labLog.setFont("font/st.ttf",15); // 标签汉字字库,字体大小,必须指定
//labLog.setText("标签上的测试文字\n换行123");
//lab.setColor(0,0,0,1);  // 标签背景颜色为黑色并透明
//labLog.setRotate(180); // 标签旋转180度
labLog.upDate((time)=>{ // 设置帧率回调,如果不需要可以注释
 //log("Lab callback");
});
scene.addNode(labLog);  // 把标签增加到场景中
 
// Node节点控件,这个是很多控件的基类。左上角显示一个绿色小方块,中间有个蓝色小方块
// ----------------------------------------------------------------------------------------------
log("\nNode节点控件 -------------------------------------------------------------------------");
var node = new Node(); // 新建节点
node.setPosition(1, 1);  // 节点位置横坐标,纵坐标
var pos = node.getPosition(); // 获取节点坐标
log("节点横坐标x:" + pos.x + "节点纵坐标y:" + pos.y);
node.setSize(20,20);    // 设置节点宽,高
var size = node.getSize(); // 获取节点大小
log("节点宽度:" + size.x + "节点宽度:" + size.y);
node.setName("Hello world"); // 设置节点文字
var name = node.getName(); // 获取节点文字
log("节点文字:"+name);
node.setColor(1,2,3,0.5);  // 设置节点颜色
var color = node.getColor(); // 获取节点颜色
log("获取节点颜色值为:r:" + color.x + "  g:" + color.y + "  b:" + color.z+ "  a:" + color.w);
node.setRotate(90); // 设置节点选择角度0~360
var routate = node.getRotate(); // 获取节点选择角度
log("旋转角度为:"+routate);
node.setHide(false); // 设置节点是否隐藏
var hide = node.isHide(); // 获取节点是否隐藏
log("node节点是否隐藏:" + hide);
scene.addNode(node); // 把节点增加到场景中
node.upDate((time)=>{ // 设置帧率回调,如果不需要可以注释
 //log("Node callback");
});
// 增加节点:在绿色小方块上,添加子节点,红色小方块,然后改为蓝色小方块
var node1 = new Node(); // 新建子节点
node1.setPosition(2, 2);  // 节点位置横坐标,纵坐标
node1.setSize(10,10);    // 设置节点宽,高
node1.setColor(255,0,0,1);  // 设置节点颜色,红色
node.addNode(node1); // 把子节点添加到父节点中
var nodeArray = node.getNodes(); // 获取node节点数组对象数据,从0开始 
var nodeTemp = nodeArray[0]; // 获取第一个node对象
nodeTemp.setColor(0,0,255,1);  // 设置子节点颜色,蓝色
  
// Edit编辑框设置,输入用户名称
// ----------------------------------------------------------------------------------------------
var resEditBg = game.getResource().getTexture("img/edit.png"); // 获取纹理数据对象
var editName = new Edit(); // 新建编辑框
editName.setTexture(resEditBg); // 设置底图
editName.setPosition(290, 340); // 编辑框的位置,横坐标和纵坐标
editName.setPadding(10); // 编辑框中开始输入的地方
editName.setSize(180, 60); // 编辑框的大小,宽度和高度
editName.setFont("font/st.ttf", 20); // 编辑框的汉字字库,字体大小,必不可少
//editName.setColor(255, 255, 255, 0.1);  // 编辑框背景颜色为白色并透明
//editName.setPubText("编辑框内容"); // 编辑框字体颜色为黑色不透明
scene.addNode(editName);  // 加入到场景中
 
// Sprite精灵设置,登录按钮,点击登录后替换背景音乐
// ----------------------------------------------------------------------------------------------
var resBtnBg = game.getResource().getTexture("img/button.png"); // 获取纹理数据对象
var sprLogin = new Sprite(); // 新建精灵
sprLogin.setTexture(resBtnBg); // 设置精灵背景
sprLogin.setSize(200,60); // 设置精灵大小
sprLogin.setPosition(275, 420); // 标签位置横坐标,纵坐标。
sprLogin.click(()=>{ // 点击回调函数,更换图片
    var edittext = editName.getText(); // 点击时,读取edit框内容
    log("Edit框内容:"+edittext);
    audio.stopMusic(); // 停止当前背景音乐
    audio.playMusic("sound/Normal2.mp3"); // 循环播放音乐
    audio.playSound("sound/1.wav"); // 播放音效
    aWebSocket.emitMsg("SIO_MESSAGE_UP","SIO_MESSAGE_UP");   // 发送长链接数据
});
sprLogin.longClick(()=>{ // 长按回调函数,更换图片
   log("长按");
});
scene.addNode(sprLogin); // 加入到场景中
//var nodes = scene.getChilds();
 
// ProgressBar进度条设置
// ----------------------------------------------------------------------------------------------
var resLoad = game.getResource().getTexture("img/load.png"); // 获取纹理数据对象
var progLoad = new ProgressBar(); // 新建进度条
progLoad.setBgTexture(resLoad); // 设置进度条图片
progLoad.setTexture(resLoad); // 设置进度条图片
progLoad.setPosition(200, 550); // 进度条显示位置
progLoad.setSize(380, 20); // 进度条区域大小,宽和高
progLoad.setBgColor(1.0,0.5,0.2,1); // 进度条背景颜色,透明
progLoad.setMax(100); // 进度条最大值
progLoad.setValue(0); // 设置初始进度为0
var i = 0;
progLoad.upDate((time)=>{ // 设置帧率回调
    if (i++>100) i = 0;
    progLoad.setValue(i); // 设置当前进度
    var max = progLoad.getMax(); // 获取最大进度值
    var val = progLoad.getValue(); // 获取当前进度值
    //log("进度条最大值:"+max+"进度条当前值:"+val);
});
scene.addNode(progLoad);  // 加入到场景中
 
 // Slide滑动控件,音量调节
// ----------------------------------------------------------------------------------------------
var resSlide = game.getResource().getTexture("img/slide.png"); // 获取纹理数据对象
var slideLoad = new Slide(); // 新建滑块条
slideLoad.setBarTexture(resSlide); // 设置滑块指针显示的图片
slideLoad.setPosition(300, 500); // 滑块显示位置,横坐标,纵坐标
slideLoad.setSize(150, 15); // 滑块区域大小,宽和高
//slideLoad.setBarColor(0,1,0,1); // 滑块颜色绿色,不透明
slideLoad.setColor(128,128,128,0.2); // 滑块背景颜色,透明
slideLoad.setMax(100); // 滑块最大值
slideLoad.setValue(audio.getMusicVolume()*100); // 设置初始值
var i = 0;
slideLoad.upDate((time)=>{ // 设置帧率回调
    var max = slideLoad.getMax(); // 获取最大进度值
    var val = slideLoad.getValue(); // 获取当前进度值

    audio.setMusicVolume(val*1.0/max); // 设置背景音乐音量大小
    audio.setSoundVolume(0.5); // 设置音效音量大小
    var MusicVal = audio.getMusicVolume(); // 获取背景音乐音量大小
    var SoundVal = audio.getSoundVolume();// 获取音效音量大小

    //log("滑块最大值:"+max+"进度条当前值:"+val +"背景音乐音量大小:"+MusicVal +"音效音量大小:"+SoundVal );
});
scene.addNode(slideLoad);  // 加入到场景中
  
// ScrollView滚动视图
// ----------------------------------------------------------------------------------------------
log("\nScrollView滚动视图 --------------------------------------------------------------------");
// 设置滚动视图大小,位置,背景等。半透明背景图中有白色的底图
var resScrollViewBg = game.getResource().getTexture("img/ScrollViewBg.png"); // 获取纹理数据对象
var scrollview = new ScrollView(); // 新建滚动视图
scrollview.setTexture(resScrollViewBg); //设置滚动视图背景图
scrollview.setColor(0.2, 0.5, 0.8, 0.5); // 设置滚动视图颜色
scrollview.setPosition(10,400);// 滚动视图的位置,横坐标和纵坐标
scrollview.setSize(100,100);// 滚动视图的大小,宽度和高度
scrollview.setContentSize(400,400); // 设置滚动视图中内容大小
 
// 是否隐藏滚动试图中,水平和垂直滑块
//scrollview.setShowHBar(false); // flase隐藏;ture显示;默认显示水平滚动条
//scrollview.setShowVBar(false); // flase隐藏;ture显示;默认显示垂直滚动条
 
// 获取滚动视图位置
scrollview.setScrollOffsetX(10); //  水平滚动滑块的初始位置,横坐标从10开始
scrollview.setScrollOffsetY(20); //  垂直滚动滑块的初始位置,纵坐标从20开始
var sx = scrollview.getOffsetX(); // 获取水平滚动滑块的位置
var sy = scrollview.getOffsetY(); // 获取垂直滚动滑块的位置
log("scrollview滚动窗口水平滑块初始位置:"+sx);
log("scrollview滚动窗口垂直滑块初始位置:"+sy);
 
// 设置滚动试图中,水平和垂直滑道的宽窄,如果不调用此函数,默认为20
scrollview.setHBarHeight(10); // 设置水平滚动条滑道的高度
scrollview.setVBarWidth(10);  // 设置垂直滚动条滑道的宽度
 
// 滚动视图中加入一张图片
var resSpr1 = game.getResource().getTexture("img/resSpr1.png"); // 获取纹理数据对象
var spr1 = new Sprite(); // 新建精灵
spr1.setTexture(resSpr1); // 设置精灵为白色背景图
spr1.setSize(160,160); // 设置精灵大小
spr1.setPosition(10, 50); // 标签位置横坐标,纵坐标。
scrollview.addNode(spr1); // 向滚动动窗口中增加精灵,效果为:黑色的滚动窗口中有一个白色的图
 
// 设置滚动视图垂直滚动条
var vscrollBar =scrollview.getVScrollBar(); // 获取滚动窗口中的垂直滚动条
var resVScrollBarBg = game.getResource().getTexture("img/resVScrollBarBg.png"); // 获取纹理数据对象,灰色背景图
vscrollBar.setColor(0,255,0,1); // 设置垂直滚动条背景颜色为绿色
vscrollBar.setTexture(resVScrollBarBg); // 设置滚动条里面滑块背景图为灰色
vscrollBar.setBarColor(0,0,255,1);  // 设置滚动条中滑块颜色为蓝色
vscrollBar.setBarTexture(resVScrollBarBg);// 设置滚动条中滑块背景图
 
// 设置滚动视图水平滚动条
var hscrollBar =scrollview.getHScrollBar(); // 获取滚动窗口中的水平滚动条
var resHScrollBarBg = game.getResource().getTexture("img/resVScrollBarBg.png"); // 获取纹理数据对象,灰色背景图
hscrollBar.setColor(0,255,255,1); // 设置水平滚动条背景颜色为青色
hscrollBar.setTexture(resHScrollBarBg); // 设置水平滚动条里面滑块背景图为灰色
hscrollBar.setBarColor(255,0,255,1);  // 设置水平滚动条中滑块颜色为红色
hscrollBar.setBarTexture(resHScrollBarBg);// 设置水平滚动条中滑块背景图
 
scene.addNode(scrollview); // // 加入到场景中 
 
// Http网络类
// ----------------------------------------------------------------------------------------------
log("\nHttp网络类 -----------------------------------------------------------------------------");
 var http = new Http();
 http.get("https://ctrljs.ikaiwei.com/api/test/request_logs.do?sf=sf",(str)=>{
 log(str);
 });
 http.post("https://ctrljs.ikaiwei.com/api/test/request_logs.do?","sff=sf111&se=1",(str)=>{
 });
  
 
// websocket类
// ----------------------------------------------------------------------------------------------
log("\nwebsocket长链接类 --------------------------------------------------------------------");
var aWebSocket = new SocketIO(); // 创建长连接类
var appid= "h11do3gq";
aWebSocket.initIO(appid);  // 初始化长链接中的appid,区分项目用,也可以为空
  
// 设置长连接
aWebSocket.connectIO("https://imtest.linchixuan.com/"+appid,"appId="+appid+"&uid=68661f92a88ebd78856482bc&deviceId=132441241244"); // 建立长链接
 aWebSocket.on("SIO_INFO",function(str){ // 监听长链接数据,设置回调函数
   log(JSON.stringify(str));
});
aWebSocket.on("connect",function(){
    aWebSocket.emitMsg("SIO_MESSAGE_UP","SIO_MESSAGE_UP");   // 发送长链接数据
    //aWebSocket.disConnect(); // 关闭长链接
});
  
 // 获取场景里面对象数据,从0开始 
var nodeArray = scene.getChilds();
var labTest = nodeArray[0]; // 获取第一个场景对象
//labTest.setText("世界,你好!"); // lab对象重写设置内容
 
 
// ----------------------------------------------------------------------------------
// 键盘回调方法,键值参考帮助文档中的键值表
// ----------------------------------------------------------------------------------
 
// 全局类,全局变量和参数
class GlobalVariable
{
  // 键盘键值
  static KEY_W = 87;
  static KEY_S = 83;
  static KEY_A = 65;
  static KEY_D = 68;
  static KEY_BOTTOM = 40;
  static KEY_UP = 38;
  static KEY_LEFT = 37;
  static KEY_RIGHT = 39;
}
 
// 函数功能:键盘回调函数,定义wasd或上下左右健
// 函数参数:key-键值;action-动作;
game.setKeyCallBack((key,action)=>{
  let type = "";
  if (key == GlobalVariable.KEY_W || key == GlobalVariable.KEY_UP)
      type = "up";
  else if (key == GlobalVariable.KEY_S || key == GlobalVariable.KEY_BOTTOM)
      type =  "down";
  else if (key == GlobalVariable.KEY_A || key == GlobalVariable.KEY_LEFT)
      type =  "left";
  else if (key == GlobalVariable.KEY_D || key == GlobalVariable.KEY_RIGHT)
      type =  "right";
   
  // 控制台中显示调试信息
  log("key "+key+" action "+action+" type "+type);
  logic(type) // 调用操控函数
});
 
// 函数功能:游戏中的键盘操作
// 函数参数:direction,方向 up down left right
function logic(direction)
{
  // 处理玩家输入的方向,移动所有格子并合并相同数字
  if(direction == "up") 
      log("上");
  else if (direction == "down") 
      log("下");
  else if (direction == "left") 
      log("左");
  else if (direction == "right") 
      log("右");
}
 
// 运行游戏
game.run();

导出的网页版游戏运行页面:

在这里插入图片描述

开维游戏引擎下载: www.ikaiwei.com/download/ga…

AI自动生成代码:飞翔的小鸟 FlappyBird:

www.ikaiwei.com/gamejs/exam…

源码下载: github.com/ctrljshaha/…

gamejs.ikaiwei.com/#/Market

开发文档: www.ikaiwei.com/gamejs/api/…