碰撞检测
- 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
},
- 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
}
- 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