Skip to content
This repository has been archived by the owner on Dec 4, 2019. It is now read-only.

Commit

Permalink
Update readme, levels and bg music
Browse files Browse the repository at this point in the history
  • Loading branch information
soupi committed May 5, 2018
1 parent 7506bc4 commit 69a92c5
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 62 deletions.
55 changes: 54 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,56 @@
Playing with Haskell
# yh

A tech demo for a shmup game.

Currently works on Linux and OS X.

* [Animated gif](https://streamable.com/0biaj)


## Controls:

* Arrows to move
* Z to shoot
* X to squeeze
* C to restart from checkpoint


## How to Run

### From Source

You will need [Stack](https://haskellstack.org).

#### Ubuntu:

```sh
sudo apt install libsdl2-dev libsdl2-ttf-dev libsdl2-image-dev libsdl2-gfx-dev libsdl2-mixer-dev
make build
make exec
```

#### OS X

```sh
brew install sdl2 sdl2_ttf sdl2_image sdl2_gfx sdl2_mixer
make build
make exec
```

### From Compiled Binary

> Binaries available [here](https://github.com/soupi/yh/releases).
#### Ubuntu:

```sh
sudo apt install libsdl2-2.0-0 libsdl2-ttf-2.0-0 libsdl2-image-2.0-0 libsdl2-gfx-1.0-0 libsdl2-mixer-2.0-0
./shmup
```

#### OS X

```sh
brew install sdl2 sdl2_ttf sdl2_image sdl2_gfx sdl2_mixer
./shmup
```
6 changes: 2 additions & 4 deletions app/GameState.hs
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,9 @@ update input state = do
-- state stack manipulation
if
| keyReleased KeyC input -> do
pure (State.Push $ state ^. restart, state)
| keyReleased KeyD input ->
pure (State.Done, state)
pure (State.Replace $ state ^. restart, state)
| otherwise ->
pure (State.None, newState)
pure (Script.command acts, newState)

flipEnemyDir :: Either () () -> Either () ()
flipEnemyDir = \case
Expand Down
75 changes: 75 additions & 0 deletions app/Script/Boss.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{-# LANGUAGE OverloadedStrings #-}

module Script.Boss where

import qualified Play.Engine.MySDL.MySDL as MySDL

import Script
import Play.Engine.Types
import qualified Enemy.CrossDown as CDE
import qualified Enemy.SideToSideSpiral as SSE
import qualified Enemy.Fast as Fast
import qualified Play.Engine.State as State
import qualified GameState as GS
import qualified TextBox as TB
import qualified Data.Map as M


boss :: State.State
boss =
GS.mkGameState $ Script
wantedAssets
lScript


wantedAssets :: [(String, MySDL.ResourceType FilePath)]
wantedAssets =
CDE.wantedAssets
++ SSE.wantedAssets
++ TB.wantedAssets
++ [ ("bga", MySDL.Texture "bga.png")
]
++ [ ("chikua", MySDL.Texture "chikua.png")
, ("saito", MySDL.Texture "saito.png")
, ("saito2", MySDL.Texture "saito2.png")
, ("music", MySDL.Music "battle.ogg")
, ("music-end", MySDL.Music "shushushu.ogg")
, ("rin", MySDL.Texture "rin.png")
]


lScript :: MySDL.Resources -> Script
lScript MySDL.Resources{ MySDL.textures = ts, MySDL.fonts = fs, MySDL.music = _ms } =

[ goToLoc $ Point 380 800
, LoadTextBox act{ stopTheWorld = True } $
TB.make TB.Top 5 "It's not over yet!" (M.lookup "saito" ts) (M.lookup "unispace" fs)
] ++

-- Boss
[ Spawn $ sequence [Fast.make (Point 350 (-100)) ts]
, WaitUntil noAction (const $ null)

, Wait noAction 100

-- End
, LoadTextBox act{ stopTheWorld = True } $
TB.make TB.Top 5 "orz" (M.lookup "saito" ts) (M.lookup "unispace" fs)
, LoadTextBox act{ stopTheWorld = True } $
TB.make TB.Top 15 "I'll be back!!!" (M.lookup "saito" ts) (M.lookup "unispace" fs)
, Wait noAction 400
, PlayMusic ("music-end", M.lookup "music-end" _ms)
] ++
cycle
(concat $ replicate 5
[ LoadTextBox act{ stopTheWorld = True } $
TB.make TB.Top 3 "Thanks for playing!" (M.lookup "saito" ts) (M.lookup "unispace" fs)
, LoadTextBox act{ stopTheWorld = True } $
TB.make TB.Bottom 3 "Thanks for playing!" (M.lookup "rin" ts) (M.lookup "unispace" fs)
] ++ pure
[ LoadTextBox act{ stopTheWorld = True } $
TB.make TB.Top 5 "Thanks for playing!" (M.lookup "chikua" ts) (M.lookup "unispace" fs)
, LoadTextBox act{ stopTheWorld = True } $
TB.make TB.Bottom 3 "Thanks for playing!" (M.lookup "rin" ts) (M.lookup "unispace" fs)
]
)
63 changes: 6 additions & 57 deletions app/Script/Level1.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import Play.Engine.Types
import qualified Enemy.Static as St
import qualified Enemy.CrossDown as CDE
import qualified Enemy.SideToSideSpiral as SSE
import qualified Enemy.Fast as Fast
import qualified Play.Engine.State as State
import qualified GameState as GS
import qualified Script.Level2 as L2
import qualified TextBox as TB
import qualified Data.Map as M

Expand All @@ -28,24 +28,24 @@ wantedAssets =
CDE.wantedAssets
++ SSE.wantedAssets
++ TB.wantedAssets
++ [ ("test", MySDL.Texture "test.jpg")
, ("bga", MySDL.Texture "bga.png")
++ [ ("bga", MySDL.Texture "bga.png")
]
++ [ ("chikua", MySDL.Texture "chikua.png")
, ("saito", MySDL.Texture "saito.png")
, ("saito2", MySDL.Texture "saito2.png")
, ("music", MySDL.Music "shushushu.ogg")
, ("music", MySDL.Music "battle.ogg")
, ("music-end", MySDL.Music "shushushu.ogg")
, ("rin", MySDL.Texture "rin.png")
]


lScript :: MySDL.Resources -> Script
lScript MySDL.Resources{ MySDL.textures = ts, MySDL.fonts = fs, MySDL.music = _ms } =
-- [ PlayMusic ("music", M.lookup "music" _ms)

-- [ Spawn $ sequence [Fast.make (Point 350 (-100)) ts]
-- , WaitUntil noAction (const $ null)

[ PlayMusic ("music", M.lookup "music" _ms) ] ++
[ LoadTextBox act{ stopTheWorld = True } $
TB.make TB.Top 6 "..." Nothing (M.lookup "unispace" fs)

Expand Down Expand Up @@ -105,58 +105,7 @@ lScript MySDL.Resources{ MySDL.textures = ts, MySDL.fonts = fs, MySDL.music = _m
[ WaitUntil noAction (const $ null)
, Wait noAction 200
, Wait act{ stopTheWorld = True } 30
, goToLoc $ Point 380 800
] ++

-- Second wave
concat
[ [ Spawn $ sequence [CDE.make (Point 100 (-180)) (Right ()) ts]
, Wait noAction 100
]
, spawnStaticAndWait 400 300 ts
, [ Spawn $ sequence [CDE.make (Point 700 (-180)) (Left ()) ts]
, Wait noAction 100
]
, [ Spawn $ sequence [CDE.make (Point 650 (-150)) (Left ()) ts]
, Wait noAction 100
]
, [ Spawn $ sequence [CDE.make (Point 100 (-180)) (Right ()) ts]
, Wait noAction 100
]
, spawnStaticAndWait 600 300 ts
, spawnStaticAndWait 250 250 ts
, [ spawnTwoCDEs (Left ()) (Right ()) ts
, Wait noAction 100
, spawnTwoCDEs (Right ()) (Left ()) ts
, Wait noAction 100
]
, [ spawnTwoCDEs (Left ()) (Right ()) ts
, Wait noAction 60
, spawnTwoCDEs (Right ()) (Left ()) ts
]
, spawnStaticAndWait 600 300 ts
, spawnStaticAndWait 250 250 ts
, [ spawnTwoCDEs (Left ()) (Right ()) ts
, Wait noAction 60
, spawnTwoCDEs (Right ()) (Left ()) ts
]
] ++

-- Second wave done
[ WaitUntil noAction (const $ null)
, Wait noAction 200
, Wait act{ stopTheWorld = True } 30
, goToLoc $ Point 380 800
] ++

-- Boss
[ Spawn $ sequence [Fast.make (Point 350 (-100)) ts]
, WaitUntil noAction (const $ null)

, Wait noAction 100

, LoadTextBox act{ stopTheWorld = True } $
TB.make TB.Top 5 "orz" (M.lookup "saito" ts) (M.lookup "unispace" fs)
, Wait act{ command = State.Replace L2.level2 } 60
]

spawnTwoCDEs dir1 dir2 ts =
Expand Down
102 changes: 102 additions & 0 deletions app/Script/Level2.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{-# LANGUAGE OverloadedStrings #-}

module Script.Level2 where

import qualified Play.Engine.MySDL.MySDL as MySDL

import Script
import Play.Engine.Types
import qualified Enemy.Static as St
import qualified Enemy.CrossDown as CDE
import qualified Enemy.SideToSideSpiral as SSE
import qualified Play.Engine.State as State
import qualified GameState as GS
import qualified Script.Boss as Boss
import qualified TextBox as TB
import qualified Data.Map as M


level2 :: State.State
level2 =
GS.mkGameState $ Script
wantedAssets
lScript


wantedAssets :: [(String, MySDL.ResourceType FilePath)]
wantedAssets =
CDE.wantedAssets
++ SSE.wantedAssets
++ TB.wantedAssets
++ [ ("bga", MySDL.Texture "bga.png")
]
++ [ ("chikua", MySDL.Texture "chikua.png")
, ("saito", MySDL.Texture "saito.png")
, ("saito2", MySDL.Texture "saito2.png")
, ("music", MySDL.Music "battle.ogg")
, ("music-end", MySDL.Music "shushushu.ogg")
, ("rin", MySDL.Texture "rin.png")
]


lScript :: MySDL.Resources -> Script
lScript MySDL.Resources{ MySDL.textures = ts, MySDL.fonts = fs, MySDL.music = _ms } =

[ goToLoc $ Point 380 800
, LoadTextBox act{ stopTheWorld = True } $
TB.make TB.Top 5 "Not bad!" (M.lookup "saito" ts) (M.lookup "unispace" fs)
] ++

-- Second wave
concat
[ [ Spawn $ sequence [CDE.make (Point 100 (-180)) (Right ()) ts]
, Wait noAction 100
]
, spawnStaticAndWait 400 300 ts
, [ Spawn $ sequence [CDE.make (Point 700 (-180)) (Left ()) ts]
, Wait noAction 100
]
, [ Spawn $ sequence [CDE.make (Point 650 (-150)) (Left ()) ts]
, Wait noAction 100
]
, [ Spawn $ sequence [CDE.make (Point 100 (-180)) (Right ()) ts]
, Wait noAction 100
]
, spawnStaticAndWait 600 300 ts
, spawnStaticAndWait 250 250 ts
, [ spawnTwoCDEs (Left ()) (Right ()) ts
, Wait noAction 100
, spawnTwoCDEs (Right ()) (Left ()) ts
, Wait noAction 100
]
, [ spawnTwoCDEs (Left ()) (Right ()) ts
, Wait noAction 60
, spawnTwoCDEs (Right ()) (Left ()) ts
]
, spawnStaticAndWait 600 300 ts
, spawnStaticAndWait 250 250 ts
, [ spawnTwoCDEs (Left ()) (Right ()) ts
, Wait noAction 60
, spawnTwoCDEs (Right ()) (Left ()) ts
]
] ++

-- Second wave done
[ WaitUntil noAction (const $ null)
, Wait noAction 200
, Wait act{ stopTheWorld = True } 30
, Wait act{ command = State.Replace Boss.boss } 60
]

spawnTwoCDEs dir1 dir2 ts =
Spawn $ sequence
[ CDE.make (Point 300 (-180)) dir1 ts
, CDE.make (Point 400 (-180)) dir2 ts
]

spawnStaticAndWait posx target ts =
[ Spawn $ sequence
[ St.make (Point posx (-100)) (Point 0 1) target ts
]
, Wait noAction 120
]
Binary file added assets/audio/battle.ogg
Binary file not shown.
Binary file removed assets/imgs/rin_spritemap.png
Binary file not shown.
Binary file removed assets/imgs/test.jpg
Binary file not shown.
Binary file removed assets/imgs/test.png
Binary file not shown.

0 comments on commit 69a92c5

Please sign in to comment.