Example #1
0
func (cs *CollisionSystem) Update(entity *ecs.Entity, dt float32) {
	var (
		space     *SpaceComponent
		collision *CollisionComponent
		ok        bool
	)

	if space, ok = entity.ComponentFast(space).(*SpaceComponent); !ok {
		return
	}

	if collision, ok = entity.ComponentFast(collision).(*CollisionComponent); !ok {
		return
	}

	if !collision.Main {
		return
	}

	var (
		otherSpace     *SpaceComponent
		otherCollision *CollisionComponent
	)

	for _, other := range cs.Entities() {
		if other.ID() != entity.ID() {
			if otherSpace, ok = other.ComponentFast(otherSpace).(*SpaceComponent); !ok {
				return
			}

			if otherCollision, ok = other.ComponentFast(otherCollision).(*CollisionComponent); !ok {
				return
			}

			entityAABB := space.AABB()
			offset := Point{collision.Extra.X / 2, collision.Extra.Y / 2}
			entityAABB.Min.X -= offset.X
			entityAABB.Min.Y -= offset.Y
			entityAABB.Max.X += offset.X
			entityAABB.Max.Y += offset.Y
			otherAABB := otherSpace.AABB()
			offset = Point{otherCollision.Extra.X / 2, otherCollision.Extra.Y / 2}
			otherAABB.Min.X -= offset.X
			otherAABB.Min.Y -= offset.Y
			otherAABB.Max.X += offset.X
			otherAABB.Max.Y += offset.Y
			if IsIntersecting(entityAABB, otherAABB) {
				if otherCollision.Solid && collision.Solid {
					mtd := MinimumTranslation(entityAABB, otherAABB)
					space.Position.X += mtd.X
					space.Position.Y += mtd.Y
				}

				Mailbox.Dispatch(CollisionMessage{Entity: entity, To: other})
			}
		}
	}
}
Example #2
0
func (m *Maze) Update(entity *ecs.Entity, dt float32) {
	if entity.ID() != m.playerEntity.ID() {
		return
	}

	var (
		move *MovementComponent
		ok   bool
	)

	if move, ok = entity.ComponentFast(move).(*MovementComponent); ok {
		return // because we're still moving!
	}

	if m.currentLevel.Width == 0 || m.currentLevel.Height == 0 {
		return // because there's no maze
	}

	oldX, oldY := m.currentLevel.PlayerX, m.currentLevel.PlayerY

	if m.currentLevel.Grid[oldY][oldX] == TileGoal {
		// Goal achieved!

		if strings.HasPrefix(m.currentLevel.Name, "Random ") {
			engi.Mailbox.Dispatch(MazeMessage{})
			return
		}

		if m.sequence != SequenceNone {
			m.cleanup()
			m.initialize("")
			return
		}
	}

	switch m.Controller.Action(m.currentLevel) {
	case ActionUp:
		m.currentLevel.PlayerY--
	case ActionDown:
		m.currentLevel.PlayerY++
	case ActionLeft:
		m.currentLevel.PlayerX--
	case ActionRight:
		m.currentLevel.PlayerX++
	case ActionStop:
		return // so don't move
	}

	if !m.currentLevel.IsAvailable(m.currentLevel.PlayerX, m.currentLevel.PlayerY) {
		m.currentLevel.PlayerX, m.currentLevel.PlayerY = oldX, oldY
		return // because it's an invalid move
	}

	entity.AddComponent(&MovementComponent{
		From: engi.Point{float32(oldX) * tileWidth, float32(oldY) * tileHeight},
		To:   engi.Point{float32(m.currentLevel.PlayerX) * tileWidth, float32(m.currentLevel.PlayerY) * tileHeight},
		In:   time.Second / moveSpeed,
		Callback: func() {
			if m.currentLevel.Grid[m.currentLevel.PlayerY][m.currentLevel.PlayerX] == TileRoute {
				m.currentLevel.Grid[m.currentLevel.PlayerY][m.currentLevel.PlayerX] = TileBlank
				m.currentLevel.GridEntities[m.currentLevel.PlayerY][m.currentLevel.PlayerX].AddComponent(tileBlank)
			} else if m.currentLevel.Grid[oldY][oldX] == TileError ||
				m.currentLevel.Grid[oldY][oldX] == TileBlank {
				m.currentLevel.Grid[oldY][oldX] = TileRoute

				if m.currentLevel.Grid[m.currentLevel.PlayerY][m.currentLevel.PlayerX] == TileHiddenError {
					m.currentLevel.Grid[m.currentLevel.PlayerY][m.currentLevel.PlayerX] = TileError
				}
			}
		},
	})
}