3D小游戏(three)-简易Box碰撞检测自实现

碰撞检测

  1. utils/index.js

pointInPolygon(point, vs) {//光线追踪

var x = point[0], y = point[1]

var inside = false

const xMin = vs[0][0] > vs[2][0] ? vs[2][0] : vs[0][0]

const xMax = vs[0][0] < vs[2][0] ? vs[2][0] : vs[0][0]

const yMin = vs[0][1] > vs[1][1] ? vs[1][1] : vs[0][1]

const yMax = vs[0][1] < vs[1][1] ? vs[1][1] : vs[0][1]

if (x > xMin && x < xMax && y > yMin && y < yMax) {

inside = true

}

// for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {

// var xi = vs[i][0], yi = vs[i][1]

// var xj = vs[j][0], yj = vs[j][1]

// var intersect = ((yi > y) != (yj > y))

// && (x < (xj - xi) * (y - yi) / (yj - yi) + xi)

// if (intersect) inside = !inside

// }

return inside

},

  1. Block/base.js

getVertices () {//获取中心,检测碰撞

const vertices = []

const centerPosition = {

x: this.instance.position.x,

z: this.instance.position.z

}

vertices.push([centerPosition.x + this.width / 2, centerPosition.z + this.width / 2])

vertices.push([centerPosition.x + this.width / 2, centerPosition.z - this.width / 2])

vertices.push([centerPosition.x - this.width / 2, centerPosition.z + this.width / 2])

vertices.push([centerPosition.x - this.width / 2, centerPosition.z - this.width / 2])

return vertices

}

 

  1. game-page.js

checkBottleHit () {

if (this.checkingHit && this.bottle.obj.position.y <= blockConf.height / 2 + 0.1 && this.bottle.status === 'jump' && this.bottle.flyingTime > 0.3) {

this.checkingHit = false

if (this.hit == 1 || this.hit == 7 || this.hit == 2) { // 游戏继续

this.state = 'stop'

this.bottle.stop()

this.bottle.obj.position.y = blockConf.height / 2

this.bottle.obj.position.x = this.bottle.destination[0]

this.bottle.obj.position.z = this.bottle.destination[1]

// this.updateScore(++this.score)

// this.updateNextBlock()

} else { //游戏结束

this.state = 'over'

// this.removeTouchEvent()

// this.callbacks.showGameOverPage()

}

}

}

//碰撞检测

getHitStatus (bottle, currentBlock, nextBlock, initY) {

var flyingTime = bottle.velocity.vy / gameConf.gravity * 2

initY = initY || +bottle.obj.position.y.toFixed(2)

var destinationY = blockConf.height / 2

var differenceY = destinationY

var time = +((-bottle.velocity.vy + Math.sqrt(Math.pow(bottle.velocity.vy, 2) - 2 * gameConf.gravity * differenceY)) / -gameConf.gravity).toFixed(2)

flyingTime -= time

flyingTime = +flyingTime.toFixed(2)

var destination = []

var bottlePosition = new THREE.Vector2(bottle.obj.position.x, bottle.obj.position.z)

var translate = new THREE.Vector2(this.axis.x, this.axis.z).setLength(bottle.velocity.vx * flyingTime)

bottlePosition.add(translate)

bottle.destination = [+bottlePosition.x.toFixed(2), +bottlePosition.y.toFixed(2)]

destination.push(+bottlePosition.x.toFixed(2), +bottlePosition.y.toFixed(2))

if (nextBlock) {

var nextDiff = Math.pow(destination[0] - nextBlock.instance.position.x, 2) + Math.pow(destination[1] - nextBlock.instance.position.z, 2)

var nextPolygon = nextBlock.getVertices()

var result1

if (utils.pointInPolygon(destination, nextPolygon)) {

if (Math.abs(nextDiff) < 5) {

return 1

} else {

return 7

}

} else if (utils.pointInPolygon([destination[0] - bottleConf.bodyWidth / 2, destination[1]], nextPolygon) || utils.pointInPolygon([destination[0], destination[1] + bottleConf.bodyDepth / 2], nextPolygon)) {

result1 = 5

} else if (utils.pointInPolygon([destination[0], destination[1] - bottleConf.bodyDepth / 2], nextPolygon) || utils.pointInPolygon([destination[0] + bottleConf.bodyDepth / 2, destination[1]], nextPolygon)) {

result1 = 3

}

}

var currentPolygon = currentBlock.getVertices()

var result2

if (utils.pointInPolygon(destination, currentPolygon)) {

return 2

} else if (utils.pointInPolygon([destination[0], destination[1] + bottleConf.bodyDepth / 2], currentPolygon) || utils.pointInPolygon([destination[0] - bottleConf.bodyWidth / 2, destination[1]], currentPolygon)) {

if (result1) return 6

return 4

}

return result1 || result2 || 0

}

引入文件

//碰撞检测用到

import blockConf from '../../confs/block-conf'

import gameConf from '../../confs/game-conf'

import utils from '../utils/index'

import bottleConf from '../../confs/bottle-conf'

constructor中

//碰撞参数

this.checkingHit = false

render中

this.checkBottleHit()//检测碰撞

touchEndCallback中

//碰撞检测

this.hit = this.getHitStatus(this.bottle, this.currentBlock, this.nextBlock, blockConf.height / 2 - (1 - this.currentBlock.instance.scale.y) * blockConf.height)

this.checkingHit = true

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值