aardio版-跳一跳(天气干扰版)源码

By admin at 4 天前 • 0人收藏 • 72人看过

aardio版-跳一跳(天气干扰+辅助线)源码

纯Gemini 设计, 我只提了需求

screenshots.gif

编译好的exe游戏下载:

tiaoyitiao.zip



import win.ui;
import gdip;
import math;
/*DSG{{*/
winform = win.form(text="aardio 跳一跳 (辅助线版)";right=539;bottom=709;bgcolor=0xFFFFFF)
winform.add(
plus={cls="plus";left=0;top=0;right=540;bottom=710;db=1;dl=1;dr=1;dt=1;notify=1;z=1}
)
/*}}*/

// ==========================================
// 1. 游戏配置
// ==========================================
var config = {
    blockWidth = 100;    
    blockHeight = 60;    
    bodyHeight = 40;     
    maxPower = 30;       
    jumpHeight = 150;    
    minDist = 110;        
    maxDist = winform.plus.width/2-20;
    powerRatio = 10; 
    cameraSpeed = 0.1; // 镜头跟随平滑度
    
    // 天气配置
    cloudCount = 6;      
    rainCount = 100;      
}

var gameState = {
    blocks = {};          
    playerPos = {x=0;y=0};
    cameraOffset = {x=0;y=0};
    score = 0;
    isGameOver = false;
    action = "idle";      
    power = 0;            
    jumpStartPos = {x=0;y=0};
    jumpTargetDist = 0;
    jumpDirection = {x=0;y=0};
    jumpProgress = 0;
    
    // 天气状态
    weather = {
        type = "sunny"; 
        items = {};     
        bgColor = 0;    
        lightning = { active=false; segments={}; timer=0; flashAlpha=0; duration=0 }
    }
}

// ==========================================
// 2. 几何与天气算法
// ==========================================
var getPolyPoints = function(cx, cy, r, sides, angleOffset){
    var points = {};
    for(i=0; sides-1){
        var theta = angleOffset + (i * 2 * math.pi / sides);
        table.push(points, cx + r * math.cos(theta)); 
        table.push(points, cy + (r * 0.6) * math.sin(theta));
    }
    return points;
}

var createLightningBolt = function(){
    var segments = {};
    var currX = math.random(50, winform.plus.width-50);
    var currY = -50;
    var segCount = math.random(5, 8); 
    var stepY = (winform.plus.height * 0.8) / segCount;
    for(i=1; segCount){
        var nextX = currX + math.random(-80, 80); 
        var nextY = currY + stepY + math.random(-20, 20);
        table.push(segments, {x1=currX; y1=currY; x2=nextX; y2=nextY});
        currX, currY = nextX, nextY;
    }
    return segments;
}

var initWeather = function(){
    gameState.weather.items = {};
    gameState.weather.lightning = { active=false; segments={}; timer=100; flashAlpha=0; duration=0 };
    
    if(math.random(0,1) == 0){
        // ☀️ 晴天
        gameState.weather.type = "sunny"; 
        gameState.weather.bgColor = 0xFF87CEEB; 
        for(i=1; config.cloudCount){
            table.push(gameState.weather.items, { x=math.random(-50,450); y=math.random(20,200); speed=math.random(2,5)*0.1; scale=math.random(8,15)*0.1; type="cloud" });
        }
    } else {
        // ⛈️ 雷雨天
        gameState.weather.type = "rainy"; 
        gameState.weather.bgColor = 0xFF4B5B6B; // 深蓝灰背景
        for(i=1; config.cloudCount){
            table.push(gameState.weather.items, { x=math.random(-50,450); y=math.random(20,150); speed=math.random(5,10)*0.1; scale=math.random(8,15)*0.1; type="darkcloud" });
        }
        for(i=1; config.rainCount){
            table.push(gameState.weather.items, { x=math.random(0,450); y=math.random(0,600); speed=math.random(10,20); len=math.random(10,25); type="rain" });
        }
    }
}

var updateWeather = function(){
    var w, h = winform.plus.width, winform.plus.height;
    // 更新云雨位置
    for(i=1; #gameState.weather.items){
        var item = gameState.weather.items[i];
        if(item.type == "cloud" || item.type == "darkcloud"){
            item.x += item.speed; if(item.x > w + 100) item.x = -100;
        } elseif(item.type == "rain"){
            item.y += item.speed; if(item.y > h){ item.y = -item.len; item.x = math.random(0, w); }
        }
    }
    // 更新闪电
    if(gameState.weather.type == "rainy"){
        var ln = gameState.weather.lightning;
        if(ln.flashAlpha > 0) ln.flashAlpha -= 10; // 闪光渐隐
        if(ln.flashAlpha < 0) ln.flashAlpha = 0;
        
        if(ln.active){ ln.duration--; if(ln.duration <= 0) ln.active = false; }
        
        ln.timer--;
        if(ln.timer <= 0){
            // 随机触发闪电
            if(math.random(1, 100) < 5){ 
                ln.active = true; ln.duration = math.random(3, 6); 
                ln.segments = createLightningBolt(); ln.flashAlpha = 150; 
                ln.timer = math.random(100, 300); 
            }
        }
    }
}

