Scenario viewpoint, Z index management, and arrow controls

This commit is contained in:
2020-04-20 00:16:21 +01:00
parent 1f4bfc771c
commit 9d0750d134
10 changed files with 194 additions and 63 deletions

View File

@@ -22,16 +22,21 @@ type IsoPt struct {
func (s *Scenario) Update(screenX, screenY int) error {
s.tick += 1
x, y := ebiten.CursorPosition()
geo := s.geoForCam()
geo.Translate(cellWidthHalf, 0)
geo.Scale(s.Zoom, s.Zoom)
geo.Invert()
cX, cY := ebiten.CursorPosition()
x, y := geo.Apply(float64(cX), float64(cY))
screenPos := CartPt{
X: float64(s.Viewpoint.X + x),
Y: float64(s.Viewpoint.Y + y),
X: x,
Y: y,
}
s.selectedCell = screenPos.ToISO()
// TODO: zoom support will need a camera
// FIXME: adjust for Z level
s.selectedCell = screenPos.ToISO()
return nil
}
@@ -41,17 +46,18 @@ func (s *Scenario) Draw(screen *ebiten.Image) error {
// http://www.java-gaming.org/index.php?topic=24922.0
// https://stackoverflow.com/questions/892811/drawing-isometric-game-worlds
// https://gamedev.stackexchange.com/questions/25896/how-do-i-find-which-isometric-tiles-are-inside-the-cameras-current-view
// FIXME: we don't cope with zoom very neatly here
sw, sh := screen.Size()
topLeft := CartPt{
X: float64(s.Viewpoint.X - 2*cellWidth), // Ensure all visible cells are rendered
Y: float64(s.Viewpoint.Y - 2*cellHeight),
X: float64(s.Viewpoint.X) - (2*cellWidth/s.Zoom), // Ensure all visible cells are rendered
Y: float64(s.Viewpoint.Y) - (2*cellHeight/s.Zoom),
}.ToISO()
bottomRight := CartPt{
X: float64(s.Viewpoint.X + sw + 2*cellHeight),
Y: float64(s.Viewpoint.Y + sh + 5*cellHeight), // Z dimension requires it
X: float64(s.Viewpoint.X) + (float64(sw)/s.Zoom) + (2*cellHeight/s.Zoom),
Y: float64(s.Viewpoint.Y) + (float64(sh)/s.Zoom) + (5*cellHeight/s.Zoom), // Z dimension requires it
}.ToISO()
// X+Y is constant for all tiles in a column
@@ -101,29 +107,53 @@ func (s *Scenario) Draw(screen *ebiten.Image) error {
//log.Printf("%#+v", counter)
// Finally, draw cursor chrome
// FIXME: it looks like we might need to do this in normal painting order...
spr, err := s.specials.Sprite(0)
if err != nil {
return err
}
op := ebiten.DrawImageOptions{}
op.GeoM = s.geoForCoords(int(s.selectedCell.X), int(s.selectedCell.Y), 0)
op.GeoM.Translate(-cellWidthHalf, -cellHeightHalf)
geo := s.geoForCoords(int(s.selectedCell.X), int(s.selectedCell.Y), 0)
op.GeoM = geo
op.GeoM.Translate(-209, -332)
op.GeoM.Translate(float64(spr.Rect.Min.X), float64(spr.Rect.Min.Y))
op.GeoM.Scale(s.Zoom, s.Zoom)
if err := screen.DrawImage(spr.Image, &op); err != nil {
return err
}
x1, y1 := geo.Apply(0, 0)
ebitenutil.DebugPrintAt(
screen,
fmt.Sprintf("(%d,%d)", int(s.selectedCell.X), int(s.selectedCell.Y)),
int(x1),
int(y1),
)
sx, sy := op.GeoM.Apply(0, 0)
ebitenutil.DebugPrintAt(screen, fmt.Sprintf("(%.0f,%.0f)", s.selectedCell.X, s.selectedCell.Y), int(sx), int(sy))
/*
// debug: draw a square around the selected cell
x2, y2 := geo.Apply(cellWidth, cellHeight)
ebitenutil.DrawLine(screen, x1, y1, x2, y1, colornames.Green) // top line
ebitenutil.DrawLine(screen, x1, y1, x1, y2, colornames.Green) // left line
ebitenutil.DrawLine(screen, x2, y1, x2, y2, colornames.Green) // right line
ebitenutil.DrawLine(screen, x1, y2, x2, y2, colornames.Green) // bottom line
*/
return nil
}
func (s *Scenario) geoForCoords(x, y, z int) ebiten.GeoM {
func (s *Scenario) geoForCam() ebiten.GeoM {
geo := ebiten.GeoM{}
geo.Translate(-float64(s.Viewpoint.X), -float64(s.Viewpoint.Y))
return geo
}
func (s *Scenario) geoForCoords(x, y, z int) ebiten.GeoM {
geo := s.geoForCam()
pix := IsoPt{X: float64(x), Y: float64(y)}.ToCart()
geo.Translate(pix.X, pix.Y)
@@ -157,6 +187,9 @@ func (s *Scenario) renderCell(x, y, z int, screen *ebiten.Image, counter map[str
op.GeoM.Translate(float64(spr.Rect.Min.X), float64(spr.Rect.Min.Y))
// Zoom has to come last
op.GeoM.Scale(s.Zoom, s.Zoom)
if err := screen.DrawImage(spr.Image, &op); err != nil {
return err
}
@@ -166,11 +199,11 @@ func (s *Scenario) renderCell(x, y, z int, screen *ebiten.Image, counter map[str
}
const (
cellWidth = 128
cellHeight = 64
cellWidth = 128.0
cellHeight = 63.0
cellWidthHalf = cellWidth / 2
cellHeightHalf = cellHeight / 2
cellWidthHalf = cellWidth / 2.0
cellHeightHalf = cellHeight / 2.0
)
func (p CartPt) ToISO() IsoPt {
@@ -186,28 +219,3 @@ func (p IsoPt) ToCart() CartPt {
Y: (p.X + p.Y) * cellHeightHalf,
}
}
/*
// Doesn't take the camera or Z level into account
func cellToPix(pt image.Point) image.Point {
return image.Pt(
(pt.X-pt.Y)*cellWidthHalf,
(pt.X+pt.Y)*cellHeightHalf,
)
}
// Doesn't take the camera or Z level into account
func pixToCell(pt image.Point) image.Point {
fX := pt.X
fY := pt.Y
return image.Pt(
// (pt.X / cellWidthHalf + pt.Y / cellHeightHalf) / 2,
// (pt.Y / cellHeightHalf - (pt.Y / cellWidthHalf)) / 2,
// int(fY/cellHeight+fX/(cellWidth*2)),
// int(fY/cellHeight-fX/(cellWidth*2)),
//int((fY / cellHeight) + (fX / cellWidth)),
//int((-fX / cellWidth) + (fY / cellHeight)),
)
}*/