OUC移动软件开发 实验六

一、实验目标

1、综合所学知识创建完整的推箱子游戏;

2、能够在开发过程中熟练掌握真机预览、调试等操作。

二、实验步骤

1.公共设计

1.1导航栏设计

在app.json中添加以下代码,将导航栏修改为红色背景,白色字体的效果:

"window": {
    "navigationBarBackgroundColor": "#E64340",
    "navigationBarTitleText": "推箱子游戏"
  },

效果如图:

1.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;
}

2.页面设计

2.1首页设计

首页主要包括标题和关卡列表,这里使用view组件来构建整个页面,在.wxml中写入以下代码:

<view class='container'>
  <view class='title'>游戏选关</view>
  <view class='levelBox'>
    <view class="box">
      <image src="/images/level01.png"/>
      <text>第一关</text>
    </view>
  </view>
</view>

在.wxss文件中为其添加样式:

.levelBox{
  width: 100%;
}
.box{
  width: 50%;
  float: left;
  margin: 20rpx 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}
image{
  width: 300rpx;
  height: 300rpx;
}

当前页面如图所示:

2.2游戏页面设计

游戏页面共有四个组成部分:标题,游戏区域,方向键和重新开始按钮。

由于还未在首页设置跳转函数,因此需要通过添加编译模式来预览游戏页面的效果:

然后开始构建页面,首先在game.wxml中写入以下代码:

<view class='container'>
  <view class='title'>第一关</view>
  <canvas canvas-id="myCanvas"/>
  <view class='btnBox'>
    <button type="warn">↑</button>
    <view>
      <button type="warn">←</button>
      <button type="warn">↓</button>
      <button type="warn">→</button>
    </view>
  </view>
  <button type="warn">重新开始</button>
</view>

在.wxss中设置样式:

canvas{
  border: 1rpx solid;
  width: 320px;
  height: 320px;
}
.btnBox{
  display: flex;
  flex-direction: column;
  align-items: center;
}
.btnBox view{
  display: flex;
  flex-direction: row;
}
.btnBox button{
  width: 90rpx;
  height: 90rpx;
}
button{
  margin: 10rpx;
}

此时的效果如下图所示:

3.逻辑实现

3.1公共逻辑

在utils文件下新建一个data.js文件,用于存储游戏的地图数据等公共数据,在其中写入以下代码:

var map1 = [
  [0,1,1,1,1,1,0,0],
  [0,1,2,2,1,1,1,0],
  [0,1,5,4,2,2,1,0],
  [1,1,1,2,1,2,1,1],
  [1,3,1,2,1,2,2,1],
  [1,3,4,2,2,1,2,1],
  [1,3,2,2,2,4,2,1],
  [1,1,1,1,1,1,1,1]
]
var map2 = [
  [0,0,1,1,1,0,0,0],
  [0,0,1,3,1,0,0,0],
  [0,0,1,2,1,1,1,1],
  [1,1,1,4,2,4,3,1],
  [1,3,2,4,5,1,1,1],
  [1,1,1,1,4,1,0,0],
  [0,0,0,1,3,1,0,0],
  [0,0,0,1,1,1,0,0]
]
var map3=[
  [0,0,1,1,1,1,0,0],
  [0,0,1,3,3,1,0,0],
  [0,1,1,2,3,1,1,0],
  [0,1,2,2,4,3,1,0],
  [1,1,2,2,5,4,1,1],
  [1,2,2,1,4,4,2,1],
  [1,2,2,2,2,2,2,1],
  [1,1,1,1,1,1,1,1]
]
var map4=[
  [0,1,1,1,1,1,1,0],
  [0,1,3,2,3,3,1,0],
  [0,1,3,2,4,3,1,0],
  [1,1,1,2,2,4,1,1],
  [1,2,4,2,2,4,2,1],
  [1,2,1,4,1,1,2,1],
  [1,2,2,2,5,2,2,1],
  [1,1,1,1,1,1,1,1]
]
module.exports={
  maps:[map1,map2,map3,map4]
}

其中,地图中1代表墙,2代表道路,3代表终点,4代表箱子,5代表人物,6代表地图外围。

之后需要在其他页面中引用该文件,在game.js页面的顶部添加以下代码:

var data=require('../../utils/data.js')
3.2关卡展示与跳转

首先在index.js文件中写入以下数据:

data: {
    levels:[
      'level101.png',
      'level102.png',
      'level103.png',
      'level104.png',
    ]
  },

用于记录图片的信息。

接下来修改view组件,通过wx:for循环显示关卡数据:

<view class="box" wx:for="{{levels}}" wx:key="levels{{index}}">
      <image src="/images/{{item}}"/>
      <text>第{{index+1}}关</text>

此时程序的效果如图:

然后继续修改.wxml文件,为其添加点击事件,实现点击后跳转关卡的功能:

  <view class="box" wx:for="{{levels}}" wx:key="levels{{index}}" bind:tap="chooseLevel" data-level='{{index}}'>

接下来就要在js文件中添加相应的相应函数:

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

现在就可以实现点击关卡的跳转功能了。

3.3游戏逻辑实现

首先修改game.js文件,加入level数据,来显示当前游戏为第几关,在data内加入level属性,并且在OnLoad函数中接受跳转页面时传递来的参数,使用setData将level设置为接受到的参数:

