「见缝插针」游戏源码aardio版,由AI编写测试

By admin at 8 天前 • 0人收藏 • 84人看过

仍然由Gemini 编写, 不过这次改了好几次才成功, 主要集中在射箭后的穿模问题上

exe下载:

见缝插针.zip


screenshots.gif

import win.ui;
import gdip;
import math;
 
/*DSG{{*/
var winform = win.form(text="见缝插针 (Aardio Plus版)";right=400;bottom=600;bgcolor=16777215)
winform.add(
plus={cls="plus";left=0;top=0;right=400;bottom=600;db=1;dl=1;dr=1;dt=1;notify=1;z=1}
)
/*}}*/
 
// ==========================================
// 1. 视觉主题配置 (Theme)
// ==========================================
var theme = {
    bgDefault = 0xFFF0EFE9;   // 默认米色背景
    bgWin     = 0xFF1ABC9C;   // 胜利绿色
    bgFail    = 0xFFE74C3C;   // 失败红色
    objColor  = 0xFF2C3E50;   // 物体颜色(深蓝黑)
    textColor = 0xFFF0EFE9;   // 中心文字颜色(同背景色)
    fontName  = "Segoe UI";   // 字体
}
 
var config = {
    centerX = 200;      // 中心X
    centerY = 220;      // 中心Y
    radius = 50;        // 核心球半径
    pinLen = 110;       // 针长度
    ballRadius = 7;     // 针头半径
    safeAngle = 12;     // 碰撞角度阈值
    bulletSpeed = 35;   // 发射速度
    startY = 520;       // 发射点Y
}
 
var game = {
    level = 1;          
    state = "menu";     // menu, playing, gameover, levelup
    rotation = 0;       
    rotSpeed = 0;       
    pins = {};          // 已插入的针
    bulletsLeft = 0;    
    activePin = { y = config.startY; active = false }; 
    bgColor = theme.bgDefault;
}
 
// ==========================================
// 2. 逻辑控制
// ==========================================
 
var initLevel = function(lv){
    game.level = lv;
    game.state = "playing";
    game.rotation = 0;
    game.pins = {};
    game.activePin.active = false;
    game.activePin.y = config.startY;
    game.bgColor = theme.bgDefault;
     
    // 难度曲线算法
    var baseSpeed = 1.5;
    game.rotSpeed = baseSpeed + (lv * 0.2); 
    if(game.rotSpeed > 8) game.rotSpeed = 8;
     
    // 偶数关卡逆时针
    if(lv % 2 == 0) game.rotSpeed = -game.rotSpeed;
     
    // 初始障碍针 (第2关开始出现)
    var obstacleCount = math.floor(lv / 3);
    if(lv > 1) table.push(game.pins, { angle = 0 }); 
    for(i=1; obstacleCount){
        table.push(game.pins, { angle = math.random(0, 359) });
    }
     
    // 子弹数量
    game.bulletsLeft = 6 + math.floor(lv / 2);
}
 
// 碰撞检测
var checkCollision = function(newAngle){
    for(i=1; #game.pins){
        var p = game.pins[i];
        var diff = math.abs(p.angle - newAngle);
        if(diff > 180) diff = 360 - diff; 
        if(diff < config.safeAngle) return true;
    }
    return false;
}
 
// 统一操作入口 (鼠标/键盘共用)
var gameAction = function(){
    if(game.state == "playing"){
        // 游戏中:发射
        if(!game.activePin.active && game.bulletsLeft > 0){
            game.activePin.active = true;
            game.activePin.y = config.startY;
        }
    }
    elseif(game.state == "gameover"){
        // 失败:重试
        initLevel(game.level); 
        winform.plus.redraw();
    }
    elseif(game.state == "menu"){
        // 菜单:开始
        initLevel(1);
    }
}
 
