code: func drawGroundImage(screen *ebiten.Image, ground *ebiten.Image) {
  	perspectiveGroundImage.Clear()
  	gw, _ := ground.Size()
  	pw, ph := perspectiveGroundImage.Size()
  	for j := 0; j < ph; j++ {
  		// z is in [2, -1]
  		rate := float64(j) / float64(ph)
  		z := (1-rate)*2 + rate*-1
  		if z <= 0 {
  			break
  		}
  		op := &ebiten.DrawImageOptions{}
  		op.GeoM.Translate(-float64(pw)/2, 0)
  		op.GeoM.Scale(1/z, 8) // 8 is an arbitrary number not to make empty lines.
  		op.GeoM.Translate(float64(pw)/2, float64(j)/z)
  
  		perspectiveGroundImage.DrawImage(ground.SubImage(image.Rect(0, j, gw, j+1)).(*ebiten.Image), op)
  	}
  
  	perspectiveGroundImage.DrawImage(fogImage, nil)
  
  	op := &ebiten.DrawImageOptions{}
  	op.GeoM.Translate(-float64(pw)/2, 0)
  	op.GeoM.Rotate(-1 * float64(thePlayer.lean) / maxLean * math.Pi / 8)
  	op.GeoM.Translate(float64(screenWidth)/2, screenHeight/3)
  	screen.DrawImage(perspectiveGroundImage, op)
  }
docs: // drawGroundImage draws the ground image to the given screen image.