[gdip] 用plus控件制作一个简单的拼图游戏

Mr_MAO 11小时前 62

以前写的,放在这个网站和aar爱好者交流一下,天资愚笨,纯兴趣使然,写的不好,欢迎大家批评指正。

用刘大美女坐镇↓

这种游戏的关键点,一个一维数组到指定宽度二位数组的映射,另一个是二维数组对边界的判断。

其实都是图像编程的基础知识...


import win.ui;
/*DSG{{*/
var winform = win.form(text="拼图小游戏 (by Mr_MAO)";right=847;bottom=455)
winform.add(
plus={cls="plus";left=16;top=16;right=640;bottom=440;db=1;dl=1;dr=1;dt=1;edge=1;foreRepeat="expand";linearGradient=2;notify=1;z=1};
plus2={cls="plus";left=648;top=16;right=832;bottom=128;dr=1;dt=1;frame=1;notify=1;repeat="scale";z=4};
static={cls="static";left=648;top=184;right=840;bottom=224;align="center";center=1;color=8388736;db=1;dr=1;dt=1;font=LOGFONT(h=-24;weight=700);transparent=1;z=2};
static2={cls="static";text="计步器";left=648;top=160;right=832;bottom=192;align="center";center=1;color=8421504;dr=1;dt=1;transparent=1;z=3};
static3={cls="static";left=640;top=184;right=840;bottom=224;align="center";center=1;color=8388736;dr=1;dt=1;font=LOGFONT(h=-24;weight=700);transparent=1;z=5};
static4={cls="static";left=664;top=240;right=832;bottom=280;align="center";center=1;color=255;dr=1;dt=1;font=LOGFONT(h=-21;name='微软雅黑';weight=700);notify=1;transparent=1;z=6};
static5={cls="static";left=648;top=272;right=832;bottom=312;align="center";center=1;color=255;dr=1;dt=1;font=LOGFONT(h=-21;name='微软雅黑';weight=700);notify=1;transparent=1;z=7}
)
/*}}*/
 
x_cellNum, y_cellNum = 3,   3 //要切成的横向、竖向方块数量
gameEnd = false  //标记是否结束
isCheat = false  //标记是否作弊
 
import inet.http;
var path2bitmap = function(path){
    if(path){
        var bmp = gdip.bitmap(path)
        var w, h = bmp.width,   bmp.height;
        return bmp,w,h; 
    }
}
 
var shuffedBitmap2Arr = function(bmp,x_cellNum, y_cellNum,cellW, cellH){
    if(bmp==null) return ; 
    var cells = bmp.split(x_cellNum, y_cellNum) //返回图像数组
    table.pop(cells,1)   //弹出最后面的小图片,为了下一步替换为空白小方块
    var s_imgs = table.map(cells,function(v,k,result){
        result[k] = {id = k; value = v} //**改为二维数组,加个id字段用来判断是否复位
    })
    table.shuffle(s_imgs);  //打乱顺序
     
    blankImg = gdip.bitmap(cellW, cellH);   //生成一个空白图片
    blankCellIndex = x_cellNum * y_cellNum; 
    table.push(s_imgs, {id = blankCellIndex; value = blankImg}); 
    return s_imgs; 
}
 
var arr2bitmap =function(bmp,arr,imgW, imgH,x_cellNum, y_cellNum,cellW, cellH){
    if(bmp==null) return ; 
    if(#arr){
        var g = bmp.getGraphics().clear()
        for (y = 1; y_cellNum; 1) {
            for (x = 1; x_cellNum; 1) {
                var index = (y - 1) * x_cellNum + x;
                g.fastDrawBitmap(img_cells[index].value, (x - 1) * cellW: 1, (y - 1) * cellH: 1);
            }
        }
    }
}
 
var loadandshowImage = function(imgPath){
    if(!imgPath) return; 
    winform.plus2.background = imgPath //预览图
 
    bmp, imgW, imgH = path2bitmap(imgPath);
    cellW, cellH = math.ceil(bmp.width / x_cellNum),    math.ceil(bmp.height / y_cellNum);
    img_cells =  shuffedBitmap2Arr(bmp,x_cellNum, y_cellNum,cellW, cellH)
     
    var bmp2 = gdip.bitmap(imgW, imgH)
    arr2bitmap(bmp2,img_cells,imgW, imgH,x_cellNum, y_cellNum,cellW, cellH); 
    winform.plus.foreground =bmp2//显示
}
 
var cellRECTs = {}
winform.plus.adjust = function(cx, cy, wParam) {
    table.clear(cellRECTs)
    var cellW2 = cx / x_cellNum;
    var cellH2 = cy / y_cellNum;
    for (y = 1; y_cellNum; 1) {
        for (x = 1; x_cellNum; 1) {
            var l = (x - 1) * cellW2: 1;
            var t = (y - 1) * cellH2: 1;
            var w = l + cellW2;
            var h = t + cellH2;
            table.push(cellRECTs, ::RECT(l, t, w, h));
        }
    }
};
 
