예제 #1
0
func (p *Player) onMoveAction(dt time.Duration) {
	// check if moving would create a collision
	nextPos := p.Movable.ComputeMove(p.Pos, dt)
	nextBB := d2.RectFromCircle(nextPos, 0.5)
	colliding := p.world.AABBSpatialQuery(nextBB)

	var curActionEnded bool

	// by design moving action can't be the last one
	nextAction := p.actions.PeekN(2)[1]

	colliding.Each(func(e Entity) bool {

		if e == p {
			// it's just me... pass
			return true
		}

		switch nextAction.Type {
		case actions.BuildId, actions.RepairId:
			if e == p.curBuilding {
				log.WithField("ent", e).Debug("collision with target building")
				// we are colliding with the building we wanna build/repair
				// current action has terminated
				p.actions.Pop()
				// do not check for other collisions
				curActionEnded = true
				return false
			}
		}
		return true
	})

	if !curActionEnded {

		// perform the actual move
		p.posDirty = p.Movable.Move(dt)
		if p.Movable.HasReachedDestination() {
			// pop current action to get ready for next update
			next := p.actions.Pop()
			log.WithField("action", next).Debug("next player action")
		}
	}
	return
}
예제 #2
0
/*
 * moveOrCollide moves the zombies or resolve collision
 *
 * It returns the next zombie state, in order to resolve the possible collision
 * If -1 is returned, there was no collision and the zombie should go
 * ahead with its current action
 */
func (z *Zombie) moveOrCollide(dt time.Duration) (state int) {
	//func (z *Zombie) moveOrCollide(dt time.Duration) (hasCollided bool) {
	// check if moving would create a collision
	nextPos := z.Movable.ComputeMove(z.Pos, dt)
	nextBB := d2.RectFromCircle(nextPos, 0.5)
	colliding := z.world.AABBSpatialQuery(nextBB)

	var wouldCollide bool
	colliding.Each(func(e Entity) bool {

		if e == z {
			// it's just me... pass
			return true
		}
		if _, ok := e.(*Player); ok {
			// what? it's a player! let's kill him
			// change target, in case we were following somebody else
			state = attackingState
			z.target = e
			// we are colliding and the current framework allows us to 'resolve'
			// one collision only so no need to check further
			return false
		}
		state = lookingState
		wouldCollide = true
		return true
	})

	if !wouldCollide {
		if z.Movable.Move(dt) {
			z.world.UpdateEntity(z)
		}
		state = -1
	}
	return
}
예제 #3
0
func (me *Movable) Rectangle() d2.Rectangle {
	return d2.RectFromCircle(me.Pos, 0.5)
}