移动软件开发实验四

本文详细介绍了如何利用微信小程序开发一个完整的拼图游戏,包括创建项目、设置界面、编写关键代码(如主页面布局、游戏逻辑和canvas操作)以及解决实际问题的过程。通过这个项目,作者掌握了组件应用和canvas组件的使用,以及小程序开发中的常见技巧。
摘要由CSDN通过智能技术生成

一、实验目标

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

二、实验步骤

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

1.创建一个新的项目,同时新增images文件夹,将所需的图片放入其中。

在这里插入图片描述

2.关键代码

index.wxml

主页面的视图设计,主要是将六张图片摆放好,并赋上名字,标明是第几关。

<!--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>

index.js

主页面的逻辑实现,主要是要初始化数据,要让主页面有图片显示,第二就是要能够通过点击图片进入到游戏页面,通过chooseLevel函数来实现

// 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:wx.navigateTo({
      url: '../game/game?level='+level
    })
  },
})

game.wxml

游戏页面的视图设计,主要是有由主页面不同关卡点进来的关卡图片,还有由canvas组件组成的画布区域,绑定触摸画布的函数。

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

game.js

游戏页面的逻辑实现,最重要的有以下几个功能

(1)接受在主页面点击的关卡信息,成功跳转页面

(2)规划一片画布区域,drawCanvas将关卡图片信息赋在画布上,将挂关卡图片分成九个方块,并把(2,2)赋为空白方块

(3)shuffle函数,实现将九个方块(其中有一个空白方块)打乱

(4)touchBox和moveBox函数触摸方块并移动方块(能够移动的方块,它的周围一定是存在空白方块的)

(5)要存在一个判断是否将拼图拼好的isWin函数,成功则会显示图片,并出现一定的文字

(6)重新开始的按钮,也就是再次打乱方块

// pages/game/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
  },
/**
 * 
 * 自定义函数--判断游戏是否成功 
 */
isWin:function()
{
  //使用双重for循环遍历整个数组
  for(var i=0;i<3;i++)
  {
    for(var j=0;j<3;j++)
    {
      //如果有方块位置不对,则返回false
      if(num[i][j]!=i*10+j)
      {
        return false
      }
    }
  }
  //更新游戏成功状态
  this.setData({iswin:true})
  return true
},
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    //更新图片信息
    url='/images/'+ options.level
    //更新提示图片地址
    this.setData({
      url:url
    })
     //创建画布上下文
    this.ctx=wx.createCanvasContext('myCanvas')
    //打乱方块顺序
   this.shuffle()
   //绘制画布内容
   this.drawCanvas()
  },
  /**
   * 自定义函数--随机打乱方块顺序
   */
  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++)
    {
      //随机产生一个方向,上下左右,0123
      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()
},
/**
 * 自定义函数--监听点击方块事件
 * 
 */
touchBox:function(e)
 {
  //如果游戏已经成功,不做任何操作
  if(this.data.isWin)
  {
    return
  }
  //获取被点击的方块坐标
  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()
    }
  }
 },
 /**
  * 自定义函数--移动被点击的方块
  */
 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
    }
  }
 },
 /**
  * 自定义函数--重新开始游戏
  */
 restartGame:function()
 {
   //更新游戏成功状态、
   this.setData({isWin:false})
   //打乱方块顺序
   this.shuffle()
   //绘制画布内容
   this.drawCanvas()
 },

4.最后的主页面和游戏页面

在这里插入图片描述

三、程序运行结果

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

初始页面

在这里插入图片描述

点击第二关的图片,跳转页面

在这里插入图片描述

然后点击根据提示图,点击图片,移动位置,将拼图拼完整,就会得到以下的结果。

在这里插入图片描述

同时,如果拼图太难或者已经拼图成功,可以点击重新开始,就会出现不一样的拼图顺序。

在这里插入图片描述

四、问题总结与体会

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

总结:

1.方块点击后无法移动,经过检查,发现是this.drawCanvas()后面的括号忘加了。出现问题时候,可以根据错误的提示找到对应行数以及相关函数的代码进行检查。

2.明明代码没有错,但模拟器的图片大小不太对,可以看看左上角手机型号,不同手机型号,屏幕大小也不同

在这里插入图片描述

3.在创建画布上下文的时候,会出现this.ctx=wx.createCanvasContext(‘myCanvas’)这个语句中createCanvasContext被划掉的情况,经查询,wx.createCanvasContext已经被废弃了,但是目前使用起来并没有问题,于是也没有进行更改。

体会:

本次实验,熟悉了解了canvas组件,也巩固了前面学的小程序知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值