mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
parent
063153e41d
commit
56c4dbf28b
@ -173,58 +173,22 @@ func updateGroundImage(ground *ebiten.Image) {
|
|||||||
ground.DrawImage(repeatedGophersImage, op)
|
ground.DrawImage(repeatedGophersImage, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
// scaleForLine calculates the scale to render at y-th line of the ground image.
|
|
||||||
func scaleForLine(y int) float64 {
|
|
||||||
// c |
|
|
||||||
// |\ |
|
|
||||||
// | \|
|
|
||||||
// | s
|
|
||||||
// | |\
|
|
||||||
// | | \
|
|
||||||
// A--B--C (plane)
|
|
||||||
//
|
|
||||||
// c: camera
|
|
||||||
// s: intersection of the ray and the screen
|
|
||||||
// A-c: camera height
|
|
||||||
// B-s: horizon height
|
|
||||||
// A-C: far point on the plane
|
|
||||||
// A-B: the distance from the camera to the screen
|
|
||||||
//
|
|
||||||
// The ground image is on the plane, and the head of the ground image is on 'C'.
|
|
||||||
const (
|
|
||||||
horizonHeight = screenHeight * 2.0 / 3.0
|
|
||||||
cameraHeight = horizonHeight + 100.0
|
|
||||||
farPointOnPlane = 200.0
|
|
||||||
cameraToScreen = farPointOnPlane - farPointOnPlane/cameraHeight*horizonHeight
|
|
||||||
)
|
|
||||||
s1 := cameraHeight / (farPointOnPlane - float64(y)) * (farPointOnPlane - float64(y) - cameraToScreen)
|
|
||||||
s2 := cameraHeight / (farPointOnPlane - float64(y+1)) * (farPointOnPlane - float64(y+1) - cameraToScreen)
|
|
||||||
if math.IsInf(s1, 0) || math.IsInf(s2, 0) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return s1 - s2
|
|
||||||
}
|
|
||||||
|
|
||||||
func drawGroundImage(screen *ebiten.Image, ground *ebiten.Image) {
|
func drawGroundImage(screen *ebiten.Image, ground *ebiten.Image) {
|
||||||
perspectiveGroundImage.Clear()
|
perspectiveGroundImage.Clear()
|
||||||
gw, gh := ground.Size()
|
gw, _ := ground.Size()
|
||||||
pw, ph := perspectiveGroundImage.Size()
|
pw, ph := perspectiveGroundImage.Size()
|
||||||
y := 0.0
|
for j := 0; j < ph; j++ {
|
||||||
for i := 0; i < ph; i++ {
|
// z is in [1.5, 0.01]
|
||||||
|
rate := float64(j) / float64(ph)
|
||||||
|
z := (1-rate)*1.5 + rate*0.01
|
||||||
op := &ebiten.DrawImageOptions{}
|
op := &ebiten.DrawImageOptions{}
|
||||||
s := scaleForLine(i)
|
op.GeoM.Translate(-float64(pw)/2, 0)
|
||||||
dx0 := -float64(gw)*s/2 + float64(pw)/2
|
op.GeoM.Scale(1/z, 4) // 4 is an arbitrary number not to make empty lines.
|
||||||
op.GeoM.Scale(s, s+1)
|
op.GeoM.Translate(float64(pw)/2, float64(j)/z)
|
||||||
op.GeoM.Translate(float64(dx0), y)
|
|
||||||
|
|
||||||
src := image.Rect(0, i, gw, i+1)
|
src := image.Rect(0, j, gw, j+1)
|
||||||
op.SourceRect = &src
|
op.SourceRect = &src
|
||||||
perspectiveGroundImage.DrawImage(ground, op)
|
perspectiveGroundImage.DrawImage(ground, op)
|
||||||
|
|
||||||
y += s
|
|
||||||
if y > float64(gh) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
perspectiveGroundImage.DrawImage(fogImage, nil)
|
perspectiveGroundImage.DrawImage(fogImage, nil)
|
||||||
|
Loading…
Reference in New Issue
Block a user