2023年夏季《移动软件开发》实验报告之实验4:拼图游戏

一、实验目标

1、综合应用所学知识创建完整的拼图游戏项目;2、熟练掌握<canvas>组件。

二、实验步骤

列出实验的关键步骤、代码解析、截图。

一.创建模板并添加文件

下载images图像包并加入文件夹

创建games文件夹以存放游戏界面

二.页面设计

1.主页设计

index.wxml如下:

<!--index.wxml-->
<view class="container">
    <!--标题-->
    <view class="title">Level Selection</view>
    <!--关卡列表-->
    <view class="levelbox">
        <view class='box'wx:for='{{levels}}'wx:key='levels{{index}}'bindtap='chooseLevel'data-level='{{item}}'>
        <image src='/images/{{item}}'></image>
        <text>Level-{{index+1}}</text>
        </view>
    </view>
</view>
 

index.wxss如下:

/**index.wxss**/
.levelbox{
    width:100%;
}
.box{
    width:50%;
    float: left;
    margin: 25rpx 0;
    display: flex;
    flex-direction: column;
    align-items: center;
}
image{
    width:260rpx;
    height: 260rpx;
}

结果如图:

2.游戏界面设计

wxml如下:

<!--pages/game/game.wxml-->
<view class="container">
    <!--提示图-->
    <view class="title">hinter</view>
    <image src='{{url}}'></image>
    <!--游戏画布-->
    <canvas canvas-id="myCanvas"bindtouchstart='touchBox'></canvas>
    <!--重新开始按钮-->
    <button type="warn"bindtap='restartGame'>Restart</button>
</view>

wxss如下:

/* pages/game/game.wxss */
image{
  width:250rpx;
  height:250rpx;
}
canvas{
  border: 1rpx solid;
  width: 300px;
  height:300px;
}

结果如图:

三.逻辑设计

1.主页逻辑设计

首先录入图片信息

Page({
  data: {
      levels:[
          'pic01.jpg',
          'pic02.jpg',
          'pic03.jpg',
          'pic04.jpg',
          'pic05.jpg',
          'pic06.jpg'
      ]     
  },
})

接着添加循环选关功能与点击跳转功能

<!--关卡列表-->
    <view class="levelbox">
        <view class='box' wx:for='{{levels}}'wx:key='levels{{index}}'bindtap='chooseLevel'data-level='{{item}}'>
        <image src='/images/{{item}}'></image>
        <text>Level-{{index+1}}</text>
        </view>
    </view>

js文件中添加chooseLevel函数

chooseLevel:function(e){
    let level=e.currentTarget.dataset.level
    wx.navigateTo({
      url: '../game/game?level='+level,
    })
   } ,

2.游戏页逻辑设计

(1)显示提示图

js代码如下:

onLoad(options) {
        url='/images/'+options.level
        this.setData({url:url})
    },

wxml代码修改如下:

<view class="container">
    <!--提示图-->
    <view class="title">hinter</view>
    <image src='{{url}}'></image>
    ...
</view>

运行结果如图:

(2)游戏主体逻辑

初始化拼图画面。传统做法是随机抽取画面中的任意两个方块,然后交换彼此位置,在进行足够多次数的交换后基本可以实现随机打乱的效果。但是这种方法有一个弊端,就是有时候会陷入无解的死局。因此可以考虑从空白方块的所在位置入手,每次随机让它和周围的邻近方块交换位置,这样可以通过方块反向移动回到最初始状态(确保本局有解),并且在交换足够多的次数后也可以实现随机打乱的效果。

js的Page部分中加入shuffle函数用于初始化图片

