module RenderPlayer (renderPlayer, renderPlayerDebug)
where
import Data.Bits
import GHC.Int
import Data.Array
import Control.Monad
import Physics
import Data.Time.Clock
import Data.Convertible
import FRP.Yampa.Geometry
import Graphics.UI.SDL as SDL
import Graphics.UI.SDL.Primitives as SDLp
import Graphics.UI.SDL.TTF as SDLt
import Graphics.UI.SDL.Mixer as SDLm
import BasicTypes
import RenderUtil
import Global
orange = rgbColor 0xE7 0x5B 0x12
-- Alles rund um den Fußballer...
r1 z = 3.0 + z -- Punkte zwischen Kreisrand und äußerem Ring
r2 z = 6.0 + z -- Punkte zwischen Kreisrand innerem Ring
angle = 0.45 -- Winkel des Zeiger-Dreiecks
pr1 z = truncate $ r1 z
triangle x y height radD alpha r1 r2 angle =
let l1 = radD - (r1 height)
l2 = radD - (r2 height)
a = (x + truncate (l1 * cos alpha), y + truncate (l1 * sin alpha))
b = (x + truncate (l2 * cos (alpha-angle)), y + truncate (l2 * sin (alpha-angle)))
c = (x + truncate (l2 * cos (alpha+angle)), y + truncate (l2 * sin (alpha+angle)))
in (a,b,c)
playersizeMin = 25 :: Int16 -- in Pixeln
playersizeMax = 50
maxJump = 3.0 -- in Meter
blinker = do
t <- fmap ((100 *) . convert) getCurrentTime :: IO Double
let t' = truncate t `mod` 100
return $ t' < 50
playerSize :: Param -> Double -> Int16
playerSize param z = -- zwischen 0 und 2 Meter Höhe, dann wechselt der Spieler zwischen 30 und 50 Dicke...
if z > maxJump then playersizeMax
else if z < pGround param then playersizeMin
else truncate $ fromIntegral playersizeMin + z * (fromIntegral playersizeMax - fromIntegral playersizeMin) / 10.0
renderPlayer param surface p alpha sel number cCircle cTriangle cBorder kicked nonai designated fonts wav =
do
when kicked $ playChannel (-1) wav 0 >> return ()
let Point3 px py pz = p
let radius = playerSize param pz `shiftR` 1
let radius' = (radius `shiftR` 1)-4 -- hacky: try to align exactly with ball...
let (x', y') = pitchToPoint param (px, py)
let (x, y) = (x'+radius', y'+radius')
let xAdjust = truncate (-0.4*pz) + if number > 9 then 3 else 1 :: Int16 -- Zentrieren der Rückennummer
let yAdjust = if pz < 1 then 4 else if pz < 2 then 5 else 5 :: Int16 -- Zentrieren der Rückennummer
let radD = fromIntegral radius
let ((ax, ay),
(bx, by),
(cx, cy)) = triangle x y pz radD alpha r1 r2 angle
let font = if pz < 1 then fonts ! 1
else if pz < 2 then fonts ! 2
else fonts ! 3
let markFont = fonts ! 5
blinkOn <- blinker
let cBorderBlinking = if nonai && blinkOn then cCircle else cBorder
let cTriangleBlinking = if nonai && blinkOn then cCircle else cTriangle
let cCircleBlinking = if nonai && blinkOn then cBorder else cCircle
fontSurface <- SDLt.renderTextSolid font (show number) (colorFromPixel cTriangleBlinking)
-- f2 <- SDL.convertSurface fontSurface (SDL.surfaceGetPixelFormat surface) []
SDLp.filledCircle surface x y radius cBorderBlinking
SDLp.filledCircle surface x y (radius - (pr1 pz)) cCircleBlinking
when designated $ do
markSurface <- SDLt.renderTextSolid markFont "!" (colorFromPixel orange)
SDL.blitSurface markSurface Nothing surface (Just $ Rect (fromIntegral (x-xAdjust+1))
(fromIntegral (y-yAdjust-5))
(fromIntegral (x-xAdjust+10))
(fromIntegral (y-yAdjust+10)))
return ()
SDLp.filledTrigon surface ax ay bx by cx cy cTriangleBlinking
SDL.blitSurface fontSurface Nothing surface (Just $ Rect (fromIntegral (x-xAdjust))
(fromIntegral (y-yAdjust))
(fromIntegral (x-xAdjust+10))
(fromIntegral (y-yAdjust+10)))
renderPlayerDebug surface sel number bState tState color font baseDef baseOff oosTeam =
do
fontSurface <- SDLt.renderTextSolid font (show number ++ ": " ++
show tState ++ ", " ++
show bState ++ ", " -- ++
-- show baseDef ++ ", " ++
-- show baseOff
)
(colorFromPixel color)
-- f2 <- SDL.convertSurface fontSurface (SDL.surfaceGetPixelFormat surface) []
let adjust = if oosTeam == Home then 150 else 500
SDL.blitSurface fontSurface Nothing surface (Just $ Rect 850 (adjust+20*number) 950 (adjust+50+20*number))