Scenario viewpoint, Z index management, and arrow controls
This commit is contained in:
@@ -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)),
|
||||
|
||||
|
||||
)
|
||||
}*/
|
||||
|
Reference in New Issue
Block a user