// ==========================================
// 3. 绘图渲染
// ==========================================
winform.plus.onDrawForegroundEnd = function(graphics, rc){
    graphics.smoothingMode = 4;     // 抗锯齿
    graphics.textRenderingHint = 4; // 文字抗锯齿
     
    // --- 1. 绘制背景 ---
    var brushBg = gdip.solidBrush(game.bgColor);
    graphics.fillRectangle(brushBg, 0, 0, rc.right, rc.bottom);
    brushBg.delete();
 
    // 常用资源
    var penObj = gdip.pen(theme.objColor, 2);
    var brushObj = gdip.solidBrush(theme.objColor);
    var brushText = gdip.solidBrush(theme.textColor);
 
    // --- 2. 游戏主画面 ---
    if(game.state == "playing" || game.state == "gameover" || game.state == "levelup"){
         
        // A. 绘制已插入的针
        for(i=1; #game.pins){
            var p = game.pins[i];
            var currentAngle = p.angle + game.rotation;
            var rad = currentAngle * (math.pi / 180); 
             
            var x1 = config.centerX + math.cos(rad) * config.radius;
            var y1 = config.centerY + math.sin(rad) * config.radius;
            var x2 = config.centerX + math.cos(rad) * (config.radius + config.pinLen);
            var y2 = config.centerY + math.sin(rad) * (config.radius + config.pinLen);
             
            graphics.drawLine(penObj, x1, y1, x2, y2);
            graphics.fillEllipse(brushObj, x2-config.ballRadius, y2-config.ballRadius, config.ballRadius*2, config.ballRadius*2);
        }
         
        // B. 绘制中心大球
        graphics.fillEllipse(brushObj, config.centerX-config.radius, config.centerY-config.radius, config.radius*2, config.radius*2);
         
        // C. 绘制关卡数字 (居中)
        var font = gdip.font(theme.fontName, 32, 1);
        var fmt = gdip.stringformat();
        fmt.align = 1; // Center Horizontal
        fmt.lineAlign = 1; // Center Vertical
        graphics.drawString(tostring(game.level), font, ::RECTF(config.centerX-config.radius, config.centerY-config.radius, config.radius*2, config.radius*2), fmt, brushText);
        font.delete(); fmt.delete();
         
        // D. 绘制飞行的针
        if(game.activePin.active){
            var y = game.activePin.y;
            graphics.drawLine(penObj, config.centerX, y, config.centerX, y - config.pinLen);
            graphics.fillEllipse(brushObj, config.centerX-config.ballRadius, y, config.ballRadius*2, config.ballRadius*2); 
            // 针头连接点
            graphics.fillEllipse(brushObj, config.centerX-3, y-config.pinLen, 6, 6);
        }
         
        // E. 绘制等待队列
        var waitY = config.startY;
        var maxShow = 6; 
        var count = game.bulletsLeft;
        if(game.activePin.active) count = count - 1; 
         
        for(i=0; math.min(count, maxShow)-1){
            var y = waitY + i * 25; 
            graphics.fillEllipse(brushObj, config.centerX-config.ballRadius, y, config.ballRadius*2, config.ballRadius*2);
        }
    }
 
    // --- 3. UI 覆盖层 ---
     
    // 菜单界面
    if(game.state == "menu"){
        var fTitle = gdip.font(theme.fontName, 40, 1);
        var fSub = gdip.font(theme.fontName, 14, 0);
        var bTitle = gdip.solidBrush(theme.objColor);
        var fmt = gdip.stringformat(); fmt.align=1; fmt.lineAlign=1;
 
        // Logo
        graphics.fillEllipse(bTitle, config.centerX-60, 180, 120, 120);
        graphics.drawString("AA", fTitle, ::RECTF(0,180,400,120), fmt, brushText);
         
        // 提示文本
        graphics.drawString("点击或按空格开始", fSub, ::RECTF(0, 360, 400, 50), fmt, bTitle);
         
        fTitle.delete(); fSub.delete(); bTitle.delete(); fmt.delete();
    }
     
    // 游戏结束界面
    if(game.state == "gameover"){
        var fFail = gdip.font(theme.fontName, 20, 1);
        var bFail = gdip.solidBrush(0xFFFFFFFF);
        var fmt = gdip.stringformat(); fmt.align=1; fmt.lineAlign=1;
         
        graphics.drawString("游戏失败", fFail, ::RECTF(0, 100, 400, 50), fmt, bFail);
        graphics.drawString("点击或空格重试", fFail, ::RECTF(0, 150, 400, 50), fmt, bFail);
         
        fFail.delete(); bFail.delete(); fmt.delete();
    }
 
    // 资源清理
    penObj.delete();
    brushObj.delete();
    brushText.delete();
}
 
