利用aardio制作简单的连连看游戏

Mr_MAO 2天前 92

//《连连看》小游戏 - (青春回忆版)
import win.ui;
import gdip;
import fonts.fontAwesome;
/*DSG{{*/
winform = win.form(text="连连看小游戏 (By: Mr_MAO)";right=583;bottom=639;bgcolor=0xFFFFFF;border="dialog frame";max=false)
winform.add(
btnReset={cls="button";text="重新开始";left=440;top=576;right=560;bottom=612;db=1;dr=1;z=2};
gameBoard={cls="plus";left=20;top=60;right=560;bottom=560;bgcolor=0xC0C0C0;db=1;dl=1;dr=1;dt=1;notify=1;z=1};
lblTime={cls="static";text="剩余时间: 60s";left=24;top=24;right=152;bottom=48;dl=1;dt=1;font=LOGFONT(h=-16;weight=700);z=3};
progressTime={cls="plus";left=160;top=28;right=560;bottom=44;bgcolor=0xEEEEEE;border={radius=8;width=1};dl=1;dr=1;dt=1;forecolor=0xFFAA44;z=4}
)
/*}}*/

var ROWS, COLS, TYPE_COUNT = 12, 12, 8;
var TOTAL_TIME = 100; // 游戏总时间(秒)
var timeLeft = TOTAL_TIME;
var timerId, map, firstSelect, activePath, isAnimating;

// 初始化地图
var initMap = function(){
    var temp = {};
    var total = (ROWS-2) * (COLS-2);
    for(i=1;total;2){
        var t = math.random(1, TYPE_COUNT);
        table.push(temp, t, t);
    }
    for(i=#temp;1;-1){
        var j = math.random(1, i);
        temp[i], temp[j] = temp[j], temp[i];
    }
    map = {};
    for(r=1;ROWS){
        map[r] = {};
        for(c=1;COLS){
            if(r==1 || r==ROWS || c==1 || c==COLS) map[r][c] = 0;
            else map[r][c] = table.remove(temp);
        }
    }
}

// 连通逻辑
var getDirectPath = function(r1, c1, r2, c2) {
    if (r1 != r2 && c1 != c2) return null;
    if (r1 == r2) {
        var start, stop = math.min(c1, c2), math.max(c1, c2);
        for (i = start + 1; stop - 1) if (map[r1][i] != 0) return null;
    } else {
        var start, stop = math.min(r1, r2), math.max(r1, r2);
        for (i = start + 1; stop - 1) if (map[i][c1] != 0) return null;
    }
    return {{r=r1; c=c1}; {r=r2; c=c2}};
}

var getOneCornerPath = function(r1, c1, r2, c2) {
    if (map[r1][c2] == 0) {
        var p1 = getDirectPath(r1, c1, r1, c2);
        var p2 = getDirectPath(r1, c2, r2, c2);
        if(p1 && p2) return {{r=r1; c=c1}; {r=r1; c=c2}; {r=r2; c=c2}};
    }
    if (map[r2][c1] == 0) {
        var p1 = getDirectPath(r1, c1, r2, c1);
        var p2 = getDirectPath(r2, c1, r2, c2);
        if(p1 && p2) return {{r=r1; c=c1}; {r=r2; c=c1}; {r=r2; c=c2}};
    }
    return null;
}

var getConnectPath = function(r1, c1, r2, c2) {
    if (map[r1][c1] != map[r2][c2]) return null;
    if (r1 == r2 && c1 == c2) return null;
    var path = getDirectPath(r1, c1, r2, c2);
    if(path) return path;
    path = getOneCornerPath(r1, c1, r2, c2);
    if(path) return path;
    for (c = 1; COLS) {
        if (map[r1][c] == 0) {
            var p1 = getDirectPath(r1, c1, r1, c);
            var p2 = getOneCornerPath(r1, c, r2, c2);
            if(p1 && p2) return {{r=r1; c=c1}; {r=r1; c=c}; p2[2]; {r=r2; c=c2}};
        }
    }
    for (r = 1; ROWS) {
        if (map[r][c1] == 0) {
            var p1 = getDirectPath(r1, c1, r, c1);
            var p2 = getOneCornerPath(r, c1, r2, c2);
            if(p1 && p2) return {{r=r1; c=c1}; {r=r; c=c1}; p2[2]; {r=r2; c=c2}};
        }
    }
    return null;
}

// 检查是否游戏结束
var checkGameOver = function(){
    for(r=1;ROWS){
        for(c=1;COLS){
            if(map[r][c] != 0) return false;
        }
    }
    return true;
}

// 停止游戏
var stopGame = function(win){
    if(timerId) winform.clearInterval(timerId);
    isAnimating = true; // 锁定操作
    if(win) winform.msgbox("恭喜你,挑战成功!","胜利");
    else winform.msgbox("很遗憾,时间用完了!","游戏结束");
}

