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}) } } } }
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 } } }, }) }