2024-02-06 15:26:20 +01:00
|
|
|
package components
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"image"
|
|
|
|
|
. "openquell/config"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-06 19:02:25 +01:00
|
|
|
func NewPosition(point image.Point, cellsize int) *Position {
|
2024-02-06 15:26:20 +01:00
|
|
|
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, position.Y+velosity.Data.Y, position.Cellsize)
|
|
|
|
|
|
|
|
|
|
return pos
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-06 19:02:25 +01:00
|
|
|
func (position *Position) Point() image.Point {
|
|
|
|
|
return image.Point{position.X / position.Cellsize, position.Y / position.Cellsize}
|
2024-02-06 15:26:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
position.Update(position.X+velocity.Data.X, position.Y+velocity.Data.Y)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
fmt.Printf(" velocity: %d,%d\n", velocity.Data.X, velocity.Data.Y)
|
|
|
|
|
fmt.Printf(" player: %s\n", moving.Rect)
|
|
|
|
|
fmt.Printf("moved player: %s\n", object.Rect)
|
|
|
|
|
fmt.Printf("collision at: %s\n", is)
|
|
|
|
|
// 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)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true, object
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false, nil
|
|
|
|
|
}
|