精华内容
下载资源
问答
  • 拼图游戏制作

    2013-01-10 11:32:43
    武汉理工大华夏学院flash拼图游戏制作包括报告书,
  • js美女拼图游戏制作

    2013-10-07 15:05:41
    通过js实现美女拼图游戏制作,代码简短,可供初学者,学习研究使用
  • 制作的工具条件 android studio工具和ps 选择适合手机屏幕的图片 利用ps分成九等份,在制作一张空白图片 ...会Intent传值 会安卓基础的控件和布局 创建项目之后 第一件事就是写布局 ...就是拼图游戏的布局; 用Linea...

    制作的工具条件

    android studio工具和ps
    选择适合手机屏幕的图片
    利用ps分成九等份,在制作一张空白图片
    会安卓的点击事件处理
    会Intent传值
    会安卓基础的控件和布局

    创建项目之后
    第一件事就是写布局

    第一个布局

    选择图片的布局,称呼为选择图片的布局

    布局如图
    写两个按钮用来切换图片,点击中间按钮开始游戏
    并给id;
    我是用图片代替按钮。

    第二个布局

    就是拼图游戏的布局;
    在这里插入图片描述
    用LinearLayout标签中的 android:layout_weight属性把九个图片控件平分屏幕。
    并给id;

    选择图片的Activity

    很简单,一共有三个按钮,就写三个点击事件;
    在定义一个 int tu_ID的变量,用来代表选中的是哪张图片;
    首先是开始游戏的点击事件
    s
    利用Intent传值给拼图的Activity

    其次是上一张的点击事件
    在这里插入图片描述
    点击后,tu_ID加一,并相应的改变背景图;

    最后是下一张的点击事件
    跟上一张差不多

    拼图的Activity

    第一件事就是拿到传过来的值,判断是哪张图片
    然后创建一个长度为九的int数组,分别拿到8张图片的资源值
    ,第九张填空白图片的资源值。

    打乱图片,图片不能直接随机打乱,否则会出现拼不了的现象;
    我写了一个打乱方法

     public int[] sjsss(int[] ai){
    
                int weizhi=8;//表示白板的位置
                int tihuan=0;
                for (int i = 0; i < 50; i++) {//这个50次,你觉得少可以加
                    int sj1=(int)(Math.random()*4+1);
                    if (sj1==1) {
                        int pd=weizhi;
                        if (weizhi==2||weizhi==1||weizhi==0) {
                            pd=weizhi;
                        }else {
                            pd=weizhi-3;
                        }
    
                        tihuan=ai[weizhi];
                        ai[weizhi]=ai[pd];
                        ai[pd]=tihuan;
                        weizhi=pd;
                    }else if (sj1==2) {
                        int pd=weizhi;
                        if (weizhi==6||weizhi==7||weizhi==8) {
                            pd=weizhi;
                        }else {
                            pd=weizhi+3;
                        }
    
                        tihuan=ai[weizhi];
                        ai[weizhi]=ai[pd];
                        ai[pd]=tihuan;
                        weizhi=pd;
                    }else if (sj1==3) {
                        int pd=weizhi;
                        if (weizhi==0||weizhi==3||weizhi==6) {
                            pd=weizhi;
                        }else {
                            pd=weizhi-1;
                        }
    
                        tihuan=ai[weizhi];
                        ai[weizhi]=ai[pd];
                        ai[pd]=tihuan;
                        weizhi=pd;
                    }else if (sj1==4) {
                        int pd=weizhi;
                        if (weizhi==2||weizhi==5||weizhi==8) {
                            pd=weizhi;
                        }else {
                            pd=weizhi+1;
                        }
    
                        tihuan=ai[weizhi];
                        ai[weizhi]=ai[pd];
                        ai[pd]=tihuan;
                        weizhi=pd;
                    }
    
                }
                return ai;
            }
    

    打乱后,在把数组的资源分别填充到九个控件中
    这里封装一个方法

        public void runX(){
            pt1.setImageDrawable(getResources().getDrawable(x[0]));
            pt2.setImageDrawable(getResources().getDrawable(x[1]));
            pt3.setImageDrawable(getResources().getDrawable(x[2]));
            pt4.setImageDrawable(getResources().getDrawable(x[3]));
            pt5.setImageDrawable(getResources().getDrawable(x[4]));
            pt6.setImageDrawable(getResources().getDrawable(x[5]));
            pt7.setImageDrawable(getResources().getDrawable(x[6]));
            pt8.setImageDrawable(getResources().getDrawable(x[7]));
            pt9.setImageDrawable(getResources().getDrawable(x[8]));
        }
    


    然后就在写九个控件的点击事件
    看着多,其实简单写,
    首先拿到白板的位置,
    在每个点击事件里判断是否靠近白板
    如果是,则交换数组的值,
    然后在执行runX()
    然后在写一个判断是否拼图完成的方法;
    就是判断数组的每个值是否等于原先的值;
    如果正确就可以弹出提示框或者什么;

    最后

    可以打包给同学朋友玩玩
    也可以加个计时器进去。
    有什么不懂的欢迎留言;

    展开全文
  • HTML5游戏实战:计时拼图游戏制作

    千次阅读 2015-07-13 08:52:34
    这次使用www.tangide.com制作了一款推广类用的拼图游戏  这游戏复杂点在各种拖动, 滑动的动画实现上. 下面我主要分享下动画部分的实现方法. 0 在线运行:  ... ...首

    这次使用www.tangide.com制作了一款推广类拼图游戏 ,

    这游戏复杂点在各种拖动, 滑动的动画实现上. 下面我主要分享下动画部分的实现方法.


    0 在线运行: 

    http://www.tangide.com/apprun.html?appid=previewupyunosgames1-241435729564104



    1: 确认界面布局


    首先是对游戏功能区域的设计和

    划分

    滑动选择区在屏幕最下方, 每一块小的拼图会出现在这里, 玩家可以左右滑动让整个滑动区域轮动以查看全部拼图块.

    这里我放入了一张图片在屏幕最左下角,游戏开始时通过对这张图的自动复制, 随机排序, 插入图片等操作来


    拼图放置区在计时器下方, 玩家需要吧小拼图从滑动选择区拖到这个区域的正确位置以完成游戏.

    这里是4X4的游戏, 我放置了16张小图片用来确认16个格子的位置, 并让这16个格子以第一个格子为基准自动对齐.

    这么做确认麻烦但由于我是首次开发此类型游戏,这样做利于调试.


    可以看到滑动选择区和拼图放置区之间有一段空隙, 这主要是为不同分辨率的手机预留的.截图分辨率为480*800.

    这样的布局可以在不同屏幕比的设备 例如ip4S,5S上都显示得体.



    2: 滑动区域初始化


    win.initPictrue = function() {
        var tempPicList = [];
        
        for (var i=1;i<=16;i++) {//排列图片
            picBar[i-1] = "图片"+i;
            tempPicList[i-1] = i-1;
            if (! win.find("图片"+i)) {
                win.dupChild("图片1").setName("图片"+i);
            }
            var x = (i-1)*basePic.w;
            win.find("图片"+i,true).setPosition(x,win.h-basePic.h);
            win.find("图片"+i,true).setVisible(true);
        }
        //打乱图片顺序
        
        var w = 404/4;
        var h = 404/4;
        
        for (i=0; i<16; i++) {
            var random = Math.floor(Math.random()*tempPicList.length);
            if (!DEBUG) {
                picOrder[i] = tempPicList[random];
                tempPicList.splice(random,1);
            }else {
                picOrder[i] = i;
            }
            var s = {xx:0,yy:0};
            coord.push(s);
            coord[i].xx = w*((i+1)%4 === 0 ? 3 : ((i+1)%4) - 1);
            coord[i].yy = h*(Math.ceil((i+1)/4) - 1);
            if (DEBUG) {
                console.log("dd_initPictrue x="+coord[i].xx+" y="+coord[i].yy);
            }
        }
        
        for (i=0;i<16;i++) {//给picBar的位置设置图片
            win.find(picBar[i]).setImageSrc(PUZZLEIMAGE);
            win.find(picBar[i]).setImageSrcRect(
                coord[picOrder[i]].xx, coord[picOrder[i]].yy, w, h);
            
            if (DEBUG) { 
                win.find(picBar[i]).setText(picOrder[i]+1);
            }
            win.find(picBar[i]).key = picOrder[i]+1;
        }
    };


    通过对屏幕下方拖动栏的初始化完成了picBar的随机排序, 随机插入图片, 以及最终用来判断游戏结束的key值记录.


    3: 图片放置区域初始化

    win.initSeat = function() {
        for (var i=1; i<=16; i++) {
            var x = baseSeat.x + baseSeat.w*((i%4) === 0 ? 3: (i%4) -1) + GAP;
            var y = baseSeat.y + baseSeat.h*(Math.ceil(i/4) -1) + GAP;
            //console.log("dd_initSeat SEAT="+SEAT + i);
            win.find("座位"+i).setPosition(x,y);
            seatGuest[i-1] = "";
        }
    };
    
    这一步自动调整好座位位置.


    4: 图片选择区滑动效果


    OnSwipeLeft = function(args) {
        var win = this.getWindow();
        win.swipeMe("left");
    };
    
    win.swipeMe = function(direction) {
        if(hold === ""
            || hold.indexOf("图片") !== 0
            || picHolding == 1
            || hold.y < win.h-basePic.h) {
            return;
        }
        console.log("dd_swipeMe "+direction);
                //距离限制:
        if (win.moveOutOfRange(direction)) {
            direction = "shake";
            return;
        }
        win.swipeAnimation(direction);
    };
    
    
    win.swipeAnimation = function(direction) {
        for (var i=1; i<=picBar.length ;i++) {
            var targetPic = win.find(picBar[i-1]);
            
            var swipe = {
                duration:500,
                xStart:targetPic.x,
                yStart:targetPic.y,
                xEnd:targetPic.x-3*targetPic.w,
                yEnd:targetPic.y,
                interpolator:"l"};
                
            if (direction == "left") {
                swipe.xEnd = targetPic.x-3*targetPic.w;
            
            }else if (direction == "right") {
                swipe.xEnd = targetPic.x+3*targetPic.w;
                
            }else if (direction == "shake") {
                swipe.xEnd = targetPic.x;
                swipe.interpolator = "l";
                
            }else {
                console.log("dd_swipeAnimation ERROR");
                return;
            }
            
            targetPic.animate(swipe,function onDone(_obj) {});
        }
    }; 
    通过获取窗口的滑动事件 并对其做出简单的位置判断后. 将整个picBar向左或向右使用animation移动. 

    如果picBar第一个元素已经在屏幕内则无法继续从左往右滑, 反之最后一个元素在屏幕内时 无法从右向左滑.



    4: 图片拖动效果

    游戏中对图片的选择,拖动, 放开 我使用指针按下, 移动, 松开事件来完成.


    拖出动作的逻辑


    1: 判断指针按下时必须选中的是有效成员, 该有效成员将成为hold  

    2: 上一次指针按下以后又进行了指针移动(pointMove)且Y坐标移动到了一定范围以外, 此时将hold从picBar中删除 

    3: 对所选中的picBar成员使用setPositon来实现拖动他的效果.

    4: 对仍然在屏幕底端的 且在发生移动时处于hold成员右侧的picBar成员播放向左移动的动画.

    5: 根据指针抬起时所在的位置判断需要执行放下图片 还是重置图片位置.



    图片放下的逻辑: 


    1:放下的位置如是正确则播放动画提示玩家,

    2: 放下位置如是非正确的seat则没有动画效果,只是将图片移动到的合适位置.

    3: 放下位置如是无效区域则hold的图片返回到屏幕下边栏,且已在屏幕下边栏的picBar成员全体向右移动一格.

    win.pointDown = function(point) {
        if (picBarPlaying == 1
            || picHolding == 1) {
            hold = "";
            return;
        }
        var targetElement = this.findChildByPoint(point, true);
        holdPoint = point;
        if (targetElement.name){
            if (targetElement.name == "图片0") {
                hold = "";
                return;
            }
            console.log("dd_you are point down at "+targetElement.name);
            
            if (targetElement.name == "游戏界面") {
                return;
            }
            
            if (targetElement.name.indexOf("图片") === 0) {
                hold = targetElement.name;
            }else {
                hold = "";
                return;
            }
            win.find(hold).setZIndex(50);
        }
    };
    
    win.pointMove = function(point) {
        if(!win.pointerDown
            || hold === "") {
            return;
        }
                
        if (point.y < win.h-basePic.h || picHolding === 1) {
            win.drawOutPic(point);//移动被hold的图片
            if (picHolding === 0) {//首次移动出范围需删除其位置数据
                picHolding = 1;
                
                if (holdPoint !== ""){//删除失效的seatGuest
                    for (var s=1;s<=16;s++) {
                        var seat = win.find("座位"+s);
                        if (   holdPoint.x >= seat.x
                            && holdPoint.x < seat.x+seat.w
                            && holdPoint.y >= seat.y
                            && holdPoint.y < seat.y+seat.h) {
                                break;
                        }
                    }
                    seatGuest[s-1] = "";
                }
    
                win.renewPicBar();
            }
        }
    };
    
    win.pointUp = function(point) {
        if (hold === "") {
            return;
        }
        //放置在SEAT区域 
        var lastSeat = win.find("座位16");
        if (   point.x >= baseSeat.x 
            && point.x < lastSeat.x+lastSeat.w
            && point.y >= baseSeat.y
            && point.y < lastSeat.y+lastSeat.h){
                
                var seatNum = 0;//获取hold的图放置的新位置
                for (var i=1;i<=16;i++) {
                    var seat = win.find("座位"+i);
                    if (   point.x >= seat.x
                        && point.x < seat.x+seat.w
                        && point.y >= seat.y
                        && point.y < seat.y+seat.h) {
                            seatNum = i;
                            break;
                    }
                }
                if (seatNum < 1) {
                    console.log("dd_pointUp : seatNum ERROR");
                    return;
                }else {
                    console.log("dd_pointUp : pointUp at 座位"+i);
                }
                
                //放置在有图片的SEAT,旧图被插回第一位
                if (seatGuest[i-1] !== ""
                    && seatGuest[i-1].indexOf("图片")===0) {
                    win.waitForAnimation(0,seatGuest[i-1]);//播放旧图插回动画   
                }
                seatGuest[i-1] = hold;
                win.putPicInSeat(i);//新图放入seat
                
                console.log("dd_key="+win.find(hold).key);
                
                //播放拼图放对的特效
                if (win.find(hold).key == i) {
                    console.log("dd_放对啦!!!!");
                    picHolding = 1;
                    win.playBlink(hold);
                }
         
        } else if (picHolding === 1 && hold !== "") {
            //放在了无意义的区域, 需要重置图片位置
            win.waitForAnimation(0,hold);
        } else {
            console.log("dd_pointUp : ELSE ??");
        }
        
        //检测是否游戏完成now
        var gameOver = win.gameOverCheck();
        if (gameOver == 1) {
            console.log ("dd_gameOver");
            win.find("计时器控件").pause();
            
            function overThisGame() {
                var initData = {};
                me.openWindow("游戏结束界面", function (retData) {
                    console.log("window closed.");
                    win.newGame();
                    win.initGame();
                }, false, initData);
            }
            setTimeout(function() {overThisGame();}, 510);
        }
        
        picHolding = 0;
        hold = "";
        holdPoint = "";
    };
    pointDown中实现对按下图片的识别 并将有效控件的名称记录为hold,


    pointMove中结合hold 判断玩家是否在移动一个图片到可移动区域,

    如果图片被拖动出滑动选择区,则留在滑动选择去的picBar成语播放对其动画.


    pointUp中结合上两种方法中收集的数据,判断正在被hold的图片是否需要播放动画.

    动画主要包含,1:放置在无效区域时 图片返回屏幕最下方, 2:最下方的其他图片右移给新插入的图片腾出位置

    3:picBar中被拖出的图片放入puzzle座位区域的动画效果 4: 放置在了有效的区域,判断是否放置正确并播放动画.

    每一次opintUp会检测游戏是否结束.


    4: 其他方法代码展示

    setStroke 为图片添加边框效果

    win.setStroke = function(picName,canvas) {
        console.log("dd_setStroke : name="+picName);
        if (picName == "图片0") {
            return;
        }
        var pic = win.find(picName);
        pic.view.canvas.strokeStyle = "#E3881F";
        pic.view.canvas.lineWidth = 1;
        pic.view.canvas.strokeRect(0, 0, this.w, this.h);
    };


    insertPic 将放置在无效区域的图片插入回屏幕最下方

    win.insertPic = function(seat,hold) {
        if (seat > picBar.length 
            || (seat == picBar.length && picBar.length !== 0)) {
            console.log("dd_insertPic : seat  ERROR = "+ seat);
            return;
        }
    
        var targetPic = win.find(hold);
        var targetSeat;
        if (win.find(picBar[seat])) {
            targetSeat = win.find(picBar[seat]);
        }
        var backToSeat = {
                duration:200,
                xStart:targetPic.x,
                yStart:targetPic.y,
                xEnd:targetSeat.x,
                yEnd:targetSeat.y,
                interpolator:"l"
        };
       
        if (picBar.length === 0) {
            backToSeat.xEnd = 0;
            backToSeat.yEnd = win.h-basePic.h,
            picBar.push(hold);
        }
                
        targetPic.animate(backToSeat,function onDone(_obj) {
            setTimeout(function() {picHolding = 0;}, 60);
        });
    };

    drawOutPic 完成对拖出图片的移动显示

    win.drawOutPic = function(point) {
        //console.log("dd_pointMove : "+point.x+" "+point.y);
        var x = point.x-basePic.w/2;
        var y = point.y-basePic.h/2;
        win.find(hold).setPosition(x,y);
    };

    swapeAnimation 完成播放滑动选择区的滑动效果
    win.swipeAnimation = function(direction) {
        for (var i=1; i<=picBar.length ;i++) {
            var targetPic = win.find(picBar[i-1]);
            
            var swipe = {
                duration:500,
                xStart:targetPic.x,
                yStart:targetPic.y,
                xEnd:targetPic.x-3*targetPic.w,
                yEnd:targetPic.y,
                interpolator:"l"};
                
            if (direction == "left") {
                swipe.xEnd = targetPic.x-3*targetPic.w;
            
            }else if (direction == "right") {
                swipe.xEnd = targetPic.x+3*targetPic.w;
                
            }else if (direction == "shake") {
                swipe.xEnd = targetPic.x;
                swipe.interpolator = "l";
                
            }else {
                console.log("dd_swipeAnimation ERROR");
                return;
            }
            
            targetPic.animate(swipe,function onDone(_obj) {});
        }
    };

    moveOutOfRange 判断是否可以继续滑动 滑动区域

    win.moveOutOfRange = function(direction) {
        if (direction == "left"
            && win.find(picBar[(picBar.length-1)]).x+basePic.w <= win.w) {
                //向左滑时,如队末图片已完整出现在视野内则不处理.
                return 1;
        } else if (direction == "right"
            && win.find(picBar[0]).x >= 0 ){
                //向右滑时,如队末图片已完整出现在视野内则不处理.
                return 1;
        }
        return 0;
    };


    picBarRight 负责将滑动区域的picBar成员集体向右移动
    win.picBarRight = function(seat,hold) {
        var i = seat;
        if (picBar.length === 0) {
            console.log("dd_picBarRight : picBar is enpty!!!");
            return;
        }
        
        for (i; i<picBar.length; i++) {
            win.newPicBarAnimation(picBar[i],"insert");
        }
        picBar.splice(seat, 0, hold);
        console.log("dd_picBarRight : picBar =");
        if (DEBUG) {
            for (var r=0;r<picBar.length;r++) {
                console.log(picBar[r]);
            }
        }
    };


    removeHoldFromPicBar 负责将被拖出的picBar成员从picBar列表中删除

    win.removeHoldFromPicBar = function() {
        var index = -1;
        for (var i=0;i<picBar.length;i++) {
            if (hold == picBar[i]) {
                index = i;
                break;
            }
        }
        if (index >= 0) {
            picBar.splice(index,1);
            console.log("dd_removeHoldFromPicBar: index is "+index);
        }else {
            console.log("dd_removeHoldFromPicBar: index ERROR");
        }
    };


    playBlink 负责播放当玩家拖动图片到正确位置时的提示动画
    win.playBlink = function(target){
        if ( !win.find(target,true) ) {
            console.log("dd_playBlink : target notFound");
            return;
        }
        targetPic = win.find(target,true);
        var opRate = 0.3;
        var zoom = 0.8;
    
        var blinkP1 = {
                duration:60,
                opacityStart:1,
                opacityEnd:opRate,
                scaleXStart:1,
                scaleXEnd:zoom,
                scaleYStart:1,
                scaleYEnd:zoom,
            };
        var blinkP2 = {
            duration:60,
            opacityStart:opRate,
            opacityEnd:1,
            scaleXStart:zoom,
            scaleXEnd:1,
            scaleYStart:zoom,
            scaleYEnd:1,
        };
    
        targetPic.animate(blinkP1,function onDone(_obj) {
            targetPic.animate(blinkP2,function onDone(_obj) {
                blinkP1.duration = 140;
                blinkP2.duration = 140;
                targetPic.animate(blinkP1,function onDone(_obj) {
                    targetPic.animate(blinkP2,function onDone(_obj) {
                    });
                });
            });
        });
    };

    gameOverCheck 负责检测游戏是否结束

    win.gameOverCheck = function() {
        var i = 0;
        var key;
        seatGuest.length = 16;
        if (DEBUG) {
            for (i in seatGuest){
                key = win.find(seatGuest[i]).key-1;
                console.log("dd_seatGuest["+i+"]="+seatGuest[i]+"key="+key);
            }
        }
        i = 0;
        for (i in seatGuest){
            key = win.find(seatGuest[i]).key-1;
            if (seatGuest[i] === ""
                || key == "undefined"
                || key != i){
                return 0;
            }
        }
        return 1;
    };


    timmerGameRule 负责在进入游戏后显示游戏开始的倒计时,玩家有3秒钟去记忆拼图完成时该有的样子.
    win.timmerGameRule = function() {
        var timePic = [];
        var add = "http://osgames1.b0.upaiyun.com/games/diwy_source/businessSample/timeLimitPuzzle/pic/number";
        for (var i=0;i<=3;i++){
            timePic[i]= add+i+".png";
        }
        
        var time = 3;
        function timmer() {
            if (!win.children) {
                clearInterval(Interval);
                return;
            }
            win.timmerView(true);
            win.find("计时板").setImageSrc(timePic[time]);
            if (time < 0) {
                clearInterval(Interval);
                win.timmerView(false);
                win.find("图片1").setVisible(true);
    	        win.initSeat();
                win.initPictrue();
                win.find("计时器控件").start();
            }
            time --;
        }
        
        var Interval = setInterval(timmer,1000);
    };


    这次的分享就到这里. 2015-07-13

    展开全文
  • C++九宫格拼图游戏,九宫格相信大家都知道,九个格子,不过在书法上九宫格有不同的意思,这里只是一个九个格子的拼图游戏,只要你能拼对出一张完整的图形,你就成功了,小时候玩过这种小游戏。 设计流程图: 项目...

    C++九宫格拼图游戏,九宫格相信大家都知道,九个格子,不过在书法上九宫格有不同的意思,这里只是一个九个格子的拼图游戏,只要你能拼对出一张完整的图形,你就成功了,小时候玩过这种小游戏。
    在这里插入图片描述
    设计流程图:
    在这里插入图片描述
    项目结构展示:
    在这里插入图片描述
    部分源码展示:
    在这里插入图片描述
    支持载入外部图片,可以自动打乱,然后对照原图慢慢拼起来,希望新手朋友研究一下这个小程序,一起进步。
    在这里插入图片描述
    最后,如果你在学习C/C++的过程中遇到了问题,可以来问小编哦~小编很热情的(●’◡’●)

    声明:本文内容来源于网络,如有侵权请联系删除

    展开全文
  • 拼图块随机打乱,并保证其能有解。在屏幕上留出一个空白块,当点空白块旁边的块,将这块移动到空白块。判断是否已经拼好。 实现目标1.将图片拉伸成屏幕大小,并将其切成若干块。想拉伸成屏幕大小,首先要知道屏幕...

    目标

    在做这个游戏之前,我们先定一些小目标列出来,一个一个的解决,这样,一个小游戏就不知不觉的完成啦。我们的目标如下:

    游戏全屏,将图片拉伸成屏幕大小,并将其切成若干块。

    将拼图块随机打乱,并保证其能有解。

    在屏幕上留出一个空白块,当点空白块旁边的块,将这块移动到空白块。

    判断是否已经拼好。

    f5be67f2885c62d274971198c8360933.gif

    实现目标

    1.将图片拉伸成屏幕大小,并将其切成若干块。

    想拉伸成屏幕大小,首先要知道屏幕的大小,Android获得屏幕大小的代码如下:

    DisplayMetrics metrics =new DisplayMetrics();

    getWindowManager().getDefaultDisplay().getRealMetrics(metrics);//sdk17+

    int screenWidth = metrics.widthPixels;//屏幕宽

    int screenHeight = metrics.heightPixels;//屏幕高

    将图片拉伸到屏幕大小

    Bitmap back=Bitmap.createScaledBitmap(bitmap,

    MainActivity.getScreenWidth(),

    MainActivity.getScreenHeight(),

    true);

    将图片切成若干块

    private final int COL=3;//列,默认3列

    private final int ROW=3;//行,默认3行

    int tileWidth=back.getWidth()/COL;//每一块的宽

    int tileHeight=back.getHeight()/ROW;//每一块的高

    Bitmap[] bitmapTiles =new Bitmap[COL*ROW];

    int idx=0;

    for(int i=0;i

    {

    for(int j=0;j

    {

    bitmapTiles[idx++]=Bitmap.createBitmap(back,

    j*tileWidth,

    i*tileHeight,

    tileWidth,tileHeight);

    }

    }

    ###2. 将拼图块随机打乱,并保证其能有解。 这个问题应该是这个小游戏的核心了,有些人在做拼图的时候就随便乱摆,最后发现拼不回来,超级尴尬。要想打乱了还能拼回来,我们呢,就想到了模拟人打乱拼图的方法,就是将空白块与旁边的非空白块交换位置,与旁边哪个非空白块交换是随机的,然后将这个过程重复若干次,重复的次数也是随机的,这样一来,保证了图块的随机,又保证了能拼回来。在这里我们用数字0到N-1(N为块的数量)表示每一块,并用二维数组存储他们。

    private void createIntegerArray(int row,int col)

    {

    array=new int[row][col];

    int idx=0;

    for(int i=0;i

    for(int j=0;j

    array[i][j]=idx++;

    }

    下面是打乱块的算法,最后一块是空白块,让它随机与旁边的某一块进行交换,这个过程中要检查数组边界,不要让它越界。

    //四个方向

    private int[][] dir={

    {0,1},//下

    {1,0},//右

    {0,-1},//上

    {-1,0}//左

    };

    /**

    * 移动块的位置

    * @param srcX 初始x位置

    * @param srcY 初始y位置

    * @param xOffset x偏移量

    * @param yOffset y偏移量

    * @return 新的位置,错误返回new Point(-1,-1);

    */

    private Point move(int srcX,int srcY,int xOffset,int yOffset)

    {

    int x=srcX+xOffset;

    int y=srcY+yOffset;

    if(x<0||y<0||x>=col||y>=row)

    return new Point(-1,-1);

    int temp=array[y][x];

    array[y][x]=array[srcY][srcX];

    array[srcY][srcX]=temp;

    return new Point(x,y);

    }

    /**

    * 得到下一个可以移动的位置

    * @param src 初始的点

    * @return

    */

    private Point getNextPoint(Point src)

    {

    Random rd=new Random();

    int idx=rd.nextInt(4);//,因为有4个方向,所以产生0~3的随机数

    int xOffset=dir[idx][0];

    int yOffset=dir[idx][1];

    Point newPoint=move(src.getX(),src.getY(),xOffset,yOffset);

    if(newPoint.getX()!=-1&&newPoint.getY()!=-1) {

    return newPoint;//找到了新的点

    }

    return getNextPoint(src);//没有找到,继续

    }

    /**

    * 生成拼图数据

    * @param row

    * @param col

    * @return

    */

    public int[][] createRandomBoard(int row,int col)

    {

    if(row<2||col<2)

    throw new IllegalArgumentException("行和列都不能小于2");

    this.row=row;

    this.col=col;

    createIntegerArray(row,col);//初始化拼图数据

    int count=0;

    Point tempPoint=new Point(col-1,row-1);//最后一块是空白块

    Random rd=new Random();

    int num=rd.nextInt(100)+20;//产生20~119的随机数,表示重复的次数

    while (count

    {

    tempPoint=getNextPoint(tempPoint);//获得下个点,并更新空白块位置

    count++;

    }

    return array;

    }

    ###3. 在屏幕上留出一个空白块,当点空白块旁边的块,将这块移动到空白块。 留出空白块很简单,由于上面我们将最后一块作为空白块。当我们绘图时,略过它即可。代码实现如下:

    @Override

    protected void onDraw(Canvas canvas) {

    canvas.drawColor(Color.GRAY);

    for(int i=0;i

    for (int j = 0; j < COL; j++) {

    int idx=dataTiles[i][j];

    if(idx==ROW*COL-1&&!isSuccess)

    continue;

    canvas.drawBitmap(bitmapTiles[idx],

    j*tileWidth,

    i*tileHeight,paint);

    }

    }

    }

    移动块也很简单,当点击屏幕时,计算其在拼图数据中对应的索引。当计算到点击非空白块就寻找它旁边有没有空白块,有,则将拼图数据中表示空白块和非空白块的数据交换,并刷新View即可

    /**

    * 将屏幕上的点转换成,对应拼图块的索引

    * @param x

    * @param y

    * @return

    */

    private Point xyToIndex(int x,int y)

    {

    int extraX=x%tileWidth>0?1:0;

    int extraY=x%tileWidth>0?1:0;

    int col=x/tileWidth+extraX;

    int row=y/tileHeight+extraY;

    return new Point(col-1,row-1);

    }

    /**

    *点击屏幕时发生

    */

    @Override

    public boolean onTouchEvent(MotionEvent event) {

    if(event.getAction()==MotionEvent.ACTION_DOWN) {

    Point point = xyToIndex((int) event.getX()

    , (int) event.getY());

    for(int i=0;i

    {

    int newX=point.getX()+dir[i][0];

    int newY=point.getY()+dir[i][1];

    if(newX>=0&&newX

    =0&&newY

    if(dataTiles[newY][newX]==COL*ROW-1)

    {

    int temp=dataTiles[point.getY()][point.getX()];

    dataTiles[point.getY()][point.getX()]=dataTiles[newY][newX];

    dataTiles[newY][newX]=temp;

    invalidate();

    }

    }

    }

    }

    return true;

    }

    ###4. 判断是否已经拼好 我们初始化数据时,是从0开始,依次增加作为拼图数据。当拼好的时候,拼图数据也应该是一样的,所以我们比较数组中每一个数据与它的下一个数据,如果每一个数据都小于它的下一个数据,说明数组里面的数据已经从小到大排列好。

    /**

    * 判断是否拼图成功

    * @param arr

    * @return

    */

    public boolean isSuccess(int[][] arr)

    {

    int idx=0;

    for(int i=0;i

    {

    for(int j=0;j

    {

    if(arr[idx/row][idx%col]>arr[(idx+1)/row][(idx+1)%col])

    {

    return false;

    }

    idx++;

    }

    }

    return true;

    }

    ##拼图游戏技巧 拼图技巧觉得也有必要说一下,不然有些人就会说:你的算法有问题,这根本拼不好!我也是超级无奈啊!拼图的技巧是,我们先把上面的第一行拼好,然后再把第二行拼好,这样,一直下去~就能完全拼好了。

    ##总结 这个小游戏简单,可以拿来练手,还可以拿来装(liao)逼(mei),如果不会,何乐而不看呢。这个小游戏也是将视图和数据分开,代码容易移植。

    展开全文
  • 运用authorware软件制作一幅拼图游戏,你可以发现拼图游戏制作很简单 ,也很有成就感
  • Unity3d制作的简单拼图游戏 制作流程可以看我的博客:http://blog.csdn.net/cube454517408/article/details/7907247
  • C#制作拼图游戏

    2018-04-11 16:17:33
    详细讲述了用C#开发拼图游戏的过程,并且文末附有代码。
  • 拼图游戏JavaScript制作

    2009-08-18 11:27:20
    请用↑↓←→键头玩游戏!!4×4 不久前,闲着无聊, 用自己的智慧, 用图片作了一个小小的拼图游戏, 没想到很受大家的喜爱, 很多人 想知道制作的方法及拼法?
  • java制作拼图游戏

    2013-05-22 12:51:07
    制作相当好的拼图游戏,稍加修改,基本可以玩,代码分为三个类,简洁易懂。
  • 拼图游戏制作

    2016-07-21 19:16:46
    今天把计算器 的连加连加功能实现了,还有就是拼图游戏的场景切换和设置的实现: //添加界面  _init:function() {  this._mainUI1 = ccs.load(res.main2_json).node;  this.addChild(this._mainUI1);  this...
  • flash拼图游戏制作过程
  • PPT制作拼图游戏

    2014-02-26 11:04:55
    PPT制作拼图游戏,用VBA代码完成,非常棒
  • Qt环境下制作的3*3拼图游戏,c++实现,简单可玩!!!
  • 使用jQuery制作web拼图游戏使用jQuery制作web拼图游戏
  • 用authorware制作拼图游戏!也就是目标区响应!
  • flash制作拼图游戏

    2011-05-21 16:48:45
    利用flash8制作拼图游戏,有代码,有控件
  • 主要为大家详细介绍了基于javascript制作拼图游戏的相关内容,经典传统的拼图游戏是大家最喜爱的游戏之一,具有挑战性,感兴趣的小伙伴们可以参考一下
  • jQuery制作拼图游戏

    2020-10-24 21:45:37
    主要介绍了jQuery制作拼图游戏,思路与源码都分享给大家,需要的朋友可以参考下
  • C#制作拼图游戏

    2014-09-11 22:36:28
    使用C#编写的拼图游戏,包括imagelist的用法,简单易学
  • mfc制作拼图游戏

    2011-05-08 10:01:47
    使用MFC制作游戏拼图.可直接运行。欢迎大家下载,并指正改进。
  • js 代码制作拼图游戏

    2021-01-17 19:51:59
    拼图游戏 游戏玩法:点击选中一个方块,在点击放在对应的方块里。 参考原图 var sortList = []; for (var a = 0; a < wt * hg; a++) { sortList.push(a); } sortList.sort(randomsort); ...
  • 主要介绍了原生javascript制作拼图游戏实现方法,结合实例形式详细分析了JavaScript制作拼图游戏的相关步骤、原理、实现方法及相关操作注意事项,需要的朋友可以参考下
  • 主要介绍了C#利用控件拖拽技术制作拼图游戏的方法以及核心代码,需要的朋友可以参考下
  • 易语言动画框制作简单拼图游戏源码

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 394
精华内容 157
关键字:

拼图游戏制作