onLoad(options) {
    let level=options.level
    this.setData({
      level:parseInt(level)+1
    })
  },

修改.wxml文件,使其动态显示关卡数:

<view class='title'>第{{level}}关</view>

此时点击不同的关卡就会跳转到不同的页面了:

之后开始进行最重要的一部分,也就是游戏运行的逻辑,首先在game.js文件中添加以下数据:

var map=[
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0]
]
var box=[
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0]
]
var w=40
var row=0
var col=0

然后在其中添加一个初始化函数,用来读取地图数据,在js文件添加以下代码:

initMap:function(level){
    let mapData=data.maps[level]
    for(var i=0;i<8;i++){
      for(var j=0;j<8;j++){
        box[i][j]=0
        map[i][j]=mapData[i][j]
        if(mapData[i][j]==4){
          box[i][j]=4
          map[i][j]=2
        }else if(mapData[i][j]==5){
          map[i][j]=2
          row=i
          col=j
        }
      }
    }
  },

之后继续添加自定义函数,绘制画布:

drawCanvas:function(){
    let ctx=this.ctx
    ctx.clearRect(0,0,320,320)
    for(var i=0;i<8;i++){
      for(var j=0;j<8;j++){
        let img='ice'
        if(map[i][j]==1){
          img='stone'
        }else if(map[i][j]==3){
          img='pig'
        }
        ctx.drawImage('/images/icons'+img+'.png',j*w,i*w,w,w)
        if(box[i][j]==4){
          ctx.drawImage('/images/icons/box.png',j*w,i*w,w,w)
        }
      }
    }
    ctx.drawImage('/images/icons/bird.png',col*w,row*w,w,w)
    ctx.draw()
  },

最后只需在OnLoad函数中依次调用自定义的函数,即可实现整个游戏地图的加载和绘制:

onLoad(options) {
    let level=options.level
    console.log(options.level)
    this.setData({
      level:parseInt(level)+1
    })
    this.ctx=wx.createCanvasContext('myCanvas')
    this.initMap(level)
    this.drawCanvas()
  },

现在就可以有整个画面了:

但是现在也仅仅只是有画面,并不能进行人物的移动,因此现在来为四个方向健添加点击事件:

 <button type="warn" bind:tap="up">↑</button>
<button type="warn" bind:tap="left">←</button>
      <button type="warn" bind:tap="down">↓</button>
      <button type="warn" bind:tap="right">→</button>

然后在,js文件中添加对应的函数,来实现人物的移动:

up:function(){
    if(row>0){
      if(map[row-1][col]!=1 && box[row-1][col]!=4){
        row=row-1
      }
      else if(box[row-1][col]==4){
        if(row-1>0){
          if(map[row-2][col]!=1&&box[row-2][col]!=4){
            box[row-2][col]=4
            box[row-1][col]=0
            row=row-1
          }
        }
      }
      this.drawCanvas()
    }
  },
  down:function(){
    if(row<7){
      if(map[row+1][col]!=1 && box[row+1][col]!=4){
        row=row+1
      }
      else if(box[row+1][col]==4){
        if(row+1<7){
          if(map[row+2][col]!=1&&box[row+2][col]!=4){
            box[row+2][col]=4
            box[row+1][col]=0
            row=row+1
          }
        }
      }
      this.drawCanvas()
    }
  },
  left:function(){
    if(col>0){
      if(map[row][col-1]!=1 && box[row][col-1]!=4){
        col=col-1
      }
      else if(box[row][col-1]==4){
        if(col-1>0){
          if(map[row][col-2]!=1&&box[row][col-2]!=4){
            box[row][col-2]=4
            box[row][col-1]=0
            col=col-1
          }
        }
      }
      this.drawCanvas()
    }
  },
​
  right:function(){
    if(col<7){
      if(map[row][col+1]!=1 && box[row][col+1]!=4){
        col=col+1
      }
      else if(box[row][col+1]==4){
        if(col+1<7){
          if(map[row][col+2]!=1&&box[row][col+2]!=4){
            box[row][col+2]=4
            box[row][col+1]=0
            col=col+1
          }
        }
      }
      this.drawCanvas()
    }
  },

现在人物已经可以移动了,也能够推箱子,接下来进行游戏成功的判定。

在js文件中添加以下函数在判断游戏是否成功:

 isWin:function(){
    for(var i=0;i<8;i++){
      for(var j=0;j<8;j++){
        if(box[i][j]==4&&map[i][j]!=3){
          return false
        }
      }
    }
    return true
  },

之后继续添加函数,调用判断函数并弹出提示框:

checkWin:function(){
    if(this.isWin()){
      wx.showModal({
        title: '恭喜',
        content: '游戏成功',
        showCancel:false
      })
    }
  },

然后将这个函数添加到方向键的相应函数,这样每次点击移动一次,就会判断这一次移动以后游戏是否成功,在四个函数的最后均加入以下语句:

this.checkWin()

这样游戏就可以顺利进行了。

最后需要为重新开始按钮添加响应事件:

<button type="warn" bind:tap="restartGame">重新开始</button>

添加对应函数:

  restartGame:function(){
    this.initMap(this.data.level-1)
    this.drawCanvas()
  },

至此,所有的功能都实现完成。

三、程序运行结果

首页:

游戏页面:

游戏成功:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值