package components import ( "fmt" "image" . "openquell/config" "log/slog" ) // physical location on screen type Position struct { X int Y int Cellsize int Rect *image.Rectangle } func (position *Position) Update(x, y int, size ...int) { if len(size) == 1 { position.Cellsize = size[0] } position.X = x position.Y = y rect := image.Rect(x, y, x+position.Cellsize, y+position.Cellsize) position.Rect = &rect } func NewPosition(point image.Point, cellsize int) *Position { position := &Position{} position.Update(point.X*cellsize, point.Y*cellsize, cellsize) return position } func (position *Position) GetMoved(velosity *Velocity) *Position { pos := &Position{} pos.Update(position.X+(velosity.Data.X*velosity.Speed), position.Y+(velosity.Data.Y*velosity.Speed), position.Cellsize) return pos } func (position *Position) Point() image.Point { return image.Point{position.X / position.Cellsize, position.Y / position.Cellsize} } func (position *Position) Left() int { return position.X } func (position *Position) Right() int { return position.X + position.Cellsize } func (position *Position) Top() int { return position.Y } func (position *Position) Bottom() int { return position.Y + position.Cellsize } func (position *Position) String() string { return fmt.Sprintf("[%d,%d](Left:%d,Top:%d) x (Right:%d,Bottom:%d)", position.X/32, position.Y/32, position.X, position.Y, position.Right(), position.Bottom(), ) } func (position *Position) Move(velocity *Velocity) { // if velocity.Direction != 0 { // slog.Debug("moving", "velocity", velocity, "speed", speed) // } position.Update( position.X+(velocity.Data.X*velocity.Speed), position.Y+(velocity.Data.Y*velocity.Speed), ) } func (position *Position) Set(newpos *Position) { position.Update(newpos.X, newpos.Y) } func (tile *Position) Intersects(moving *Position, velocity *Velocity) (bool, *Position) { object := moving.GetMoved(velocity) is := tile.Rect.Bounds().Intersect(object.Rect.Bounds()) if is != image.ZR { // collision, snap into neighbouring tile depending on the direction switch velocity.Direction { case West: object.Update(tile.Rect.Max.X, tile.Y) case East: object.Update(tile.Rect.Min.X-tile.Cellsize, tile.Y) case South: object.Update(tile.X, tile.Rect.Min.Y-tile.Cellsize) case North: object.Update(tile.X, tile.Rect.Max.Y) } slog.Debug("Intersect", "velocity", velocity.Data, "player", moving, "moved player", object, "collision at", is, "tilepos", tile, ) return true, object } return false, nil }