//在plus控件中点击鼠标左键
winform.plus.onMouseDown = function(wParam, lParam) {
    if(gameEnd) return; 
    var x, y = win.getMessagePos(lParam);
    for (i = 1; #cellRECTs; 1) {
        //确定鼠标所在的方块
        if (cellRECTs[i].contains(x, y) == true) {
            //如果上下左右有一个方位是空白方块
            if ( ((i + 1) == blankCellIndex && i % x_cellNum != 0/*确保i+1方块不折行*/)
                    || ((i - 1) == blankCellIndex && (i - 1) % x_cellNum != 0/*确保i-1方块不折行*/)
                    || (i - x_cellNum) == blankCellIndex
                    || (i + x_cellNum) == blankCellIndex) {
 
                //交换方块图片
                img_cells[blankCellIndex].value = img_cells[i].value;
                img_cells[blankCellIndex].id = img_cells[i].id;
                img_cells[i].value = blankImg;
                img_cells[i].id = blankCellIndex;
                blankCellIndex = i; //重新标识空白图像的index
 
                //重新绘图,并显示在plus中
                arr2bitmap(owner.foreground,img_cells,imgW, imgH,x_cellNum, y_cellNum,cellW, cellH); 
                owner.redraw();
 
                //增加计数
                var totalStep = tonumber(winform.static.text): 0;
                totalStep++;
                winform.static.text = tostring(totalStep);
                 
                //检查是否拼接成功
                var correctNum = 1
                for(i=1;#img_cells;1){
                    if(img_cells[i].id == i) correctNum++
                }
                if(correctNum == #img_cells) {
                    gameEnd = true
                    win.msgbox("拼图成功,你赢了~","提示",,winform.hwnd,5000)
                    winform.plus.foreground = winform.plus2.background
                    //更新输赢提示
                    winform.static4.text = "恭喜~ 你赢了!"
                    if(isCheat==false){
                        select(totalStep) {
                            case   0;100 { winform.static5.text = "★★★★★"}
                            case 101;200 { winform.static5.text = "★★★★"}
                            case 201;300 { winform.static5.text = "★★★"}
                            case 301;400 { winform.static5.text = "★★"}
                            else { winform.static5.text = "★"}
                        }
                    }
                }
            }
        }
    }
}
 
//作弊(彩蛋) -- ctrl+鼠标右键
winform.plus.wndproc = function(hwnd,message,wParam,lParam){
    if(gameEnd) return; //已经拼正确了
    select( message ) { 
        case 0x205/*_WM_RBUTTONUP*/{
            if(ctrlDown==false) return; 
            //鼠标右键弹起,下面获取坐标
            var x,y = win.getMessagePos(lParam);
            for (i = 1; #cellRECTs; 1) {
                //确定鼠标所在的方块
                if (cellRECTs[i].contains(x, y) == true) {
                    //如果点击的不是空白图像,开始作弊
                    if(i !=blankCellIndex ){
                        isCheat = true;
                        //交换方块图片
                        img_cells[blankCellIndex].value = img_cells[i].value;
                        img_cells[blankCellIndex].id = img_cells[i].id;
                        img_cells[i].value = blankImg; img_cells[i].id = blankCellIndex;
                        blankCellIndex = i; //重新标识空白图像的index
         
                        //重新绘图,并显示在plus中
                        arr2bitmap(owner.foreground,img_cells,imgW, imgH,x_cellNum, y_cellNum,cellW, cellH); 
                        owner.redraw();
 
                        //检查是否拼接成功
                        var correctNum = 1
                        for(i=1;#img_cells;1){
                            if(img_cells[i].id == i) correctNum++
                        }
                        if(correctNum == #img_cells) {
                            gameEnd = true
                            win.msgbox("拼图成功,你赢了~","提示",,winform.hwnd,5000)
                            winform.plus.foreground = winform.plus2.background
                            winform.static4.text = "恭喜~ 你赢了!"
                        }
                    }
                }
            }   
        }
    }
}
 
//利用winform自带事件-捕获全局键盘按键
winform.isDialogMessage = function(hwnd,msg){
    if( msg.message == 0x100/*_WM_KEYDOWN*/){
        if( msg.wParam == 0x11/*_VK_CONTROL*/){ 
            ctrlDown = true
            return true;
        }
    }    
    ctrlDown = false
    return win.isDialogMessage(hwnd,msg);
}
 
//启动程序时,默认加载一张网络图片
var url = "http://img.7qile.com/tags/liutao/48.jpg";
loadandshowImage(url)
 
//点击预览图,打开一张新的图片
import fsys.dlg;
winform.plus2.oncommand = function(id,event){
    var imgPath = fsys.dlg.open("图片格式文件|*.jpg;*.bmp;*.png;*.gif")
    if(imgPath){
        loadandshowImage(imgPath)
        winform.static.text = "" //清空计步器
        gameEnd = false;  isCheat = false
        winform.static4.text = "" //隐藏胜利提示
        winform.static5.text = ""
    }
}
 
//初始化一些控件的状态
winform.plus.backgroundColor = 0xffff8bbb8; //plus控件设置背景色
winform.static4.text = ""; winform.static5.text = ""
 
winform.show();
win.loopMessage();


最新回复 (1)
  • 光庆 9小时前
    0 2



    这个大美女是谁

返回