package main import ( "github.com/veandco/go-sdl2/sdl" "image/color" ) type GameObject struct { baseRect *sdl.Rect prevBaseRect *sdl.Rect borderRect *sdl.Rect collisionRect *sdl.Rect orientation uint8 visualRects [][]*ColoredRect colors []color.Color inView bool } type ColoredRect struct { color color.Color rect *sdl.Rect } func adjustRectToCamera(object *sdl.Rect, camera *sdl.Rect) *sdl.Rect { return &sdl.Rect{ X: object.X - camera.X, Y: object.Y - camera.Y, W: object.W, H: object.H, } } func (gameObject *GameObject) adjustRectWorld(offset *sdl.Rect) *sdl.Rect { return &sdl.Rect{ X: gameObject.baseRect.X + offset.X, Y: gameObject.baseRect.Y + offset.Y, W: offset.W, H: offset.H, } } func (gameObject *GameObject) adjustColoredRectWorld(offset *ColoredRect) *ColoredRect { return &ColoredRect{ color: offset.color, rect: gameObject.adjustRectWorld(offset.rect), } } func (gameObject *GameObject) adjustRectToCamera(offset *sdl.Rect, camera *sdl.Rect) *sdl.Rect { return &sdl.Rect{ X: gameObject.baseRect.X + offset.X - camera.X, Y: gameObject.baseRect.Y + offset.Y - camera.Y, W: offset.W, H: offset.H, } } func (gameObject *GameObject) adjustBaseRect() { first := true oldX, oldY := gameObject.baseRect.X, gameObject.baseRect.Y for _, rect := range gameObject.getCurrentRects() { if first { gameObject.baseRect = gameObject.adjustRectWorld(rect.rect) first = false } else { } newRect := gameObject.baseRect.Union(gameObject.adjustRectWorld(rect.rect)) gameObject.baseRect = &newRect gameObject.baseRect.X, gameObject.baseRect.Y = oldX, oldY } } func (gameObject *GameObject) render(camera *sdl.Rect, surface *sdl.Surface) { if camera.HasIntersection(gameObject.baseRect) { gameObject.inView = true if config.Debug { baseRectFinal := adjustRectToCamera(gameObject.baseRect, camera) _ = surface.FillRect(baseRectFinal, sdl.MapRGBA(surface.Format, 255, 20, 10, 64)) if !gameObject.collisionRect.Empty() { _ = surface.FillRect(adjustRectToCamera(gameObject.collisionRect, camera), sdl.MapRGBA(surface.Format, 40, 192, 255, 64)) } } if config.RenderGameObjects { for _, coloredRect := range gameObject.visualRects[gameObject.orientation] { finalRect := gameObject.adjustRectToCamera(coloredRect.rect, camera) r, g, b, a := coloredRect.color.RGBA() _ = surface.FillRect(finalRect, sdl.MapRGBA(surface.Format, uint8(r), uint8(g), uint8(b), uint8(a))) } } } else { gameObject.inView = false } } func (gameObject *GameObject) addColoredRect(x, y, w, h int32, color uint8) { if gameObject.visualRects == nil { gameObject.visualRects = make([][]*ColoredRect, 0) } if uint8(len(gameObject.visualRects)) <= gameObject.orientation { gameObject.visualRects = append(gameObject.visualRects, make([]*ColoredRect, 0)) } if uint8(len(gameObject.colors)) > color { gameObject.visualRects[gameObject.orientation] = append(gameObject.visualRects[gameObject.orientation], &ColoredRect{ color: gameObject.colors[color], rect: &sdl.Rect{ X: x, Y: y, W: w, H: h, }, }) } } func (gameObject *GameObject) getCurrentRects() []*ColoredRect { return gameObject.visualRects[gameObject.orientation] } func (gameObject *GameObject) addColor(color color.Color) { gameObject.colors = append(gameObject.colors, color) }