// ==========================================
// 4. 游戏循环 (完美修复穿模版)
// ==========================================
winform.setInterval(
    function(){
        if(game.state == "playing"){
            
            // 1. 更新旋转
            game.rotation = game.rotation + game.rotSpeed;
            if(game.rotation >= 360) game.rotation -= 360;
            if(game.rotation < 0) game.rotation += 360;
            
            // 2. 针的飞行
            if(game.activePin.active){
                // 计算关键坐标
                var pinTailY = game.activePin.y;           // 针尾 (当前坐标变量)
                var pinHeadY = pinTailY - config.pinLen;   // 针头 (向上延伸)
                var surfaceY = config.centerY + config.radius; // 球体表面Y坐标
                
                // ★★★ 核心修复:基于“针头”预判碰撞 ★★★
                // 预测下一帧针头的位置
                var nextHeadY = pinHeadY - config.bulletSpeed;
                
                // 如果针头下一帧会碰到或穿过表面
                if(nextHeadY <= surfaceY){
                    
                    // 1. 物理位置修正:
                    // 我们要把“针尾”强制设置在 (表面 + 针长) 的位置
                    // 这样“针头”就刚好停在表面 (surfaceY) 上
                    game.activePin.y = surfaceY + config.pinLen;
                    
                    // 2. 计算插入角度
                    var angle = 90 - game.rotation;
                    if(angle < 0) angle += 360;
                    
                    // 3. 碰撞判断(判断针尖插进去的位置是否有障碍)
                    if(checkCollision(angle)){
                        game.state = "gameover";
                        game.bgColor = theme.bgFail; 
                    } else {
                        // 插入成功
                        table.push(game.pins, { angle = angle });
                        game.bulletsLeft--;
                        
                        // 重置发射针
                        game.activePin.active = false;
                        game.activePin.y = config.startY;
                        
                        // 过关判断
                        if(game.bulletsLeft <= 0){
                            game.state = "levelup"; 
                            game.bgColor = theme.bgWin; 
                            winform.plus.redraw();
                            
                            win.setTimeout(function(){
                                initLevel(game.level + 1);
                                winform.plus.redraw();
                            }, 600)
                        }
                    }
                } else {
                    // 如果没撞到,正常向上飞行
                    game.activePin.y -= config.bulletSpeed;
                }
            }
            winform.plus.redraw();
        } 
        elseif(game.state == "gameover" || game.state == "menu"){
             // 待机旋转动画
             game.rotation = game.rotation + 0.5;
             if(game.rotation >= 360) game.rotation -= 360;
             winform.plus.redraw();
        }
    }, 16
)
 
// ==========================================
// 5. 交互 (鼠标 + 键盘)
// ==========================================
 
// 鼠标交互
winform.plus.onMouseDown = function(wParam,lParam){
    gameAction();
}
 
// 键盘交互 (新增)
winform.plus.onKeyDown = function(keyCode, lParam){
    if(keyCode == 0x20){ // Spacebar
        gameAction();
    }
}
 
// 强制控件获取焦点,确保能响应键盘
winform.plus.setFocus();
 
winform.show();
win.loopMessage();


1 个回复 | 最后更新于 6 天前
6 天前   #1

很流畅啊

登录后方可回帖

登 录
信息栏
本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 Popdes@126.com

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...