// 绘制立体小球函数
var drawGlassBall = function(graphics, rect, color, isSelected) {
    // 1. 绘制主体阴影
    var shadowBrush = gdip.solidBrush(0x30000000);
    graphics.fillEllipse(shadowBrush, rect.x+2, rect.y+2, rect.width, rect.height);
    shadowBrush.delete();

    // 2. 绘制球体底色
    var ballBrush = gdip.solidBrush(color);
    graphics.fillEllipse(ballBrush, rect);
    ballBrush.delete();

    // 3. 绘制立体渐变蒙层
    var highlightRect = ::RECTF(rect.x + rect.width*0.15, rect.y + rect.height*0.1, rect.width*0.5, rect.height*0.4);
    var highlightBrush = gdip.solidBrush(0x80FFFFFF);
    graphics.fillEllipse(highlightBrush, highlightRect);
    highlightBrush.delete();

    // 如果被选中,加一个外圈发光
    if(isSelected){
        var selectPen = gdip.pen(0xFFF00F00, 3);
        graphics.drawEllipse(selectPen, rect);
        selectPen.delete();
    }
}

winform.gameBoard.onDrawContent = function(graphics, rc) {
    var tileW = rc.width() / COLS;
    var tileH = rc.height() / ROWS;
    var colors = { 0xFFFF4444, 0xFF44FF44, 0xFF4444FF, 0xFFFFFF44, 0xFFFF44FF, 0xFF44FFFF, 0xFFFFA500, 0xFF800080 };

    // 1. 绘制方块
    for(r=1;ROWS){
        for(c=1;COLS){
            var val = map[r][c];
            if(val == 0) continue;

            var x = (c-1) * tileW;
            var y = (r-1) * tileH;
            var ballRect = ::RECTF(x+6, y+6, tileW-12, tileH-12);
            var isSelected = (firstSelect && firstSelect.r == r && firstSelect.c == c);

            drawGlassBall(graphics, ballRect, colors[val], isSelected);
        }
    }

    // 2. 绘制连线动效
    if(activePath){
        var points = {};
        for(i=1;#activePath){
            var p = activePath[i];
            table.push(points, (p.c - 0.5) * tileW, (p.r - 0.5) * tileH);
        }
        var linePen = gdip.pen(0xAAFF0000, 4); 
        linePen.dashStyle = 1/*_DashStyleDash*/;
        linePen.lineJoin = 2/*_LineJoinRound*/;
        graphics.drawCurve2(linePen, 0, points);
        linePen.delete();
    }
}

winform.gameBoard.onMouseDown = function(wParam, lParam){
    if(isAnimating) return; 

    var x, y = win.getMessagePos(lParam);
    var rc = owner.getClientRect();
    var c = math.floor(x / (rc.width() / COLS)) + 1;
    var r = math.floor(y / (rc.height() / ROWS)) + 1;

    if(r < 1 || r > ROWS || c < 1 || c > COLS || map[r][c] == 0) return;

    if(!firstSelect || (firstSelect.r == r && firstSelect.c == c)){
        firstSelect = {r=r; c=c};
        owner.redraw();
    } else {
        var path = getConnectPath(firstSelect.r, firstSelect.c, r, c);
        if(path){
            activePath = path;
            isAnimating = true;
            var r1, c1, r2, c2 = firstSelect.r, firstSelect.c, r, c;
            firstSelect = null;
            owner.redraw();

            winform.setTimeout(function(){
                map[r1][c1], map[r2][c2] = 0, 0;
                activePath = null;
                isAnimating = false;
                winform.gameBoard.redraw();
                if(checkGameOver()) stopGame(true);
            }, 150);
        } else {
            firstSelect = {r=r; c=c};
            owner.redraw();
        }
    }
}

// 开始/重置游戏
var startGame = function(){
    if(timerId) winform.clearInterval(timerId);
    timeLeft = TOTAL_TIME;
    isAnimating = false;
    firstSelect = null;
    activePath = null;

    initMap();
    winform.progressTime.setProgressRange(1, TOTAL_TIME);
    winform.progressTime.progressPos = TOTAL_TIME;

    timerId = winform.setInterval(function(){
        timeLeft--;
        winform.lblTime.text = "剩余时间: " + timeLeft + "s";
        winform.progressTime.progressPos = timeLeft;

        if(timeLeft <= 0) stopGame(false);
    }, 1000);

    winform.gameBoard.redraw();
}

winform.btnReset.oncommand = function(id,event){
    startGame();
}

startGame();
winform.show();
win.loopMessage();


最新回复 (3)
  • 光庆 2天前
    0 2
    非常精彩的代码,学习了。
  • 光庆 1天前
    0 3
    // 初始化地图
    var initMap = function(){
        var temp = {};
        for(i=1;..math.floor((ROWS-2)*(COLS-2)/2)){
            var t = math.random(1, TYPE_COUNT);
            ..table.push(temp, t, t);
        }
        ..table.shuffle(temp);
        map = ..table.array(ROWS,COLS,0);
        for(r=2;ROWS-1){
            for(c=2;COLS-1;1){
    			map[r][c] = ..table.pop(temp):0;
            }
        }
    }


  • Mr_MAO 1天前
    0 4
    庆大厉害👍👍👍
返回