mischief-render-0.1.0.0: examples/start/Start.hs
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad (void)
import Data.Default
import Data.Text (Text)
import Mischief.Animation
import Mischief.Assets
import Mischief.ECS
import Mischief.ECS.Time qualified as Time
import Mischief.Input
import Mischief.Input.Keys qualified as Keys
import Mischief.Math hiding (qd)
import Mischief.Math.Transform qualified as Transform
import Mischief.Render
import MyMaterial (MyColor (..), MyMaterial)
main :: IO ()
main = do
app <- newApp
setAssetSource "assets/" app
addPlugin @MainPlugin app
runApp app
data MainPlugin
instance Plugin MainPlugin where
init = do
systems setup
& schedule @Startup
systems (movement, maintainBuffer @MyColor)
& schedule @RenderPrepare
systems (renderSortedMaterial @MyMaterial def getY)
& schedule @RenderUpdate
deps = [dep @RenderPlugin, dep @InputPlugin, dep @TimePlugin, dep @AnimationPlugin, dep @FileWatcherPlugin]
data Player = Player deriving (Component)
getY :: Entity -> Query System Float
getY entity = do
Transform {translation} <- [q|entity. Transform|]
pure (-translation.y)
setup :: System ()
setup = do
window <- spawn Window
void $ spawn (Camera, Rel OutputTo window)
e <-
spawn
( Animator MyAnimator,
Anchor $ V2 0.5 0.9,
WithMaterial @MyMaterial,
def {translation = V3 (-60) 0 0},
MyColor @CPU (V3 1 1 0),
Player
)
shift (ChangeCharacter Pink) e
e <-
spawn
( Animator MyAnimator,
Anchor $ V2 0.5 0.9,
WithMaterial @MyMaterial,
MyColor @CPU (V3 0 1 1),
def {translation = V3 60 0 0}
)
shift (ChangeCharacter Green) e
movement :: System ()
movement = do
Just keys <- res @Keys
Just (player, transform) <- single [q|Entity, Transform / With Player|]
delta <- Time.delta
let speed = 150
let dirX =
if
| Keys.pressed keys Keys.A -> -1
| Keys.pressed keys Keys.D -> 1
| otherwise -> 0
let dirY =
if
| Keys.pressed keys Keys.S -> -1
| Keys.pressed keys Keys.W -> 1
| otherwise -> 0
let dir = normalize $ V3 dirX dirY 0
let walk = norm dir > 0
input @MyAnimator (\i -> i {walk}) player
let flip = dir.x < 0
insert (SpriteFlip {x = False, y = flip}) player
insert (Transform.move (dir ^* delta * speed) transform) player
data MyAnimator = MyAnimator
data Character = Green | Pink
charName :: Character -> Text
charName Green = "green"
charName Pink = "pink"
data AnimationType = Idle | Walk
instance AnimatorTag MyAnimator where
data Input MyAnimator = Input {walk :: Bool} deriving (Generic, Default)
data Shift MyAnimator = ChangeCharacter Character
data State MyAnimator = Start | CharacterAnimation Character AnimationType
animation (CharacterAnimation c Idle) = selAnim "animations.kdl" (charName c <> "_idle")
animation (CharacterAnimation c Walk) = selAnim "animations.kdl" (charName c <> "_walk")
animation Start = noAnimation
transition (CharacterAnimation c Idle) Input {walk = True} _ _ = Just (CharacterAnimation c Walk)
transition (CharacterAnimation c Walk) Input {walk = False} _ _ = Just (CharacterAnimation c Idle)
transition Start _ (Just (ChangeCharacter c)) _ = Just (CharacterAnimation c Idle)
transition _ _ _ _ = Nothing
start = Start