Skip to content

Instantly share code, notes, and snippets.

@andrevdm
Last active June 22, 2020 14:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrevdm/d753fcf38005e26ed662adf12228f283 to your computer and use it in GitHub Desktop.
Save andrevdm/d753fcf38005e26ed662adf12228f283 to your computer and use it in GitHub Desktop.
Haskell perlin noise terrain (2D ascii) with SDL2 display
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiWayIf #-}
module Main (main) where
import Protolude
import Foreign.C.Types (CInt (..))
import Linear (V2 (..), V3 (..), V4 (..) )
import qualified SDL
import SDL (($=))
import qualified Numeric.Noise.Perlin as Pn
main :: IO ()
main = do
-- Initialise SDL
SDL.initialize [SDL.InitVideo]
SDL.HintRenderScaleQuality $= SDL.ScaleNearest
--SDL window
window <- SDL.createWindow "Perlin terrain" SDL.defaultWindow
--SDL renderer
renderer <-
SDL.createRenderer window (-1)
SDL.RendererConfig
{ SDL.rendererType = SDL.AcceleratedVSyncRenderer
, SDL.rendererTargetTexture = False
}
-- http://bjh21.me.uk/bedstead/
tiles' <- SDL.loadBMP "bedstead-10-df.bmp"
SDL.surfaceColorKey tiles' $= Just (V4 255 0 255 0) --r g b a
tiles <- SDL.createTextureFromSurface renderer tiles'
SDL.showWindow window
runGame renderer window tiles
SDL.destroyRenderer renderer
SDL.destroyWindow window
SDL.quit
runGame :: SDL.Renderer -> SDL.Window -> SDL.Texture -> IO ()
runGame renderer window tiles = do
payload <- map SDL.eventPayload <$> SDL.pollEvents
unless (SDL.QuitEvent `elem` payload) $ do
-- Set the background colour and clear the screen
SDL.rendererDrawColor renderer $= V4 0 0 0 0
SDL.clear renderer
-- Render the world
draw renderer tiles
SDL.present renderer
SDL.delay 1000
runGame renderer window tiles
draw :: SDL.Renderer -> SDL.Texture -> IO ()
draw renderer tiles = do
let
seed = 10
octaves = 5
scale = 0.05
persistance = 0.5
perlinNoise = Pn.perlin seed octaves scale persistance
for_ [0..120] $ \c ->
for_ [0..55] $ \r -> do
let
tileWidth = 6
tileHeight = 10
tilesPerRow = 16
x' = Pn.noiseValue perlinNoise (fromIntegral r, fromIntegral c, 0)
x = x' + 1 -- range is 0..2
(letter, clr) =
if | x < 0.40 -> ('~', V3 0 191 255)
| x < 1.20 -> ('-', V3 72 60 50)
| x < 1.80 -> ('^', V3 0 100 0)
| otherwise -> ('#', V3 255 255 255)
letterIx = ord letter
tileX = letterIx `mod` tilesPerRow
tileY = letterIx `div` tilesPerRow
tileRect = toCIntV2 $ V2 tileWidth tileHeight
src = SDL.Rectangle (SDL.P . toCIntV2 $ V2 (tileX * tileWidth) (tileY * tileHeight)) tileRect
dest = SDL.Rectangle (SDL.P . toCIntV2 $ V2 (c * tileWidth) (r * tileHeight)) tileRect
SDL.textureColorMod tiles $= clr
SDL.copy renderer tiles (Just src) (Just dest)
toCIntV2 :: V2 Int -> V2 CInt
toCIntV2 (V2 x y) = V2 (CInt $ fromIntegral x) (CInt $ fromIntegral y)
cabal-version: 2.2
name: perlinTerrainSdl2
version: 0.1.0.0
-- synopsis:
-- description:
homepage: https://github.com/andrevdm
license: BSD-3-Clause OR Apache-2.0
author: Andre Van Der Merwe
maintainer: andre@andrevdm.com
copyright: 2020 Andre Van Der Merwe
category: Web
build-type: Simple
executable sdl2Tiles01-exe
hs-source-dirs: .
main-is: Main.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wimplicit-prelude -Wcompat -Wredundant-constraints -Wnoncanonical-monad-instances -Widentities -fhide-source-paths -Wmissing-export-lists -Wpartial-fields -fhide-source-paths -freverse-errors
build-depends: base
, protolude
, text
, containers
, hsnoise
, linear
, sdl2
default-language: Haskell2010
source-repository head
type: git
location: https://github.com/andrevdm
import Distribution.Simple
main = defaultMain
resolver: lts-15.7
packages:
- .
extra-deps:
- hsnoise-0.0.2@sha256:ebde231014d8c1f4c44e9760742824af87645cdff1f223c2efe16d79bc418587,1306
@andrevdm
Copy link
Author

Very basic haskell perlin noise for 2d terrain generation example.
Displayed using SDL2 and a bmp ascii tileset (from http://bjh21.me.uk/bedstead/)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment