移动软件开发——拼图游戏

2023年夏季《移动软件开发》实验报告

一、实验目标

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

二、实验步骤

1.项目创建

本项目一共需要两个页面,即首页和游戏页面,其中,首页用于呈现关卡菜单,点击对应难度的关卡后进入游戏画面。

1.1首页功能需求

首页功能需求如下:(1) 首页需要包含标题和关卡列表。(2) 关卡至少要有 6 个关卡选项,每个关卡显示预览图片和第几关。(3) 点击关卡列表可以打开对应的游戏画面。

1.2游戏页功能需求

游戏页功能需求如下:(1)游戏页面需要显示游戏提示图、游戏画面和“重新开始”按钮。(2)每关游戏提示图显示对应的图片预览。(3)游戏画面随机将原图打乱为3×3的小方块,并且可移动被点击的方块。(4)点击“重新开始”按钮可以重新随机打乱小方块并开始游戏。

2.页面配置

2.1创建页面文件

2.2删除和修改文件

2.3创建其他文件

3.视图设计

3.1导航栏设计

"window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#E64340",
    "navigationBarTitleText": "拼图游戏",
    "navigationBarTextStyle": "white"
  },

上述代码可以更改导航栏内背景色为珊瑚红色,字体为白色。

3.2页面设计

(1)公共样式设计:首先在app.wxss中设置页面窗口和顶端标题的公共样式,代码如下:

/* 页面容器样式 */
.container{
  height:100vh;
  color: #E64340;
  font-weight: bold;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content:space-evenly;
}
/* 顶端标题样式 */
.title{
  font-size: 18pt;
}

(2)首页设计:首页主要包含两部分内容,即标题和关卡列表,计划使用如下组件:

顶端标题:view容器;

关卡列表:view容器,内部使用数组循环。

WXML(pages/index/index.wxml)代码如下:

<view class='container'>
  <!-- 标题 -->
  <view class='title'>游戏选关</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>第{{index+1}}关</text>
    </view>
  </view>
</view>

相关WXSS (pages/index/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;
}

(3)游戏页面设计:游戏页面需要用户点击首页的关卡列表,然后在新窗口中打开该页面口游戏页面包括游戏提示图、游戏画面和“重新开始”按钮。

由于暂时没有做点击跳转的逻辑设计,所以可以在开发工具顶端选择“普通编译”下的“添加编译模式”,并携带临时测试参数level=pic01.jpg,如图所示:
在这里插入图片描述

此时预览就可以直接显示game页面了,设计完毕后再改回“普通编译”模式即可重新显示首页。

4.逻辑实现

4.1首页逻辑

首页主要有两个功能需要实现,一是展示关卡列表,二是点击图片能够跳转到游戏页面。

index.js

Page({

  /**
   * 页面的初始数据
   */
  data: {
    levels:[
      'pic01.jpg',
      'pic02.jpg',
      'pic03.jpg',
      'pic04.jpg',
      'pic05.jpg',
      'pic06.jpg'
    ]
  },

  // 自定义函数-游戏选关
  chooseLevel:function(e){
    let level=e.currentTarget.dataset.level
    wx.navigateTo({
      url: '../game/game?level='+level
    })
  }
})

4.2游戏页逻辑

游戏页主要有两个功能需要实现,一是显示提示图;二是游戏逻辑实现。

game.js

//方块的初始位置
var num=[
  ['00','01','02'],
  ['10','11','12'],
  ['20','21','22']
]
//方块的宽度
var w=100
//图片的初始位置
var url='/images/pic01.jpg'

Page({

  /**
   * 页面的初始数据
   */
  data: {
    isWin:false
  },

 
  // 自定义函数-随机打乱方块顺序
  shuffle:function(){
    //先令所有方块回归初始位置
    num=[
      ['00','01','02'],
      ['10','11','12'],
      ['20','21','22']
    ]
    //记录当前空白方块的行和列
    var row=2
    var col=2
    //打乱方块顺序100次
    for(var i=0;i<100;i++){
      //随机产生其中一个方向:上(0)下(1)左(2)右(3)
      var direction=Math.round(Math.random()*3)
      //上:0
      if(direction==0){
        if(row!=0){
          num[row][col]=num[row-1][col]
          num[row-1][col]='22'
          row-=1
        }
      }
      //下:1
      else if(direction==1){
        if(row!=2){
          num[row][col]=num[row+1][col]
          num[row+1][col]='22'
          row+=1
        }
      }
      //左:2
      else if(direction==2){
        if(col!=0){
          num[row][col]=num[row][col-1]
          num[row][col-1]='22'
          col-=1
        }
      }
      //右:3
      else if(direction==3){
        if(col!=2){
          num[row][col]=num[row][col+1]
          num[row][col+1]='22'
          col+=1
        }
      }
    }
  },
  // 自定义函数-绘制画布内容
  drawCanvas:function(){
    let ctx=this.ctx
    //清空画布内容
    ctx.clearRect(0,0,300,300)
    //使用双重for循环绘制3*3的拼图
    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()
  },

  //自定义函数-移动被点击的方块
  moveBox:function(i,j){
    //情况1:如果被点击的方块不在最上方,检查可否上移
    if(i>0){
      if(num[i-1][j]=='22'){
        num[i-1][j]=num[i][j]
        num[i][j]='22'
        return
      }
    }
    //情况2:如果被点击的方块不在最下方,检查可否下移
    if(i<2){
      if(num[i+1][j]=='22'){
        num[i+1][j]=num[i][j]
        num[i][j]='22'
        return
      }
    }
    //情况3:如果被点击的方块不在最左边,检查可否左移
    if(j>0){
      if(num[i][j-1]=='22'){
        num[i][j-1]=num[i][j]
        num[i][j]='22'
        return
      }
    }
    //情况4:如果被点击的方块不在最右边,检查可否右移
    if(j<2){
      if(num[i][j+1]=='22'){
        num[i][j+1]=num[i][j]
        num[i][j]='22'
        return
      }
    }
  },
  //自定义函数-判断游戏是否成功
  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
  },

  //自定义函数-监听点击方块事件
  touchBox:function(e){
    //如果游戏已经成功,不做任何操作
    if(this.data.isWin){
      //终止本函数
      return
    }
    //获取被点击方块的坐标x和y
    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('#E64340')
        ctx.setTextAlign('center')
        ctx.setFontSize(60)
        ctx.fillText('游戏成功',150,150)
        ctx.draw()
      }
    }
  },
  
  //自定义函数-重新开始游戏
  restartGame:function(){
    this.setData({isWin:false})
    this.shuffle()
    this.drawCanvas()
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    //更新图片路径地址
    url='/images/'+options.level
    //更新提示图的地址
    this.setData({url:url})
    //创建画布上下文
    this.ctx=wx.createCanvasContext('myCanvas')
    //打乱方块顺序
    this.shuffle()
    //绘制画布内容
    this.drawCanvas()
  }
})

三、程序运行结果

首页界面:

在这里插入图片描述

选择第2关后的游戏页面:

在这里插入图片描述

游戏成功:
在这里插入图片描述

点击“重新开始”后,游戏重新开始:
在这里插入图片描述

四、问题总结与体会

​ 通过此次实验,我学会了如何使用组件以及如何实现页面跳转,并对以往所学知识有了更深入的了解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值