实验4 :拼图游戏

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

姓名: 学号:21020007***

姓名和学号? 21020007***
本实验属于哪门课程?中国海洋大学23夏《移动软件开发》
实验名称?实验4:拼图游戏
博客地址?用户Id: m0_62135967 用户名称:Pane
Github仓库地址?XXXXXXX

(备注:将实验报告发布在博客、代码公开至 github 是 加分项,不是必须做的)

一、实验目标

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

12.1.1 首页功能需求

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

12.1.2 游戏页功能需求

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

二、实验步骤

1.项目创建:本项目创建选择空白文件夹jigsawGame,效果如图所示。单击“新建”按钮完成项目创建,然后准备手动修改页面配置。

2.页面配置

(1)创建页面文件:项目创建完毕后,在根目录中会生成文件夹pags用于存放页面文件。一般来说首页默认命名为index,表示小程序运行的第一个页面;其他页面名回称可以自定义。本项目有两个页面文件,需要创建index(首页页面)和game视频讲解(游戏页面):将app.json文件内pages属性中的“pags/logs/logs改成“pages/game/game”;按快捷键Ctrl+S保存修改后会在page文件夹下自动生成game目录。

(2)删除和修改文件:删除和修改文件:按照指导删除utils文件夹及其内部所有内容,pages文件夹下的logs目录及其内部所有内容、index.wxml和index.wxss中的全部代码、Index.js中的全部代码,并输入关键词page补全函数、删除app.wxss全部代码、app.js中全部代码

3.创建其他文件:创建一个新的文件夹用于存放播放图标,文件夹名称命名为images,并将所需要用到的图片放进文件夹里

3.视图设计

(1)导航栏设计:小程序默认导航栏是黑底白字的效果,app.json中可以进行自定义导航栏标题和背景颜色,下面代码可以更改所有页面的导航栏标题文本

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

(2)页面设计:

①公共样式设计:首先在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;
}

②首页设计:首页主要包含两部分内容,即标题和关卡列表,如图12-7所示。计划使用如下组件:

顶端标题:<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;
}

③游戏页面设计:游戏页面需要用户点击首页的关卡列表,然后在新窗口中打开该页面口游戏页面包括游戏提示图、游戏画面和“重新开始”按钮,此时预览就可以直接显示game页面了,设计完毕后再改回“普通编译”模式即可重新显示首页。

4.逻辑实现: (1)首页逻辑:

①关卡列表展示:在JS文件的 data 中录入关卡图片的数据信息,这里以6个关卡为例 。

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

接着为关卡对应的<view>组件添加wx:for属性循环显示关卡列表数据和图片。修改后的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>

②点击跳转游戏页面:若希望用户点击关卡图片即可实现跳转,需要首先为关卡列表项目添加点击事件。相关WXML(pages/index/index.wxml)代码相关片段修改如下:

 <view class="box" wx:for="{{levels}}" wx:key="levels{{index}}" bindtap="chooseLevel" data-level="{{item}}">

上述代码表示为关卡添加了自定义点击事件函数chooseLevel,并且使用data--level属性携带了关卡图片信息。然后在对应的index.js文件中添加chooseLevel函数的内容,代码片段如下:

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

(2)游戏页逻辑

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

①显示提示图:在首页逻辑中已经实现了页面跳转并携带了关卡对应的图片信息,现在视频讲解需要在游戏页面接收关卡信息,并显示对应的图片内容。相关JS(pages/game/game.js)代码片段如下:

/**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    // console.log(options.level)
 
    // 更新图片路径地址
    url = '/images/' + options.level
    // 更新提示图的地址
    this.setData({
      url: url
    })
 

②游戏逻辑实现:

a.准备工作。首先在game.js文件的顶端记录一些游戏初始数据信息。对应的JS(pages/game/game.js)代码片段添加如下:

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

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

 /**
   * 自定义函数--随机打乱方块顺序
   */
  shuffle: function() {
    // 先令所有方块回归初始位置
    num = [
      ['00', '01', '02'],
      ['10', '11', '12'],
      ['20', '21', '22']
    ]
 
    .....
 
  },

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

/**
   * 自定义函数--绘制画布内容
   */
  drawCanvas: function() {
    let ctx = this.ctx
 
    // 清空画布
    ctx.clearRect(0, 0, 300, 300)
 
    // 使用双重for循环语句绘制3x3拼图
    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()
  },

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

三、程序运行结果

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

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

③移动被点击的方块。修改game.wxml页面中的画布组件(<canvas>),为其绑定触摸事件;在game.js文件添加自定义函数 touchBox,用于实现图片方块的移动

/**
   * 自定义函数--监听点击方块事件
   */
  touchBox: function(e) {
    // 如果游戏已经成功,不做任何操作
    if (this.data.isWin) {
      // 终止本函数
      return
    }
 
    // 获取被点击方块的坐标x和y
    var x = e.changedTouches[0].x
    var y = e.changedTouches[0].y
    // console.log('x:'+x+',y:'+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()
      }
    }
  },
 

③判断游戏成功

首先在game.js文件中的data中添加初始数据 isWin,用于标记游戏成功与否。对应的JS(pages/game/game.js)代码片段添加如下:

data: {
    isWin: false
 
  },

④重新开始游戏

修改game.wxml代码,为“重新开始”按钮追加自定义函数的点击事件。WXML(pages/game/game.wxml)代码片段修改如下:

/**
   * 自定义函数--重新开始游戏
   */
  restartGame: function() {
    // 更新游戏状态
    this.setData({
      isWin: false
    })
 
    // 打乱方块顺序
    this.shuffle()
 
    // 绘制画布内容
    this.drawCanvas()
  },

三、程序运行结果

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

四、问题总结与体会

我学习到了如何使用微信小程序框架和组件来展示新闻内容。通过阅读相关文档和教程,我了解到可以使用<view>、<text>和<image>等组件来布局和显示拼图游戏的标题、内容和配图。这个过程让我对微信小程序的组件和布局有了更深入的了解。

总的来说,通过编写拼图游戏微信小程序代码,我不仅学到了如何使用微信小程序的组件和布局技巧,还学到了如何处理用户点击事件等。这个实验让我更加熟悉了编程的一些基本概念和技巧,并提升了我的实践能力和问题解决能力。此次实验,对于我《移动软件开发》这门课的学习有非常大的帮助,同时也为我以后计算机专业的学习打下了坚实基础。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值