// ==========================================
// 3. 游戏核心逻辑
// ==========================================
var spawnBlock = function(){
    var lastBlock = gameState.blocks[#gameState.blocks];
    var newBlock = {};
    var types = {"cube", "cylinder", "pentagon"};
    newBlock.type = types[math.random(1, 3)];
    math.randomize();
    var direction = math.random(0, 1); 
    var distance = math.random(config.minDist, config.maxDist);
    if(!lastBlock){ newBlock.x=225; newBlock.y=400; newBlock.type="cube"; } 
    else {
        if(direction==0) { newBlock.x=lastBlock.x-distance*0.8; newBlock.y=lastBlock.y-distance*0.5; } 
        else { newBlock.x=lastBlock.x+distance*0.8; newBlock.y=lastBlock.y-distance*0.5; }
    }
    var colors = {0xFFEEEEEE, 0xFFFFE4E1, 0xFF98FB98, 0xFFAFEEEE, 0xFFFFD700};
    newBlock.color = colors[math.random(1, #colors)];
    if(!lastBlock) newBlock.color = 0xFFFFFFFF;
    table.push(gameState.blocks, newBlock);
    if(#gameState.blocks > 6) table.remove(gameState.blocks, 1);
}

var initGame = function(){
    gameState.blocks = {}; gameState.score = 0; gameState.isGameOver = false;
    gameState.action = "idle"; gameState.power = 0; gameState.cameraOffset = {x=0; y=0};
    initWeather(); spawnBlock(); spawnBlock();
    gameState.playerPos.x = gameState.blocks[1].x; gameState.playerPos.y = gameState.blocks[1].y;
}

var checkLanding = function(){
    var px, py = gameState.playerPos.x, gameState.playerPos.y;
    for(i=1; #gameState.blocks){
        var b = gameState.blocks[i];
        if(math.sqrt((px-b.x)**2 + (py-b.y)**2) < (config.blockWidth/2.2)){
            if(i==#gameState.blocks){ 
                gameState.score++; 
                spawnBlock(); 
                gameState.action="idle"; // 立即允许下次操作
            } else { 
                gameState.action="idle"; 
            }
            return true;
        }
    }
    return false;
}

// ==========================================
// 4. 渲染绘制
// ==========================================
var drawCloud = function(g, x, y, scale, isDark){
    var color = isDark ? 0xAA444444 : 0x88FFFFFF; var brush = gdip.solidBrush(color);
    g.fillEllipse(brush, x, y, 50*scale, 50*scale);
    g.fillEllipse(brush, x+25*scale, y-20*scale, 60*scale, 60*scale);
    g.fillEllipse(brush, x+50*scale, y, 50*scale, 50*scale); brush.delete();
}
var drawCube = function(g, x, y, w, h, bh, color){
    var b1=gdip.solidBrush(0xFF999999); g.fillPolygon(b1,{x,y+h/2;x+w/2,y;x+w/2,y+bh;x,y+h/2+bh}); b1.delete();
    var b2=gdip.solidBrush(0xFFBBBBBB); g.fillPolygon(b2,{x,y+h/2;x-w/2,y;x-w/2,y+bh;x,y+h/2+bh}); b2.delete();
    var bTop=gdip.solidBrush(color); g.fillPolygon(bTop,{x,y-h/2;x+w/2,y;x,y+h/2;x-w/2,y}); bTop.delete();
}
var drawCylinder = function(g, x, y, w, h, bh, color){
    var bSide=gdip.solidBrush(0xFFAAAAAA); g.fillRectangle(bSide,x-w/2,y,w,bh); g.fillEllipse(bSide,x-w/2,y+bh-h/2,w,h); bSide.delete();
    var bTop=gdip.solidBrush(color); g.fillEllipse(bTop,x-w/2,y-h/2,w,h); bTop.delete();
}
var drawPentagon = function(g, x, y, w, h, bh, color){
    var ptsTop=getPolyPoints(x,y,w/2,5,-1.5);
    var bSide=gdip.solidBrush(0xFF999999); 
    for(i=1;#ptsTop;2){ var nx=(i<#ptsTop-1)?i+2:1; if(ptsTop[i+1]>y||ptsTop[nx+1]>y){ 
        g.fillPolygon(bSide,{ptsTop[i],ptsTop[i+1];ptsTop[nx],ptsTop[nx+1];ptsTop[nx],ptsTop[nx+1]+bh;ptsTop[i],ptsTop[i+1]+bh});
    }} bSide.delete();
    var bTop=gdip.solidBrush(color); g.fillPolygon(bTop,ptsTop); bTop.delete();
}
var drawPlayer = function(g, x, y){
    x-=gameState.cameraOffset.x; y-=gameState.cameraOffset.y;
    var compress=(gameState.action=="charge")?gameState.power*0.5:0;
    var bS=gdip.solidBrush(0x50000000); g.fillEllipse(bS,x-10,y-5,20,10); bS.delete();
    var bB=gdip.solidBrush(0xFF333333); var w,h=20+compress/2,40-compress;
    g.fillRectangle(bB,x-w/2,y-h-10,w,h); g.fillEllipse(bB,x-12,y-h-25+compress,24,24); bB.delete();
}
var drawTrajectory = function(graphics){
    if(gameState.action != "charge") return;
    var targetBlock = gameState.blocks[#gameState.blocks];
    var dx = targetBlock.x - gameState.playerPos.x;
    var dy = targetBlock.y - gameState.playerPos.y;
    var len = math.sqrt(dx*dx + dy*dy) || 1;
    var dirX, dirY = dx/len, dy/len;
    var predictDist = gameState.power * config.powerRatio;
    
    var points = {};
    var step = 0.05; var penGuide = gdip.pen(0xAAFFFFFF, 2, 2/*Dash*/); 
    for(t=0; 1; step){
        var tx = gameState.playerPos.x + dirX * predictDist * t;
        var ty = gameState.playerPos.y + dirY * predictDist * t;
        var height = math.sin(t * math.pi) * config.jumpHeight;
        ty -= height;
        table.push(points, tx - gameState.cameraOffset.x);
        table.push(points, ty - gameState.cameraOffset.y);
    }
    if(#points > 2) graphics.drawCurve(penGuide, points);
    penGuide.delete();
    
    var landX = gameState.playerPos.x + dirX * predictDist - gameState.cameraOffset.x;
    var landY = gameState.playerPos.y + dirY * predictDist - gameState.cameraOffset.y;
    var bMark = gdip.solidBrush(0xAAFF0000); graphics.fillEllipse(bMark, landX-5, landY-2.5, 10, 5); bMark.delete();
}

winform.plus.onDrawForegroundEnd = function(graphics, rc){
    // 1. 绘制背景
    graphics.clear(gameState.weather.bgColor); 
    graphics.smoothingMode = 4;
    
    // 2. 绘制闪电 (云层后)
    var ln = gameState.weather.lightning;
    if(ln.active){
        var penBolt = gdip.pen(0xFFFFFFFF, 3); 
        for(i=1; #ln.segments){ var seg=ln.segments[i]; graphics.drawLine(penBolt, seg.x1, seg.y1, seg.x2, seg.y2); }
        var penGlow = gdip.pen(0x50FFFFFF, 8);
        for(i=1; #ln.segments){ var seg=ln.segments[i]; graphics.drawLine(penGlow, seg.x1, seg.y1, seg.x2, seg.y2); }
        penBolt.delete(); penGlow.delete();
    }
    
    // 3. 绘制云
    for(i=1; #gameState.weather.items){
        var item = gameState.weather.items[i];
        if(item.type=="cloud") drawCloud(graphics, item.x, item.y, item.scale, false);
        elseif(item.type=="darkcloud") drawCloud(graphics, item.x, item.y, item.scale, true);
    }
    
    // 4. 绘制方块
    var drawList = table.clone(gameState.blocks); table.sort(drawList, function(b){ return owner.y < b.y });
    for(i=1; #drawList){
        var b = drawList[i];
        var dx, dy = b.x - gameState.cameraOffset.x, b.y - gameState.cameraOffset.y;
        if(b.type=="cylinder") drawCylinder(graphics, dx, dy, config.blockWidth, config.blockHeight, config.bodyHeight, b.color);
        elseif(b.type=="pentagon") drawPentagon(graphics, dx, dy, config.blockWidth, config.blockHeight, config.bodyHeight, b.color);
        else drawCube(graphics, dx, dy, config.blockWidth, config.blockHeight, config.bodyHeight, b.color);
    }
    
    // 5. 绘制辅助线和玩家
    drawTrajectory(graphics);
    var py = gameState.playerPos.y;
    if(gameState.action=="jump") py-=math.sin(gameState.jumpProgress*math.pi)*config.jumpHeight;
    drawPlayer(graphics, gameState.playerPos.x, py);
    
    // 6. 绘制雨滴 (最上层)
    if(gameState.weather.type == "rainy"){
        var penRain = gdip.pen(0x88AAAAFF, 1);
        for(i=1; #gameState.weather.items){
            var item = gameState.weather.items[i];
            if(item.type=="rain") graphics.drawLine(penRain, item.x, item.y, item.x, item.y+item.len);
        }
        penRain.delete();
    }
    
    // 7. 闪电全屏闪光
    if(ln.flashAlpha > 0){
        var argb = (math.floor(ln.flashAlpha) << 24) | 0xFFFFFF;
        var brushFlash = gdip.solidBrush(argb); graphics.fillRectangle(brushFlash, 0, 0, rc.right, rc.bottom); brushFlash.delete();
    }
    
    // 8. UI
    var font = gdip.font("微软雅黑", 20, 1);
    var txtColor = (ln.flashAlpha > 100) ? 0xFF000000 : 0xFFFFFFFF;
    var info = "分数: " + gameState.score;
    graphics.drawString(info, font, ::RECTF(20,20,400,60), gdip.stringformat(), gdip.solidBrush(txtColor));
    if(gameState.isGameOver) graphics.drawString("挂了! 按空格重开", font, ::RECTF(120,200,400,100), gdip.stringformat(), gdip.solidBrush(0xFFFF0000));
    font.delete();
}

// ==========================================
// 5. 循环与控制 (集成版)
// ==========================================
winform.setInterval(function(){
    if(gameState.isGameOver) return;
    
    // 1. 更新天气
    updateWeather();
    
    // 2. 独立更新镜头 (丝滑跟随)
    var targetCamX = gameState.playerPos.x - winform.plus.width/2;
    var targetCamY = gameState.playerPos.y - winform.plus.height/1.5;
    gameState.cameraOffset.x += (targetCamX - gameState.cameraOffset.x) * config.cameraSpeed;
    gameState.cameraOffset.y += (targetCamY - gameState.cameraOffset.y) * config.cameraSpeed;
    
    // 3. 玩家动作
    if(gameState.action=="charge"){ 
        if(gameState.power<config.maxPower) gameState.power+=0.8; 
    }
    elseif(gameState.action=="jump"){
        gameState.jumpProgress+=0.04;
        if(gameState.jumpProgress>=1){
            gameState.jumpProgress=1;
            var dist=gameState.jumpTargetDist;
            gameState.playerPos.x=gameState.jumpStartPos.x+gameState.jumpDirection.x*dist;
            gameState.playerPos.y=gameState.jumpStartPos.y+gameState.jumpDirection.y*dist;
            if(!checkLanding()){ gameState.action="fall"; gameState.isGameOver=true; }
        } else {
            var dist=gameState.jumpTargetDist*gameState.jumpProgress;
            gameState.playerPos.x=gameState.jumpStartPos.x+gameState.jumpDirection.x*dist;
            gameState.playerPos.y=gameState.jumpStartPos.y+gameState.jumpDirection.y*dist;
        }
    }
    winform.plus.redraw();
}, 16)

winform.plus.onKeyDown = function(keyCode,lParam,repeat){
    if(gameState.isGameOver){ initGame(); winform.plus.redraw(); return; }
    if(gameState.action=="idle"){ gameState.action="charge"; gameState.power=0; }    
}
winform.plus.onKeyUp = function(keyCode,lParam){
    if(gameState.action=="charge"){
        gameState.action="jump"; gameState.jumpProgress=0; gameState.jumpStartPos=table.clone(gameState.playerPos);
        gameState.jumpTargetDist=gameState.power * config.powerRatio; 
        var tb=gameState.blocks[#gameState.blocks];
        var dx,dy=tb.x-gameState.playerPos.x, tb.y-gameState.playerPos.y;
        var len=math.sqrt(dx*dx+dy*dy)||1;
        gameState.jumpDirection={x=dx/len; y=dy/len};
    }    
}
winform.plus.setFocus();

initGame();
winform.show();
return win.loopMessage();				
3 个回复 | 最后更新于 3 小时前
4 天前   #1

wow 不错啊,你用的免费的还是收费的

4 天前   #2

回复#1 @aubreychao :白嫖AI一年学生卡

3 小时前   #3

回复#2 @admin :

哈哈

登录后方可回帖

登 录
信息栏
本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



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

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

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...