shuffle:function () {
        num=[
            ['00','01','02'],
            ['10','11','12'],
            ['20','21','22']
        ]
        var row=2
        var col=2
        for(var i=0;i<100;i++){
            var direction=Math.round(Math.random()*3)
            if(direction==0){
                if(row!=0){
                    num[row][col]=num[row-1][col]
                    num[row-1][col]='22'
                    row-=1
                }
            }
            else if(direction==1){
                if(row!=2){
                    num[row][col]=num[row+1][col]
                    num[row+1][col]='22'
                    row+=1
                }
            }
            else if(direction==2){
                if(col!=0){
                    num[row][col]=num[row][col-1]
                    num[row][col-1]='22'
                    col-=1
                }
            }
            else if(direction==3){
                if(col!=2){
                    num[row][col]=num[row][col+1]
                    num[row][col+1]='22'
                    col+=1
                }
            }
        }
    },

上述代码表示使用for循环进行了100次打乱,开发者可以根据自己的需求更改循环次数。每次使用Math.random()方法从上下、左、右4个方向中随机产生一个方向,之后如果符合条件则交换空白方块和图片方块的位置。

然后在game.js中添加自定义函数drawCanvas,用于将打乱后的图片方块绘制到画布上。对应的js代码片段添加如下:

    
drawCanvas: function () {
        let ctx=this.ctx
        ctx.clearRect(0,0,300,300)
        for(var i=0;i<3;i++){
            for(var j=0;j<3;j++){
                if(num[i][j]!='22'){
                    var row=parseInt(num[i][j]/10)
                    var col=num[i][j]%10
                    ctx.drawImage(url,col*w,row*w,w,w,j*w,i*w,w,w)
                }
            }
        }
        ctx.draw() 
    },

最后在game.js的onLoad函数中调用自定义函数shuffle和drawCanvas。对应的js代码片段添加如下:

onLoad(options) {
        url='/images/'+options.level
        this.setData({url:url})
        this.ctx=wx.createCanvasContext('myCanvas')
        this.shuffle()
        this.drawCanvas()
    },

移动被点击的方块。修改game.wxml页面中的画布组件(<canvas>),为其绑定触摸事件。wxml代码修改后如下:

  
<!--游戏画布-->
  <canvas canvas-id="myCanvas"bindtouchstart='touchBox'></canvas>

在game.js文件添加自定义函数 touchBox,用于实现图片方块的移动,对应的js代码片段添加如下:

touchBox:function (e) {
        if(this.data.isWin){
            return
        }
        var x=e.changedTouches[0].x
        var y=e.changedTouches[0].y
        var row=parseInt(y/w)
        var col=parseInt(x/w)
        if(num[row][col]!='22'){
            this.moveBox(row,col)
            this.drawCanvas()
            if(this.isWin()){
                let ctx=this.ctx
                ctx.drawImage(url,0,0)
                ctx.setFillStyle('E63404')
                ctx.setTextAlign('center')
                ctx.setFontSize(60)
                ctx.fillText('Victory',150,150)
                ctx.draw()
            }
        }
    },

要判断游戏成功首先在game.js文件中的data中添加初始数据 isWin,用于标记游戏成功与否。再编写isWin函数来判断是否游戏成功对应的js代码片段添加如下:

data: {      
        isWin:false
    },
isWin:function () {
        for(var i=0;i<3;i++){
            for(var j=0;j<3;j++){
                if(num[i][j]!=i*10+j){
                    return false
                }
            }
        } 
        this.setData({isWin:true})
        return true
    },

要重新开始游戏则修改game.wxml代码,为“重新开始”按钮追加自定义函数的点击事件。wxml代码片段修改如下:

<!--重新开始按钮-->
 <button type="warn"bindtap='restartGame'>Restart</button>

在game.js文件中添加 restartGame函数,用于重新开始游戏。对应的js代码片段添加如下:

   restartGame:function () {
        this.setData({isWin:false})
        this.shuffle()
        this,this.drawCanvas()
    },

三、程序运行结果

列出程序的最终运行结果及截图。

运行结果如下

主页

游戏页

四、问题总结与体会

描述实验过程中所遇到的问题,以及是如何解决的。有哪些收获和体会,对于课程的安排有哪些建议。

实验中遇到最多的问题是打错了大小写,导致不能正确调用内容,我应该写一些就编译运行一些,一边写一遍检查,而不是写完再检查

通过本次实验我了解了canvas的用法,进一步提升了编写能力

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值