Repository: Vladar4/nimgame2 Branch: master Commit: afd289aefd84 Files: 195 Total size: 2.8 MB Directory structure: gitextract_oovdsi4y/ ├── LICENSE ├── README.md ├── STYLE.md ├── demos/ │ ├── README.md │ ├── assets/ │ │ ├── csv/ │ │ │ ├── atlas.csv │ │ │ ├── map0.csv │ │ │ └── map_camera_test.csv │ │ └── mus/ │ │ ├── absolu.mod │ │ ├── biotech.xm │ │ ├── cancan.mod │ │ └── cornered!.xm │ ├── demo1/ │ │ ├── README.md │ │ ├── demo1.nim │ │ ├── mainscene.nim │ │ └── spaceman.nim │ ├── demo10/ │ │ ├── README.md │ │ ├── demo10.nim │ │ ├── earth.nim │ │ ├── mainscene.nim │ │ └── spaceman.nim │ ├── demo11/ │ │ ├── README.md │ │ ├── demo11.nim │ │ ├── earth.nim │ │ └── mainscene.nim │ ├── demo12/ │ │ ├── README.md │ │ ├── demo12.nim │ │ └── mainscene.nim │ ├── demo13/ │ │ ├── README.md │ │ ├── cursor.nim │ │ ├── demo13.nim │ │ └── mainscene.nim │ ├── demo14/ │ │ ├── README.md │ │ ├── demo14.nim │ │ ├── dwarf.nim │ │ └── mainscene.nim │ ├── demo15/ │ │ ├── README.md │ │ ├── demo15.nim │ │ └── mainscene.nim │ ├── demo16/ │ │ ├── README.md │ │ ├── demo16.nim │ │ └── mainscene.nim │ ├── demo17/ │ │ ├── README.md │ │ ├── btnCircle.nim │ │ ├── btnSquare.nim │ │ ├── demo17.nim │ │ └── mainscene.nim │ ├── demo18/ │ │ ├── README.md │ │ ├── demo18.nim │ │ └── mainscene.nim │ ├── demo19/ │ │ ├── README.md │ │ ├── demo19.nim │ │ └── mainscene.nim │ ├── demo2/ │ │ ├── README.md │ │ ├── demo2.nim │ │ ├── earth.nim │ │ ├── mainscene.nim │ │ └── spaceman.nim │ ├── demo20/ │ │ ├── README.md │ │ ├── demo20.nim │ │ └── mainscene.nim │ ├── demo21/ │ │ ├── README.md │ │ ├── demo21.nim │ │ ├── joypoint.nim │ │ └── mainscene.nim │ ├── demo22/ │ │ ├── README.md │ │ ├── demo22.nim │ │ ├── mainscene.nim │ │ └── video.mpg │ ├── demo23/ │ │ ├── README.md │ │ ├── demo23.nim │ │ ├── mainscene.nim │ │ └── private/ │ │ ├── border_fill_graphic.nim │ │ ├── circle_graphic.nim │ │ └── frame.nim │ ├── demo3/ │ │ ├── README.md │ │ ├── demo3.nim │ │ ├── mainscene.nim │ │ └── spaceman.nim │ ├── demo4/ │ │ ├── README.md │ │ ├── demo4.nim │ │ ├── dwarf.nim │ │ └── mainscene.nim │ ├── demo5/ │ │ ├── README.md │ │ ├── cursor.nim │ │ ├── demo5.nim │ │ ├── earth.nim │ │ ├── line.nim │ │ ├── mainscene.nim │ │ ├── poly1.nim │ │ ├── poly2.nim │ │ ├── poly3.nim │ │ ├── poly9.nim │ │ └── spaceman.nim │ ├── demo6/ │ │ ├── README.md │ │ ├── demo6.nim │ │ ├── earth.nim │ │ ├── mainscene.nim │ │ └── spaceman.nim │ ├── demo7/ │ │ ├── README.md │ │ ├── demo7.nim │ │ ├── earth.nim │ │ └── mainscene.nim │ ├── demo8/ │ │ ├── README.md │ │ ├── demo8.nim │ │ └── mainscene.nim │ ├── demo9/ │ │ ├── README.md │ │ ├── demo9.nim │ │ └── mainscene.nim │ └── nim.cfg ├── docs/ │ ├── changelog.html │ ├── demos.html │ ├── docs/ │ │ ├── assets.html │ │ ├── audio.html │ │ ├── bitmapfont.html │ │ ├── count.html │ │ ├── draw.html │ │ ├── emitter.html │ │ ├── entity.html │ │ ├── font.html │ │ ├── graphic.html │ │ ├── gui/ │ │ │ ├── button.html │ │ │ ├── progressbar.html │ │ │ ├── radio.html │ │ │ ├── textinput.html │ │ │ └── widget.html │ │ ├── indexedimage.html │ │ ├── input.html │ │ ├── mosaic.html │ │ ├── nimgame.html │ │ ├── perspectiveimage.html │ │ ├── plugin/ │ │ │ ├── mpeggraphic.html │ │ │ ├── tar.html │ │ │ └── zzip.html │ │ ├── private/ │ │ │ └── collider.html │ │ ├── procgraphic.html │ │ ├── scene.html │ │ ├── settings.html │ │ ├── textfield.html │ │ ├── textgraphic.html │ │ ├── textureatlas.html │ │ ├── texturegraphic.html │ │ ├── tilemap.html │ │ ├── truetypefont.html │ │ ├── tween.html │ │ ├── types.html │ │ ├── typewriter.html │ │ └── utils.html │ ├── docs.html │ ├── index.html │ ├── links.html │ ├── snippets.html │ ├── structure.js │ ├── style.css │ ├── template.html │ ├── template_tutorial.html │ ├── tut101_bounce.html │ ├── tut102_platformer.html │ └── tutorials.html ├── nimgame2/ │ ├── assets.nim │ ├── audio.nim │ ├── bitmapfont.nim │ ├── draw.nim │ ├── emitter.nim │ ├── entity.nim │ ├── font.nim │ ├── graphic.nim │ ├── gui/ │ │ ├── button.nim │ │ ├── progressbar.nim │ │ ├── radio.nim │ │ ├── textinput.nim │ │ └── widget.nim │ ├── indexedimage.nim │ ├── input.nim │ ├── mosaic.nim │ ├── nimgame.nim │ ├── perspectiveimage.nim │ ├── plugin/ │ │ ├── mpeggraphic.nim │ │ ├── tar.nim │ │ └── zzip.nim │ ├── private/ │ │ └── collider.nim │ ├── procgraphic.nim │ ├── scene.nim │ ├── settings.nim │ ├── textfield.nim │ ├── textgraphic.nim │ ├── textureatlas.nim │ ├── texturegraphic.nim │ ├── tilemap.nim │ ├── truetypefont.nim │ ├── tween.nim │ ├── types.nim │ ├── typewriter.nim │ └── utils.nim ├── nimgame2.nim └── nimgame2.nimble ================================================ FILE CONTENTS ================================================ ================================================ FILE: LICENSE ================================================ # nimgame2 # Copyright (c) 2016-2020 Vladimir Arabadzhi (Vladar) # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # # vladar4@gmail.com # https://github.com/Vladar4 ================================================ FILE: README.md ================================================ Nimgame 2 ========= A simple 2D game engine for Nim language. For more information check [home page](https://vladar4.github.io/nimgame2/). [Coding style guide](STYLE.md) for the contributors. All pull requests should be done into the **devel** branch. Status: v0.6.2 alpha -------------------- Requires: --------- * [sdl2_nim](https://github.com/Vladar4/sdl2_nim) package (v2.0.14.2 or newer). * Runtime libraries for: * SDL 2.0.12 or newer * SDL_gfx 1.0.1 * SDL_image 2.0.2 * SDL_mixer 2.0.2 * SDL_ttf 2.0.14 (see [SDL2 links](https://github.com/Vladar4/sdl2_nim/blob/master/LINKS.md)) Optional dependencies: ---------------------- * For plugin/mpeggraphic * mpg123 runtime library (dll is distributed within SDL_) * For plugin/tar: * [zip](https://github.com/nim-lang/zip) * zlib runtime library (dll is distributed within SDL2_image builds) * For plugin/zzip: * [zip](https://github.com/nim-lang/zip) * zlib runtime library (dll is distributed within SDL2_image builds) * zzip runtime library Installation through [Nimble](https://github.com/nim-lang/nimble): ------------------------------------------------------------------ * stable version: `nimble install nimgame2@#head` * development version: `nimble install nimgame2@#devel` Recommended compilation flags: ------------------------------ `--multimethods:on -d:release --opt:speed` Links: ------ * [home page](https://vladar4.github.io/nimgame2/) * [demos](demos) * [tutorials](https://vladar4.github.io/nimgame2/tutorials) * [documentation](https://vladar4.github.io/nimgame2/docs.html) * [ng2planetoids](https://github.com/Vladar4/ng2planetoids) - first demo game. * [ng2gggrotto](https://github.com/Vladar4/ng2gggrotto) - Linux Game Jam 2017 entry. Changelog: ---------- ### v0.6.2 alpha (2021-08-20) * Maintenance release to keep up with the current versions of Nim and sdl2_nim until v0.7 is ready ### v0.6.1 alpha (2019-06-15) * Nim v0.20.0 transition ### v0.6 alpha (2019-01-21) * new modules: typewriter * new plugins: mpeggraphic (+demo22), tar, zzip * new utils procedures: textureFormat, textureFormats, toSeq, neg, new rand procedures * color constants * audio: playing template * emitter: emission areas, procedure argument for emit * entity: animation callback, blinking, scale parameters, dim template (by [CodeDoes](https://github.com/CodeDoes)) * input: mouse wheel events (by [CodeDoes](https://github.com/CodeDoes)) * icon surface init option * RW loading procedures * simplified time counters * demo23 (transform) (by [CodeDoes](https://github.com/CodeDoes)) * various minor changes and upgrades, code refactoring * Nim v0.19.0 transition ### v0.5 alpha (2017-08-01) * changed physics and logic systems * platformer physics * CoordInt type * now collider module is autmatically included into the entity module * group collider * huge Tilemap optimizations * various utility Tilemap procedures * TextureGraphic.drawTiled * GUI: * GUIProgressBar * widget actions * various minor changes and upgrades * Nim v0.17.0 transition * documentation, snippets, and demos update * [second tutorial](https://vladar4.github.io/nimgame2/tut102_platformer.html) ### v0.4 alpha (2017-05-04) * GUI: * RadioGroup * RadioButton * IndexedImage * PerspectiveImage * TextureAtlas * joysticks support * window management procedures * 4 new demos * [first tutorial](https://vladar4.github.io/nimgame2/tut101_bounce.html) ### v0.3 alpha (2017-03-10) * camera property (Scene) * new collision procedures * reworked input * Mosaic * parallax property (Entity) * TextField * GUI: * Widget * Button * TextInput * 3 new demos * home page, snippets, and documentation ### v0.2 alpha (2017-01-31) * collider optimizations * music playlists * random procedures * tilemaps * tweens * emitters * various fixes * 4 new demos ### v0.1 alpha (2017-01-16) * base scene/entity system * assets manager * basic sound and music * colliders (point, box, circle, line, and polygon) * fonts (bitmap and TrueType) and text output * keyboard and mouse input * vector drawing procedures ================================================ FILE: STYLE.md ================================================ Nimgame 2 code formatting style =============================== In general, follow [NEP1](https://nim-lang.org/docs/nep1.html) if it doesn't contradict this document. Line Spacing ------------ * two empty lines before and one empty line after the header-comment; * two empty lines between blocks (such as `const`, `type`, `proc`, etc.); * one empty line to separate segments inside these blocks if needed; * one empty line at the end of files. Comments -------- * if there is more than one type declared in one module, their procedures should be separated with header-comments: ``` #==========# # SomeType # #==========# ``` * documentation comments are always offset by one indentation level inside their procedures, have two spaces before their text, and one empty comment line to separate it from the code below. ``` proc someProc() = ## Documentation comment. ## var someVar ... ``` Naming ------ * types and constants in PascalCase; * all other identifiers in camelCase; * if an object is a first argument of a procedure, generally it should be named after its type, e.g.: ``` proc foo(bar: Bar, val: int): int = ``` Objects ------- * private and public fields should be separated with comments if possible; * `ref object` types should have the following initialization scheme: ``` type SomeType = ref object of SomeParent someValue*: int proc initSomeType*(someType: SomeType) = someType.initSomeParent() # don't forget the parent initialization SomeType.someValue = 0 ... proc newSomeType*(): SomeType = result = new SomeType result.initSomeType() ``` * types that are inherited from the `Entity` type should follow the following update scheme: ``` type SomeEntity = ref object of Entity proc updateSomeEntity*(someEntity: SomeEntiy, elapsed: float) = someEntity.updateEntity(elapsed) # don't forget the parent update ... method update*(someEntity: SomeEntiy, elapsed: float) = updateSomeEntity(someEntity, elapsed) ``` Code ---- * don't forget proper spaces between elements; * procedural arguments are separated by commas, e.g.: ``` proc someProc(arg1: int, arg2, arg3: float): float = ``` * if there are a lot of arguments, they could be brought to a new line and indented by two levels for the sake of readability, e.g.: ``` proc someLongAndComplexProcedure( arg1, arg2, arg3, arg4: int arg5, arg6, arg7, arg8: float) = ## Documentation ## ... ``` Example ------- ``` # Header type SomeType1 = object # Private fHidden: int # Public value*: int SomeType2 = object a, b*: float const SomeConst1 = 42 proc someProc*(arg1: int): int = ... #===========# # SomeType1 # #===========# proc someProc1*(someType1: SomeType1, a, b: int) = ... #===========# # SomeType2 # #===========# ... ``` ================================================ FILE: demos/README.md ================================================ Nimgame 2 Demos =============== * [demo1](demo1) Performance * [demo2](demo2) Graphic * [demo3](demo3) Input * [demo4](demo4) Sprite * [demo5](demo5) Colliders * [demo6](demo6) Grouping * [demo7](demo7) Text * [demo8](demo8) ProcGraphic * [demo9](demo9) Audio * [demo10](demo10) Layers * [demo11](demo11) Tweens * [demo12](demo12) Emitters * [demo13](demo13) TileMaps * [demo14](demo14) TileMaps, Tweens, Emitters * [demo15](demo15) Camera * [demo16](demo16) Parallax * [demo17](demo17) GUI (Button, TextField) * [demo18](demo18) IndexedImage * [demo19](demo19) PerspectiveImage * [demo20](demo20) TextureAtlas * [demo21](demo21) Joysticks * [demo22](demo22) MpegGraphic * [demo23](demo23) Transform ================================================ FILE: demos/assets/csv/atlas.csv ================================================ spaceman, 12, 33, 42, 66 gradient, 65, 9, 16, 90 button, 82, 26, 48, 72 sprite, 132, 0, 68, 100 ================================================ FILE: demos/assets/csv/map0.csv ================================================ 0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 3,3,3,1,1,1,3,1,1,1,1,1,3,1,1,1,1,1,1,1,1,3,1,1,1,3 3,1,1,1,1,1,1,1,1,1,3,1,1,1,3,3,3,3,1,1,1,3,1,2,1,3 3,1,3,1,1,1,3,3,1,3,3,3,3,3,3,1,1,3,1,3,3,3,1,1,1,3 3,1,3,3,1,3,3,1,1,1,1,1,1,1,1,1,1,3,1,3,0,3,3,1,3,3 3,1,3,1,1,1,3,3,3,3,3,1,1,3,3,1,1,3,1,3,0,0,3,1,3,0 3,1,1,1,1,1,1,1,1,1,3,3,1,3,3,3,1,3,1,3,3,3,3,1,3,0 3,3,3,1,1,1,3,1,1,1,3,1,1,1,3,3,1,1,1,3,1,1,1,1,3,0 0,0,3,3,1,3,3,1,1,1,3,1,1,1,3,3,3,3,3,3,3,3,3,1,3,0 3,3,3,1,1,1,3,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,3,1,3,0 3,1,1,1,1,1,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,1,1,1,3,0 3,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3 3,1,3,3,3,3,3,3,3,1,3,3,3,3,3,3,1,3,1,1,1,1,1,1,1,3 3,1,1,1,1,1,1,1,3,1,3,3,1,1,1,3,1,3,1,3,3,3,3,3,1,3 3,3,3,1,3,1,1,1,3,1,3,3,1,1,1,3,1,3,1,3,1,1,1,3,1,3 0,0,3,1,3,1,3,3,3,1,3,3,1,1,1,1,1,3,1,3,1,1,1,1,1,3 3,3,3,3,3,1,3,3,1,1,1,3,3,3,3,3,1,3,1,3,1,1,1,3,1,3 3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,3,3,3,3,1,3 3,1,1,3,3,3,3,3,1,1,1,3,3,3,3,3,3,3,1,1,1,1,1,1,1,3 3,3,3,3,0,0,0,3,3,3,3,3,0,0,0,0,0,3,3,3,3,3,3,3,3,3 ================================================ FILE: demos/assets/csv/map_camera_test.csv ================================================ 1,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,1 3,2,3,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,3,2,3 1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1 1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1 3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3 3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3 1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3 3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1 3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3 3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3 1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3 3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1 3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3 3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3 1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3 3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1 3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3 3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3 1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3 3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1 3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3 3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3 1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3 3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1 3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3 3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3,1,3,1,1,3,1,3,3 1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1,1,3,3,3,3,1,1,1 1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1 3,2,3,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,3,2,3 1,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,1 ================================================ FILE: demos/demo1/README.md ================================================ Nimgame 2: Demo 1 ================= Performance demo. ![Screenshot](demo1.png) ================================================ FILE: demos/demo1/demo1.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 1 (Performance)"): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo1/mainscene.nim ================================================ import nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/texturegraphic, nimgame2/scene, nimgame2/settings, nimgame2/types, spaceman const NumMin = 100 NumMax = 50_000 NumStep = 100 NumStart = 500 type MainScene = ref object of Scene spacemanG: TextureGraphic num: int proc spacemanPhysics*(entity: Entity, elapsed: float) = defaultPhysics(entity, elapsed) # Screen collision if entity.pos.x < 0: entity.vel.x *= -1 if entity.pos.y < 0: entity.vel.y *= -1 if entity.pos.x >= game.size.w.float: entity.vel.x *= -1 if entity.pos.y >= game.size.h.float: entity.vel.y *= -1 proc init*(scene: MainScene) = Scene(scene).init() scene.spacemanG = newTextureGraphic() discard scene.spacemanG.load("../assets/gfx/spaceman.png") scene.num = NumStart for i in 1..scene.num: scene.add(newSpaceman(scene, scene.spacemanG, spacemanPhysics)) proc free*(scene: MainScene) = scene.spacemanG.free proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false of K_Up: if scene.num < NumMax: scene.num += NumStep for i in scene.count..scene.num-1: scene.add(newSpaceman(scene, scene.spacemanG, spacemanPhysics)) of K_Down: if scene.num > NumMin: scene.num -= NumStep for i in scene.num..(scene.count - 1): discard scene.pop() else: discard method render*(scene: MainScene) = scene.renderScene() discard box((4, 60), (260, 84), 0x000000CC'u32) discard string( (8, 64), "Arrow Up - more entities", 0xFF0000FF'u32) discard string( (8, 72), "Arrow Down - less entities", 0xFF0000FF'u32) method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) ================================================ FILE: demos/demo1/spaceman.nim ================================================ import nimgame2/nimgame, nimgame2/entity, nimgame2/graphic, nimgame2/scene, nimgame2/types, nimgame2/utils type Spaceman* = ref object of Entity scene*: Scene proc init*(entity: Spaceman, s: Scene, g: Graphic, p: PhysicsProc) = entity.initEntity() entity.scene = s entity.graphic = g entity.physics = p entity.pos.x = rand(game.size.w).float entity.pos.y = rand(game.size.h).float entity.vel.x = rand(10.0..100.0) * randSign().float entity.vel.y = rand(10.0..100.0) * randSign().float entity.centrify() entity.rot = rand(360.0) entity.rotVel = rand(10.0..60.0) * randSign().float proc newSpaceman*(s: Scene, g: Graphic, p: PhysicsProc): Spaceman = result = new Spaceman result.init(s, g, p) ================================================ FILE: demos/demo10/README.md ================================================ Nimgame 2: Demo 10 ================== Layers demo. Demonstrates entity layering. ![Screenshot](demo10.png) ================================================ FILE: demos/demo10/demo10.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 10 (Layers)"): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo10/earth.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Earth* = ref object of Entity proc init*(entity: Earth) = entity.initEntity() entity.pos.x = 128.0 entity.pos.y = 96.0 proc newEarth*(): Earth = result = new Earth result.init() ================================================ FILE: demos/demo10/mainscene.nim ================================================ import math, nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/texturegraphic, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types, earth, spaceman type MainScene = ref object of Scene earthG, spacemanG: TextureGraphic e: Earth s: Spaceman proc init*(scene: MainScene) = Scene(scene).init() # Earth scene.e = newEarth() scene.earthG = newTextureGraphic() discard scene.earthG.load("../assets/gfx/earth.png") scene.e.graphic = scene.earthG # Spaceman scene.s = newSpaceman() scene.spacemanG = newTextureGraphic() discard scene.spacemanG.load("../assets/gfx/spaceman.png") scene.s.graphic = scene.spacemanG # add to scene scene.add(scene.s) scene.add(scene.e) proc free*(scene: MainScene) = scene.earthG.free scene.spacemanG.free proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false else: discard method render*(scene: MainScene) = scene.renderScene() discard box((4, 60), (220, 76), 0x000000CC'u32) discard string( (8, 64), "1/2 - Change layer", 0xFF0000FF'u32) method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) if Scancode1.down: scene.s.layer = -1 if Scancode2.down: scene.s.layer = 1 ================================================ FILE: demos/demo10/spaceman.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Spaceman* = ref object of Entity proc init*(entity: Spaceman) = entity.initEntity() entity.pos.x = 200.0 entity.pos.y = 64.0 proc newSpaceman*(): Spaceman = result = new Spaceman result.init() ================================================ FILE: demos/demo11/README.md ================================================ Nimgame 2: Demo 11 ================== Tweens demo. Demonstrates tweening procedures. ![Screenshot](demo11.png) ================================================ FILE: demos/demo11/demo11.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 1280, h = 720, title = "Nimgame 2: Demo 11 (Tweens)"): #showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo11/earth.nim ================================================ import nimgame2/nimgame, nimgame2/entity, nimgame2/types type Earth* = ref object of Entity proc init*(entity: Earth, pos: Coord) = entity.initEntity() entity.pos = pos proc newEarth*(pos: Coord): Earth = result = new Earth result.init(pos) ================================================ FILE: demos/demo11/mainscene.nim ================================================ import nimgame2/nimgame, nimgame2/bitmapfont, nimgame2/draw, nimgame2/entity, nimgame2/textgraphic, nimgame2/texturegraphic, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/tween, nimgame2/types, earth type MainScene = ref object of Scene earthG: TextureGraphic font: BitmapFont tweens: seq[Tween[Entity,Coord]] proc addEntity*(scene: MainScene, name: string, pos: Coord, procedure: TweenProcedure[Coord]) = # Name let n = newTextGraphic() n.font = scene.font n.lines = [name] let ne = newEntity() ne.graphic = n ne.pos = pos - (98.0, 8.0) scene.add(ne) # Entity let e = newEarth(pos) e.graphic = scene.earthG e.centrify() scene.add(e) # Tween let t = newTween[Entity,Coord]( e, proc(t: Entity): Coord = t.pos, proc(t: Entity, val: Coord) = t.pos = val) t.procedure = procedure scene.tweens.add(t) t.setup(e.pos, e.pos + (150.0, 0.0), 3.0, -1) t.play() proc init*(scene: MainScene) = Scene(scene).init() scene.tweens = @[] # Earth graphic scene.earthG = newTextureGraphic() discard scene.earthG.load("../assets/gfx/earth32.png") # Font scene.font = newBitmapFont() discard scene.font.load("../assets/fnt/default8x16.png", (8, 16)) # Column 1 scene.addEntity("linear", (100.0, 35.0), linear) scene.addEntity("inQuad", (100.0, 85.0), inQuad) scene.addEntity("outQuad", (100.0, 135.0), outQuad) scene.addEntity("inOutQuad", (100.0, 185.0), inOutQuad) scene.addEntity("inCubic", (100.0, 285.0), inCubic) scene.addEntity("outCubic", (100.0, 335.0), outCubic) scene.addEntity("inOutCubic", (100.0, 385.0), inOutCubic) scene.addEntity("outInCubic", (100.0, 435.0), outInCubic) scene.addEntity("inQuart", (100.0, 535.0), inQuart) scene.addEntity("outQuart", (100.0, 585.0), outQuart) scene.addEntity("inOutQuart", (100.0, 635.0), inOutQuart) scene.addEntity("outInQuart", (100.0, 685.0), outInQuart) # Column 2 scene.addEntity("inQuint", (400.0, 35.0), inQuint) scene.addEntity("outQuint", (400.0, 85.0), outQuint) scene.addEntity("inOutQuint", (400.0, 135.0), inOutQuint) scene.addEntity("outInQuint", (400.0, 185.0), outInQuint) scene.addEntity("inSine", (400.0, 285.0), inSine) scene.addEntity("outSine", (400.0, 335.0), outSine) scene.addEntity("inOutSine", (400.0, 385.0), inOutSine) scene.addEntity("outInSine", (400.0, 435.0), outInSine) # Column 3 scene.addEntity("inExpo", (700.0, 35.0), inExpo) scene.addEntity("outExpo", (700.0, 85.0), outExpo) scene.addEntity("inOutExpo", (700.0, 135.0), inOutExpo) scene.addEntity("outInExpo", (700.0, 185.0), outInExpo) scene.addEntity("inCirc", (700.0, 285.0), inCirc) scene.addEntity("outCirc", (700.0, 335.0), outCirc) scene.addEntity("inOutCirc", (700.0, 385.0), inOutCirc) scene.addEntity("outInCirc", (700.0, 435.0), outInCirc) # Column 4 scene.addEntity("inBounce", (1000.0, 35.0), inBounce) scene.addEntity("outBounce", (1000.0, 85.0), outBounce) scene.addEntity("inOutBounce", (1000.0, 135.0), inOutBounce) scene.addEntity("outInBounce", (1000.0, 185.0), outInBounce) scene.addEntity("inElastic", (1000.0, 285.0), inElastic) scene.addEntity("outElastic", (1000.0, 335.0), outElastic) scene.addEntity("inOutElastic", (1000.0, 385.0), inOutElastic) scene.addEntity("outInElastic", (1000.0, 435.0), outInElastic) scene.addEntity("inBack", (1000.0, 535.0), inBack) scene.addEntity("outBack", (1000.0, 585.0), outBack) scene.addEntity("inOutBack", (1000.0, 635.0), inOutBack) scene.addEntity("outInBack", (1000.0, 685.0), outInBack) proc free*(scene: MainScene) = scene.earthG.free proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false else: discard method render*(scene: MainScene) = scene.renderScene() method update*(scene: MainScene, elapsed: float) = for tween in scene.tweens: tween.update(elapsed) scene.updateScene(elapsed) ================================================ FILE: demos/demo12/README.md ================================================ Nimgame 2: Demo 12 ================== Emitter demo. Demonstrates particle emitter usage. ![Screenshot](demo12.png) ================================================ FILE: demos/demo12/demo12.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 12 (Emitter)"): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo12/mainscene.nim ================================================ import nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/emitter, nimgame2/texturegraphic, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types type MainScene = ref object of Scene particleG: TextureGraphic ePoint, eLine, eCircle, eBox, eScaled: Emitter proc init*(scene: MainScene) = Scene(scene).init() # Particle Graphic scene.particleG = newTextureGraphic() discard scene.particleG.load("../assets/gfx/puff.png") # Particle var particle: Particle particle = newParticle() particle.graphic = scene.particleG particle.initSprite((5, 5)) particle.centrify() discard particle.addAnimation("play", toSeq(0..4), 1/5) particle.play("play", 1, kill = true) # Point emitter scene.ePoint = newEmitter(scene) scene.ePoint.randomVel = (10.0, 10.0) scene.ePoint.randomAcc = (5.0, 5.0) scene.ePoint.randomTTL = 5.0 scene.ePoint.particle = particle scene.add(scene.ePoint) # Line emitter scene.eLine = newEmitter(scene, eaLine) scene.eLine.area.length = 100.0 scene.eLine.randomVel = (10.0, 10.0) scene.eLine.randomAcc = (5.0, 5.0) scene.eLine.randomTTL = 5.0 scene.eLine.particle = particle scene.eLine.pos = game.size / 2 scene.add(scene.eLine) # Circle emitter scene.eCircle = newEmitter(scene, eaCircle) scene.eCircle.area.radius = 100.0 scene.eCircle.randomVel = (10.0, 10.0) scene.eCircle.randomAcc = (5.0, 5.0) scene.eCircle.randomTTL = 5.0 scene.eCircle.particle = particle scene.eCircle.pos = game.size / 4 scene.add(scene.eCircle) # Box emitter scene.eBox = newEmitter(scene, eaBox) scene.eBox.area.dim = (100.0, 50.0) scene.eBox.rotVel = -90.0 scene.eBox.randomVel = (10.0, 10.0) scene.eBox.randomAcc = (5.0, 5.0) scene.eBox.randomTTL = 5.0 scene.eBox.particle = particle scene.eBox.pos = game.size / 2 + game.size / 4 scene.add(scene.eBox) # Scaling particles var particleScaled: Particle particleScaled = newParticle() particleScaled.graphic = scene.particleG particleScaled.initSprite((5, 5)) particleScaled.centrify() discard particleScaled.addAnimation("play", toSeq(0..4), 1/2) particleScaled.play("play", 1, kill = true) particleScaled.scale = 0.5 particleScaled.scaleVel = 1.0 scene.eScaled = newEmitter(scene) scene.eScaled.randomVel = (50.0, 50.0) scene.eScaled.randomAcc = (5.0, 5.0) scene.eScaled.randomTTL = 5.0 scene.eScaled.particle = particleScaled scene.eScaled.pos = (game.size.w div 2 + game.size.w div 4, game.size.h div 4) scene.add(scene.eScaled) proc free*(scene: MainScene) = scene.particleG.free() proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false else: discard method render*(scene: MainScene) = # Draw line between the spaceman and the mouse position if LMB is pressed scene.renderScene() method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) # Point emitter scene.ePoint.pos = mouse.abs if MouseButton.left.down: scene.ePoint.emit(5) # Line emitter scene.eLine.rot += 90 * elapsed scene.eLine.emit(5) # Circle emitter scene.eCircle.area.radius = if MouseButton.left.down: 50.0 else: 100.0 scene.eCircle.emit(scene.eCircle.area.radius.int div 20) # Box emitter scene.eBox.rot += scene.eBox.rotVel * elapsed scene.eBox.emit(5) # Scaled emitter scene.eScaled.emit(5) ================================================ FILE: demos/demo13/README.md ================================================ Nimgame 2: Demo 13 ================== TileMap demo. Demonstrates tile maps usage. Note ---- For the performance purposes TileCollider is based on BoxCollider. It means, that usually you shouldn't initialize collider on a TileMap that will be rotated. ![Screenshot](demo13.png) ================================================ FILE: demos/demo13/cursor.nim ================================================ import nimgame2/nimgame, nimgame2/entity, nimgame2/input, nimgame2/tilemap type Cursor* = ref object of Entity collidedWith*: seq[string] proc init*(entity: Cursor) = entity.initEntity() entity.tags.add("Cursor") entity.pos = mouse.abs entity.collidedWith = @[] proc newCursor*(): Cursor = result = new Cursor result.init() method update*(entity: Cursor, elapsed: float) = entity.updateEntity(elapsed) entity.collidedWith = @[] entity.pos = mouse.abs method onCollide*(entity: Cursor, target: Entity) = if target.tags.len > 0: if "map" in target.tags: let collider = TilemapCollider(target.collider) let clist = collider.collisionList(entity.pos) for tile in clist: entity.collidedWith.add( "[" & $tile.index.x & ":" & $tile.index.y & "] -> " & $tile.value) ================================================ FILE: demos/demo13/demo13.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 13 (TileMap)"): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo13/mainscene.nim ================================================ import nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/texturegraphic, nimgame2/tilemap, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types, cursor type MainScene = ref object of Scene tilesG: TextureGraphic tm: TileMap cursor: Cursor proc init*(scene: MainScene) = Scene(scene).init() # Cursor hideCursor() scene.cursor = newCursor() let cursorG = newTextureGraphic() discard cursorG.load("../assets/gfx/cursor.png") scene.cursor.graphic = cursorG scene.cursor.collider = newCollider(scene.cursor) scene.add(scene.cursor) # Tiles Graphic scene.tilesG = newTextureGraphic() discard scene.tilesG.load("../assets/gfx/sprite0.png") # TileMap scene.tm = newTileMap(scaleFix = true) scene.tm.tags.add("map") scene.tm.graphic = scene.tilesG scene.tm.initSprite((64, 64), offset = (32, 32)) scene.tm.map = @[ @[0, 0, 0, 0], @[1, 0, 0, 1], @[2, 3, 3, 2] ] scene.tm.passable.add(0) scene.tm.centrify() scene.tm.initCollider() scene.tm.pos = (320.0, 240.0) scene.add(scene.tm) proc free*(scene: MainScene) = scene.tilesG.free() proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false of K_Space: colliderOutline = not colliderOutline else: discard method render*(scene: MainScene) = scene.renderScene() discard box((4, 60), (300, 108), 0x000000CC'u32) discard string((8, 64), "WSAD or Arrows - move", 0xFFFFFFFF'u32) discard string((8, 72), "Q/E - change angle", 0xFFFFFFFF'u32) discard string((8, 80), "R/F - change scale", 0xFFFFFFFF'u32) discard string((8, 88), "Space - toggle collider outlines", 0xFFFFFFFF'u32) var collides: string = "" for collision in scene.cursor.collidedWith: collides &= collision & " " discard string((8, 96), if scene.cursor.collidedWith.len > 0: "Cursor collides with: " & collides else: "Cursor isn't over a collidable tile", 0xFFFFFFFF'u32) method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) if ScancodeW.down or ScancodeUp.down: scene.tm.pos.y -= 100 * elapsed if ScancodeS.down or ScancodeDown.down: scene.tm.pos.y += 100 * elapsed if ScancodeA.down or ScancodeLeft.down: scene.tm.pos.x -= 100 * elapsed if ScancodeD.down or ScancodeRight.down: scene.tm.pos.x += 100 * elapsed if ScancodeQ.down: scene.tm.rot -= 100 * elapsed if ScancodeE.down: scene.tm.rot += 100 * elapsed if ScancodeR.down: scene.tm.scale -= 0.5 * elapsed if ScancodeF.down: scene.tm.scale += 0.5 * elapsed ================================================ FILE: demos/demo14/README.md ================================================ Nimgame 2: Demo 14 ================== Second TileMap demo. Demonstrates practical TileMap usage, along with Tween an Emitter usage. F10 - Show/Hide info panel. ![Screenshot](demo14.png) ================================================ FILE: demos/demo14/demo14.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 14 (TileMap 2)"): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo14/dwarf.nim ================================================ import nimgame2/nimgame, nimgame2/entity, nimgame2/texturegraphic, nimgame2/tilemap, nimgame2/tween, nimgame2/types const Framerate = 1/12 ScreenOffset*: Coord = (8.0, 0.0) Step* = 24.0 type Direction* = enum dNone, dDown, dUp, dLeft, dRight Dwarf* = ref object of Entity tween*: Tween[Dwarf,Coord] virtualPos*: tuple[x: int, y: int] map*: TileMap proc init*(entity: Dwarf, graphic: TextureGraphic, map: TileMap) = entity.initEntity() entity.tags.add("dwarf") entity.graphic = graphic entity.initSprite((24, 48)) discard entity.addAnimation( "down", [0, 1, 2, 3, 4, 5], Framerate) discard entity.addAnimation( "up", [6, 7, 8, 9, 10, 11], Framerate) discard entity.addAnimation( "left", [12, 13, 14, 15, 16, 17], Framerate) discard entity.addAnimation( "right", [12, 13, 14, 15, 16, 17], Framerate, Flip.horizontal) entity.pos = (44.0, 444.0) entity.virtualPos = (1, 18) entity.center = (12.0, 36.0) entity.map = map entity.map.show = ( x: (entity.virtualPos.x - 2)..(entity.virtualPos.x + 2), y: (entity.virtualPos.y - 2)..(entity.virtualPos.y + 2) ) proc newDwarf*(graphic: TextureGraphic, map: TileMap): Dwarf = result = new Dwarf result.init(graphic, map) proc actuate(entity: Dwarf, anim: string, movement: Coord) = if entity.tween == nil or not entity.tween.playing: let newPos = entity.pos + movement newVirtualPos: tuple[x: int, y: int] = (int(newPos.x - ScreenOffset.x) div Step.int, int(newPos.y - ScreenOffset.y) div Step.int) if entity.map.map[newVirtualPos.y][newVirtualPos.x] > 2: return # unpassable entity.play(anim, 1) entity.tween = newTween[Dwarf,Coord]( entity, proc(t: Dwarf): Coord = t.pos, proc(t: Dwarf, val: Coord) = t.pos = val) entity.tween.setup(entity.pos, newPos, 0.5, 0) entity.virtualPos = newVirtualPos entity.tween.play() entity.map.show = ( x: (newVirtualPos.x - 2)..(newVirtualPos.x + 2), y: (newVirtualPos.y - 2)..(newVirtualPos.y + 2) ) proc move*(entity: Dwarf, direction: Direction) = case direction: of dDown: entity.actuate("down", (0.0, Step)) of dUp: entity.actuate("up", (0.0, -Step)) of dRight: entity.actuate("right", (Step, 0.0)) of dLeft: entity.actuate("left", (-Step, 0.0)) of dNone: discard ================================================ FILE: demos/demo14/mainscene.nim ================================================ import parseutils, nimgame2/nimgame, nimgame2/draw, nimgame2/emitter, nimgame2/entity, nimgame2/texturegraphic, nimgame2/tilemap, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/tween, nimgame2/types, nimgame2/utils, dwarf type MainScene = ref object of Scene dG, tilesG, sparkG: TextureGraphic d: Dwarf sparks: Emitter map: TileMap proc init*(scene: MainScene) = Scene(scene).init() # Spark scene.sparkG = newTextureGraphic() discard scene.sparkG.load("../assets/gfx/puff.png") # TileMap scene.tilesG = newTextureGraphic() discard scene.tilesG.load("../assets/gfx/tile0.png") scene.map = newTileMap() scene.map.tags.add("map") scene.map.graphic = scene.tilesG scene.map.initSprite((24, 24)) scene.map.map = loadCSV[int]( "../assets/csv/map0.csv", proc(input: string): int = discard parseInt(input, result)) scene.map.pos = (8.0, 0.0) # Dwarf scene.dG = newTextureGraphic() discard scene.dG.load("../assets/gfx/dwarf.png") scene.d = newDwarf(scene.dG, scene.map) scene.d.layer = 10 # Add to scene scene.add(scene.d) scene.add(scene.map) proc free*(scene: MainScene) = scene.dG.free proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false of K_F10: showInfo = not showInfo else: discard method render*(scene: MainScene) = scene.renderScene() method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) if scene.d.tween != nil: scene.d.tween.update(elapsed) # Controls and speed var direction: dwarf.Direction = if ScancodeDown.down or ScancodeS.down: dDown elif ScancodeUp.down or ScancodeW.down: dUp elif ScancodeLeft.down or ScancodeA.down: dLeft elif ScancodeRight.down or ScancodeD.down: dRight else: dNone scene.d.move(direction) # Sparks if scene.sparks == nil: if scene.map.map[scene.d.virtualPos.y][scene.d.virtualPos.x] == 2: scene.sparks = newEmitter(scene) scene.sparks.pos = ((scene.d.virtualPos.x.float, scene.d.virtualPos.y.float) * Step) + ScreenOffset + scene.d.center - (0.0, Step) scene.sparks.randomVel = (25.0, 25.0) scene.sparks.randomAcc = (10.0, 10.0) scene.sparks.randomTTL = 2.5 scene.sparks.particle = newParticle() scene.sparks.particle.graphic = scene.sparkG scene.sparks.particle.initSprite((5, 5)) scene.sparks.particle.centrify() discard scene.sparks.particle.addAnimation("play", toSeq(0..4), 1/5) scene.sparks.particle.play("play", 1, kill = true) scene.add(scene.sparks) else: scene.sparks.emit(10) ================================================ FILE: demos/demo15/README.md ================================================ Nimgame 2: Demo 15 ================== Camera demo. Demonstrates camera usage. Note a negative sign in front of the camera's position. ![Screenshot](demo15.png) ================================================ FILE: demos/demo15/demo15.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 15 (Camera)"): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo15/mainscene.nim ================================================ import parseutils, nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/texturegraphic, nimgame2/tilemap, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types, nimgame2/utils type MainScene = ref object of Scene tilesG, spacemanG: TextureGraphic spaceman: Entity map: TileMap proc init*(scene: MainScene) = Scene(scene).init() scene.camera = newEntity() scene.cameraBondOffset = game.size / 2 # Tiles Graphic scene.tilesG = newTextureGraphic() discard scene.tilesG.load("../assets/gfx/tile0.png") # TileMap scene.map = newTileMap(scaleFix = true) scene.map.parent = scene.camera scene.map.tags.add("map") scene.map.graphic = scene.tilesG scene.map.initSprite((24, 24)) scene.map.map = loadCSV[int]("../assets/csv/map_camera_test.csv", proc(s: string): int = discard parseInt(s, result)) scene.map.passable.add(0) scene.map.initCollider() scene.map.pos = (0.0, 0.0) # SpacemanG scene.spacemanG = newTextureGraphic() discard scene.spacemanG.load("../assets/gfx/spaceman.png") # Spaceman scene.spaceman = newEntity() scene.spaceman.parent = scene.map scene.spaceman.graphic = scene.spacemanG scene.spaceman.centrify() scene.spaceman.pos = (200.0, 200.0) # Add scene.add(scene.spaceman) scene.add(scene.map) proc free*(scene: MainScene) = scene.tilesG.free() scene.spacemanG.free() proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false of K_Space: colliderOutline = not colliderOutline of K_Return: scene.cameraBond = if scene.cameraBond != nil: nil else: scene.spaceman else: discard method render*(scene: MainScene) = scene.renderScene() discard box((4, 60), (300, 108), 0x000000CC'u32) discard string((8, 64), "Arrows - move camera", 0xFFFFFFFF'u32) discard string((8, 72), "WSAD - move spaceman", 0xFFFFFFFF'u32) discard string((8, 80), "Enter - toggle following (" & (if scene.cameraBond != nil: "on" else: "off") & ")", 0xFFFFFFFF'u32) discard string((8, 88), "camera.pos = " & $(-scene.camera.pos), 0xFFFFFFFF'u32) discard string((8, 96), "spaceman.pos = " & $(scene.spaceman.pos), 0xFFFFFFFF'u32) method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) let move = 100 * elapsed if scene.cameraBond == nil: if ScancodeUp.down: scene.camera.pos.y += move if ScancodeDown.down: scene.camera.pos.y -= move if ScancodeLeft.down: scene.camera.pos.x += move if ScancodeRight.down: scene.camera.pos.x -= move if ScancodeW.down: scene.spaceman.pos.y -= move if ScancodeS.down: scene.spaceman.pos.y += move if ScancodeA.down: scene.spaceman.pos.x -= move if ScancodeD.down: scene.spaceman.pos.x += move ================================================ FILE: demos/demo16/README.md ================================================ Nimgame 2: Demo 16 ================== Parallax demo. Demonstrates parallax effect. ![Screenshot](demo16.png) ================================================ FILE: demos/demo16/demo16.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 16 (Parallax)"): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo16/mainscene.nim ================================================ import nimgame2/nimgame, nimgame2/entity, nimgame2/texturegraphic, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types type MainScene = ref object of Scene spacemanG: TextureGraphic p0125, p025, p05, p1: Entity proc init*(scene: MainScene) = Scene(scene).init() # Graphics scene.spacemanG = newTextureGraphic() discard scene.spacemanG.load("../assets/gfx/spaceman.png") # Entities scene.camera = newEntity() scene.camera.pos = game.size / 2 scene.p0125 = newEntity() scene.p0125.parent = scene.camera scene.p0125.graphic = scene.spacemanG scene.p0125.centrify() scene.p0125.pos = game.size / 2 scene.p0125.pos.y -= 150 scene.p0125.parallax = 0.125 scene.p025 = newEntity() scene.p025.parent = scene.camera scene.p025.graphic = scene.spacemanG scene.p025.centrify() scene.p025.pos = game.size / 2 scene.p025.pos.y -= 100 scene.p025.parallax = 0.25 scene.p05 = newEntity() scene.p05.parent = scene.camera scene.p05.graphic = scene.spacemanG scene.p05.centrify() scene.p05.pos = game.size / 2 scene.p05.pos.y -= 50 scene.p05.parallax = 0.5 scene.p1 = newEntity() scene.p1.parent = scene.camera scene.p1.graphic = scene.spacemanG scene.p1.centrify() scene.p1.pos = game.size / 2 scene.cameraBond = scene.p1 # add to scene scene.add(scene.p1) scene.add(scene.p05) scene.add(scene.p025) scene.add(scene.p0125) proc free*(scene: MainScene) = scene.spacemanG.free() proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = scene.eventScene(event) if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false of K_Space: colliderOutline = not colliderOutline else: discard method render*(scene: MainScene) = scene.renderScene() method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) scene.camera.pos = mouse.abs - Coord(game.size / 2) ================================================ FILE: demos/demo17/README.md ================================================ Nimgame 2: Demo 17 ================== First GUI demo. Demonstrates buttons and text field usage. ![Screenshot](demo17.png) ================================================ FILE: demos/demo17/btnCircle.nim ================================================ import nimgame2/graphic, nimgame2/input, nimgame2/gui/widget, nimgame2/gui/button type CircleButton* = ref object of GuiButton proc init*(btn: CircleButton, graphic: Graphic) = GuiButton(btn).init(graphic, circle = true) proc newCircleButton*(graphic: Graphic): CircleButton = new result result.init(graphic) method onClick*(btn: CircleButton, mb: MouseButton) = echo "clicked circle button, toggled " & (if btn.toggled: "on" else: "off") ================================================ FILE: demos/demo17/btnSquare.nim ================================================ import nimgame2/graphic, nimgame2/input, nimgame2/gui/button type SquareButton* = ref object of GuiButton proc init*(btn: SquareButton, graphic: Graphic, image: Graphic = nil) = GuiButton(btn).init(graphic, image) proc newSquareButton*(graphic: Graphic, image: Graphic = nil): SquareButton = new result result.init(graphic, image) method onClick*(btn: SquareButton, mb: MouseButton) = echo "clicked square button" ================================================ FILE: demos/demo17/demo17.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 17 (GUI)"): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo17/mainscene.nim ================================================ import nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/texturegraphic, nimgame2/input, nimgame2/mosaic, nimgame2/scene, nimgame2/settings, nimgame2/truetypefont, nimgame2/types, nimgame2/gui/widget, nimgame2/gui/radio, nimgame2/gui/textinput, nimgame2/gui/progressbar, btnSquare, btnCircle type MainScene = ref object of Scene btnSquareG, btnCircleG, iconX, btnMosaicG, inputG: TextureGraphic btnsRadio: array[3, GuiRadioButton] radioGroup: GuiRadioGroup btnSquare, btnMosaic: SquareButton btnCircle: CircleButton textInput: GuiTextInput progressBar: GuiProgressBar font: TrueTypeFont proc init*(scene: MainScene) = Scene(scene).init() # Graphics scene.btnSquareG = newTextureGraphic() discard scene.btnSquareG.load("../assets/gfx/button_square.png") scene.btnCircleG = newTextureGraphic() discard scene.btnCircleG.load("../assets/gfx/button_circle.png") scene.iconX = newTextureGraphic() discard scene.iconX.load("../assets/gfx/icon_x.png") let mosaic = newMosaic("../assets/gfx/button_square.png", (8, 8)) scene.btnMosaicG = newTextureGraphic() discard scene.btnMosaicG.assignTexture mosaic.render( patternStretchBorder(4, 2)) # Square Button scene.btnSquare = newSquareButton(scene.btnSquareG, scene.iconX) scene.btnSquare.mbAllow.set(MouseButton.right) scene.btnSquare.pos = (100, 100) # Circle Button scene.btnCircle = newCircleButton(scene.btnCircleG) scene.btnCircle.pos = (150, 100) scene.btnCircle.toggle = true # Mosaic Button scene.btnMosaic = newSquareButton(scene.btnMosaicG) scene.btnMosaic.pos = (200, 100) # Text Input scene.font = newTrueTypeFont() discard scene.font.load("../assets/fnt/FSEX300.ttf", 16) let inputmosaic = newMosaic("../assets/gfx/text_input.png", (8, 8)) scene.inputG = newTextureGraphic() discard scene.inputG.assignTexture inputmosaic.render( patternStretchBorder(16, 1)) scene.textInput = newGuiTextInput(scene.inputG, scene.font) scene.textInput.pos = (100, 150) scene.textInput.text.limit = 16 # Radio Button scene.radioGroup = newGuiRadioGroup() scene.radioGroup.pos = (100, 200) for i in 0..scene.btnsRadio.high: scene.btnsRadio[i] = newGuiRadioButton( scene.radioGroup, scene.btnCircleG, circle = true) scene.btnsRadio[i].pos = (i.float * 50.0, 0.0) scene.btnsRadio[0].toggled = true # Progress Bar scene.progressBar = newProgressBar((200, 50), 0xFF0000FF'u32, 0x00FF00FF'u32, scene.font) scene.progressBar.min = 0 scene.progressBar.max = 100 scene.progressBar.value = 0 scene.progressBar.direction = Direction.leftRight scene.progressBar.outline = (1, 1) scene.progressBar.pos = (100, 250) # add to scene scene.add(scene.progressBar) scene.add(scene.radioGroup) for b in scene.btnsRadio: scene.add(b) scene.add(scene.textInput) scene.add(scene.btnMosaic) scene.add(scene.btnSquare) scene.add(scene.btnCircle) proc free*(scene: MainScene) = scene.inputG.free() scene.btnMosaicG.free() scene.btnSquareG.free() scene.btnCircleG.free() scene.iconX.free() proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = scene.eventScene(event) if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false of K_Space: colliderOutline = not colliderOutline else: discard method render*(scene: MainScene) = scene.renderScene() discard box((4, 60), (220, 76), 0x000000CC'u32) discard string( (8, 64), "Space - toggle collider outlines", 0xFFFFFFFF'u32) method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) # progressBar if scene.progressBar.value < scene.progressBar.max: scene.progressBar.value += 10 * elapsed if scene.progressBar.value > scene.progressBar.max: scene.progressBar.value = scene.progressBar.max ================================================ FILE: demos/demo18/README.md ================================================ Nimgame 2: Demo 18 ================== IndexedImage. Demonstrates palette swapping in indexed images. ![Screenshot](demo18.png) ================================================ FILE: demos/demo18/demo18.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 320, h = 240, title = "Nimgame 2: Demo 18 (IndexedImage)"): game.windowSize = (640, 480) showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo18/mainscene.nim ================================================ import nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/texturegraphic, nimgame2/input, nimgame2/indexedimage, nimgame2/scene, nimgame2/settings, nimgame2/types type MainScene = ref object of Scene idximg: IndexedImage knightG: TextureGraphic knight: Entity proc init*(scene: MainScene) = Scene(scene).init() scene.idximg = newIndexedImage("../assets/gfx/knight.gif") scene.knightG = newTextureGraphic() discard scene.knightG.assignTexture scene.idximg.render() scene.knight = newEntity() scene.knight.graphic = scene.knightG scene.knight.pos = (128, 128) # add to scene scene.add(scene.knight) proc free*(scene: MainScene) = scene.knightG.free() proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = scene.eventScene(event) if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false else: discard method render*(scene: MainScene) = scene.renderScene() discard box((4, 60), (220, 76), 0x000000CC'u32) discard string( (8, 64), "QWER - increase RGBA values (1st color)", 0xFFFFFFFF'u32) discard string( (8, 72), "ASDF - decrease RGBA values (1st color)", 0xFFFFFFFF'u32) discard string( (8, 80), "TYUI - increase RGBA values (2nd color)", 0xFFFFFFFF'u32) discard string( (8, 88), "GHJK - decrease RGBA values (2nd color)", 0xFFFFFFFF'u32) discard string( (8, 96), "1st: " & $scene.idximg.palette[3], 0xFFFFFFFF'u32) discard string( (8, 104), "2nd: " & $scene.idximg.palette[11], 0xFFFFFFFF'u32) const Step = 15 method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) let palette = scene.idximg.palette var upd = false color1 = palette[3] color2 = palette[11] # color1 if ScancodeQ.pressed: color1.r = clamp(color1.r.int + Step, 0, 255).uint8 upd = true if ScancodeW.pressed: color1.g = clamp(color1.g.int + Step, 0, 255).uint8 upd = true if ScancodeE.pressed: color1.b = clamp(color1.b.int + Step, 0, 255).uint8 upd = true if ScancodeR.pressed: color1.a = clamp(color1.a.int + Step, 0, 255).uint8 upd = true if ScancodeA.pressed: color1.r = clamp(color1.r.int - Step, 0, 255).uint8 upd = true if ScancodeS.pressed: color1.g = clamp(color1.g.int - Step, 0, 255).uint8 upd = true if ScancodeD.pressed: color1.b = clamp(color1.b.int - Step, 0, 255).uint8 upd = true if ScancodeF.pressed: color1.a = clamp(color1.a.int - Step, 0, 255).uint8 upd = true # color2 if ScancodeT.pressed: color2.r = clamp(color2.r.int + Step, 0, 255).uint8 upd = true if ScancodeY.pressed: color2.g = clamp(color2.g.int + Step, 0, 255).uint8 upd = true if ScancodeU.pressed: color2.b = clamp(color2.b.int + Step, 0, 255).uint8 upd = true if ScancodeI.pressed: color2.a = clamp(color2.a.int + Step, 0, 255).uint8 upd = true if ScancodeG.pressed: color2.r = clamp(color2.r.int - Step, 0, 255).uint8 upd = true if ScancodeH.pressed: color2.g = clamp(color2.g.int - Step, 0, 255).uint8 upd = true if ScancodeJ.pressed: color2.b = clamp(color2.b.int - Step, 0, 255).uint8 upd = true if ScancodeK.pressed: color2.a = clamp(color2.a.int - Step, 0, 255).uint8 upd = true if upd: scene.idximg.palette[3] = color1 scene.idximg.palette[11] = color2 discard scene.knightG.assignTexture(scene.idximg.render()) ================================================ FILE: demos/demo19/README.md ================================================ Nimgame 2: Demo 19 ================== PerspectiveImage. Demonstrates perspective transformations. ![Screenshot](demo19.png) ================================================ FILE: demos/demo19/demo19.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 19 (PerspectiveImage)"): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo19/mainscene.nim ================================================ import nimgame2/nimgame, nimgame2/entity, nimgame2/texturegraphic, nimgame2/input, nimgame2/perspectiveimage, nimgame2/scene, nimgame2/settings, nimgame2/types const GraphicCount = 17 Positions: array[GraphicCount, Coord] = [ (125.0, 125.0), (275, 125), (375, 125), (475, 125), (575, 125), (75, 275), (175, 275), (275, 275), (375, 275), (475, 275), (575, 275), (75, 425), (175, 425), (275, 425), (375, 425), (475, 400), (575, 425), ] type MainScene = ref object of Scene pimg: PerspectiveImage graphics: array[GraphicCount, TextureGraphic] entities: array[GraphicCount, Entity] proc init*(scene: MainScene) = Scene(scene).init() scene.pimg = newPerspectiveImage("../assets/gfx/grid.png") # graphics for i in 0..scene.graphics.high: scene.graphics[i] = newTextureGraphic() discard scene.graphics[0].assignTexture(scene.pimg.render( pdHor, 0, 0)) discard scene.graphics[1].assignTexture(scene.pimg.render( pdHor, 96, 32)) discard scene.graphics[2].assignTexture(scene.pimg.render( pdHor, 32, 96)) discard scene.graphics[3].assignTexture(scene.pimg.render( pdHor, 64, 32, 32)) discard scene.graphics[4].assignTexture(scene.pimg.render( pdHor, 32, 64, 32)) discard scene.graphics[5].assignTexture(scene.pimg.render( pdVer, 96, 32)) discard scene.graphics[6].assignTexture(scene.pimg.render( pdVer, 64, 32, 32)) discard scene.graphics[7].assignTexture(scene.pimg.render( pdHor, 64, 32, shift = 0.0)) discard scene.graphics[8].assignTexture(scene.pimg.render( pdHor, 32, 64, shift = 1.0)) discard scene.graphics[9].assignTexture(scene.pimg.render( pdHor, 64, 32, shift = 0.25)) discard scene.graphics[10].assignTexture(scene.pimg.render( pdHor, 32, 64, shift = 0.75)) discard scene.graphics[11].assignTexture(scene.pimg.render( pdVer, 32, 96)) discard scene.graphics[12].assignTexture(scene.pimg.render( pdVer, 32, 64, 32)) discard scene.graphics[13].assignTexture(scene.pimg.render( pdVer, 64, 32, shift = 0.0)) discard scene.graphics[14].assignTexture(scene.pimg.render( pdVer, 64, 32, shift = 1.0)) discard scene.graphics[15].assignTexture(scene.pimg.render( pdVer, 64, 32, shift = 0.25)) discard scene.graphics[16].assignTexture(scene.pimg.render( pdVer, 32, 64, shift = 0.75)) # entities for i in 0..scene.entities.high: scene.entities[i] = newEntity() scene.entities[i].graphic = scene.graphics[i] scene.entities[i].centrify() scene.entities[i].pos = Positions[i] # add to scene for entity in scene.entities: scene.add(entity) proc free*(scene: MainScene) = scene.pimg.free() for graphic in scene.graphics: graphic.free() proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = scene.eventScene(event) if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false else: discard method render*(scene: MainScene) = scene.renderScene() ================================================ FILE: demos/demo2/README.md ================================================ Nimgame 2: Demo 2 ================= Graphic demo. Demonstrates color and alpha modifiers, blending modes, and scaling. ![Screenshot](demo2.png) ================================================ FILE: demos/demo2/demo2.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 2 (Graphic)", scaleQuality = 0): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo2/earth.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Earth* = ref object of Entity proc init*(entity: Earth) = entity.initEntity() entity.pos.x = 128.0 entity.pos.y = 96.0 proc newEarth*(): Earth = result = new Earth result.init() ================================================ FILE: demos/demo2/mainscene.nim ================================================ import math, nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/texturegraphic, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types, earth, spaceman type MainScene = ref object of Scene earthG, spacemanG: TextureGraphic e: Earth s: Spaceman proc init*(scene: MainScene) = Scene(scene).init() # Earth scene.e = newEarth() scene.earthG = newTextureGraphic() discard scene.earthG.load("../assets/gfx/earth.png") scene.e.graphic = scene.earthG # Spaceman scene.s = newSpaceman() scene.spacemanG = newTextureGraphic() discard scene.spacemanG.load("../assets/gfx/spaceman.png") scene.s.graphic = scene.spacemanG # add to scene scene.add(scene.s) scene.add(scene.e) proc free*(scene: MainScene) = scene.earthG.free scene.spacemanG.free proc newMainScene*(): MainScene = new result, free result.init() proc changeBlendMod(scene: MainScene, increase = true) = # get blend mod var b = TextureGraphic(scene.s.graphic).blendMod # change blend mod if increase: if b.int == 0: b = Blend(1) elif b < Blend.high: b = Blend(b.int shl 1) else: # decrease if b.int > 0: b = Blend(b.int shr 1) # set blend mod TextureGraphic(scene.s.graphic).blendMod = b const ScaleMax = 3 ScaleMin = 0.5 ScaleMod = 0.25 proc changeResolution(scene: MainScene, increase = true) = # get current scale var scale = game.scale # change scale if increase: if scale.x < ScaleMax: scale.x += ScaleMod scale.y += ScaleMod else: # decrease if scale.x > ScaleMin: scale.x -= ScaleMod scale.y -= ScaleMod # set resolution game.windowSize = Dim(Coord(game.size) * scale) method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false of K_T: scene.changeBlendMod() of K_G: scene.changeBlendMod(false) of K_Y: scene.changeResolution() of K_H: scene.changeResolution(false) else: discard method render*(scene: MainScene) = scene.renderScene() let c = TextureGraphic(scene.s.graphic).colorMod let res = game.windowSize let scale: Coord = (game.scale.x.round(2), game.scale.y.round(2)) discard box((4, 60), (220, 124), 0x000000CC'u32) discard string( (8, 64), "Q/A - red mod: " & $c.r.int, 0xFF0000FF'u32) discard string( (8, 72), "W/S - green mod: " & $c.g.int, 0xFF0000FF'u32) discard string( (8, 80), "E/D - blue mod: " & $c.b.int, 0xFF0000FF'u32) discard string( (8, 88), "R/F - alpha mod: " & $TextureGraphic(scene.s.graphic).alphaMod.int, 0xFF0000FF'u32) discard string( (8, 96), "T/G - blend mod: " & $TextureGraphic(scene.s.graphic).blendMod, 0xFF0000FF'u32) discard string( (8, 104), "Y/H - resolution: " & $res.w & "x" & $res.h, 0xFF0000FF'u32) discard string( (8, 112), "Scale: " & $scale.x & "x" & $scale.y, 0xFF0000FF'u32) type ColorElement = enum ceR, ceG, ceB proc changeColorMod(scene: MainScene, elem: ColorElement, val: int) = var color = TextureGraphic(scene.s.graphic).colorMod # Get color element var e = int(case elem: of ceR: color.r of ceG: color.g of ceB: color.b) # Change color element inc(e, val) # Correct value if e < 0x00: e = 0x00 elif e > 0xFF: e = 0xFF # Set color mod case elem: of ceR: color.r = e.uint8 of ceG: color.g = e.uint8 of ceB: color.b = e.uint8 TextureGraphic(scene.s.graphic).colorMod = color proc changeAlphaMod(scene: MainScene, val: int) = # Get alpha mod var a = TextureGraphic(scene.s.graphic).alphaMod.int # Change alpha mod inc(a, val) # Correct value if a < 0x00: a = 0x00 elif a > 0xFF: a = 0xFF # Set alpha mod TextureGraphic(scene.s.graphic).alphaMod = a.uint8 method update*(scene: MainScene, elapsed: float) = let val = int(0xFF * elapsed) scene.updateScene(elapsed) if ScancodeQ.down: scene.changeColorMod(ceR, val) if ScancodeA.down: scene.changeColorMod(ceR, -val) if ScancodeW.down: scene.changeColorMod(ceG, val) if ScancodeS.down: scene.changeColorMod(ceG, -val) if ScancodeE.down: scene.changeColorMod(ceB, val) if ScancodeD.down: scene.changeColorMod(ceB, -val) if ScancodeR.down: scene.changeAlphaMod(val) if ScancodeF.down: scene.changeAlphaMod(-val) ================================================ FILE: demos/demo2/spaceman.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Spaceman* = ref object of Entity proc init*(entity: Spaceman) = entity.initEntity() entity.pos.x = 200.0 entity.pos.y = 64.0 proc newSpaceman*(): Spaceman = result = new Spaceman result.init() ================================================ FILE: demos/demo20/README.md ================================================ Nimgame 2: Demo 20 ================== TextureAtlas. Demonstrates texture atlas loading and access. ![Screenshot](demo20.png) ================================================ FILE: demos/demo20/demo20.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 320, h = 240, title = "Nimgame 2: Demo 20 (TextureAtlas)"): showInfo = true game.windowSize = (640, 480) game.scene = newMainScene() game.run() ================================================ FILE: demos/demo20/mainscene.nim ================================================ import nimgame2/nimgame, nimgame2/entity, nimgame2/gui/button, nimgame2/texturegraphic, nimgame2/textureatlas, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types type MainScene = ref object of Scene atlas: TextureAtlas proc init*(scene: MainScene) = Scene(scene).init() scene.atlas = newTextureAtlas("../assets/gfx/atlas.png", "../assets/csv/atlas.csv") let eSpaceman = newEntity() eGradient = newEntity() eButton = newGuiButton(scene.atlas["button"]) eSprite = newEntity() eSpaceman.graphic = scene.atlas["spaceman"] eSpaceman.pos = (50.0, 100.0) eGradient.graphic = scene.atlas["gradient"] eGradient.pos = (150.0, 100.0) eButton.pos = (200.0, 100.0) eSprite.graphic = scene.atlas["sprite"] eSprite.initSprite((32, 32), (0, 32), (1, 1)) discard eSprite.addAnimation("play", toSeq(0..3), 1/4) eSprite.play("play") eSprite.pos = (200.0, 150.0) scene.add(eSpaceman) scene.add(eGradient) scene.add(eButton) scene.add(eSprite) proc free*(scene: MainScene) = scene.atlas.free() proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = scene.eventScene(event) if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false else: discard method render*(scene: MainScene) = scene.renderScene() ================================================ FILE: demos/demo21/README.md ================================================ Nimgame 2: Demo 21 ================== Joysticks. Demonstrates joystick input handling. ![Screenshot](demo21.png) ================================================ FILE: demos/demo21/demo21.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 21 (Joysticks)"): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo21/joypoint.nim ================================================ import nimgame2/nimgame, nimgame2/entity, nimgame2/textgraphic, nimgame2/texturegraphic, nimgame2/font, nimgame2/bitmapfont, nimgame2/input, nimgame2/types type JoyPoint* = ref object of Entity joy: int label: TextGraphic proc init(jp: JoyPoint, id: int) = jp.initEntity() jp.joy = id jp.graphic = newTextureGraphic("../assets/gfx/target.png") jp.centrify() jp.pos = game.size / 2 # label let font = newBitmapFont() discard font.load("../assets/fnt/default8x16.png", (8, 16)) jp.label = newTextGraphic(font) jp.label.lines = [$id] proc newJoyPoint*(joystick: int): JoyPoint = new result result.init(joystick) method render*(jp: JoyPoint) = jp.renderEntity() jp.label.draw( jp.absPos + jp.center - Coord(jp.label.dim / 2) + (1.0, 1.0), jp.absRot, jp.absScale, jp.center, jp.flip) const Speed = 100 method update*(jp: JoyPoint, elapsed: float) = let move = Speed * elapsed / JoyAxis.high.float jp.updateEntity(elapsed) jp.pos.x += jp.joy.joyAxis(0).float * move jp.pos.x = clamp(jp.pos.x, 0.0, game.size.w.float) jp.pos.y += jp.joy.joyAxis(1).float * move jp.pos.y = clamp(jp.pos.y, 0.0, game.size.h.float) ================================================ FILE: demos/demo21/mainscene.nim ================================================ import nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/texturegraphic, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types, joypoint type MainScene = ref object of Scene joypoints: seq[JoyPoint] proc init*(scene: MainScene) = Scene(scene).init() scene.joypoints = @[] for i in 0..= game.size.w.float: entity.vel.x *= -1 if entity.pos.y >= game.size.h.float: entity.vel.y *= -1 proc init*(scene: MainScene) = Scene(scene).init() # Movie scene.movie = newMpegGraphic("video.mpg") scene.movie.loop = true scene.e = newEntity() scene.e.graphic = scene.movie scene.e.physics = moviePhysics scene.e.pos.x = rand(game.size.w).float scene.e.pos.y = rand(game.size.h).float scene.e.vel.x = rand(10.0..100.0) * randSign().float scene.e.vel.y = rand(10.0..100.0) * randSign().float scene.e.centrify() scene.e.rotVel = rand(10.0..60.0) * randSign().float # add to scene scene.add(scene.e) proc free*(scene: MainScene) = scene.movie.free() proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false else: discard method render*(scene: MainScene) = scene.renderScene() discard box((4, 60), (220, 124), 0x000000CC'u32) discard string( (8, 64), "Enter - play", 0xFF0000FF'u32) discard string( (8, 72), "Space - pause", 0xFF0000FF'u32) discard string( (8, 80), "Backspace - stop", 0xFF0000FF'u32) discard string( (8, 88), "R - Rewind", 0xFF0000FF'u32) discard string( (8, 96), "Up/Down - volume: " & $scene.movie.volume, 0xFF0000FF'u32) discard string( (8, 104), "Right - skip 5s", 0xFF0000FF'u32) discard string( (8, 112), "Time: " & scene.movie.currentTime.formatFloat(precision = 3) & "s of " & scene.movie.totalTime.formatFloat(precision = 3) & "s", 0xFF0000FF'u32) method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) if ScancodeReturn.pressed: scene.movie.play() if ScancodeSpace.pressed: scene.movie.pause() if ScancodeBackspace.pressed: scene.movie.stop() if ScancodeR.pressed: scene.movie.rewind() if ScancodeUp.pressed: scene.movie.volume = (scene.movie.volume + 10).clamp(0, 100) if ScancodeDown.pressed: scene.movie.volume = (scene.movie.volume - 10).clamp(0, 100) if ScancodeRight.pressed: scene.movie.skip(5.0) ================================================ FILE: demos/demo23/README.md ================================================ Nimgame 2: Demo 23 ================== Transform demo by [CodeDoes](https://github.com/CodeDoes). ![Screenshot](demo23.png) ================================================ FILE: demos/demo23/demo23.nim ================================================ import nimgame2 / [ nimgame, settings ], mainscene game = newGame() if game.init(640, 480, "Nimgame 2: Demo 22 (Transform)"): game.scene = newMainScene() settings.updateInterval = 1000 settings.showInfo = true game.run() ================================================ FILE: demos/demo23/mainscene.nim ================================================ import nimgame2 / [ truetypefont, textgraphic, entity, nimgame, scene, types, graphic, input, settings], nimgame2 / gui / widget, private / [ circle_graphic, frame] type MainScene* = ref object of Scene font*: TrueTypeFont proc newCircleEntity*(): Entity = var cgraphic = newCircleGraphic() cgraphic.radius = 4.0 cgraphic.draw_border = false result = newEntity() result.graphic = cgraphic result.centrify() proc createRotScaleTestEnts*( scene: MainScene, text: string, pos: var Coord, rot: Angle = 0.0, scale: Scale = 1.0) = var textEnt = newEntity() textgraphic = newTextGraphic(scene.font) scene.add(textEnt) textEnt.graphic = textgraphic textgraphic.setText text textEnt.scale = scale textEnt.pos = pos + (textEnt.bottomleft * textEnt.absScale) textEnt.center += textEnt.bottomleft echo textEnt.pos # Want rel_pos before rotation pos.y = (textEnt.transform * textEnt.bottomleft).y textEnt.rot = rot * 90.0 for p in textEnt.world_corners.items(): var cent = newCircleEntity() scene.add(cent) cent.pos = p var frameEnt = newGuiWidget() scene.add(frameEnt) var fGraphic = newFrameGraphic() frameEnt.graphic = fGraphic fGraphic.draw_filled = false fGraphic.border_color = ColorRed fGraphic.rect.x = textEnt.topleft.x.cint fGraphic.rect.y = textEnt.topleft.y.cint fGraphic.rect.w = textEnt.dim.w.cint fGraphic.rect.h = textEnt.dim.h.cint frameEnt.logic = proc (entity: Entity, elapsed: float) = let color = if entity.GuiWidget.state.isFocused: ColorOrange else: ColorGreen entity.graphic.FrameGraphic.border_color = color frameEnt.center = textEnt.center frameEnt.pos = textEnt.pos frameEnt.rot = textEnt.rot frameEnt.scale = textEnt.scale var corners = newseq[Coord]() for c in frameEnt.corners: corners.add(c) frameEnt.collider = frameEnt.newPolyCollider(frameEnt.pos, corners) proc init*(scene: MainScene) = scene.Scene.init() scene.font = newTrueTypeFont() discard scene.font.load("../assets/fnt/FSEX300.ttf", 32) var rel_pos: Coord = (0.0, 100.0) for scale in [0.8, 0.3, 0.4, 0.6, 0.7, 0.2]: createRotScaleTestEnts(scene, "Scale Test", rel_pos, scale = scale) for f in [0.8, 0.3, 0.4, 0.6, 0.7, 0.2]: createRotScaleTestEnts(scene, "Rot Scale Test", rel_pos, rot = f, scale = f) rel_pos = (400.0, 0.0) for rot in [0.8, 0.3, 0.4, 0.6, 0.7, 0.2]: createRotScaleTestEnts(scene, "Rot Test", rel_pos, rot = rot) proc newMainScene*(): MainScene = new result result.init() ================================================ FILE: demos/demo23/private/border_fill_graphic.nim ================================================ import nimgame2 / [ types, graphic, types ] type BorderFillGraphic* = ref object of Graphic border_color*, fill_color*: Color # border_thickness*: float #NOTE can't set border thickness at the moment draw_border*, draw_filled*: bool proc initBorderFillGraphic*(self: BorderFillGraphic) = self.draw_border = true self.draw_filled = true self.fill_color = ColorPurple ## Traditional visual debugging color self.border_color = ColorPink # self.border_thickness = 1.0 method draw*(graphic: BorderFillGraphic, pos: Coord = (0.0, 0.0), angle: Angle = 0.0, scale: Scale = 1.0, center: Coord = (0.0, 0.0), flip: Flip = Flip.none, region: Rect = Rect(x: 0, y: 0, w: 0, h: 0)) = raise newException(CatchableError, "Can't use BorderFillGraphic draw method.") method dim*(graphic: BorderFillGraphic): Dim = raise newException(CatchableError, "Can't use BorderFillGraphic dim method.") ================================================ FILE: demos/demo23/private/circle_graphic.nim ================================================ import nimgame2 / [ types, graphic, draw, utils ], border_fill_graphic type CircleGraphic* = ref object of BorderFillGraphic radius*: float proc drawCircleGraphic*(self: CircleGraphic, pos: Coord = (0.0, 0.0), angle: Angle = 0.0, scale: Scale = 1.0, center: Coord = (0.0, 0.0), flip: Flip = Flip.none, region: Rect = Rect(x: 0, y: 0, w: 0, h: 0)) = let point: Coord = pos if self.draw_filled: discard circle(point, self.radius, self.fill_color, DrawMode.filled) if self.draw_border: discard circle(point, self.radius, self.border_color, DrawMode.default) method draw*(graphic: CircleGraphic, pos: Coord = (0.0, 0.0), angle: Angle = 0.0, scale: Scale = 1.0, center: Coord = (0.0, 0.0), flip: Flip = Flip.none, region: Rect = Rect(x: 0, y: 0, w: 0, h: 0)) = drawCircleGraphic(graphic, pos, angle, scale, center, flip, region) proc newCircleGraphic*(): CircleGraphic = new result result.initBorderFillGraphic() result.radius = 5.0 method dim*(self: CircleGraphic): Dim = return (int self.radius * 2, int self.radius * 2) ================================================ FILE: demos/demo23/private/frame.nim ================================================ import nimgame2 / [ types, graphic, draw, utils ], border_fill_graphic type FrameGraphic* = ref object of BorderFillGraphic rect*: Rect Bounds = tuple[a: Coord, b: Coord] AngledBounds* = ref object of RootObj bounds*: Bounds angle*: Angle center*: Coord proc points*(abounds: AngledBounds): auto {.inline.} = let a = abounds.bounds.a b = abounds.bounds.b center = abounds.center angle = abounds.angle template apply(coord: Coord): Coord = rotate(coord, center, angle) return @[ apply(a), apply((b.x, a.y)), apply(b), apply((a.x, b.y)) ] proc points*(graphic: FrameGraphic, pos: Coord, angle: Angle, scale: Scale, center: Coord): seq[Coord] = var abounds = new AngledBounds abounds.bounds = (a: -center * scale, b: (-center + graphic.dim.toCoord) * scale).Bounds abounds.angle = angle abounds.center = pos return abounds.points proc initFrameGraphic(graphic: FrameGraphic) = graphic.initBorderFillGraphic() graphic.rect= Rect(x: 0, y: 0, w: 0, h: 0) proc newFrameGraphic*(): FrameGraphic = new result result.initFrameGraphic() method dim*(self: FrameGraphic): Dim = (self.rect.w.int, self.rect.h.int) proc drawFrameGraphic*(self: FrameGraphic, pos: Coord, angle: Angle, scale: Scale, center: Coord, flip: Flip, region: Rect) = var points = self.points(pos,angle, scale,center) if self.draw_border: discard draw.polygon(points, self.border_color, DrawMode.default) if self.draw_filled: discard draw.polygon(points, self.fill_color, DrawMode.filled) method draw*( graphic: FrameGraphic, pos: Coord = (0.0, 0.0), angle: Angle = 0.0, scale: Scale = 1.0, center: Coord = (0.0, 0.0), flip: Flip = Flip.none, region: Rect = Rect(x: 0, y: 0, w: 0, h: 0)) = drawFrameGraphic(graphic, pos, angle, scale, center, flip, region) ================================================ FILE: demos/demo3/README.md ================================================ Nimgame 2: Demo 3 ================= Input demo. Demonstrates keyboard and mouse input. ![Screenshot](demo3.png) ================================================ FILE: demos/demo3/demo3.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 3 (Input & Physics)"): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo3/mainscene.nim ================================================ import nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/texturegraphic, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types, spaceman type MainScene = ref object of Scene spacemanG: TextureGraphic s: Spaceman proc spacemanPhysics(entity: Entity, elapsed: float) = defaultPhysics(entity, elapsed) if entity.pos.x.int < 0: entity.pos.x = 0 entity.vel.x = 0 if entity.pos.x.int > game.size.w: entity.pos.x = game.size.w.float entity.vel.x = 0 if entity.pos.y.int < 0: entity.pos.y = 0 entity.vel.y = 0 if entity.pos.y.int > game.size.h: entity.pos.y = game.size.h.float entity.vel.y = 0 proc init*(scene: MainScene) = Scene(scene).init() # Spaceman scene.s = newSpaceman() scene.spacemanG = newTextureGraphic() discard scene.spacemanG.load("../assets/gfx/spaceman.png") scene.s.graphic = scene.spacemanG scene.s.physics = spacemanPhysics scene.s.centrify() scene.add(scene.s) # Mouse #discard mouseRelative(true) proc free*(scene: MainScene) = scene.spacemanG.free() proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false else: discard method render*(scene: MainScene) = # Draw line between the spaceman and the mouse position if LMB is pressed if MouseButton.left.down: discard line(scene.s.pos, mouse.abs, 0xFF0000FF'u32) scene.renderScene() var arrows: string = "" if ScancodeUp.down: arrows &= "Up " if ScancodeDown.down: arrows &= "Down " if ScancodeLeft.down: arrows &= "Left " if ScancodeRight.down: arrows &= "Right" var wsad: string = "" if ScancodeW.down: wsad &= "W " if ScancodeS.down: wsad &= "S " if ScancodeA.down: wsad &= "A " if ScancodeD.down: wsad &= "D " var mouse: string = "Abs(" & $mouse.abs.x.int & ":" & $mouse.abs.y.int & ") Rel(" & $mouse.rel.x.int & ":" & $mouse.rel.y.int & ")" var buttons: string = "" if MouseButton.left.down: buttons &= "L " if MouseButton.middle.down: buttons &= "M " if MouseButton.right.down: buttons &= "R " if MouseButton.x1.down: buttons &= "X1 " if MouseButton.x2.down: buttons &= "X2 " discard box((4, 60), (260, 100), 0xCC000000'u32) discard string( (8, 64), "Arrows: " & arrows, 0xFF0000FF'u32) discard string( (8, 72), "WSAD: " & wsad, 0xFF0000FF'u32) discard string( (8, 80), "Mouse: " & mouse, 0xFF0000FF'u32) discard string( (8, 88), "Mouse buttons: " & buttons, 0xFF0000FF'u32) discard string( (8, 96), "Mouse wheel: " & $mouseWheel, 0xFF0000FF'u32) const Acc = 100.0 method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) # Arrows and WSAD if ScancodeUp.down or ScancodeW.down: scene.s.vel.y -= Acc * elapsed if ScancodeDown.down or ScancodeS.down: scene.s.vel.y += Acc * elapsed if ScancodeLeft.down or ScancodeA.down: scene.s.vel.x -= Acc * elapsed if ScancodeRight.down or ScancodeD.down: scene.s.vel.x += Acc * elapsed # Mouse if MouseButton.left.down: var vector: Coord vector = (mouse.abs - scene.s.pos) * elapsed scene.s.vel += vector ================================================ FILE: demos/demo3/spaceman.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Spaceman* = ref object of Entity proc init*(entity: Spaceman) = entity.initEntity() entity.pos.x = game.size.w.float / 2 entity.pos.y = game.size.h.float / 2 entity.drg.x = 10.0 entity.drg.y = 10.0 proc newSpaceman*(): Spaceman = result = new Spaceman result.init() ================================================ FILE: demos/demo4/README.md ================================================ Nimgame 2: Demo 4 ================= Sprite demo. Demonstrates sprite animation. ![Screenshot](demo4.png) ================================================ FILE: demos/demo4/demo4.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 4 (Sprite & Animation)"): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo4/dwarf.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Dwarf* = ref object of Entity proc init*(entity: Dwarf) = entity.initEntity() entity.centrify() entity.physics = defaultPhysics proc newDwarf*(): Dwarf = result = new Dwarf result.init() ================================================ FILE: demos/demo4/mainscene.nim ================================================ import math, nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/texturegraphic, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types, dwarf type MainScene = ref object of Scene dG: TextureGraphic d: Dwarf const Framerate = 1/12 proc init*(scene: MainScene) = Scene(scene).init() # Dwarf scene.dG = newTextureGraphic() discard scene.dG.load("../assets/gfx/dwarf.png") scene.d = newDwarf() scene.d.pos = (200, 100) scene.d.graphic = scene.dG scene.d.initSprite((24, 48)) discard scene.d.addAnimation( "down", [0, 1, 2, 3, 4, 5], Framerate) discard scene.d.addAnimation( "up", [6, 7, 8, 9, 10, 11], Framerate) discard scene.d.addAnimation( "left", [12, 13, 14, 15, 16, 17], Framerate) discard scene.d.addAnimation( "right", [12, 13, 14, 15, 16, 17], Framerate, Flip.horizontal) scene.add(scene.d) proc free*(scene: MainScene) = scene.dG.free proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false else: discard method render*(scene: MainScene) = scene.renderScene() const Speed = 50 method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) # Controls and speed type Direction = enum none, down, up, left, right var direction = if ScancodeDown.down or ScancodeS.down: down elif ScancodeUp.down or ScancodeW.down: up elif ScancodeLeft.down or ScancodeA.down: left elif ScancodeRight.down or ScancodeD.down: right else: none case direction: of none: if not scene.d.sprite.playing: scene.d.vel = (0, 0) of down: if not scene.d.sprite.playing or (scene.d.currentAnimationName != "down"): scene.d.play("down", 1) scene.d.vel = (0, Speed) of up: if not scene.d.sprite.playing or (scene.d.currentAnimationName != "up"): scene.d.play("up", 1) scene.d.vel = (0, -Speed) of left: if not scene.d.sprite.playing or (scene.d.currentAnimationName != "left"): scene.d.play("left", 1) scene.d.vel = (-Speed, 0) of right: if not scene.d.sprite.playing or (scene.d.currentAnimationName != "right"): scene.d.play("right", 1) scene.d.vel = (Speed, 0) ================================================ FILE: demos/demo5/README.md ================================================ Nimgame 2: Demo 5 ================= Colliders demo. Demonstrates different colliders. ![Screenshot](demo5.png) ================================================ FILE: demos/demo5/cursor.nim ================================================ import nimgame2/nimgame, nimgame2/entity, nimgame2/input type Cursor* = ref object of Entity collidedWith*: seq[string] proc init*(entity: Cursor) = entity.initEntity() entity.tags.add("Cursor") entity.pos = mouse.abs entity.collidedWith = @[] proc newCursor*(): Cursor = result = new Cursor result.init() method update*(entity: Cursor, elapsed: float) = entity.updateEntity(elapsed) entity.collidedWith = @[] entity.pos = mouse.abs method onCollide*(entity: Cursor, target: Entity) = if target.tags.len > 0: entity.collidedWith.add(target.tags[0]) ================================================ FILE: demos/demo5/demo5.nim ================================================ import sdl2_nim/sdl, nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 5 (Collisions)", scaleQuality = 0): showInfo = true colliderOutline = true discard sdl.showCursor(0) game.scene = newMainScene() game.run() ================================================ FILE: demos/demo5/earth.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Earth* = ref object of Entity collidedWith*: seq[string] proc init*(entity: Earth) = entity.initEntity() entity.tags.add("Earth") entity.pos = (0.0, 150.0) entity.collidedWith = @[] proc newEarth*(): Earth = result = new Earth result.init() method update*(entity: Earth, elapsed: float) = entity.updateEntity(elapsed) entity.collidedWith = @[] method onCollide*(entity: Earth, target: Entity) = if target.tags.len > 0: entity.collidedWith.add(target.tags[0]) ================================================ FILE: demos/demo5/line.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Line* = ref object of Entity collidedWith*: seq[string] proc init*(entity: Line) = entity.initEntity() entity.tags.add("Line") entity.collidedWith = @[] proc newLine*(): Line = result = new Line result.init() method update*(entity: Line, elapsed: float) = entity.updateEntity(elapsed) entity.collidedWith = @[] method onCollide*(entity: Line, target: Entity) = if target.tags.len > 0: entity.collidedWith.add(target.tags[0]) ================================================ FILE: demos/demo5/mainscene.nim ================================================ import math, nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/texturegraphic, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types, cursor, earth, line, poly1, poly2, poly3, poly9, spaceman type MainScene = ref object of Scene cursorG, earthG, spacemanG: TextureGraphic c: Cursor e: Earth d1, d2: Line s: Spaceman p1: Poly1 p2: Poly2 p3: Poly3 p9: Poly9 proc init*(scene: MainScene) = Scene(scene).init() # Cursor scene.c = newCursor() scene.cursorG = newTextureGraphic() discard scene.cursorG.load("../assets/gfx/cursor.png") scene.c.graphic = scene.cursorG scene.c.collider = newCollider(scene.c) # Line 1 scene.d1 = newLine() scene.d1.pos = (50.0, 420.0) scene.d1.center = (25.0, 0.0) scene.d1.collider = scene.d1.newLineCollider((-25, 0), (25, 0)) # Line 2 scene.d2 = newLine() scene.d2.pos = (50.0, 450.0) scene.d2.collider = scene.d2.newLineCollider((0, 0), (100, 0)) # Earth scene.e = newEarth() scene.earthG = newTextureGraphic() discard scene.earthG.load("../assets/gfx/earth.png") scene.e.graphic = scene.earthG let radius = scene.earthG.dim.w.float / 2 scene.e.collider = newCircleCollider(scene.e, (radius, radius), radius) # Spaceman scene.s = newSpaceman() scene.spacemanG = newTextureGraphic() discard scene.spacemanG.load("../assets/gfx/spaceman.png") scene.s.graphic = scene.spacemanG scene.s.centrify() scene.s.collider = newBoxCollider(scene.s, (0, 0), scene.spacemanG.dim) # Poly1 scene.p1 = newPoly1() scene.p1.pos = (350, 160) # Poly2 scene.p2 = newPoly2() scene.p2.pos = (350, 210) # Poly3 scene.p3 = newPoly3() scene.p3.pos = (350, 260) # Poly9 scene.p9 = newPoly9() scene.p9.pos = (350, 360) # add to scene scene.add(scene.d1) scene.add(scene.d2) scene.add(scene.s) scene.add(scene.e) scene.add(scene.c) scene.add(scene.p1) scene.add(scene.p2) scene.add(scene.p3) scene.add(scene.p9) proc free*(scene: MainScene) = scene.earthG.free scene.spacemanG.free proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false of K_Space: colliderOutline = not colliderOutline else: discard proc generateCollisionString(name: string, list: seq[string]): string = if list.len > 0: result = name & " collides with: " for tag in list: result.add(tag & ", ") result = result[0 .. ^3] else: result = name & " isn't colliding with anything" method render*(scene: MainScene) = scene.renderScene() discard box((4, 60), (380, 140), 0x000000CC'u32) discard string( (8, 64), generateCollisionString("Cursor", scene.c.collidedWith), 0xFFFFFFFF'u32) discard string( (8, 72), generateCollisionString("Line", scene.d1.collidedWith), 0xFFFFFFFF'u32) discard string( (8, 80), generateCollisionString("Earth", scene.e.collidedWith), 0xFFFFFFFF'u32) discard string( (8, 88), generateCollisionString("Spaceman", scene.s.collidedWith), 0xFFFFFFFF'u32) discard string( (8, 96), generateCollisionString("Poly9", scene.p9.collidedWith), 0xFFFFFFFF'u32) discard string( (8, 120), "Space toggles outlines, Arrows control spaceman", 0xFFFFFFFF'u32) discard string( (8, 128), "WASDQE control line, IJKLUO control polygon", 0xFFFFFFFF'u32) method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) # Spaceman if ScancodeRight.down: scene.s.pos.x += 1 if ScancodeLeft.down: scene.s.pos.x -= 1 if ScancodeDown.down: scene.s.pos.y += 1 if ScancodeUp.down: scene.s.pos.y -= 1 # Line if ScancodeD.down: scene.d1.pos.x += 1 if ScancodeA.down: scene.d1.pos.x -= 1 if ScancodeS.down: scene.d1.pos.y += 1 if ScancodeW.down: scene.d1.pos.y -= 1 if ScancodeQ.down: scene.d1.rot -= 1 if ScancodeE.down: scene.d1.rot += 1 # Poly9 if ScancodeL.down: scene.p9.pos.x += 1 if ScancodeJ.down: scene.p9.pos.x -= 1 if ScancodeK.down: scene.p9.pos.y += 1 if ScancodeI.down: scene.p9.pos.y -= 1 if ScancodeU.down: scene.p9.rot -= 1 if ScancodeO.down: scene.p9.rot += 1 ================================================ FILE: demos/demo5/poly1.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Poly1* = ref object of Entity collidedWith*: seq[string] proc init*(entity: Poly1) = entity.initEntity() entity.tags.add("Poly1") entity.collider = entity.newPolyCollider((0.0, 0.0), [ (0.0, 0.0)]) entity.collidedWith = @[] proc newPoly1*(): Poly1 = result = new Poly1 result.init() method update*(entity: Poly1, elapsed: float) = entity.updateEntity(elapsed) entity.collidedWith = @[] method onCollide*(entity: Poly1, target: Entity) = if target.tags.len > 0: entity.collidedWith.add(target.tags[0]) ================================================ FILE: demos/demo5/poly2.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Poly2* = ref object of Entity collidedWith*: seq[string] proc init*(entity: Poly2) = entity.initEntity() entity.tags.add("Poly2") entity.collider = entity.newPolyCollider((0.0, 0.0), [ (0.0, 0.0), (50.0, 0.0)]) entity.collidedWith = @[] proc newPoly2*(): Poly2 = result = new Poly2 result.init() method update*(entity: Poly2, elapsed: float) = entity.updateEntity(elapsed) entity.collidedWith = @[] method onCollide*(entity: Poly2, target: Entity) = if target.tags.len > 0: entity.collidedWith.add(target.tags[0]) ================================================ FILE: demos/demo5/poly3.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Poly3* = ref object of Entity collidedWith*: seq[string] proc init*(entity: Poly3) = entity.initEntity() entity.tags.add("Poly3") entity.collider = entity.newPolyCollider((0.0, 0.0), [ (0.0, 0.0), (50.0, 0.0), (25.0, 35.0)]) entity.collidedWith = @[] proc newPoly3*(): Poly3 = result = new Poly3 result.init() method update*(entity: Poly3, elapsed: float) = entity.updateEntity(elapsed) entity.collidedWith = @[] method onCollide*(entity: Poly3, target: Entity) = if target.tags.len > 0: entity.collidedWith.add(target.tags[0]) ================================================ FILE: demos/demo5/poly9.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Poly9* = ref object of Entity collidedWith*: seq[string] proc init*(entity: Poly9) = entity.initEntity() entity.tags.add("Poly9") entity.centrify entity.collider = entity.newPolyCollider((0.0, 0.0), [ (-40.0, -50.0), (-20.0, -50.0), (-30.0, 20.0), ( 30.0, 20.0), ( 20.0, -50.0), ( 40.0, -50.0), ( 40.0, 30.0), ( 0.0, 50.0), (-40.0, 30.0)]) entity.collidedWith = @[] proc newPoly9*(): Poly9 = result = new Poly9 result.init() method update*(entity: Poly9, elapsed: float) = entity.updateEntity(elapsed) entity.collidedWith = @[] method onCollide*(entity: Poly9, target: Entity) = if target.tags.len > 0: entity.collidedWith.add(target.tags[0]) ================================================ FILE: demos/demo5/spaceman.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Spaceman* = ref object of Entity collidedWith*: seq[string] proc init*(entity: Spaceman) = entity.initEntity() entity.tags.add("Spaceman") entity.pos = (450.0, 100.0) entity.collidedWith = @[] proc newSpaceman*(): Spaceman = result = new Spaceman result.init() method update*(entity: Spaceman, elapsed: float) = entity.updateEntity(elapsed) entity.collidedWith = @[] method onCollide*(entity: Spaceman, target: Entity) = if target.tags.len > 0: entity.collidedWith.add(target.tags[0]) ================================================ FILE: demos/demo6/README.md ================================================ Nimgame 2: Demo 6 ================= Grouping demo. Demonstrates effects of setting up entity parent. ![Screenshot](demo6.png) ================================================ FILE: demos/demo6/demo6.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 6 (Grouping)", scaleQuality = 0): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo6/earth.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Earth* = ref object of Entity proc init*(entity: Earth) = entity.initEntity() entity.tags.add("Earth") entity.pos = (320.0, 240.0) proc newEarth*(): Earth = result = new Earth result.init() ================================================ FILE: demos/demo6/mainscene.nim ================================================ import math, nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/texturegraphic, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types, earth, spaceman type MainScene = ref object of Scene cursorG, earthG, spacemanG: TextureGraphic e: Earth s: Spaceman proc init*(scene: MainScene) = Scene(scene).init() # Earth scene.e = newEarth() scene.earthG = newTextureGraphic() discard scene.earthG.load("../assets/gfx/earth.png") scene.e.graphic = scene.earthG scene.e.centrify() scene.e.collider = scene.e.newCircleCollider((0, 0), 128) # Spaceman scene.s = newSpaceman() scene.spacemanG = newTextureGraphic() discard scene.spacemanG.load("../assets/gfx/spaceman.png") scene.s.graphic = scene.spacemanG scene.s.centrify() scene.s.parent = scene.e scene.s.collider = scene.s.newBoxCollider((0, 0), (100, 160)) # add to scene scene.add(scene.s) scene.add(scene.e) proc free*(scene: MainScene) = scene.earthG.free scene.spacemanG.free proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false of K_Space: colliderOutline = not colliderOutline else: discard method render*(scene: MainScene) = scene.renderScene() discard box((4, 60), (260, 100), 0x000000CC'u32) discard string((8, 64), "WASD - move group", 0xFFFFFFFF'u32) discard string((8, 72), "QE - rotate group", 0xFFFFFFFF'u32) discard string((8, 80), "RF - scale group", 0xFFFFFFFF'u32) discard string((8, 88), "Space - toggle outlines", 0xFFFFFFFF'u32) method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) if ScancodeD.down: scene.e.pos.x += 1 if ScancodeA.down: scene.e.pos.x -= 1 if ScancodeS.down: scene.e.pos.y += 1 if ScancodeW.down: scene.e.pos.y -= 1 if ScancodeQ.down: scene.e.rot -= 1 if ScancodeE.down: scene.e.rot += 1 if ScancodeR.down: scene.e.scale -= 0.01 if ScancodeF.down: scene.e.scale += 0.01 ================================================ FILE: demos/demo6/spaceman.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Spaceman* = ref object of Entity proc init*(entity: Spaceman) = entity.initEntity() entity.tags.add("Spaceman") entity.pos = (200.0, 0.0) proc newSpaceman*(): Spaceman = result = new Spaceman result.init() method update*(entity: Spaceman, elapsed: float) = entity.updateEntity(elapsed) ================================================ FILE: demos/demo7/README.md ================================================ Nimgame 2: Demo 7 ================= Text demo. Demonstrates bitmap and TrueType fonts. ![Screenshot](demo7.png) ================================================ FILE: demos/demo7/demo7.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 6 (Text)", scaleQuality = 0): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo7/earth.nim ================================================ import nimgame2/nimgame, nimgame2/entity type Earth* = ref object of Entity proc init*(entity: Earth) = entity.initEntity() entity.tags.add("Earth") entity.pos = (0.0, 50.0) proc newEarth*(): Earth = result = new Earth result.init() ================================================ FILE: demos/demo7/mainscene.nim ================================================ import math, nimgame2/nimgame, nimgame2/font, nimgame2/bitmapfont, nimgame2/truetypefont, nimgame2/draw, nimgame2/entity, nimgame2/graphic, nimgame2/textgraphic, nimgame2/texturegraphic, nimgame2/typewriter, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types, earth type MainScene = ref object of Scene earthG: TextureGraphic e: Earth bmFont: BitmapFont bmText: TextGraphic bmEntity: Entity ttFont: TrueTypeFont ttText: TextGraphic ttEntity: Entity twText: TextGraphic twEntity: Typewriter proc init*(scene: MainScene) = Scene(scene).init() # Earth scene.e = newEarth() scene.earthG = newTextureGraphic() discard scene.earthG.load("../assets/gfx/earth.png") scene.e.graphic = scene.earthG # BitmapFont scene.bmFont = newBitmapFont() discard scene.bmFont.load("../assets/fnt/default8x16.png", (8, 16)) # TrueTypeFont scene.ttFont = newTrueTypeFont() discard scene.ttFont.load("../assets/fnt/FSEX300.ttf", 16) # Text scene.bmText = newTextGraphic() scene.bmText.font = scene.bmFont scene.bmText.lines = [ "The quick brown fox", "jumps over the lazy dog"] scene.ttText = newTextGraphic() scene.ttText.font = scene.ttFont scene.ttText.lines = [ "В чащах юга жил бы цитрус?", "Да, но фальшивый экземпляр!"] scene.twText = newTextGraphic() scene.twText.font = scene.ttFont # Entity scene.bmEntity = newEntity() scene.bmEntity.pos = (8, 128) scene.bmEntity.graphic = scene.bmText scene.ttEntity = newEntity() scene.ttEntity.pos = (8, 192) scene.ttEntity.graphic = scene.ttText scene.twEntity = newTypewriter(scene.twText, 0.1) #scene.twEntity.width = 10 # uncomment to enable text wrapping scene.twEntity.pos = (300, 8) scene.twEntity.add "Fancy typewriter effect!" # add to scene scene.add(scene.bmEntity) scene.add(scene.ttEntity) scene.add(scene.twEntity) scene.add(scene.e) proc free*(scene: MainScene) = scene.bmFont.free() scene.ttFont.free() scene.bmText.free() scene.ttText.free() proc newMainScene*(): MainScene = new result, free result.init() proc changeAlign(scene: MainScene, increase = true) = # get var a = scene.bmText.align # change if increase: if a.int == 0: a = TextAlign(1) elif a < TextAlign.high: a = TextAlign(a.int shl 1) else: # decrease if a.int > 0: a = TextAlign(a.int shr 1) # set scene.bmText.align = a scene.ttText.align = a let colors = [0xFFFFFFFF'u32, 0xFF0000FF'u32, 0x00FF00FF'u32, 0x0000FFFF'u32] colorNames = ["white", "red", "green", "blue"] var clr = 0 proc changeColor(scene: MainScene, increase = true) = # get alpha let a = scene.bmText.color.a # change if increase: if clr < colors.high: inc clr else: # decrease if clr > 0: dec clr # set var color: Color = colors[clr] color.a = a scene.bmText.color = color scene.ttText.color = color proc changeAlpha(scene: MainScene, increase = true) = # get var c = scene.bmText.color a = c.a.int # change if increase: a += 15 else: # decrease a -= 15 # check limits if a < 0: a = 0 if a > 255: a = 255 # set c.a = a.uint8 scene.bmText.color = c scene.ttText.color = c method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false of K_Q: scene.changeAlign() of K_A: scene.changeAlign(false) of K_W: scene.changeColor() of K_S: scene.changeColor(false) of K_E: scene.changeAlpha() of K_D: scene.changeAlpha(false) else: discard method render*(scene: MainScene) = scene.renderScene() discard box((4, 60), (260, 100), 0x000000CC'u32) discard string((8, 64), "BitmapFont and TrueTypeFont:", 0xFFFFFFFF'u32) discard string((8, 72), "QA - change alignment: " & $scene.bmText.align, 0xFFFFFFFF'u32) discard string((8, 80), "WS - change color: " & colorNames[clr], 0xFFFFFFFF'u32) discard string((8, 88), "ED - change alpha: " & $scene.bmText.color.a.int, 0xFFFFFFFF'u32) method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) if ScancodeReturn.down: scene.twEntity.force() ================================================ FILE: demos/demo8/README.md ================================================ Nimgame 2: Demo 8 ================= ProcGraphic demo. Demonstrates procedural graphics. ![Screenshot](demo8.png) ================================================ FILE: demos/demo8/demo8.nim ================================================ import nimgame2/nimgame, nimgame2/settings, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 8 (ProcGraphic)", scaleQuality = 0): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo8/mainscene.nim ================================================ import math, nimgame2/nimgame, nimgame2/draw, nimgame2/entity, nimgame2/graphic, nimgame2/input, nimgame2/procgraphic, nimgame2/scene, nimgame2/settings, nimgame2/types, nimgame2/utils type MainScene = ref object of Scene polyG: ProcGraphic poly: Entity const polyLines0 = [ ( 0.0, -70.0), ( 40.0, -30.0), ( 80.0, -50.0), ( 60.0, 30.0), (-60.0, 30.0), (-80.0, -50.0), (-40.0, -30.0)] const polyLines1 = [ ((-30.0, 10.0), (-30.0, -10.0)), ((-30.0, -10.0), (-10.0, 10.0)), ((-10.0, 10.0), (-10.0, -10.0)), (( 0.0, -10.0), ( 0.0, 10.0)), (( 10.0, 10.0), ( 10.0, -10.0)), (( 10.0, -10.0), ( 20.0, 0.0)), (( 20.0, 0.0), ( 30.0, -10.0)), (( 30.0, -10.0), ( 30.0, 10.0))] proc polyProc(graphic: ProcGraphic, pos: Coord, angle: Angle, scale: Scale, center: Coord, flip: Flip, region: Rect) = let color0: Color = 0xFFFF00FF'u32 color1: Color = 0x000000FF'u32 var poly: seq[Coord] = @[] for p in polyLines0: poly.add(rotate(p, (0.0, 0.0), angle) * scale + pos) discard polygon(poly, color0, DrawMode.filled) for i in polyLines1: let p0 = rotate(i[0], (0.0, 0.0), angle) * scale + pos p1 = rotate(i[1], (0.0, 0.0), angle) * scale + pos discard aaLine(p0, p1, color1) proc init*(scene: MainScene) = Scene(scene).init() # Poly scene.poly = newEntity() scene.polyG = newProcGraphic() scene.polyG.procedure = polyProc scene.poly.graphic = scene.polyG scene.poly.pos = (320, 240) # add to scene scene.add(scene.poly) proc free*(scene: MainScene) = discard proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false else: discard method render*(scene: MainScene) = scene.renderScene() discard box((4, 60), (260, 92), 0x000000CC'u32) discard string((8, 64), "WSAD - move", 0xFFFFFFFF'u32) discard string((8, 72), "QE - rotate", 0xFFFFFFFF'u32) discard string((8, 80), "RF - scale", 0xFFFFFFFF'u32) method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) if ScancodeA.down: scene.poly.pos.x -= 1 if ScancodeD.down: scene.poly.pos.x += 1 if ScancodeW.down: scene.poly.pos.y -= 1 if ScancodeS.down: scene.poly.pos.y += 1 if ScancodeQ.down: scene.poly.rot -= 1 if ScancodeE.down: scene.poly.rot += 1 if ScancodeR.down: scene.poly.scale -= 0.01 if ScancodeF.down: scene.poly.scale += 0.01 ================================================ FILE: demos/demo9/README.md ================================================ Nimgame 2: Demo 9 ================= Audio demo. Demonstrates sound effects. ![Screenshot](demo9.png) ================================================ FILE: demos/demo9/demo9.nim ================================================ import nimgame2/nimgame, nimgame2/settings, nimgame2/assets, nimgame2/texturegraphic, mainscene game = newGame() if game.init(w = 640, h = 480, title = "Nimgame 2: Demo 9 (Audio)", scaleQuality = 0): showInfo = true game.scene = newMainScene() game.run() ================================================ FILE: demos/demo9/mainscene.nim ================================================ import math, nimgame2/assets, nimgame2/audio, nimgame2/nimgame, nimgame2/draw, nimgame2/input, nimgame2/scene, nimgame2/settings, nimgame2/types, nimgame2/utils type MainScene = ref object of Scene tack: Sound var musicData: Assets[Music] proc init*(scene: MainScene) = Scene(scene).init() # Sound scene.tack = newSound("../assets/sfx/tack.wav") scene.tack.volume = Volume.high div 2 # Music musicData = newAssets[Music]("../assets/mus", proc(file: string): Music = newMusic(file)) playlist = newPlaylist() for track in musicData.values: playlist.list.add(track) proc free*(scene: MainScene) = discard proc newMainScene*(): MainScene = new result, free result.init() method event*(scene: MainScene, event: Event) = if event.kind == KeyDown: case event.key.keysym.sym: of K_Escape: gameRunning = false of K_Space: discard scene.tack.play() of K_M: discard playlist.play() else: discard method render*(scene: MainScene) = scene.renderScene() discard box((4, 60), (260, 92), 0x000000CC'u32) discard string((8, 64), "Space - play sound", 0xFFFFFFFF'u32) discard string((8, 72), "Up/Down - sound volume: " & $scene.tack.volume, 0xFFFFFFFF'u32) discard string((8, 80), "M - play random music track", 0xFFFFFFFF'u32) discard string((8, 88), "PgUp/PgDn - music volume: " & $getMusicVolume(), 0xFFFFFFFF'u32) method update*(scene: MainScene, elapsed: float) = scene.updateScene(elapsed) if ScancodeUp.down: scene.tack.volumeInc(1) if ScancodeDown.down: scene.tack.volumeDec(1) if ScancodePageUp.down: musicVolumeInc(1) if ScancodePageDown.down: musicVolumeDec(1) ================================================ FILE: demos/nim.cfg ================================================ --multimethods:on ================================================ FILE: docs/changelog.html ================================================ Nimgame 2

CHANGELOG

v0.5 alpha (2017-08-01)

  • changed physics and logic systems
  • platformer physics
  • CoordInt type
  • now collider module is autmatically included into the entity module
  • group collider
  • huge Tilemap optimizations
  • various utility Tilemap procedures
  • TextureGraphic.drawTiled
  • GUI:
    • GUIProgressBar
    • widget actions
  • various minor changes and upgrades
  • Nim v0.17.0 transition
  • documentation, snippets, and demos update
  • second tutorial

v0.4 alpha (2017-05-04)

  • GUI:
    • RadioGroup
    • RadioButton
  • IndexedImage
  • PerspectiveImage
  • TextureAtlas
  • joysticks support
  • window management procedures
  • 4 new demos
  • first tutorial

v0.3 alpha (2017-03-10)

  • camera property (Scene)
  • new collision procedures
  • reworked input
  • Mosaic
  • parallax property (Entity)
  • TextField
  • GUI:
    • Widget
    • Button
    • TextInput
  • 3 new demos
  • home page, snippets, and documentation

v0.2 alpha (2017-01-31)

  • collider optimizations
  • music playlists
  • random procedures
  • tilemaps
  • tweens
  • emitters
  • various fixes
  • 4 new demos

v0.1 alpha (2017-01-16)

  • base scene/entity system
  • assets manager
  • basic sound and music
  • colliders (point, box, circle, line, and polygon)
  • fonts (bitmap and TrueType) and text output
  • keyboard and mouse input
  • vector drawing procedures
================================================ FILE: docs/demos.html ================================================ Nimgame 2

DEMOS

Game Demos

Feature Demos

================================================ FILE: docs/docs/assets.html ================================================ assets

assets

Search:
Group by:

Types

Assets[T] = OrderedTableRef[string, T]

Procs

proc newAssets[T](files: openArray[string]; init: proc (file: string): T): Assets[T]

Create a new assets collection.

files an array of target files.

init T's init/load procedure.

proc newAssets[T](dir: string; init: proc (file: string): T): Assets[T]

Create a new assets collection.

dir target directory.

init T's init/load procedure.

================================================ FILE: docs/docs/audio.html ================================================ audio

audio

Types

Channel = int
Distance = range[0 .. 255]
Panning = range[0 .. 255]
Volume = range[0 .. mix.MaxVolume]
Sound = ref object of RootObj
  fChunk: mix.Chunk
  fChannel: Channel
Music = ref object of RootObj
  fMusic: mix.Music
Playlist = ref object of RootObj
  list*: seq[Music]
  fIndex: int
  fFinished: bool

Vars

playlist: Playlist = nil

Procs

proc free(sound: Sound) {...}{.raises: [], tags: [].}
proc load(sound: Sound; file: string): bool {...}{.raises: [], tags: [].}
proc load(sound: Sound; src: ptr RWops; freeSrc: bool = true): bool {...}{.raises: [], tags: [].}
proc newSound(file: string): Sound {...}{.raises: [], tags: [].}
proc newSound(src: ptr RWops; freeSrc: bool = true): Sound {...}{.raises: [], tags: [].}
proc available(sound: Sound): bool {...}{.raises: [], tags: [].}
Return true if the sound is ready to use, or false otherwise.
proc playing(sound: Sound): bool {...}{.raises: [], tags: [].}
Return true if the sound is playing, or false otherwise.
proc stop(sound: Sound) {...}{.raises: [], tags: [].}
Stop the sound.
proc play(sound: Sound; loops: int = 0): Channel {...}{.raises: [], tags: [].}

Play the sound loops + 1 times.

Return the channel the sound is played on.

proc channel(sound: Sound): Channel {...}{.raises: [], tags: [].}
Return the channel, the sound is played on.
proc paused(sound: Sound): bool {...}{.raises: [], tags: [].}
Return true if the sound is paused, or false otherwise.
proc pause(sound: Sound) {...}{.raises: [], tags: [].}
Pause the sound.
proc resume(sound: Sound) {...}{.raises: [], tags: [].}
Resume the sound if it is paused.
proc volume(sound: Sound): Volume {...}{.inline, raises: [], tags: [].}
Return the volume of the sound.
proc normalizeVolume(val: int): Volume {...}{.raises: [], tags: [].}
proc volume=(sound: Sound; val: Volume) {...}{.inline, raises: [], tags: [].}
Set sound volume.
proc setDistance(channel: Channel; distance: Distance) {...}{.inline, raises: [], tags: [].}
Set the distance on a channel.
distance:
0 - near (loud) 255 - far (quiet)
proc setPanning(channel: Channel; left: Panning = Panning.high;
               right: Panning = Panning.high) {...}{.inline, raises: [], tags: [].}

Set the panning on a channel.

Setting both left and right to 255 (Panning.high) will unregister the effect from channel.

proc setPosition(channel: Channel; angle: Angle; distance: Distance) {...}{.inline,
    raises: [], tags: [].}
Set the position on a channel.
angle:
0 - front 90 - right 180 - behind 270 - left
distance:
0 - near (loud) 255 - far (quiet)
proc soundStop() {...}{.inline, raises: [], tags: [].}
Stop all sound channels.
proc soundPlayingNum(): int {...}{.inline, raises: [], tags: [].}
Return the number of currently playing channels.
proc soundPausedNum(): int {...}{.inline, raises: [], tags: [].}
Return the number of currently paused channels.
proc soundPause() {...}{.inline, raises: [], tags: [].}
Pause all sound channels.
proc soundResume() {...}{.inline, raises: [], tags: [].}
Resume all sound channels.
proc getSoundVolume(): Volume {...}{.inline, raises: [], tags: [].}
Return average sound volume.
proc setSoundVolume(val: Volume) {...}{.inline, raises: [], tags: [].}
Set new volume for all sound channels.
proc free(music: Music) {...}{.raises: [], tags: [].}
proc load(music: Music; file: string): bool {...}{.raises: [], tags: [].}
proc load(music: Music; src: ptr RWops; freeSrc: bool = true): bool {...}{.raises: [], tags: [].}
proc newMusic(file: string): Music {...}{.raises: [], tags: [].}
proc newMusic(src: ptr RWops; freeSrc: bool = true): Music {...}{.raises: [], tags: [].}
proc available(music: Music): bool {...}{.inline, raises: [], tags: [].}
Return true if the music is ready to use, or false otherwise.
proc play(music: Music; loops: int = 0) {...}{.raises: [], tags: [].}
Play the music loops + 1 times.
proc musicPaused(): bool {...}{.inline, raises: [], tags: [].}
Return true if music is paused, or false otherwise.
proc musicPause() {...}{.inline, raises: [], tags: [].}
Pause music.
proc musicResume() {...}{.inline, raises: [], tags: [].}
Resume music.
proc musicRewind() {...}{.inline, raises: [], tags: [].}
Rewind music.
proc musicPlaying(): bool {...}{.inline, raises: [], tags: [].}
Return true if music is playing, or false otherwise.
proc musicStop() {...}{.inline, raises: [], tags: [].}
Stop music.
proc musicPosition(val: float) {...}{.inline, raises: [], tags: [].}

Set current position in the music stream.

Works only on MOD, OGG, and MP3 music:

MOD val is a pattern number.

OGG val is seconds from from the beginning.

MP3 val is seconds from the current position.

proc init(pl: Playlist) {...}{.raises: [], tags: [].}
proc newPlaylist(): Playlist {...}{.raises: [], tags: [].}
proc index(pl: Playlist): int {...}{.inline, raises: [], tags: [].}
Return current track index.
proc play(pl: Playlist; index: int = -1): int {...}{.raises: [], tags: [].}

Play a music track from the playlist.

index track index, or -1 for a random track.

Retrun current track index.

proc stop(pl: Playlist) {...}{.raises: [], tags: [].}
proc update(pl: Playlist) {...}{.raises: [], tags: [].}

Templates

template volumeInc(sound: Sound; val: int)
Increase sound volume by val.
template volumeDec(sound: Sound; val: int)
Decrease sound volume by val.
template playing(channel: Channel): bool
Return true if channel is playing right now, false otherwise.
template soundVolumeInc(val: int)
Increase global sound volume by val.
template soundVolumeDec(val: int)
Decrease global sound volume by val.
template setMusicVolume(val: Volume)
Set music volume, or return current setting, if val = -1.
template getMusicVolume(): Volume
template musicVolumeInc(val: int)
Increase music volume by val.
template musicVolumeDec(val: int)
Decrease music volume by val.
================================================ FILE: docs/docs/bitmapfont.html ================================================ bitmapfont

bitmapfont

Types

BitmapFont = ref object of Font
  fSurface: Surface            ## Source font surface
  fDim, fCharDim: Dim           ## Dimensions of the surface and a single character
  fChars: seq[CoordInt]        ## Coordinates of all characters
  

Procs

proc free(font: BitmapFont) {...}{.raises: [], tags: [].}
proc init(font: BitmapFont) {...}{.raises: [], tags: [].}
proc load(font: BitmapFont; file: string; charDim: Dim; offset: Dim = (0, 0);
         border: Dim = (0, 0)): bool {...}{.raises: [], tags: [].}

Load font data from a file.

charDim dimensions of a single font character.

offset offset from the edge of the texture.

border border around individual characters.

Return true on success, or false otherwise.

proc load(font: BitmapFont; src: ptr RWops; charDim: Dim; offset: Dim = (0, 0);
         border: Dim = (0, 0); freeSrc: bool = true): bool {...}{.raises: [], tags: [].}
proc newBitmapFont(): BitmapFont {...}{.raises: [], tags: [].}
proc newBitmapFont(file: string; charDim: Dim; offset: Dim = (0, 0); border: Dim = (0, 0)): BitmapFont {...}{.
    raises: [], tags: [].}
Create and load a new bitmap font from a file.
proc newBitmapFont(src: ptr RWops; charDim: Dim; offset: Dim = (0, 0);
                  border: Dim = (0, 0); freeSrc: bool = true): BitmapFont {...}{.raises: [],
    tags: [].}
proc renderBitmapFont(font: BitmapFont; line: string; color: Color = DefaultFontColor): Surface {...}{.
    raises: [Exception], tags: [RootEffect].}

Methods

method charH(font: BitmapFont): int {...}{.inline, raises: [], tags: [].}
Return a font character's height.
method lineDim(font: BitmapFont; line: string): Dim {...}{.inline, raises: [], tags: [].}
Return dimensions of a line of text, written in font.
method render(font: BitmapFont; line: string; color: Color = DefaultFontColor): Surface {...}{.
    raises: [Exception], tags: [RootEffect].}
================================================ FILE: docs/docs/count.html ================================================ Module count

Module count

Search:
Group by:

Types

CountMgr* = ref object
  counter: int
  timerId: sdl.TimerID
  current*: int
Current counter value   Source Edit

Procs

proc update*(mgr: CountMgr) {.
inline
.}
Increase the counter by one.   Source Edit
proc start*(mgr: CountMgr; interval: uint32 = 1000)

Start the timer.

interval Timer interval in ms.

  Source Edit
proc stop*(mgr: CountMgr)
Stop the timer.   Source Edit
proc free*(mgr: CountMgr)
  Source Edit
proc newCountMgr*(): CountMgr
  Source Edit
proc timeDiff*(first, second: uint64): int {.
inline
.}

first, second two results of sdl.getPerformanceCounter().

Return time difference between two time stamps (in ms).

  Source Edit
================================================ FILE: docs/docs/draw.html ================================================ draw

draw

Types

DrawMode {...}{.pure.} = enum
  default, aa, filled

Procs

proc pixel(pos: Coord; color: Color): bool {...}{.inline, raises: [], tags: [].}
Draw a single pixel.
proc hline(pos: Coord; length: float; color: Color): bool {...}{.inline, raises: [], tags: [].}
Draw a horizontal line from pos to the right.
proc vline(pos: Coord; height: float; color: Color): bool {...}{.inline, raises: [], tags: [].}
Draw a vertical line from pos down.
proc rect(pos1, pos2: Coord; color: Color): bool {...}{.inline, raises: [], tags: [].}
Draw a rectangle.
proc roundedRect(pos1, pos2: Coord; rad: float; color: Color): bool {...}{.inline, raises: [],
    tags: [].}
Draw a rounded rectangle.
proc box(pos1, pos2: Coord; color: Color): bool {...}{.inline, raises: [], tags: [].}
Draw a filled rectangle (box).
proc roundedBox(pos1, pos2: Coord; rad: float; color: Color): bool {...}{.inline, raises: [],
    tags: [].}
Draw a rounded filled rectangle (box).
proc line(pos1, pos2: Coord; color: Color): bool {...}{.inline, raises: [], tags: [].}
Draw a line.
proc aaLine(pos1, pos2: Coord; color: Color): bool {...}{.inline, raises: [], tags: [].}
Draw an anti-aliased line.
proc thickLine(pos1, pos2: Coord; width: float; color: Color): bool {...}{.inline, raises: [],
    tags: [].}
Draw a width pixels wide line.
proc circle(pos: Coord; rad: float; color: Color; mode: DrawMode = DrawMode.default): bool {...}{.
    raises: [], tags: [].}
Draw a circle.
proc arc(pos: Coord; rad, start, finish: Angle; color: Color): bool {...}{.inline, raises: [],
    tags: [].}
Draw an arc.
proc ellipse(pos, rad: Coord; color: Color; mode: DrawMode = DrawMode.default): bool {...}{.
    raises: [], tags: [].}
Draw an ellipse.
proc pie(pos: Coord; rad, start, finish: Angle; color: Color;
        mode: DrawMode = DrawMode.default): bool {...}{.raises: [], tags: [].}
Draw a circular sector (pie).
proc trigon(pos1, pos2, pos3: Coord; color: Color; mode: DrawMode = DrawMode.default): bool {...}{.
    raises: [], tags: [].}
Draw a trigon.
proc polygon(pos: openArray[Coord]; color: Color; mode: DrawMode = DrawMode.default;
            surface: sdl.Surface = nil; surfaceD: Coord = (0, 0)): bool {...}{.
    raises: [Exception], tags: [].}
Draw a polygon.
proc bezier(pos: openArray[Coord]; s: float; color: Color): bool {...}{.raises: [Exception],
    tags: [].}
Draw a bezier curve.
proc setFont(fontdata: pointer; dim: Dim) {...}{.raises: [], tags: [].}
Set sdl_gfx_primitives font.
proc character(pos: Coord; c: char; color: Color): bool {...}{.inline, raises: [], tags: [].}
Draw a single character.
proc string(pos: Coord; s: string; color: Color): bool {...}{.inline, raises: [], tags: [].}
Draw a string of text.

Templates

template setFont()
Set default sdl_gfx_primitives font.
template setFontRotation(rotation: uint32)
Set sdl_gfx_primitives font rotation.
================================================ FILE: docs/docs/emitter.html ================================================ emitter

emitter

Types

Particle = ref object of Entity
  ttl*: float                  ## Time to live (in seconds)
  
EmissionAreaKind = enum
  eaPoint, eaLine, eaCircle, eaBox
EmissionArea = object
  case kind*: EmissionAreaKind
  of eaPoint:
    nil
  of eaLine:
    length*: float             ## line length
  of eaCircle:
    radius*: float             ## circle radius
  of eaBox:
    dim*: Dim                  ## box dimensions
  
Emitter = ref object of Entity
  randomVel*, randomAcc*: Coord ## Ranges of vel and acc deviation
  randomRot*, randomRotVel*: Angle ## Ranges of rot and rotVel deviation
  randomScale*: Scale          ## Range of scale deviation
  randomTTL*: float            ## Range of TTL deviation
  scene*: Scene                ## Target scene
  area*: EmissionArea          ## Area of particle emission
  particle*: Particle          ## A stencil particle, its properties will be \\
                    ## assigned to any created particles.
  

Procs

proc initParticle(particle: Particle) {...}{.raises: [], tags: [].}
proc newParticle(): Particle {...}{.raises: [], tags: [].}
proc updateParticle(particle: Particle; elapsed: float) {...}{.raises: [Exception],
    tags: [RootEffect].}
proc initEmitter(emitter: Emitter; scene: Scene; area = eaPoint) {...}{.raises: [], tags: [].}
Create a new Emitter for the scene.
proc newEmitter(scene: Scene; area = eaPoint): Emitter {...}{.raises: [], tags: [].}
Create a new Emitter in the scene.
proc emit(emitter: Emitter; amount: int = 1; procedure: proc (p: Particle) = nil) {...}{.
    raises: [], tags: [].}
Emit an amount of particles, apply the procedure for each emitted particle.

Methods

method update(particle: Particle; elapsed: float) {...}{.raises: [Exception],
    tags: [RootEffect].}

Templates

template copy(target, source: Particle)
Copy source properties to the target.
================================================ FILE: docs/docs/entity.html ================================================ entity

entity

Search:
Group by:

Do not import this file. It is included in entity.nim automatically.

Types

Animation = object
  frames*: seq[int]            ## List of animation's frame indexes
  frameRate*: float            ## Frame rate (in seconds per frame)
  flip*: Flip                  ## Flip flag
  
AnimationCallback = proc (entity: Entity; index: int)

Called after animation is finished (see play() procedure).

index The index of the finished animation.

Sprite = ref object
  animationKeys*: seq[string]  ## List of animation names
  animations*: seq[Animation]  ## List of animations
  currentAnimationIndex*: int  ## Index of currently playing animation
  currentFrame*: int           ## Index of current frame in currentAnimation \
                   ## (or in ``frames``, if no currentAnimation is set)
  cycles*: int                 ## Animation cycles counter (`-1` for looping)
  kill*: bool                  ## Kill when animation is finished
  callback*: AnimationCallback ## Call this when animation is finished
  time*: float                 ## Animation timer
  playing*: bool               ## Animation playing flag
  dim*: Dim                    ## Sprite frame dimensions
  frames*: seq[Rect]           ## Frames' coordinates
  
Collider = ref object of RootObj
  parent*: Entity
  tags*: seq[string]           ## only check collisios with entities with given tags
  pos*: Coord
BoxCollider = ref object of Collider
  dim*: Dim
CircleCollider = ref object of Collider
  radius*: float
LineCollider = ref object of Collider
  pos2*: Coord
PolyCollider = ref object of Collider
  farthest: float
  points*: seq[Coord]
GroupCollider = ref object of Collider
  list*: seq[Collider]
Entity = ref object of RootObj
  fLayer: int                  ## Rendering layer
  fBlinkTimer: float           ## Used internally for blinking
  parent*: Entity              ## Parent entity reference
  tags*: seq[string]           ## List of entity tags
  dead*: bool                  ## `true` if marked for removal
  updLayer*: bool              ## `true` if entity's layer was changed
  graphic*: Graphic
  sprite*: Sprite
  logic*: LogicProc
  physics*: PhysicsProc
  fastPhysics*: bool           ## rough and fast physics flag
  collisionEnvironment*: seq[Entity] ## List of collidable entites
                                   ## used in some physics procedures
  collider*: Collider
  colliding*: seq[Entity]      ## List of Entities currently colliding with
  pos*, vel*, acc*, drg*: Coord   ## Position, velocity, acceleration, drag
  rot*: Angle                  ## Rotation angle in degrees
  rotVel*, rotAcc*, rotDrg*: Angle ## Rotation velocity, acceleration, drag
  parallax*, scale*: Scale      ## Parallax and scale ratio
  scaleVel*, scaleAcc*, scaleDrg*: Scale ## Scale's velocity, accel., and drag
  center*: Coord               ## Center for drawing and rotating
  flip*: Flip                  ## Texture flip status
  visible*: bool               ## Visibility status
  blinking*: bool              ## Blinking status
  blinkOn*, blinkOff*: float    ## Blinking rate (in seconds)
  
LogicProc = proc (entity: Entity; elapsed: float)
PhysicsProc = proc (entity: Entity; elapsed: float)

Procs

proc initSprite(entity: Entity; dim: Dim; offset: Dim = (0, 0); border: Dim = (0, 0)) {...}{.
    raises: [Exception], tags: [RootEffect].}

Creeate a sprite for the given entity with the attached Graphic.

dim dimensions of one frame.

offset offset from the edge of the texture.

border border around individual frames.

proc animationIndex(sprite: Sprite; name: string): int {...}{.inline, raises: [], tags: [].}
Return the index of the animation named name.
proc animation(sprite: Sprite; name: string): var Animation {...}{.raises: [], tags: [].}
proc animation(sprite: Sprite; index: int): var Animation {...}{.raises: [], tags: [].}
proc currentAnimation(sprite: Sprite): var Animation {...}{.raises: [], tags: [].}
Return the current animation.
proc currentAnimationName(sprite: Sprite): string {...}{.raises: [], tags: [].}
Return the name of the current animation, or empty string if none.
proc changeFramerate(sprite: Sprite; frameRate: float = 0.1) {...}{.raises: [], tags: [].}
Change framerate for all created animations.
proc addAnimation(sprite: Sprite; name: string; frames: openArray[int];
                 frameRate: float = 0.1; flip: Flip = Flip.none): bool {...}{.raises: [],
    tags: [].}

Add a new animation to the sprite.

name name of the animation.

frames array of animation frames' indexes.

frameRate animation speed in seconds per frame.

flip animation flip flag.

proc play(sprite: Sprite; anim: string; cycles = -1; kill: bool = false;
         callback: AnimationCallback = nil) {...}{.raises: [], tags: [].}

Start playing the animation.

anim name of the animation.

cycles number of times to repeat the animation, or -1 for looping.

kill kill when finished.

callback called when animation is finished.

proc defaultPhysics(entity: Entity; elapsed: float) {...}{.raises: [], tags: [].}

Default physics procedure. Disabled by default.

Assign it as your entity's physics.

proc platformerPhysics(entity: Entity; elapsed: float) {...}{.raises: [Exception],
    tags: [RootEffect].}

Platformer physics procedure.

Assign it as your entity's physics.

proc initEntity(entity: Entity) {...}{.raises: [], tags: [].}

Default entity initialization procedure.

Call it after creating a new entity.

proc newEntity(): Entity {...}{.raises: [], tags: [].}
proc layer(entity: Entity): int {...}{.inline, raises: [], tags: [].}
Return current rendering layer of the entity.
proc layer=(entity: Entity; val: int) {...}{.raises: [], tags: [].}
Change the rendering layer of the entity.
proc copy(target, source: Entity) {...}{.raises: [], tags: [].}

Copy source's properties to the other entity.

No new objects will be allocated.

proc absRot(entity: Entity): Angle {...}{.raises: [], tags: [].}
Return the absolute (counting the parent's) rotation angle of the entity.
proc absScale(entity: Entity): Scale {...}{.raises: [], tags: [].}
Return the absolute (counting the parent's) scale of the entity.
proc absPos(entity: Entity): Coord {...}{.raises: [], tags: [].}
Return the absolute (counting the parent's) scale of the entity.
proc centrify(entity: Entity; hor = HAlign.center; ver = VAlign.center) {...}{.
    raises: [Exception], tags: [RootEffect].}

Set entity's center, according to the given align.

hor Horisontal align: left, center, or right

ver Vertical align: top, center, or bottom

proc renderEntity(entity: Entity) {...}{.raises: [Exception], tags: [RootEffect].}

Default entity render procedure.

Call it from your entity render method.

proc updateEntity(entity: Entity; elapsed: float) {...}{.raises: [Exception],
    tags: [RootEffect].}

Default entity update procedure.

Call it from your entity update method.

proc init(a: Collider; parent: Entity; pos: Coord = (0, 0)) {...}{.raises: [], tags: [].}
proc newCollider(parent: Entity; pos: Coord = (0, 0)): Collider {...}{.raises: [], tags: [].}
proc renderCollider(a: Collider) {...}{.raises: [], tags: [].}
proc init(b: BoxCollider; parent: Entity; pos: Coord = (0, 0); dim: Dim = (0, 0)) {...}{.raises: [],
    tags: [].}
proc newBoxCollider(parent: Entity; pos: Coord = (0, 0); dim: Dim = (0, 0)): BoxCollider {...}{.
    raises: [], tags: [].}
proc init(c: CircleCollider; parent: Entity; pos: Coord = (0, 0); radius: float = 0) {...}{.
    raises: [], tags: [].}
proc newCircleCollider(parent: Entity; pos: Coord = (0, 0); radius: float = 0): CircleCollider {...}{.
    raises: [], tags: [].}
proc init(d: LineCollider; parent: Entity; pos: Coord = (0, 0); pos2: Coord = (0, 0)) {...}{.
    raises: [], tags: [].}
proc newLineCollider(parent: Entity; pos: Coord = (0, 0); pos2: Coord = (0, 0)): LineCollider {...}{.
    raises: [], tags: [].}
proc init(p: PolyCollider; parent: Entity; pos: Coord = (0, 0); points: openArray[Coord]) {...}{.
    raises: [], tags: [].}
proc updateFarthest(p: PolyCollider) {...}{.inline, raises: [], tags: [].}
Call this procedure any time you changed points' coordinates.
proc newPolyCollider(parent: Entity; pos: Coord = (0, 0); points: openArray[Coord]): PolyCollider {...}{.
    raises: [], tags: [].}
proc init(g: GroupCollider; parent: Entity) {...}{.raises: [], tags: [].}
proc newGroupCollider(parent: Entity): GroupCollider {...}{.raises: [], tags: [].}
proc checkCollisions(entity: Entity; list: seq[Entity]) {...}{.raises: [Exception],
    tags: [RootEffect].}
Trigger onCollide method of entity with a given list of targets.
proc isColliding(entity: Entity; list: seq[Entity]): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
Return true if entity collides with one of the elements in the given list, or false if no collisions occurs.
proc willCollide(entity: Entity; pos: Coord; rot: Angle; scale: Scale; list: seq[Entity]): bool {...}{.
    raises: [Exception], tags: [RootEffect].}
Return true if entity will collide with one of the elements in the given list, if entity's coordinates or dimentsions will change.

Methods

method event(entity: Entity; e: sdl.Event) {...}{.base, raises: [], tags: [].}
method render(entity: Entity) {...}{.base, raises: [Exception], tags: [RootEffect].}
method update(entity: Entity; elapsed: float) {...}{.base, raises: [Exception],
    tags: [RootEffect].}
method onCollide(entity, target: Entity) {...}{.base, raises: [], tags: [].}
Called when entity collides with target.
method collide(pos: Coord; a: Collider): bool {...}{.base, inline, raises: [], tags: [].}
method collide(pos: Coord; b: BoxCollider): bool {...}{.inline, raises: [], tags: [].}
method collide(pos: Coord; c: CircleCollider): bool {...}{.inline, raises: [], tags: [].}
method collide(pos: Coord; d: LineCollider): bool {...}{.raises: [], tags: [].}
method collide(pos: Coord; p: PolyCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method render(a: Collider) {...}{.base, raises: [], tags: [].}
method collide(a: Collider; pos: Coord): bool {...}{.base, inline, raises: [Exception],
    tags: [RootEffect].}
method collide(a1, a2: Collider): bool {...}{.base, inline, raises: [], tags: [].}
method collide(a: Collider; b: BoxCollider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(a: Collider; c: CircleCollider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(a: Collider; d: LineCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(a: Collider; p: PolyCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(a: Collider; g: GroupCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method render(b: BoxCollider) {...}{.raises: [], tags: [].}
method collide(b: BoxCollider; pos: Coord): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(b: BoxCollider; a: Collider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(b1, b2: BoxCollider): bool {...}{.raises: [], tags: [].}
method collide(b: BoxCollider; c: CircleCollider): bool {...}{.raises: [], tags: [].}
method collide(b: BoxCollider; d: LineCollider): bool {...}{.raises: [], tags: [].}
method collide(b: BoxCollider; p: PolyCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(b: BoxCollider; g: GroupCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method render(c: CircleCollider) {...}{.raises: [], tags: [].}
method collide(c: CircleCollider; pos: Coord): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(c: CircleCollider; a: Collider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(c: CircleCollider; b: BoxCollider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(c1, c2: CircleCollider): bool {...}{.inline, raises: [], tags: [].}
method collide(c: CircleCollider; d: LineCollider): bool {...}{.raises: [], tags: [].}
method collide(c: CircleCollider; p: PolyCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(c: CircleCollider; g: GroupCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method render(d: LineCollider) {...}{.raises: [], tags: [].}
method collide(d: LineCollider; pos: Coord): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(d: LineCollider; a: Collider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(d: LineCollider; b: BoxCollider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(d: LineCollider; c: CircleCollider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(d1, d2: LineCollider): bool {...}{.raises: [], tags: [].}
method collide(d: LineCollider; p: PolyCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(d: LineCollider; g: GroupCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method render(p: PolyCollider) {...}{.raises: [Exception], tags: [RootEffect].}
method collide(p: PolyCollider; pos: Coord): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(p: PolyCollider; a: Collider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(p: PolyCollider; b: BoxCollider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(p: PolyCollider; c: CircleCollider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(p: PolyCollider; d: LineCollider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(p1, p2: PolyCollider): bool {...}{.raises: [Exception], tags: [RootEffect].}
method collide(p: LineCollider; g: GroupCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method render(g: GroupCollider) {...}{.raises: [Exception], tags: [RootEffect].}
method collide(g: GroupCollider; pos: Coord): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(g: GroupCollider; a: Collider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(g: GroupCollider; b: BoxCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(g: GroupCollider; c: CircleCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(g: GroupCollider; d: LineCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(g: GroupCollider; p: PolyCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}

Templates

template animationIndex(entity: Entity; name: string): int
Return the index of the animation named name.
template animation(entity: Entity; name: string): var Animation
Return the animation named name.
template animation(entity: Entity; index: int): var Animation
Return the animation under given index.
template currentAnimationIndex(entity: Entity): int
template currentAnimation(entity: Entity): var Animation
Return the current animation.
template currentAnimationName(entity: Entity): string
Return the name of the current animation or empty string if none.
template changeFramerate(entity: Entity; frameRate: float = 0.1)
Change framerate for all created animations.
template addAnimation(entity: Entity; name: string; frames: openArray[int];
                     frameRate: float = 0.1; flip: Flip = Flip.none): bool

Add a new animation to the entity.

name name of the animation.

frames array of animation frames' indexes.

frameRate animation speed in seconds per frame.

flip animation flip flag.

template play(entity: Entity; anim: string; cycles = -1; kill: bool = false;
             callback: AnimationCallback = nil)

Start playing the animation.

anim name of the animation.

cycles number of times to repeat the animation, or -1 for looping.

kill kill when finished.

callback called when animation is finished.

template dim(entity: Entity): Dim
Return entity.sprite.dim if entity.sprite is not nil, or entity.graphic.dim otherwise.
template transform(entity: Entity): Transform
template transform=(entity: Entity; transform: Transform)
template rect(entity: Entity): Rect
template topleft(entity: Entity): Coord
template topright(entity: Entity): Coord
template bottomright(entity: Entity): Coord
template bottomleft(entity: Entity): Coord
template corners(entity: Entity): untyped
template worldCorners(entity: Entity): untyped
template collide(pos1, pos2: Coord): bool
================================================ FILE: docs/docs/font.html ================================================ font

font

Types

Font = ref object of RootObj

Consts

DefaultFontColor: Color = 0xFFFFFFFF'u32

Procs

proc renderLineFont(font: Font; line: string; color: Color = DefaultFontColor): Texture {...}{.
    raises: [Exception], tags: [RootEffect].}
Render a text line in font with given color.
proc renderTextFont(font: Font; text: openArray[string]; align = TextAlign.left;
                   color: Color = DefaultfontColor): Texture {...}{.raises: [Exception],
    tags: [RootEffect].}
Render a multi-line text in font with given align and color.

Methods

method charH(font: Font): int {...}{.base, raises: [], tags: [].}
method lineDim(font: Font; text: string): Dim {...}{.base, raises: [], tags: [].}
method render(font: Font; line: string; color: Color = DefaultFontColor): Surface {...}{.base,
    raises: [], tags: [].}
method renderLine(font: Font; line: string; color: Color = DefaultFontColor): Texture {...}{.
    base, raises: [Exception], tags: [RootEffect].}
Base renderLine() font method.
method renderText(font: Font; text: openArray[string]; align = TextAlign.left;
                 color: Color = DefaultfontColor): Texture {...}{.base,
    raises: [Exception], tags: [RootEffect].}
Base renderText() font method.
================================================ FILE: docs/docs/graphic.html ================================================ graphic

graphic

Types

Graphic = ref object of RootObj

Methods

method w(graphic: Graphic): int {...}{.base, raises: [], tags: [].}
method h(graphic: Graphic): int {...}{.base, raises: [], tags: [].}
method dim(graphic: Graphic): Dim {...}{.base, raises: [], tags: [].}
method draw(graphic: Graphic; pos: Coord = (0.0, 0.0); angle: Angle = 0.0;
           scale: Scale = 1.0; center: Coord = (0.0, 0.0); flip: Flip = Flip.none;
           region: Rect = Rect(x: 0, y: 0, w: 0, h: 0)) {...}{.base, raises: [], tags: [].}

Templates

template rect(self: Graphic; offset: Coord): Rect
================================================ FILE: docs/docs/gui/button.html ================================================ button

button

Types

GuiButton = ref object of GuiWidget
  image*: Graphic              ## The graphic to render on top of a button
  imageOffset*: Coord          ## Image drawing offset from button's center. \
                    ## Calcuclated automatically if the image is passed in ``init()``
  imageShift*: Coord           ## Image shift when button is pressed
  

Procs

proc init(button: GuiButton; graphic: Graphic; image: Graphic = nil; circle: bool = false) {...}{.
    raises: [Exception], tags: [RootEffect].}

GuiButton initialization.

graphic 2x3 button graphic: defaultUp, defaultDown, focusedUp, focusedDown, disabledUp, disabledDown.

image The graphic to render on top of a butotn.

circle Set to true if you want a circle shape instead of square one.

proc newGuiButton(graphic: Graphic; image: Graphic = nil; circle: bool = false): GuiButton {...}{.
    raises: [Exception], tags: [RootEffect].}

Create a new GuiButton.

graphic 2x3 button graphic: defaultUp, defaultDown, focusedUp, focusedDown, disabledUp, disabledDown.

image The graphic to render on top of a butotn.

circle Set to true if you want a circle shape instead of square one.

proc renderGuiButton(button: GuiButton) {...}{.raises: [Exception], tags: [RootEffect].}

Default button render procedure.

Call it from your button render method.

Methods

method state=(button: GuiButton; val: GuiState) {...}{.raises: [], tags: [].}
Return button's state.
method render(button: GuiButton) {...}{.raises: [Exception], tags: [RootEffect].}
================================================ FILE: docs/docs/gui/progressbar.html ================================================ progressbar

progressbar

Types

GuiProgressBar = ref object of GuiWidget
  fText: TextGraphic
  min*, max*, value*: float
  precision*: range[0 .. 32]     ## value format precision (defaults to 0)
  unit*: string                ## value format unit (defaults to '%')
  decimalSep*: char            ## value format decimal separator (defaults to '.')
  direction*: Direction
  dim*: Dim
  outline*: Dim                ## outline border size
  bgColor*, fgColor*: Color
  bgGraphic*, fgGraphic*: TextureGraphic
  reverseX*, reverseY*: bool

Procs

proc init(bar: GuiProgressBar; dim: Dim; bgColor, fgColor: Color; font: Font;
         bgGraphic, fgGraphic: TextureGraphic) {...}{.raises: [Exception],
    tags: [RootEffect].}

GuiProgressBar initialization.

dim bar's dimensions.

bgColor, fgColor background (empty) and foreground (full) colors.

font info text font. Might be nil.

bgGraphic, fgGraphic background (empty) and foreground (full) textures that replace bgColor and fgColor if specified.

proc newProgressBar(dim: Dim; bgColor: Color; fgColor: Color; font: Font = nil;
                   bgGraphic: TextureGraphic = nil; fgGraphic: TextureGraphic = nil): GuiProgressBar {...}{.
    raises: [Exception], tags: [RootEffect].}

Create a new GuiProgressBar.

dim bar's dimensions.

bgColor, fgColor background (empty) and foreground (full) colors.

font info text font. Might be nil.

bgGraphic, fgGraphic background (empty) and foreground (full) textures that replace bgColor and fgColor if specified.

proc renderGuiProgressBar(bar: GuiProgressBar) {...}{.raises: [Exception],
    tags: [RootEffect].}

Default progress bar render procedure.

Call it from your progress bar render method.

Methods

method render(bar: GuiProgressBar) {...}{.raises: [Exception], tags: [RootEffect].}
================================================ FILE: docs/docs/gui/radio.html ================================================ radio

radio

Types

GuiRadioGroup = ref object of Entity
  list*: seq[GuiWidget]
GuiRadioButton = ref object of GuiButton
  group*: GuiRadioGroup

Procs

proc init(radiogroup: GuiRadioGroup) {...}{.raises: [], tags: [].}
proc newGuiRadioGroup(): GuiRadioGroup {...}{.raises: [], tags: [].}
proc toggle(radiogroup: GuiRadioGroup; target: GuiWidget) {...}{.raises: [Exception],
    tags: [RootEffect].}
Toggle a target element of the radiogroup.
proc init(radiobutton: GuiRadioButton; group: GuiRadioGroup; graphic: Graphic;
         image: Graphic = nil; circle: bool = false) {...}{.raises: [Exception],
    tags: [RootEffect].}

GuiRadioButton initialization.

group GuiRadioGroup the radiobutton belongs to.

graphic, image, circle See "gui/button.nim" initialization docs.

proc newGuiRadioButton(group: GuiRadioGroup; graphic: Graphic; image: Graphic = nil;
                      circle: bool = false): GuiRadioButton {...}{.raises: [Exception],
    tags: [RootEffect].}

Create a new GuiRadioButton.

group GuiRadioGroup the radiobutton belongs to.

graphic, image, circle See "gui/button.nim" initialization docs.

proc setToggled(radiobutton: GuiRadioButton; val: bool) {...}{.raises: [Exception],
    tags: [RootEffect].}
Toggle radiobutton to a given state.

Methods

method toggled=(radiobutton: GuiRadioButton; val: bool) {...}{.raises: [Exception],
    tags: [RootEffect].}
================================================ FILE: docs/docs/gui/textinput.html ================================================ textinput

textinput

Types

GuiTextInput = ref object of GuiWidget
  text*: TextField
  textPos*: Coord              ## Relative text position
  keysBackspace*, keysDelete*, keysLeft*, keysRight*, keysToFirst*, keysToLast*,
  keysDone*: seq[Keycode]

Procs

proc init(input: GuiTextInput; graphic: Graphic; font: Font) {...}{.raises: [Exception],
    tags: [RootEffect].}

GuiTextInput initialization.

grapic 2x2 input field graphic: default, focused, pressed (active), disabled.

font Font object for text rendering.

proc newGuiTextInput(graphic: Graphic; font: Font): GuiTextInput {...}{.
    raises: [Exception], tags: [RootEffect].}

Create a new GuiTextInput.

grapic 2x2 input field graphic: default, focused, pressed (active), disabled.

font Font object for text rendering.

proc eventGuiTextInput(input: GuiTextInput; e: Event) {...}{.raises: [Exception],
    tags: [RootEffect].}
proc enter(input: GuiTextInput) {...}{.raises: [Exception], tags: [RootEffect].}
Start text entry mode.
proc click(input: GuiTextInput; mb: MouseButton) {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
proc renderGuiTextInput(input: GuiTextInput) {...}{.raises: [Exception],
    tags: [RootEffect].}

Default text input render procedure.

Call it from your text input render method.

Methods

method event(input: GuiTextInput; e: Event) {...}{.raises: [Exception], tags: [RootEffect].}
method state=(input: GuiTextInput; val: GuiState) {...}{.raises: [], tags: [].}
method onClick(input: GuiTextInput; mb: MouseButton) {...}{.raises: [Exception],
    tags: [RootEffect].}
method render(input: GuiTextInput) {...}{.raises: [Exception], tags: [RootEffect].}
================================================ FILE: docs/docs/gui/widget.html ================================================ widget

widget

Types

GuiAction = proc (widget: GuiWidget)
GuiState {...}{.pure.} = enum
  defaultUp, defaultDown, focusedUp, focusedDown, disabledUp, disabledDown
GuiWidget = ref object of Entity
  fState: GuiState
  fWasPressed: MouseState
  actions*: seq[GuiAction]     ## A list of action to perform on click.
  mbAllow*: MouseState         ## Mouse buttons allowed for interaction.
  toggle*, fToggled: bool       ## If `true`, the widget is in toggle on/off mode.
  

Procs

proc init(widget: GuiWidget) {...}{.raises: [], tags: [].}
proc newGuiWidget(): GuiWidget {...}{.raises: [], tags: [].}
proc state(widget: GuiWidget): GuiState {...}{.inline, raises: [], tags: [].}
proc clickAction(widget: GuiWidget) {...}{.raises: [Exception], tags: [RootEffect].}
proc setState(widget: GuiWidget; val: GuiState) {...}{.raises: [], tags: [].}
proc setToggled(widget: GuiWidget; val: bool) {...}{.raises: [Exception], tags: [RootEffect].}
proc disable(widget: GuiWidget) {...}{.raises: [Exception], tags: [RootEffect].}
proc enable(widget: GuiWidget) {...}{.raises: [Exception], tags: [RootEffect].}
proc eventGuiWidget(widget: GuiWidget; e: Event) {...}{.raises: [Exception],
    tags: [RootEffect].}

Methods

method onPress(widget: GuiWidget) {...}{.base, raises: [], tags: [].}
method onClick(widget: GuiWidget; mb = MouseButton.left) {...}{.base, raises: [Exception],
    tags: [RootEffect].}
method state=(widget: GuiWidget; val: GuiState) {...}{.base, raises: [], tags: [].}
method toggled=(widget: GuiWidget; val: bool) {...}{.base, raises: [Exception],
    tags: [RootEffect].}
method press(widget: GuiWidget) {...}{.base, raises: [Exception], tags: [RootEffect].}
method release(widget: GuiWidget) {...}{.base, raises: [Exception], tags: [RootEffect].}
method event(widget: GuiWidget; e: Event) {...}{.raises: [Exception], tags: [RootEffect].}

Templates

template isUp(state: GuiState): bool
template isDown(state: GuiState): bool
template isFocused(state: GuiState): bool
template isDisabled(state: GuiState): bool
template isEnabled(state: GuiState): bool
template toggled(widget: GuiWidget): bool
template pressWidget(widget: GuiWidget)
template releaseWidget(widget: GuiWidget)
================================================ FILE: docs/docs/indexedimage.html ================================================ indexedimage

indexedimage

Types

Palette = ptr sdl.Palette
IndexedImage = ref object of RootObj
  fSurface: Surface            ## Source surface
  

Procs

proc free(palette: Palette) {...}{.raises: [], tags: [].}
proc init(palette: var Palette; ncolors: int) {...}{.raises: [], tags: [].}
proc ncolors(palette: Palette): int {...}{.raises: [], tags: [].}
Get the number of colors in palette.
proc `[]`(palette: Palette; i: int): Color {...}{.raises: [IndexError], tags: [].}
Get the i'th color from the palette.
proc `[]=`(palette: Palette; i: int; colors: openArray[Color]) {...}{.raises: [IndexError],
    tags: [].}
Change colors in the palette starting with i'th color.
proc `[]=`(palette: Palette; i: int; color: Color) {...}{.raises: [IndexError], tags: [].}
Change i'th color in the palette.
proc free(image: IndexedImage) {...}{.raises: [], tags: [].}
proc init(image: IndexedImage) {...}{.raises: [], tags: [].}
proc load(image: IndexedImage; file: string): bool {...}{.raises: [], tags: [].}
Load image``graphic source from a ``file.
proc load(image: IndexedImage; src: ptr RWops; freeSrc: bool = true): bool {...}{.raises: [],
    tags: [].}
Load image``graphic source from a ``src RWops.
proc newIndexedImage(): IndexedImage {...}{.raises: [], tags: [].}
proc newIndexedImage(file: string): IndexedImage {...}{.raises: [], tags: [].}
Create a new IndexedImage and load it from a file.
proc newIndexedImage(src: ptr RWops; freeSrc: bool = true): IndexedImage {...}{.raises: [],
    tags: [].}
Create a new IndexedImage and load it from a src RWops.
proc palette(image: IndexedImage): Palette {...}{.inline, raises: [], tags: [].}
Get the current palette of the image.
proc palette=(image: IndexedImage; palette: Palette) {...}{.inline, raises: [], tags: [].}
Assign a new palette to the image.
proc render(image: IndexedImage): Texture {...}{.inline, raises: [], tags: [].}
Return a new Texture created from indexed image.
================================================ FILE: docs/docs/input.html ================================================ input

input

Types

MouseButton {...}{.size: 4, pure.} = enum
  left = sdl.ButtonLeft, middle = sdl.ButtonMiddle, right = sdl.ButtonRight,
  x1 = sdl.ButtonX1, x2 = sdl.ButtonX2
Mouse buttons.
MouseState = int32
JoyAxis = range[low(int16) .. high(int16)]
JoyBall = CoordInt
JoyHat = sdl.HatPosition
GeneralInputKeyboard = object
  key*: Scancode
GeneralInputDirection = enum
  dirX, dirY
GeneralInputMouseKind = enum
  mButton, mMove
GeneralInputMouse = object
  case kind*: GeneralInputMouseKind
  of mButton:
    button*: MouseButton
  of mMove:
    direction*: GeneralInputDirection
  
GeneralInputJoystickKind = enum
  jButton, jAxis, jBall, jHat
GeneralInputJoystick = object
  guid*: JoystickGUID
  case kind*: GeneralInputJoystickKind
  of jButton:
    button*: int
  of jAxis:
    axis*: int
  of jBall:
      ball*: int
      ballDirection*: GeneralInputDirection

  of jHat:
      hat*: int
      hatPosition*: HatPosition

  
GeneralInputKind = enum
  giKeyboard, giMouse, giJoystick
GeneralInput = object
  case kind*: GeneralInputKind
  of giKeyboard:
      keyboard*: GeneralInputKeyboard

  of giMouse:
      mouse*: GeneralInputMouse

  of giJoystick:
      joystick*: GeneralInputJoystick

  
InputMap = OrderedTableRef[string, GeneralInput]

Procs

proc initKeyboard() {...}{.raises: [], tags: [].}

Clear the buffers.

Called automatically from the main game cycle.

proc updateKeyboard(event: Event) {...}{.raises: [], tags: [].}
Called automatically from the main game cycle.
proc down(scancodes: openArray[Scancode]): bool {...}{.raises: [], tags: [].}
Check if any scancode in the scancodes array is down.
proc down(keymods: openArray[Keymod]): bool {...}{.raises: [], tags: [].}
Check if any keymod in the keymodes array is down.
proc pressed(scancodes: openArray[Scancode]): bool {...}{.raises: [], tags: [].}
Check if any scancode in the scancodes array was just pressed.
proc released(scancodes: openArray[Scancode]): bool {...}{.raises: [], tags: [].}
Check if any scancode in the scancodes array was just released.
proc clearPressed(scancode: Scancode) {...}{.raises: [], tags: [].}
Remove scancode from pressed keys list.
proc clearReleased(scancode: Scancode) {...}{.raises: [], tags: [].}
Remove scancode from released keys list.
proc initMouse() {...}{.raises: [], tags: [].}

Clear the buffers.

Called automatically from the main game cycle.

proc updateMouse(event: Event) {...}{.raises: [], tags: [].}
Called automatically from the main game cycle.
proc joyIsOpened(id: int): bool {...}{.raises: [], tags: [].}
proc getId(guid: JoystickGUID): int {...}{.raises: [], tags: [].}
Return the index of a joystick with a corresponding guid, or -1 otherwise.
proc joyGuid(id: int): JoystickGUID {...}{.inline, raises: [], tags: [].}
proc openJoystick(id: int): bool {...}{.raises: [], tags: [].}
proc closeJoystick(id: int): bool {...}{.raises: [], tags: [].}
proc initJoysticks() {...}{.raises: [], tags: [].}

Init the joysticks sequence.

Called automatically from the main game cycle.

proc updateJoysticks(event: Event) {...}{.raises: [], tags: [].}
Called automatically from the main game cycle.
proc joyName(joystick: int): string {...}{.raises: [], tags: [].}
Return the name of the joystick, or an empty string otherwise.
proc joyNumButtons(joystick: int): int {...}{.inline, raises: [], tags: [].}
proc joyNumAxes(joystick: int): int {...}{.inline, raises: [], tags: [].}
proc joyNumBalls(joystick: int): int {...}{.inline, raises: [], tags: [].}
proc joyNumHats(joystick: int): int {...}{.inline, raises: [], tags: [].}
proc joyDown(joystick: int; button: int): bool {...}{.raises: [], tags: [].}

Check if joystick button is down.

joystick Joystick ID, or -1 to check every opened joystick.

button Button ID.

proc joyPressed(joystick: int; button: int): bool {...}{.raises: [], tags: [].}

Check if joystick button was just pressed.

joystick Joystick ID, or -1 to check every opened joystick.

button Joystick button ID.

proc joyReleased(joystick: int; button: int): bool {...}{.raises: [], tags: [].}

Check if joystick button was just released.

joystick Joystick ID, or -1 to check every opened joystick.

button Joystick button ID.

proc joyAxis(joystick: int; axis: int): JoyAxis {...}{.raises: [], tags: [].}

Get joystick axis current position.

joystick Joystick ID.

axis Joystick axis ID.

proc joyBall(joystick: int; ball: int): JoyBall {...}{.raises: [], tags: [].}

Get joystick ball axis change since the last poll.

joystick Joystick ID.

ball Joystick ball ID.

proc joyHat(joystick: int; hat: int): JoyHat {...}{.raises: [], tags: [].}

Get joystick hat current position.

joystick Joystick ID.

hat Joystick hat ID.

proc newInputMap(): InputMap {...}{.raises: [], tags: [].}
proc addKey(map: InputMap; name: string; key: Scancode) {...}{.inline, raises: [], tags: [].}
proc addMouseButton(map: InputMap; name: string; button: MouseButton) {...}{.inline,
    raises: [], tags: [].}
proc addMouseMove(map: InputMap; name: string; direction: GeneralInputDirection) {...}{.
    inline, raises: [], tags: [].}
proc addJoyButton(map: InputMap; name: string; guid: JoystickGUID; button: int) {...}{.inline,
    raises: [], tags: [].}
proc addJoyAxis(map: InputMap; name: string; guid: JoystickGUID; axis: int) {...}{.inline,
    raises: [], tags: [].}
proc addJoyBall(map: InputMap; name: string; guid: JoystickGUID; ball: int;
               ballDirection: GeneralInputDirection) {...}{.inline, raises: [], tags: [].}
proc addJoyHat(map: InputMap; name: string; guid: JoystickGUID; hat: int;
              hatPosition: HatPosition) {...}{.inline, raises: [], tags: [].}
proc `$`(gi: GeneralInput): string {...}{.raises: [], tags: [].}
proc load(map: InputMap; filename: string): bool {...}{.raises: [CsvError, Exception],
    tags: [ReadIOEffect].}
proc save(map: InputMap; filename: string): bool {...}{.raises: [IOError, Exception],
    tags: [WriteIOEffect].}
proc down(gi: GeneralInput): bool {...}{.raises: [], tags: [].}
proc pressed(gi: GeneralInput): bool {...}{.raises: [], tags: [].}
proc released(gi: GeneralInput): bool {...}{.raises: [], tags: [].}
proc movement(gi: GeneralInput): int {...}{.raises: [], tags: [].}

Converters

converter toInt(button: MouseButton): int32 {...}{.raises: [], tags: [].}

Templates

template down(scancode: Scancode): bool
Check if scancode (keyboard key) is down.
template down(keymod: Keymod): bool
Check if keymod (keyboard mod key) is down.
template pressed(scancode: Scancode): bool
Check if scancode (keyboard key) was just pressed.
template released(scancode: Scancode): bool
Check if scancode (keyboard key) was just released.
template name(keycode: Keycode): string
Return a human-readable name for the keycode.
template name(scancode: Scancode): string
Return a human-readable name for the scancode.
template set(state: var MouseState; button: int32; enable: bool = true)
Enable or disable specific mouse button's flag in the given state.
template mouse(): Coord2
Return current mouse position.
template mouseWheel(): Coord
Return current mouse wheel motion.
template mouseWheelFlipped(): bool
Return true if mouse wheel direction is flipped.
template mouseRelative(enabled: bool): bool
Set relative mouse mode.
template mouseCapture(enabled: bool): bool
Capture or release the mouse.
template down(button: int32; state: MouseState = mBtn): bool
Check if mouse button is pressed.
template down(button: MouseButton; state: MouseState = mBtn): bool
template pressed(button: int32): bool
Check if mouse button was just pressed.
template pressed(button: MouseButton): bool
template released(button: int32): bool
Check if mouse button was just released.
template released(button: MouseButton): bool
template clearPressed(button: int32)
Remove button from pressed buttons list.
template clearPressed(button: MouseButton)
template clearReleased(button: int32)
Remove button from released buttons list.
template clearReleased(button: MouseButton)
template mbState(): MouseState
Return current mouse buttons state value.
template cursorIsVisible(): bool
Return true if the system mouse cursor is visible, or false otherwise.
template showCursor()
Show the system mouse cursor.
template hideCursor()
Hide the system mouse cursor.
template toggleCursor()
Toggle the visibility of the system mouse cursor.
================================================ FILE: docs/docs/mosaic.html ================================================ mosaic

mosaic

Types

MosaicPattern = seq[seq[int]]
Mosaic = ref object of RootObj
  fSurface: Surface            ## Source surface
  fDim: Dim                    ## Dimensions of the surface
  tileDim*, offset*: Dim        ## \
                      ##  Dimensions of a single mosaic tile, and offset from the edge.
  
RepeatPattern = seq[tuple[rows, cols: int, data: seq[int]]]
RepeatPattern meaning:
RepeatPattern = seq[tuple[rows, cols: int, data: seq[int]]]
  • rows repeat this row rows times
  • cols repeat this data sequence cols times,

gradually increasing the index.

  • data for each item repeat increasing index item times.

Example:

patternRepeat(@[
  (1, 2, @[1, 2, 1]),
  (2, 2, @[1, 2, 1]),
  (1, 2, @[1, 2, 1]),
])

will return:

@[
  @[0, 1, 1, 2, 3, 4, 4, 5],
  @[6, 7, 7, 8, 9, 10, 10, 11],
  @[6, 7, 7, 8, 9, 10, 10, 11],
  @[12, 13, 13, 14, 15, 16, 16, 17]
]

Procs

proc free(mosaic: Mosaic) {...}{.raises: [], tags: [].}
proc init(mosaic: Mosaic) {...}{.raises: [], tags: [].}
proc load(mosaic: Mosaic; file: string; tileDim: Dim; offset: Dim = (0, 0)): bool {...}{.
    raises: [], tags: [].}

Load mosaic graphic source from a file.

tileDim dimensions of a single mosaic tile.

offset offset from the edge.

Return true on success, or false otherwise.

proc load(mosaic: Mosaic; src: ptr RWops; tileDim: Dim; offset: Dim = (0, 0);
         freeSrc: bool = true): bool {...}{.raises: [], tags: [].}
proc newMosaic(): Mosaic {...}{.raises: [], tags: [].}
proc newMosaic(file: string; tileDim: Dim; offset: Dim = (0, 0)): Mosaic {...}{.raises: [],
    tags: [].}

Create a new Mosaic and load tileset from a file.

tileDim the size of a single tile.

offset offset from the edge of the tileset.

proc newMosaic(src: ptr RWops; tileDim: Dim; offset: Dim = (0, 0); freeSrc: bool = true): Mosaic {...}{.
    raises: [], tags: [].}
proc dim(mosaic: Mosaic): Dim {...}{.inline, raises: [], tags: [].}
proc renderSurface(mosaic: Mosaic; pattern: MosaicPattern): Surface {...}{.raises: [],
    tags: [].}
Return a new Surface created with mosaic tiles by a given pattern.
proc render(mosaic: Mosaic; pattern: MosaicPattern): Texture {...}{.raises: [], tags: [].}
Return a new Texture created with mosaic tiles by a given pattern.
proc patternRepeat(repeat: RepeatPattern): MosaicPattern {...}{.raises: [], tags: [].}

Generate a repeating pattern. Useful for generating GUI elements of different sizes with Mosaic.

See also: RepeatPattern type.

proc patternStretchBorder(w, h: int; nx = 2; ny = 3): MosaicPattern {...}{.raises: [], tags: [].}

Generate a repeating pattern by repeating border items of 3x3 matrix (used for GUI buttons, etc.)

w, h strethed parts repeat count.

nx, ny number of elements in the matrix.

================================================ FILE: docs/docs/nimgame.html ================================================ nimgame

nimgame

Types

Game = ref object
  fWindow: sdl.Window
  fSize: Dim
  fIcon: sdl.Surface
  fScene: Scene                ## Current scene
  

Vars

game: Game
Global game variable

Procs

proc free(game: Game) {...}{.raises: [], tags: [].}
proc init(game: Game; w, h: int; title = "Nimgame2";
         bgColor = sdl.Color(r: 0, g: 0, b: 0, a: 255); windowFlags: uint32 = 0;
         rendererFlags: uint32 = 0x00000002 or 0x00000004;
         scaleQuality: range[0 .. 2] = 0; integerScale: bool = false;
         iconSurface: sdl.Surface = nil; icon: string = "";
         imageFlags: cint = img.InitPNG; mixerFlags: cint = mix.InitOGG;
         mixerChannels: int = 32): bool {...}{.raises: [], tags: [TimeEffect].}

Init game.

w, h window dimensions

title window title

bgColor window background color

windowFlags sdl window flags

rendererFlags sdl renderer flags

scaleQuality scale quality (pixel sampling)

integerScale force integer scale only

iconSurface window icon surface (has priority over icon)

icon window icon file name

imageFlags sdl_image flags

mixerFlags sdl_mixer flags

mixerChannels Number of channels to allocate for mixing.

Return true on success, false otherwise.

proc newGame(): Game {...}{.raises: [], tags: [].}
proc title(game: Game): string {...}{.inline, raises: [], tags: [].}
proc title=(game: Game; title: string) {...}{.inline, raises: [], tags: [].}
proc pos(game: Game): Coord {...}{.raises: [], tags: [].}
proc pos=(game: Game; pos: Coord) {...}{.raises: [], tags: [].}
proc centrify(game: Game; centerX = true; centerY = true) {...}{.raises: [], tags: [].}
proc windowSize(game: Game): Dim {...}{.raises: [], tags: [].}
Return game window dimensions.
proc windowSize=(game: Game; dim: Dim) {...}{.inline, raises: [], tags: [].}
proc minSize(game: Game): Dim {...}{.raises: [], tags: [].}
proc minSize=(game: Game; dim: Dim) {...}{.raises: [], tags: [].}
proc maxSize(game: Game): Dim {...}{.raises: [], tags: [].}
proc maxSize=(game: Game; dim: Dim) {...}{.raises: [], tags: [].}
proc setBordered(game: Game; enabled: bool) {...}{.inline, raises: [], tags: [].}
proc setResizable(game: Game; enabled: bool) {...}{.inline, raises: [], tags: [].}
proc show(game: Game) {...}{.inline, raises: [], tags: [].}
proc hide(game: Game) {...}{.inline, raises: [], tags: [].}
proc focus(game: Game) {...}{.inline, raises: [], tags: [].}
proc maximize(game: Game) {...}{.inline, raises: [], tags: [].}
proc minimize(game: Game) {...}{.inline, raises: [], tags: [].}
proc restore(game: Game) {...}{.inline, raises: [], tags: [].}
proc size(game: Game): Dim {...}{.inline, raises: [], tags: [].}
Get logical size of the game renderer.
proc scale(game: Game): Coord {...}{.inline, raises: [], tags: [].}
Return the scale of the game renderer.
proc icon(game: Game): Surface {...}{.inline, raises: [], tags: [].}
Return game icon surface.
proc icon=(game: Game; icon: string) {...}{.inline, raises: [], tags: [].}
Load new game icon from the icon file name.
proc icon=(game: Game; surface: Surface) {...}{.inline, raises: [], tags: [].}
Set new game icon surface.
proc scene(game: Game): Scene {...}{.inline, raises: [], tags: [].}
Return current game scene.
proc scene=(game: Game; val: Scene) {...}{.raises: [Exception], tags: [RootEffect].}
Set a new game scene.
proc viewport(game: Game): Rect {...}{.raises: [], tags: [].}
Get current viewport.
proc viewport=(game: Game; rect: Rect) {...}{.raises: [], tags: [].}
Set current viewport.
proc resetViewport(game: Game) {...}{.raises: [], tags: [].}
Set default viewport.
proc run(game: Game) {...}{.raises: [Exception], tags: [RootEffect].}
Start the game.
================================================ FILE: docs/docs/perspectiveimage.html ================================================ perspectiveimage

perspectiveimage

Types

PerspectiveDirection = enum
  pdHor, pdVer
PerspectiveImage = ref object of RootObj
  fDim: Dim
  fSurface: Surface            ## Source surface
  

Procs

proc free(image: PerspectiveImage) {...}{.raises: [], tags: [].}
proc init(image: PerspectiveImage) {...}{.raises: [], tags: [].}
proc load(image: PerspectiveImage; file: string): bool {...}{.raises: [], tags: [].}
Load image graphic source from a file.
proc load(image: PerspectiveImage; src: ptr RWops; freeSrc: bool = true): bool {...}{.
    raises: [], tags: [].}
Load image graphic source from a src RWops.
proc newPerspectiveImage(): PerspectiveImage {...}{.raises: [], tags: [].}
proc newPerspectiveImage(file: string): PerspectiveImage {...}{.raises: [], tags: [].}
Create a new PerspectiveImage and load it from a file.
proc newPerspectiveImage(src: ptr RWops; freeSrc: bool = true): PerspectiveImage {...}{.
    raises: [], tags: [].}
Create a new PerspectiveImage and load it from a src RWops.
proc dim(image: PerspectiveImage): Dim {...}{.inline, raises: [], tags: [].}
proc render(image: PerspectiveImage; direction: PerspectiveDirection;
           sizeFrom, sizeTo: int; sizeNormal: int = 0; shift: float = 0.5): Texture {...}{.
    raises: [], tags: [].}

direction (pdHor or pdVer) direction of perspective axis.

sizeFrom, sizeTo target scaled size (left and right for the pdHor, or top and bottom for the pdVer).

sizeNormal scaled size of the normal axis.

shift perspective shift (0.5 is center symmetry).

Return a new Texture created from the image.

================================================ FILE: docs/docs/plugin/mpeggraphic.html ================================================ mpeggraphic

mpeggraphic

Note: mpg123 dynamic library should be available in the system.

Types

MpegVolume = range[0 .. 100]
MpegGraphic = ref object of TextureGraphic
  fInfo: smpeg.Info
  fSmpeg: smpeg.Smpeg
  fFrame: smpeg.Frame
  fMutex: sdl.Mutex
  fRect: sdl.Rect
  fVideo, fAudio, fLoop: bool
  fVolume: MpegVolume
  fUpdated: bool
See sdl2/mpeg documentation for the details of implementation.

Procs

proc free(graphic: MpegGraphic) {...}{.raises: [], tags: [].}
proc load(graphic: MpegGraphic; filename: string): bool {...}{.raises: [], tags: [].}

Load MPEG movie file.

Return true on success, false otherwise.

proc load(graphic: MpegGraphic; src: ptr RWops; freeSrc: bool = true): bool {...}{.raises: [],
    tags: [].}

Load MPEG movie file.

Return true on success, false otherwise.

proc newMpegGraphic(filename: string): MpegGraphic {...}{.raises: [], tags: [].}
proc newMpegGraphic(src: ptr RWops; freeSrc: bool): MpegGraphic {...}{.raises: [], tags: [].}
proc drawMpegGraphic(graphic: MpegGraphic; pos: Coord = (0.0, 0.0); angle: Angle = 0.0;
                    scale: Scale = 1.0; center: Coord = (0.0, 0.0);
                    flip: Flip = Flip.none;
                    region: Rect = Rect(x: 0, y: 0, w: 0, h: 0)) {...}{.raises: [], tags: [].}
proc video(graphic: MpegGraphic): bool {...}{.inline, raises: [], tags: [].}
proc video=(graphic: MpegGraphic; on: bool) {...}{.raises: [], tags: [].}
proc audio(graphic: MpegGraphic): bool {...}{.inline, raises: [], tags: [].}
proc audio=(graphic: MpegGraphic; on: bool) {...}{.raises: [], tags: [].}
proc playing(graphic: MpegGraphic): bool {...}{.raises: [], tags: [].}
proc volume(graphic: MpegGraphic): MpegVolume {...}{.inline, raises: [], tags: [].}
proc volume=(graphic: MpegGraphic; volume: MpegVolume) {...}{.raises: [], tags: [].}
proc loop(graphic: MpegGraphic): bool {...}{.inline, raises: [], tags: [].}
proc loop=(graphic: MpegGraphic; on: bool) {...}{.inline, raises: [], tags: [].}
proc play(graphic: MpegGraphic) {...}{.inline, raises: [], tags: [].}
proc pause(graphic: MpegGraphic) {...}{.inline, raises: [], tags: [].}
proc stop(graphic: MpegGraphic) {...}{.inline, raises: [], tags: [].}
proc rewind(graphic: MpegGraphic) {...}{.inline, raises: [], tags: [].}
proc seek(graphic: MpegGraphic; bytes: int) {...}{.raises: [], tags: [].}
proc skip(graphic: MpegGraphic; seconds: float) {...}{.raises: [], tags: [].}
proc currentFrame(graphic: MpegGraphic): int {...}{.inline, raises: [], tags: [].}
proc currentTime(graphic: MpegGraphic): float {...}{.inline, raises: [], tags: [].}
proc totalTime(graphic: MpegGraphic): float {...}{.inline, raises: [], tags: [].}
proc renderFrame(graphic: MpegGraphic; frame: int) {...}{.raises: [], tags: [].}

Methods

method w(graphic: MpegGraphic): int {...}{.raises: [], tags: [].}
method h(graphic: MpegGraphic): int {...}{.raises: [], tags: [].}
method dim(graphic: MpegGraphic): Dim {...}{.raises: [], tags: [].}
method draw(graphic: MpegGraphic; pos: Coord = (0.0, 0.0); angle: Angle = 0.0;
           scale: Scale = 1.0; center: Coord = (0.0, 0.0); flip: Flip = Flip.none;
           region: Rect = Rect(x: 0, y: 0, w: 0, h: 0)) {...}{.raises: [], tags: [].}
================================================ FILE: docs/docs/plugin/tar.html ================================================ tar

tar

Simple utility for reading TAR archives and loading their contents into sdl.RWops. Based on dxTarRead by Dmitry Hrabrov a.k.a. DeXPeriX.

Original source link: https://github.com/DeXP/dxTarRead/blob/master/dxTarRead.c

Types

TarFile = object
  data: ptr uint8
  size: int
  contents: seq[tuple[name: cstring, size: int, data: ptr uint8]]

Procs

proc contents(tar: TarFile): seq[string] {...}{.raises: [], tags: [].}
Return a sequence of filenames (including paths) inside the tar.
proc contents(tar: TarFile; sub: string; pos: int = 0): seq[string] {...}{.raises: [], tags: [].}
Return a sequence of filenames (including paths), which start with sub string, starting at pos index, inside the tar. Useful for getting all files inside one archived directory.
proc close(tar: var TarFile) {...}{.raises: [Exception], tags: [].}
proc open(tar: var TarFile; filename: string): bool {...}{.raises: [Exception, IOError],
    tags: [ReadIOEffect].}

Open uncompressed TAR archive (eg. "archive.tar").

Return true on success, or false otherwise (or if no usable files found inside).

proc openz(tar: var TarFile; filename: string): bool {...}{.raises: [Exception, IOError,
    OutOfMemError, ZlibStreamError, OverflowError], tags: [ReadIOEffect].}

Open compressed TAR archive (e.g. "archive.tar.gz").

Return true on success, or false otherwise (or if no usable files found inside).

proc index(tar: TarFile; filename: string): int {...}{.raises: [], tags: [].}
Return index of filename in tar file, or -1 if not found.
proc read(tar: TarFile; filename: string): ptr RWops {...}{.raises: [], tags: [].}
Read filename from tar and return its content as a new RWops pointer.

Templates

template exists(tar: TarFile; filename: string): bool
================================================ FILE: docs/docs/plugin/zzip.html ================================================ zzip

zzip

Search:
Group by:

You should be able to drop it in the place of a sdl.rwFromFile(). Then go to X/share/myapp and do ```cd graphics && zip -9r ../graphics.zip .``` and rename the graphics/ subfolder - and still all your files are found: a filepath like X/shared/graphics/game/greetings.bmp will open X/shared/graphics.zip and return the zipped file game/greetings.bmp in the zip-archive (for reading that is).

See original code at http://zziplib.sourceforge.net/zzip-sdl-rwops.html

Note: zzip dynamic library should be available in the system.

Procs

proc zzipSeek(context: ptr RWops; offset: int64; whence: cint): int64 {...}{.cdecl, raises: [],
    tags: [].}
proc zzipRead(context: ptr RWops; buf: pointer; size: csize; maxnum: csize): csize {...}{.cdecl,
    raises: [], tags: [].}
proc zzipWrite(context: ptr RWops; buf: pointer; size: csize; num: csize): csize {...}{.cdecl,
    raises: [], tags: [].}
proc zzipClose(context: ptr RWops): cint {...}{.cdecl, raises: [], tags: [].}
proc rwFromZZip(file, mode: string = "r"): ptr RWops {...}{.raises: [OutOfMemError], tags: [].}
================================================ FILE: docs/docs/private/collider.html ================================================ collider

collider

Do not import this file. It is included in entity.nim automatically.

Procs

proc renderCollider(a: Collider) {...}{.raises: [], tags: [].}
proc updateFarthest(p: PolyCollider) {...}{.inline, raises: [], tags: [].}
Call this procedure any time you changed points' coordinates.
proc init(g: GroupCollider; parent: Entity) {...}{.raises: [], tags: [].}
proc newGroupCollider(parent: Entity): GroupCollider {...}{.raises: [], tags: [].}
proc checkCollisions(entity: Entity; list: seq[Entity]) {...}{.raises: [], tags: [].}
Trigger onCollide method of entity with a given list of targets.
proc isColliding(entity: Entity; list: seq[Entity]): bool {...}{.raises: [], tags: [].}
Return true if entity collides with one of the elements in the given list, or false if no collisions occurs.
proc willCollide(entity: Entity; pos: Coord; rot: Angle; scale: Scale; list: seq[Entity]): bool {...}{.
    raises: [], tags: [].}
Return true if entity will collide with one of the elements in the given list, if entity's coordinates or dimentsions will change.

Methods

method collide(pos: Coord; a: Collider): bool {...}{.base, inline, raises: [], tags: [].}
method render(a: Collider) {...}{.base, raises: [], tags: [].}
method collide(a: Collider; pos: Coord): bool {...}{.base, inline, raises: [], tags: [].}
method collide(a1, a2: Collider): bool {...}{.base, inline, raises: [], tags: [].}
method collide(a: Collider; b: BoxCollider): bool {...}{.inline, raises: [], tags: [].}
method collide(a: Collider; c: CircleCollider): bool {...}{.inline, raises: [], tags: [].}
method collide(a: Collider; d: LineCollider): bool {...}{.raises: [], tags: [].}
method collide(a: Collider; p: PolyCollider): bool {...}{.raises: [], tags: [].}
method collide(a: Collider; g: GroupCollider): bool {...}{.raises: [], tags: [].}
method collide(b: BoxCollider; pos: Coord): bool {...}{.inline, raises: [], tags: [].}
method collide(b: BoxCollider; a: Collider): bool {...}{.inline, raises: [], tags: [].}
method collide(b: BoxCollider; p: PolyCollider): bool {...}{.raises: [], tags: [].}
method collide(b: BoxCollider; g: GroupCollider): bool {...}{.raises: [], tags: [].}
method collide(c: CircleCollider; pos: Coord): bool {...}{.inline, raises: [], tags: [].}
method collide(c: CircleCollider; a: Collider): bool {...}{.inline, raises: [], tags: [].}
method collide(c: CircleCollider; b: BoxCollider): bool {...}{.inline, raises: [], tags: [].}
method collide(c: CircleCollider; p: PolyCollider): bool {...}{.raises: [], tags: [].}
method collide(c: CircleCollider; g: GroupCollider): bool {...}{.raises: [], tags: [].}
method collide(d: LineCollider; pos: Coord): bool {...}{.inline, raises: [], tags: [].}
method collide(d: LineCollider; a: Collider): bool {...}{.inline, raises: [], tags: [].}
method collide(d: LineCollider; b: BoxCollider): bool {...}{.inline, raises: [], tags: [].}
method collide(d: LineCollider; c: CircleCollider): bool {...}{.inline, raises: [], tags: [].}
method collide(d: LineCollider; p: PolyCollider): bool {...}{.raises: [], tags: [].}
method collide(d: LineCollider; g: GroupCollider): bool {...}{.raises: [], tags: [].}
method collide(p: PolyCollider; pos: Coord): bool {...}{.inline, raises: [], tags: [].}
method collide(p: PolyCollider; a: Collider): bool {...}{.inline, raises: [], tags: [].}
method collide(p: PolyCollider; b: BoxCollider): bool {...}{.inline, raises: [], tags: [].}
method collide(p: PolyCollider; c: CircleCollider): bool {...}{.inline, raises: [], tags: [].}
method collide(p: PolyCollider; d: LineCollider): bool {...}{.inline, raises: [], tags: [].}
method collide(p1, p2: PolyCollider): bool {...}{.raises: [], tags: [].}
method collide(p: LineCollider; g: GroupCollider): bool {...}{.raises: [], tags: [].}
method render(g: GroupCollider) {...}{.raises: [], tags: [].}
method collide(g: GroupCollider; pos: Coord): bool {...}{.raises: [], tags: [].}
method collide(g: GroupCollider; a: Collider): bool {...}{.raises: [], tags: [].}
method collide(g: GroupCollider; b: BoxCollider): bool {...}{.raises: [], tags: [].}
method collide(g: GroupCollider; c: CircleCollider): bool {...}{.raises: [], tags: [].}
method collide(g: GroupCollider; d: LineCollider): bool {...}{.raises: [], tags: [].}
method collide(g: GroupCollider; p: PolyCollider): bool {...}{.raises: [], tags: [].}

Templates

template collide(pos1, pos2: Coord): bool
================================================ FILE: docs/docs/procgraphic.html ================================================ procgraphic

procgraphic

Types

ProcGraphic = ref object of Graphic
  procedure*: proc (graphic: ProcGraphic; pos: Coord; angle: Angle; scale: Scale;
                  center: Coord; flip: Flip; region: Rect) {...}{.locks: 0.} ## Drawing procedure.
  dimProcedure*: proc (): Dim {...}{.locks: 0.} ## Dimensions procedure.
  

Procs

proc newProcGraphic(): ProcGraphic {...}{.raises: [], tags: [].}
proc drawProcGraphic(graphic: ProcGraphic; pos: Coord = (0.0, 0.0); angle: Angle = 0.0;
                    scale: Scale = 1.0; center: Coord = (0.0, 0.0);
                    flip: Flip = Flip.none;
                    region: Rect = Rect(x: 0, y: 0, w: 0, h: 0)) {...}{.raises: [Exception],
    tags: [RootEffect].}

Methods

method w(graphic: ProcGraphic): int {...}{.raises: [Exception], tags: [RootEffect].}
Return the width of the graphic if available, or nil otherwise.
method h(graphic: ProcGraphic): int {...}{.raises: [Exception], tags: [RootEffect].}
Return the height of the graphic if available, or nil otherwise.
method dim(graphic: ProcGraphic): Dim {...}{.raises: [Exception], tags: [RootEffect].}
Return the graphic's dimensions if available, or nil otherwise.
method draw(graphic: ProcGraphic; pos: Coord = (0.0, 0.0); angle: Angle = 0.0;
           scale: Scale = 1.0; center: Coord = (0.0, 0.0); flip: Flip = Flip.none;
           region: Rect = Rect(x: 0, y: 0, w: 0, h: 0)) {...}{.raises: [Exception],
    tags: [RootEffect].}
================================================ FILE: docs/docs/scene.html ================================================ scene

scene

Types

Scene = ref object of RootObj
  fList, fAddList: seq[Entity]
  camera*, cameraBond*: Entity  ## Camera and its bond Entity
  cameraBondOffset*: Coord     ## Camera's offstet from its bond
  

Procs

proc init(scene: Scene) {...}{.raises: [], tags: [].}
proc eventScene(scene: Scene; e: sdl.Event) {...}{.raises: [Exception], tags: [RootEffect].}
proc renderScene(scene: Scene) {...}{.raises: [Exception], tags: [RootEffect].}

Default scene render procedure.

Call it from your scene render method.

proc add(scene: Scene; entity: Entity) {...}{.raises: [], tags: [].}
Add a new entity to the scene.
proc clear(scene: Scene) {...}{.raises: [], tags: [].}
Remove all entities from the scene.
proc contains(scene: Scene; entity: Entity): bool {...}{.inline, raises: [], tags: [].}
Return true if the scene has the entity, or false otherwise.
proc contains(scene: Scene; tag: string): bool {...}{.raises: [], tags: [].}
Return true if the scene has an entity with tag, or false otherwise.
proc count(scene: Scene): int {...}{.inline, raises: [], tags: [].}
Return the number of entities in the scene.
proc count(scene: Scene; tag: string): int {...}{.raises: [], tags: [].}
Return the number of entities with tag in the scene.
proc del(scene: Scene; entity: Entity): bool {...}{.raises: [], tags: [].}

Delete entity from the scene.

Return true if entity was deleted, or false if there is no such entity in the scene.

proc del(scene: Scene; tag: string) {...}{.raises: [], tags: [].}
Delete all entities with tag from the scene.
proc find(scene: Scene; tag: string): Entity {...}{.raises: [], tags: [].}
Return the first entity with tag in the scene, or nil otherwise.
proc findAll(scene: Scene; tag: string): seq[Entity] {...}{.raises: [], tags: [].}
Return a sequence of all entities with tag in the scene, or an empty sequence if no such entities are found.
proc pop(scene: Scene): Entity {...}{.inline, raises: [], tags: [].}
Return the top entity and remove it from the scene.
proc updateScene(scene: Scene; elapsed: float) {...}{.raises: [Exception],
    tags: [RootEffect].}

Default scene update procedure.

Call it from your scene update method.

Methods

method event(scene: Scene; e: sdl.Event) {...}{.base, raises: [Exception], tags: [RootEffect].}
method show(scene: Scene) {...}{.base, raises: [], tags: [].}
Called when scene is set in Game.
method hide(scene: Scene) {...}{.base, raises: [], tags: [].}
Called when scene is replaced by other one in Game.
method render(scene: Scene) {...}{.base, raises: [Exception], tags: [RootEffect].}
method update(scene: Scene; elapsed: float) {...}{.base, raises: [Exception],
    tags: [RootEffect].}

Iterators

iterator entities(scene: Scene): Entity {...}{.inline, raises: [], tags: [].}
Iterate through all entities in the scene.
iterator entities(scene: Scene; tag: string): Entity {...}{.inline, raises: [], tags: [].}
Iterate throught entities with tag in the scene.

Templates

template bindCameraTo(scene: Scene; bond: Entity; offset: Coord)
Bind the camera to the movement of the specific entity.
================================================ FILE: docs/docs/settings.html ================================================ settings

settings

Vars

background: sdl.Color
Screen clearing color
renderer: sdl.Renderer
Game renderer pointer
gameRunning: bool
If false - break main loop
gamePaused: bool
If true - do not update current scene
showInfo: bool
Show info panel
fpsLimit: int
Limit frames per second to fpsLimit, if 0 - no limit
colliderOutline: bool
Show collider outlines
colliderOutlineColor: sdl.Color
Color of collider outlines
updateInterval: int
update() is called each updateInterval ms.
================================================ FILE: docs/docs/textfield.html ================================================ textfield

textfield

Types

TextField = ref object of TextGraphic
  fActive: bool
  fCursorIndex: int
  cursor*: string
  limit*: int

Procs

proc init(tf: TextField; font: Font) {...}{.raises: [Exception], tags: [RootEffect].}
proc newTextField(font: Font): TextField {...}{.raises: [Exception], tags: [RootEffect].}
proc text(tf: TextField): string {...}{.raises: [], tags: [].}
proc text=(tf: TextField; val: string) {...}{.raises: [Exception], tags: [RootEffect].}
proc bs(tf: TextField; index = -1) {...}{.raises: [Exception], tags: [RootEffect].}
Backspace text action.
proc del(tf: TextField; index = -1) {...}{.raises: [Exception], tags: [RootEffect].}
Delete text action.
proc add(tf: TextField; str: string; index = -1) {...}{.raises: [Exception], tags: [RootEffect].}
Add text action.
proc left(tf: TextField) {...}{.raises: [Exception], tags: [RootEffect].}
Move cursor to the left.
proc right(tf: TextField) {...}{.raises: [Exception], tags: [RootEffect].}
Move cursor to the right.
proc toFirst(tf: TextField) {...}{.raises: [Exception], tags: [RootEffect].}
Move cursor to the beginning.
proc toLast(tf: TextField) {...}{.raises: [Exception], tags: [RootEffect].}
Move cursor to the end.
proc activate(tf: TextField) {...}{.raises: [Exception], tags: [RootEffect].}
Activate text field.
proc deactivate(tf: TextField) {...}{.raises: [Exception], tags: [RootEffect].}
Deactivate text field.
proc draw(tf: TextField; pos: Coord) {...}{.raises: [Exception], tags: [RootEffect].}

Templates

template isActive(tf: TextField): bool
template len(tf: TextField): int
================================================ FILE: docs/docs/textgraphic.html ================================================ textgraphic

textgraphic

Types

TextGraphic = ref object of TextureGraphic
  fLines: seq[string]
  fAlign: TextAlign
  fColor: Color
  fFont: Font

Procs

proc free(text: TextGraphic) {...}{.raises: [], tags: [].}
proc init(text: TextGraphic; font: Font) {...}{.raises: [], tags: [].}
proc newTextGraphic(font: Font = nil): TextGraphic {...}{.raises: [], tags: [].}
proc update(text: TextGraphic) {...}{.raises: [Exception], tags: [RootEffect].}
proc align(text: TextGraphic): TextAlign {...}{.inline, raises: [], tags: [].}
proc align=(text: TextGraphic; val: TextAlign) {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
proc color(text: TextGraphic): Color {...}{.inline, raises: [], tags: [].}
proc color=(text: TextGraphic; val: Color) {...}{.inline, raises: [Exception],
                                        tags: [RootEffect].}
proc font(text: TextGraphic): Font {...}{.inline, raises: [], tags: [].}
proc font=(text: TextGraphic; val: Font) {...}{.inline, raises: [Exception],
                                      tags: [RootEffect].}
proc lines(text: TextGraphic): seq[string] {...}{.inline, raises: [], tags: [].}
proc lines=(text: TextGraphic; lines: openArray[string]) {...}{.raises: [Exception],
    tags: [RootEffect].}
proc text(text: TextGraphic): string {...}{.inline, raises: [], tags: [].}
Return lines, joined in one string.
proc setText(text: TextGraphic; val: string; width: int = 0; seps: set[char] = Whitespace) {...}{.
    raises: [Exception], tags: [RootEffect].}
Set the text lines, wrapping each width characters.
================================================ FILE: docs/docs/textureatlas.html ================================================ textureatlas

textureatlas

Types

TextureAtlas = OrderedTableRef[string, TextureGraphic]

Procs

proc free(atlas: TextureAtlas) {...}{.raises: [], tags: [].}
proc newTextureAtlas(imagefile, mapfile: string; count: int = 64): TextureAtlas {...}{.
    raises: [CsvError, Exception, OverflowError, ValueError],
    tags: [ReadIOEffect, RootEffect].}

Create a new TextureAtlas.

imagefile file containging the image atlas.

mapfile CSV file containing atlas mapping in a format of:

name, x, y, w, h ...

count expected mappings count.

proc newTextureAtlas(imageSrc, mapSrc: ptr RWops; count: int = 64;
                    freeImageSrc: bool = true; freeMapSrc: bool = true): TextureAtlas {...}{.
    raises: [Exception, CsvError, OverflowError, ValueError],
    tags: [RootEffect, ReadIOEffect].}
================================================ FILE: docs/docs/texturegraphic.html ================================================ texturegraphic

texturegraphic

Types

TextureGraphic = ref object of Graphic
  fTexture: sdl.Texture
  fFormat: uint32
  fSize: Dim

Procs

proc freeTexture(graphic: TextureGraphic) {...}{.raises: [], tags: [].}
proc free(graphic: TextureGraphic) {...}{.raises: [], tags: [].}
proc init(graphic: TextureGraphic) {...}{.raises: [], tags: [].}
proc updateTexture(graphic: TextureGraphic): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
proc format(graphic: TextureGraphic): uint32 {...}{.inline, raises: [], tags: [].}
proc load(graphic: TextureGraphic; file: string): bool {...}{.raises: [Exception],
    tags: [RootEffect].}

Load texture from file.

Return true on success, false otherwise.

proc load(graphic: TextureGraphic; rw: ptr RWops; freeSrc: bool = true): bool {...}{.
    raises: [Exception], tags: [RootEffect].}

Load texture from src RWops.

Return true on success, false otherwise.

proc assignTexture(graphic: TextureGraphic; texture: Texture;
                  freeCurrent: bool = true): bool {...}{.raises: [Exception],
    tags: [RootEffect].}

Assign already created texture.

freeCurrent Free the currently assigned texture. Set to false if it used by other objects.

ATTENTION! The texture will be destroyed on free().

Return true on success, false otherwise.

proc texture(graphic: TextureGraphic): sdl.Texture {...}{.inline, raises: [], tags: [].}
Direct access to the graphic's texture. Be careful.
proc newTextureGraphic(): TextureGraphic {...}{.raises: [], tags: [].}
proc newTextureGraphic(file: string): TextureGraphic {...}{.raises: [Exception],
    tags: [RootEffect].}
proc newTextureGraphic(src: ptr RWops; freeSrc: bool = true): TextureGraphic {...}{.
    raises: [Exception], tags: [RootEffect].}
proc newTextureGraphic(texture: Texture): TextureGraphic {...}{.raises: [Exception],
    tags: [RootEffect].}
proc drawTextureGraphic(graphic: TextureGraphic; pos: Coord = (0.0, 0.0);
                       angle: Angle = 0.0; scale: Scale = 1.0;
                       center: Coord = (0.0, 0.0); flip: Flip = Flip.none;
                       region: Rect = Rect(x: 0, y: 0, w: 0, h: 0)) {...}{.raises: [Exception],
    tags: [RootEffect].}

Draw procedure.

pos Draw coordinates.

angle Rotation angle in degrees.

scale Draw scale. 1.0 for original size.

center Center of rendering, rotation, and scaling.

flip RendererFlip value, could be set to: FlipNone, FlipHorizontal, FlipVertical.

region Source texture region to draw.

proc drawTiled(graphic: TextureGraphic; rect: Rect;
              region: Rect = Rect(x: 0, y: 0, w: 0, h: 0); reverseX = false; reverseY = false) {...}{.
    raises: [Exception], tags: [RootEffect].}

Repeatedly draw the graphic to fill the rect.

region Source texture region to draw.

reverseX, reverseY Drawing progression order.

proc colorMod(graphic: TextureGraphic): Color {...}{.raises: [], tags: [].}
Return current color modifier.
proc colorMod=(graphic: TextureGraphic; color: Color) {...}{.raises: [], tags: [].}
Set a new color modifier.
proc alphaMod(graphic: TextureGraphic): uint8 {...}{.raises: [], tags: [].}
Return current alpha (transparency) modifier.
proc alphaMod=(graphic: TextureGraphic; alpha: uint8) {...}{.raises: [], tags: [].}
Set a new alpha (transparency) modifier.
proc blendMod(graphic: TextureGraphic): Blend {...}{.raises: [], tags: [].}
Return current blending mode.
proc blendMod=(graphic: TextureGraphic; blend: Blend) {...}{.raises: [], tags: [].}
Set a new blending mode.

Methods

method w(graphic: TextureGraphic): int {...}{.inline, raises: [], tags: [].}
method h(graphic: TextureGraphic): int {...}{.inline, raises: [], tags: [].}
method dim(graphic: TextureGraphic): Dim {...}{.inline, raises: [], tags: [].}
method draw(graphic: TextureGraphic; pos: Coord = (0.0, 0.0); angle: Angle = 0.0;
           scale: Scale = 1.0; center: Coord = (0.0, 0.0); flip: Flip = Flip.none;
           region: Rect = Rect(x: 0, y: 0, w: 0, h: 0)) {...}{.raises: [Exception],
    tags: [RootEffect].}
================================================ FILE: docs/docs/tilemap.html ================================================ tilemap

tilemap

Types

TileShow = tuple[x: Slice[int], y: Slice[int]]
TileMap = ref object of Entity
  map*: seq[seq[int]]          ## Two-dimensional sequence of tile indexes (y, x)
  fShow: TileShow              ## Slice of what part of map to show
  hidden*: seq[int]            ## The list of tile indexes to not render
  passable*: seq[int]          ## The list of tile indexes without colliders
  onlyReachableColliders*: bool ## Do not create colliders \
                              ## for unreachable tiles
  tileScale*: Scale ## \
                  ## The scaling of individual tiles, mostly used for gap removal. \
                  ## Increase on scales vastly different from `1.0`. \
                  ## Set to `1.0` if your map isn't rotating or scaling.
  
TileCollider = ref object of BoxCollider
  value*: int                  ## Tile kind value
  index*: CoordInt             ## Map coordinates
  
TileMapCollider = ref object of Collider
  map: TileMap
  tiles: seq[seq[TileCollider]] ## Two-dimensional sequence of colliders \
                              ## (y, x)
  
Collider to use with TileMap

Consts

DefaultTileScale: Scale = 1.02

Procs

proc init(tilemap: TileMap; scaleFix = false) {...}{.raises: [], tags: [].}

TileMap initialization.

scaleFix set tileScale to DefaultTileScale if true, or to 1.0 otherwise.

proc newTileMap(scaleFix = false): TileMap {...}{.raises: [], tags: [].}

Create a new TileMap.

scaleFix set tileScale to DefaultTileScale if true, or to 1.0 otherwise.

proc show(tilemap: TileMap): TileShow {...}{.inline, raises: [], tags: [].}
Return a currently shown slices of tiles.
proc show=(tilemap: TileMap; val: TileShow) {...}{.raises: [], tags: [].}
Set new values for the shown slices of tiles.
proc dimTiles(tilemap: TileMap): Dim {...}{.raises: [], tags: [].}
Return dimensions of the tilemap, calculated from its map (in tiles).
proc dim(tilemap: TileMap): Dim {...}{.inline, raises: [], tags: [].}
Return dimensions of the tilemap, calculated from its map (in pixels).
proc centrify(tilemap: TileMap; hor = HAlign.center; ver = VAlign.center) {...}{.raises: [],
    tags: [].}

Set tilemap's center, according to the given align.

hor Horisontal align: left, center, or right

ver Vertical align: top, center, or bottom

proc firstTileIndex(tilemap: TileMap; value: int): CoordInt {...}{.raises: [], tags: [].}
Return the first tile index with a specific value.
proc tileIndex(tilemap: TileMap; pos: Coord): CoordInt {...}{.raises: [], tags: [].}
Return the tile map index of a tile that is located at the given screen position.
proc tilePos(tilemap: TileMap; index: CoordInt): Coord {...}{.raises: [], tags: [].}
Return screen position of a tile with the given tile map index.
proc renderTileMap(tilemap: TileMap) {...}{.raises: [Exception], tags: [RootEffect].}
proc init(t: TileCollider; parent: TileMap; pos: Coord = (0, 0); dim: Dim = (0, 0); value: int;
         index: CoordInt) {...}{.raises: [], tags: [].}
proc newTileCollider(parent: TileMap; pos: Coord = (0, 0); dim: Dim = (0, 0); value: int;
                    index: CoordInt): TileCollider {...}{.raises: [], tags: [].}
proc init(t: TileMapCollider; parent: TileMap; pos: Coord = (0, 0); dim: Dim = (0, 0)) {...}{.
    raises: [], tags: [].}
proc newTileMapCollider(parent: TileMap; pos: Coord = (0, 0); dim: Dim = (0, 0)): TileMapCollider {...}{.
    raises: [], tags: [].}

Create a TileMapCollider for the parent TileMap.

Most of the times you should use initCollider() instead.

pos Collider's relative position. Usually (0, 0).

dim Tile dimensions.

proc initCollider(tilemap: TileMap) {...}{.raises: [], tags: [].}
Initialize a collider for the tilemap.

Methods

method render(tilemap: TileMap) {...}{.raises: [Exception], tags: [RootEffect].}
method render(t: TileMapCollider) {...}{.raises: [Exception], tags: [RootEffect].}
method collide(t: TileMapCollider; pos: Coord): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(t: TileMapCollider; a: Collider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(a: Collider; t: TileMapCollider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(t: TileMapCollider; b: BoxCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(b: BoxCollider; t: TileMapCollider): bool {...}{.inline, raises: [Exception],
    tags: [RootEffect].}
method collide(t: TileMapCollider; c: CircleCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(c: CircleCollider; t: TileMapCollider): bool {...}{.inline,
    raises: [Exception], tags: [RootEffect].}
method collide(t: TileMapCollider; d: LineCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(d: LineCollider; t: TileMapCollider): bool {...}{.inline,
    raises: [Exception], tags: [RootEffect].}
method collide(t: TileMapCollider; p: PolyCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(p: PolyCollider; t: TileMapCollider): bool {...}{.inline,
    raises: [Exception], tags: [RootEffect].}
method collide(t: TileMapCollider; g: GroupCollider): bool {...}{.raises: [Exception],
    tags: [RootEffect].}
method collide(g: GroupCollider; t: TileMapCollider): bool {...}{.inline,
    raises: [Exception], tags: [RootEffect].}
method collide(t1, t2: TileMapCollider): bool {...}{.raises: [Exception], tags: [RootEffect].}

Iterators

iterator tileIndex(tilemap: TileMap; value: int): CoordInt {...}{.raises: [], tags: [].}
Iterate through tiles with a specific value.
iterator tileColliders(t: TileMapCollider): TileCollider {...}{.raises: [], tags: [].}
Iterate through all tile colliders of t TilemapCollider.

Templates

template tile(tilemap: TileMap; index: CoordInt): var int
Direct access to a single tile value.
template collisionList(t: TileMapCollider; a: typed; first: bool = false): seq[
    TileCollider]

Get a list of collided TileColliders.

a collision target (Coord, any Collider, etc.)

first If true, return after the first detected collision.

================================================ FILE: docs/docs/truetypefont.html ================================================ truetypefont

truetypefont

Types

TrueTypeFont = ref object of font.Font
  fFont: ttf.Font

Procs

proc free(font: TrueTypeFont) {...}{.raises: [], tags: [].}
proc init(font: TrueTypeFont) {...}{.raises: [], tags: [].}
proc newTrueTypeFont(): TrueTypeFont {...}{.raises: [], tags: [].}
proc load(font: TrueTypeFont; file: string; size: int): bool {...}{.raises: [], tags: [].}

Load font data from a file.

size required font size.

proc load(font: TrueTypeFont; src: ptr RWops; size: int; freeSrc: bool = true): bool {...}{.
    raises: [], tags: [].}

Load font data from a src RWops.

size required font size.

proc renderTrueTypeFont(font: TrueTypeFont; line: string;
                       color: Color = DefaultFontColor): Surface {...}{.raises: [], tags: [].}

Methods

method getError(font: TrueTypeFont): string {...}{.raises: [], tags: [].}
method charH(font: TrueTypeFont): int {...}{.raises: [], tags: [].}
Return a font character's height.
method lineDim(font: TrueTypeFont; line: string): Dim {...}{.raises: [], tags: [].}
Return dimensions of a line of text, written in font.
method render(font: TrueTypeFont; line: string; color: Color = DefaultFontColor): Surface {...}{.
    raises: [], tags: [].}
================================================ FILE: docs/docs/tween.html ================================================ tween

tween

Types

TweenProcedure[V] = proc (start, distance: V; elapsed, duration: float;
                       amplitude, period: V; back: float): V
TweenEnder[T; V] = proc (tween: Tween[T, V])
Tween[T; V] = ref object of RootObj
  target: T                    ## Target object
  get: proc (e: T): V             ## A value getter procedure
  set: proc (e: T; v: V)           ## A value setter procedure
  fStart, fFinish: V            ## Starting and finishing values
  fDistance: V                 ## Total distance (finish - start)
  fElapsed, fDuration: float    ## Elapsed and total duration (in seconds)
  amplitude*, period*: V        ## Ease elastic amplitude and period
  back*: float                 ## Ease Back coefficient
  loop*, loopLimit*: int        ## Loop counter and loop limit
  playing*: bool               ## Playing status flag
  procedure*: TweenProcedure[V] ## \
                              ## Value changing procedure, called from the ``update()``
  ender*: TweenEnder[T, V]      ## \
                        ##  Loop ending procedure, called from the ``update()``
  

Procs

proc value[T, V](tween: Tween[T, V]): V {...}{.inline.}
Return the target value of tween.
proc value=[T, V](tween: Tween[T, V]; val: V) {...}{.inline.}
Set the target value of tween to val.
proc start[T, V](tween: Tween[T, V]): V {...}{.inline.}
Return starting value.
proc finish[T, V](tween: Tween[T, V]): V {...}{.inline.}
Return final value.
proc distance[T, V](tween: Tween[T, V]): V {...}{.inline.}
Return the total distance.
proc duration(tween: Tween): float {...}{.inline.}
Return tween's total duration.
proc elapsed(tween: Tween): float {...}{.inline.}
Return tween's elapsed duration.
proc progress(tween: Tween): float
Return tween progress in 0.0..`1.0` range.
proc play(tween: Tween)
Start playing tween with previously set params.
proc stop(tween: Tween)
Stop playing tween immediately.
proc setup[T, V](tween: Tween[T, V]; start, finish: V; duration: float; loops = 0)

Set up tween params.

start, finish Limiting values for the target variable.

duration Duration (in seconds).

loops Loop limit. 0 for one loop, -1 for looping forever.

proc update(tween: Tween; elapsed: float)
Tween update procedure. Call it from the scene update method.
proc linear[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
              back: float): V {...}{.procvar.}
Linear tween procedure.
proc inQuad[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
              back: float): V {...}{.procvar.}
Ease In Quadratic tween procedure.
proc outQuad[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
               back: float): V {...}{.procvar.}
Ease Out Quadratic tween procedure.
proc inOutQuad[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                 back: float): V {...}{.procvar.}
Ease In/Out Quadratic tween procedure.
proc inCubic[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
               back: float): V {...}{.procvar.}
Ease In Cubic tween procedure.
proc outCubic[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                back: float): V {...}{.procvar.}
Ease Out Cubic tween procedure.
proc inOutCubic[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                  back: float): V {...}{.procvar.}
Ease In/Out Cubic tween procedure.
proc outInCubic[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                  back: float): V {...}{.procvar.}
Ease Out/In Cubic tween procedure.
proc inQuart[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
               back: float): V {...}{.procvar.}
Ease In Quart tween procedure.
proc outQuart[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                back: float): V {...}{.procvar.}
Ease Out Quart tween procedure.
proc inOutQuart[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                  back: float): V {...}{.procvar.}
Ease In/Out Quart tween procedure.
proc outInQuart[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                  back: float): V {...}{.procvar.}
Ease Out/In Quart tween procedure
proc inQuint[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
               back: float): V {...}{.procvar.}
Ease In Quint tween procedure.
proc outQuint[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                back: float): V {...}{.procvar.}
Ease Out Quint tween procedure.
proc inOutQuint[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                  back: float): V {...}{.procvar.}
Ease In/Out Quint tween procedure.
proc outInQuint[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                  back: float): V {...}{.procvar.}
Ease Out/In Quint tween procedure.
proc inSine[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
              back: float): V {...}{.procvar.}
Ease In Sine tween procedure.
proc outSine[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
               back: float): V {...}{.procvar.}
Ease Out Sine tween procedure.
proc inOutSine[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                 back: float): V {...}{.procvar.}
Ease In/Out Sine tween procedure.
proc outInSine[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                 back: float): V {...}{.procvar.}
Ease Out/In Sine tween procedure.
proc inExpo[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
              back: float): V {...}{.procvar.}
Ease In Expo tween procedure.
proc outExpo[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
               back: float): V {...}{.procvar.}
Ease Out Expo tween procedure.
proc inOutExpo[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                 back: float): V {...}{.procvar.}
Ease In/Out Expo tween procedure.
proc outInExpo[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                 back: float): V {...}{.procvar.}
Ease Out/In Expo tween procedure.
proc inCirc[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
              back: float): V {...}{.procvar.}
Ease In Circ tween procedure.
proc outCirc[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
               back: float): V {...}{.procvar.}
Ease Out Circ tween procedure.
proc inOutCirc[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                 back: float): V {...}{.procvar.}
Ease In/Out Circ tween procedure.
proc outInCirc[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                 back: float): V {...}{.procvar.}
Ease Out/In Circ tween procedure.
proc outBounce[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                 back: float): V {...}{.procvar.}
Ease Out Bounce tween procedure.
proc inBounce[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                back: float): V {...}{.procvar.}
Ease In Bounce tween procedure.
proc inOutBounce[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                   back: float): V {...}{.procvar.}
Ease In/Out Bounce tween procedure.
proc outInBounce[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                   back: float): V {...}{.procvar.}
Ease Out/In Bounce tween procedure.
proc inElastic[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                 back: float): V {...}{.procvar.}
Ease In Elastic tween procedure.
proc outElastic[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                  back: float): V {...}{.procvar.}
Ease Out Elastic tween procedure.
proc inOutElastic[V](start, distance: V; elapsed, duration: float;
                    amplitude, period: V; back: float): V {...}{.procvar.}
Ease In/Out Elastic tween procedure.
proc outInElastic[V](start, distance: V; elapsed, duration: float;
                    amplitude, period: V; back: float): V {...}{.procvar.}
Ease Out/In Elastic tween procedure.
proc inBack[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
              back: float): V {...}{.procvar.}
Ease In Back tween procedure.
proc outBack[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
               back: float): V {...}{.procvar.}
Ease Out Back tween procedure.
proc inOutBack[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                 back: float): V {...}{.procvar.}
Ease In/Out Back tween procedure.
proc outInBack[V](start, distance: V; elapsed, duration: float; amplitude, period: V;
                 back: float): V {...}{.procvar.}
Ease Out/In Back tween procedure.
proc reversing(tween: Tween) {...}{.procvar.}

Tween ender.

Reverses the direction on each loop.

Default option.

Note: each reversal counts as one loop.

proc repeating(tween: Tween) {...}{.procvar.}

Tween ender.

Repeats from start to finish on each loop.

proc init[T, V](tween: Tween[T, V]; target: T; get: proc (e: T): V; set: proc (e: T; v: V))

Set new bindings for the tween.

target The target object of this tween.

get A value getter procedure.

set A value setter procedure.

proc newTween[T, V](target: T; get: proc (e: T): V; set: proc (e: T; v: V)): Tween[T, V]

Create a new Tween.

target The target object of this tween.

get A value getter procedure.

set A value setter procedure.

================================================ FILE: docs/docs/types.html ================================================ types

types

Search:
Group by:

Types

Coord = tuple[x: float, y: float]
Coordinates type
Coord2 = tuple[abs, rel: Coord]
Abs + Rel coordinates type
CoordInt = tuple[x: int, y: int]
Integer coordinates
Dim = tuple[w: int, h: int]
Dimensions type
Angle = float
Angle type
Scale = float
Scale type
Transform = tuple[pos: Coord, angle: Angle, scale: Scale]
Blend {...}{.size: 4, pure.} = enum
  none = sdl.BlendModeNone, blend = sdl.BlendModeBlend, bAdd = sdl.BlendModeAdd,
  bMod = sdl.BlendModeMod
Flip {...}{.size: 4, pure.} = enum
  none = sdl.FlipNone, horizontal = sdl.FlipHorizontal, vertical = sdl.FlipVertical,
  both = sdl.FlipBoth
TextAlign {...}{.pure.} = enum
  left, center, right
Direction {...}{.pure.} = enum
  leftRight, rightLeft, topBottom, bottomTop
HAlign {...}{.pure.} = enum
  left, center, right
VAlign {...}{.pure.} = enum
  top, center, bottom

Consts

ColorBlack = 255
ColourBlack = 255
ColorNavy = 33023
ColourNavy = 33023
ColorDarkBlue = 35839
ColourDarkBlue = 35839
ColorMediumBlue = 52735
ColourMediumBlue = 52735
ColorBlue = 65535
ColourBlue = 65535
ColorDarkGreen = 6553855
ColourDarkGreen = 6553855
ColorGreen = 8388863
ColourGreen = 8388863
ColorTeal = 8421631
ColourTeal = 8421631
ColorDarkCyan = 9145343
ColourDarkCyan = 9145343
ColorDeepSkyBlue = 12582911
ColourDeepSkyBlue = 12582911
ColorDarkTurquoise = 13554175
ColourDarkTurquoise = 13554175
ColorMediumSpringGreen = 16423679
ColourMediumSpringGreen = 16423679
ColorLime = 16711935
ColourLime = 16711935
ColorSpringGreen = 16744447
ColourSpringGreen = 16744447
ColorAqua = 16777215
ColourAqua = 16777215
ColorCyan = 16777215
ColourCyan = 16777215
ColorMidnightBlue = 421097727
ColourMidnightBlue = 421097727
ColorDodgerBlue = 512819199
ColourDodgerBlue = 512819199
ColorLightSeaGreen = 548580095
ColourLightSeaGreen = 548580095
ColorForestGreen = 579543807
ColourForestGreen = 579543807
ColorSeaGreen = 780883967
ColourSeaGreen = 780883967
ColorDarkSlateGray = 793726975
ColourDarkSlateGray = 793726975
ColorDarkSlateGrey = 793726975
ColourDarkSlateGrey = 793726975
ColorLimeGreen = 852308735
ColourLimeGreen = 852308735
ColorMediumSeaGreen = 1018393087
ColourMediumSeaGreen = 1018393087
ColorTurquoise = 1088475391
ColourTurquoise = 1088475391
ColorRoyalBlue = 1097458175
ColourRoyalBlue = 1097458175
ColorSteelBlue = 1182971135
ColourSteelBlue = 1182971135
ColorDarkSlateBlue = 1211993087
ColourDarkSlateBlue = 1211993087
ColorMediumTurquoise = 1221709055
ColourMediumTurquoise = 1221709055
ColorIndigo = 1258324735
ColourIndigo = 1258324735
ColorDarkOliveGreen = 1433087999
ColourDarkOliveGreen = 1433087999
ColorCadetBlue = 1604231423
ColourCadetBlue = 1604231423
ColorCornflowerBlue = 1687547391
ColourCornflowerBlue = 1687547391
ColorRebeccaPurple = 1714657791
ColourRebeccaPurple = 1714657791
ColorMediumAquaMarine = 1724754687
ColourMediumAquaMarine = 1724754687
ColorDimGray = 1768516095
ColourDimGray = 1768516095
ColorDimGrey = 1768516095
ColourDimGrey = 1768516095
ColorSlateBlue = 1784335871
ColourSlateBlue = 1784335871
ColorOliveDrab = 1804477439
ColourOliveDrab = 1804477439
ColorSlateGray = 1887473919
ColourSlateGray = 1887473919
ColorSlateGrey = 1887473919
ColourSlateGrey = 1887473919
ColorLightSlateGray = 2005441023
ColourLightSlateGray = 2005441023
ColorLightSlateGrey = 2005441023
ColourLightSlateGrey = 2005441023
ColorMediumSlateBlue = 2070474495
ColourMediumSlateBlue = 2070474495
ColorLawnGreen = 2096890111
ColourLawnGreen = 2096890111
ColorChartreuse = 2147418367
ColourChartreuse = 2147418367
ColorAquamarine = 2147472639
ColourAquamarine = 2147472639
ColorMaroon = 2147483903
ColourMaroon = 2147483903
ColorPurple = 2147516671
ColourPurple = 2147516671
ColorOlive = 2155872511
ColourOlive = 2155872511
ColorGray = 2155905279
ColourGray = 2155905279
ColorGrey = 2155905279
ColourGrey = 2155905279
ColorSkyBlue = 2278484991
ColourSkyBlue = 2278484991
ColorLightSkyBlue = 2278488831
ColourLightSkyBlue = 2278488831
ColorBlueViolet = 2318131967
ColourBlueViolet = 2318131967
ColorDarkRed = 2332033279
ColourDarkRed = 2332033279
ColorDarkMagenta = 2332068863
ColourDarkMagenta = 2332068863
ColorSaddleBrown = 2336560127
ColourSaddleBrown = 2336560127
ColorDarkSeaGreen = 2411499519
ColourDarkSeaGreen = 2411499519
ColorLightGreen = 2431553791
ColourLightGreen = 2431553791
ColorMediumPurple = 2473647103
ColourMediumPurple = 2473647103
ColorDarkViolet = 2483082239
ColourDarkViolet = 2483082239
ColorPaleGreen = 2566625535
ColourPaleGreen = 2566625535
ColorDarkOrchid = 2570243327
ColourDarkOrchid = 2570243327
ColorYellowGreen = 2597139199
ColourYellowGreen = 2597139199
ColorSienna = 2689740287
ColourSienna = 2689740287
ColorBrown = 2771004159
ColourBrown = 2771004159
ColorDarkGray = 2846468607
ColourDarkGray = 2846468607
ColorDarkGrey = 2846468607
ColourDarkGrey = 2846468607
ColorLightBlue = 2916673279
ColourLightBlue = 2916673279
ColorGreenYellow = 2919182335
ColourGreenYellow = 2919182335
ColorPaleTurquoise = 2951671551
ColourPaleTurquoise = 2951671551
ColorLightSteelBlue = 2965692159
ColourLightSteelBlue = 2965692159
ColorPowderBlue = 2967529215
ColourPowderBlue = 2967529215
ColorFireBrick = 2988581631
ColourFireBrick = 2988581631
ColorDarkGoldenRod = 3095792639
ColourDarkGoldenRod = 3095792639
ColorMediumOrchid = 3126187007
ColourMediumOrchid = 3126187007
ColorRosyBrown = 3163525119
ColourRosyBrown = 3163525119
ColorDarkKhaki = 3182914559
ColourDarkKhaki = 3182914559
ColorSilver = 3233857791
ColourSilver = 3233857791
ColorMediumVioletRed = 3340076543
ColourMediumVioletRed = 3340076543
ColorIndianRed = 3445382399
ColourIndianRed = 3445382399
ColorPeru = 3448061951
ColourPeru = 3448061951
ColorChocolate = 3530104575
ColourChocolate = 3530104575
ColorTan = 3535047935
ColourTan = 3535047935
ColorLightGray = 3553874943
ColourLightGray = 3553874943
ColorLightGrey = 3553874943
ColourLightGrey = 3553874943
ColorThistle = 3636451583
ColourThistle = 3636451583
ColorOrchid = 3664828159
ColourOrchid = 3664828159
ColorGoldenRod = 3668254975
ColourGoldenRod = 3668254975
ColorPaleVioletRed = 3681588223
ColourPaleVioletRed = 3681588223
ColorCrimson = 3692313855
ColourCrimson = 3692313855
ColorGainsboro = 3705462015
ColourGainsboro = 3705462015
ColorPlum = 3718307327
ColourPlum = 3718307327
ColorBurlyWood = 3736635391
ColourBurlyWood = 3736635391
ColorLightCyan = 3774873599
ColourLightCyan = 3774873599
ColorLavender = 3873897215
ColourLavender = 3873897215
ColorDarkSalmon = 3918953215
ColourDarkSalmon = 3918953215
ColorViolet = 4001558271
ColourViolet = 4001558271
ColorPaleGoldenRod = 4008225535
ColourPaleGoldenRod = 4008225535
ColorLightCoral = 4034953471
ColourLightCoral = 4034953471
ColorKhaki = 4041641215
ColourKhaki = 4041641215
ColorAliceBlue = 4042850303
ColourAliceBlue = 4042850303
ColorHoneyDew = 4043305215
ColourHoneyDew = 4043305215
ColorAzure = 4043309055
ColourAzure = 4043309055
ColorSandyBrown = 4104413439
ColourSandyBrown = 4104413439
ColorWheat = 4125012991
ColourWheat = 4125012991
ColorBeige = 4126530815
ColourBeige = 4126530815
ColorWhiteSmoke = 4126537215
ColourWhiteSmoke = 4126537215
ColorMintCream = 4127193855
ColourMintCream = 4127193855
ColorGhostWhite = 4177068031
ColourGhostWhite = 4177068031
ColorSalmon = 4202722047
ColourSalmon = 4202722047
ColorAntiqueWhite = 4209760255
ColourAntiqueWhite = 4209760255
ColorLinen = 4210091775
ColourLinen = 4210091775
ColorLightGoldenRodYellow = 4210742015
ColourLightGoldenRodYellow = 4210742015
ColorOldLace = 4260751103
ColourOldLace = 4260751103
ColorRed = 4278190335
ColourRed = 4278190335
ColorFuchsia = 4278255615
ColourFuchsia = 4278255615
ColorMagenta = 4278255615
ColourMagenta = 4278255615
ColorDeepPink = 4279538687
ColourDeepPink = 4279538687
ColorOrangeRed = 4282712319
ColourOrangeRed = 4282712319
ColorTomato = 4284696575
ColourTomato = 4284696575
ColorHotPink = 4285117695
ColourHotPink = 4285117695
ColorCoral = 4286533887
ColourCoral = 4286533887
ColorDarkOrange = 4287365375
ColourDarkOrange = 4287365375
ColorLightSalmon = 4288707327
ColourLightSalmon = 4288707327
ColorOrange = 4289003775
ColourOrange = 4289003775
ColorLightPink = 4290167295
ColourLightPink = 4290167295
ColorPink = 4290825215
ColourPink = 4290825215
ColorGold = 4292280575
ColourGold = 4292280575
ColorPeachPuff = 4292524543
ColourPeachPuff = 4292524543
ColorNavajoWhite = 4292783615
ColourNavajoWhite = 4292783615
ColorMoccasin = 4293178879
ColourMoccasin = 4293178879
ColorBisque = 4293182719
ColourBisque = 4293182719
ColorMistyRose = 4293190143
ColourMistyRose = 4293190143
ColorBlanchedAlmond = 4293643775
ColourBlanchedAlmond = 4293643775
ColorPapayaWhip = 4293907967
ColourPapayaWhip = 4293907967
ColorLavenderBlush = 4293981695
ColourLavenderBlush = 4293981695
ColorSeaShell = 4294307583
ColourSeaShell = 4294307583
ColorCornsilk = 4294499583
ColourCornsilk = 4294499583
ColorLemonChiffon = 4294626815
ColourLemonChiffon = 4294626815
ColorFloralWhite = 4294635775
ColourFloralWhite = 4294635775
ColorSnow = 4294638335
ColourSnow = 4294638335
ColorYellow = 4294902015
ColourYellow = 4294902015
ColorLightYellow = 4294959359
ColourLightYellow = 4294959359
ColorIvory = 4294963455
ColourIvory = 4294963455
ColorWhite = 4294967295
ColourWhite = 4294967295

Procs

proc `==`(c1, c2: Coord): bool {...}{.inline, raises: [], tags: [].}
proc `-`(c: Coord): Coord {...}{.inline, raises: [], tags: [].}
proc `+`(c1, c2: Coord): Coord {...}{.inline, raises: [], tags: [].}
proc `+=`(c1: var Coord; c2: Coord) {...}{.inline, raises: [], tags: [].}
proc `-`(c1, c2: Coord): Coord {...}{.inline, raises: [], tags: [].}
proc `-=`(c1: var Coord; c2: Coord) {...}{.inline, raises: [], tags: [].}
proc `*`(c1, c2: Coord): Coord {...}{.inline, raises: [], tags: [].}
proc `*=`(c1: var Coord; c2: Coord) {...}{.inline, raises: [], tags: [].}
proc `/`(c1, c2: Coord): Coord {...}{.inline, raises: [], tags: [].}
proc `/=`(c1: var Coord; c2: Coord) {...}{.inline, raises: [], tags: [].}
proc `+`(c: Coord; v: float): Coord {...}{.inline, raises: [], tags: [].}
proc `+=`(c: var Coord; v: float) {...}{.inline, raises: [], tags: [].}
proc `-`(c: Coord; v: float): Coord {...}{.inline, raises: [], tags: [].}
proc `-=`(c: var Coord; v: float) {...}{.inline, raises: [], tags: [].}
proc `*`(c: Coord; v: float): Coord {...}{.inline, raises: [], tags: [].}
proc `*=`(c: var Coord; v: float) {...}{.inline, raises: [], tags: [].}
proc `/`(c: Coord; v: float): Coord {...}{.inline, raises: [], tags: [].}
proc `/=`(c: var Coord; v: float) {...}{.inline, raises: [], tags: [].}
proc abs(c: Coord): Coord {...}{.inline, raises: [], tags: [].}
proc sin(c: Coord): Coord {...}{.inline, raises: [], tags: [].}
proc arcsin(c: Coord): Coord {...}{.inline, raises: [], tags: [].}
proc `==`(c1, c2: CoordInt): bool {...}{.inline, raises: [], tags: [].}
proc `-`(c: CoordInt): CoordInt {...}{.inline, raises: [], tags: [].}
proc `+`(c1, c2: CoordInt): CoordInt {...}{.inline, raises: [], tags: [].}
proc `+=`(c1: var CoordInt; c2: CoordInt) {...}{.inline, raises: [], tags: [].}
proc `-`(c1, c2: CoordInt): CoordInt {...}{.inline, raises: [], tags: [].}
proc `-=`(c1: var CoordInt; c2: CoordInt) {...}{.inline, raises: [], tags: [].}
proc `*`(c1, c2: CoordInt): CoordInt {...}{.inline, raises: [], tags: [].}
proc `*=`(c1: var CoordInt; c2: CoordInt) {...}{.inline, raises: [], tags: [].}
proc `div`(c1, c2: CoordInt): CoordInt {...}{.inline, raises: [], tags: [].}
proc div=(c1: var CoordInt; c2: CoordInt) {...}{.inline, raises: [], tags: [].}
proc `+`(c: CoordInt; v: int): CoordInt {...}{.inline, raises: [], tags: [].}
proc `+=`(c: var CoordInt; v: int) {...}{.inline, raises: [], tags: [].}
proc `-`(c: CoordInt; v: int): CoordInt {...}{.inline, raises: [], tags: [].}
proc `-=`(c: var CoordInt; v: int) {...}{.inline, raises: [], tags: [].}
proc `*`(c: CoordInt; v: int): CoordInt {...}{.inline, raises: [], tags: [].}
proc `*=`(c: var CoordInt; v: int) {...}{.inline, raises: [], tags: [].}
proc `div`(c: CoordInt; v: int): CoordInt {...}{.inline, raises: [], tags: [].}
proc div=(c: var CoordInt; v: int) {...}{.inline, raises: [], tags: [].}
proc abs(c: CoordInt): CoordInt {...}{.inline, raises: [], tags: [].}
proc `==`(d1, d2: Dim): bool {...}{.inline, raises: [], tags: [].}
proc `+`(d1, d2: Dim): Dim {...}{.inline, raises: [], tags: [].}
proc `+=`(d1: var Dim; d2: Dim) {...}{.inline, raises: [], tags: [].}
proc `-`(d1, d2: Dim): Dim {...}{.inline, raises: [], tags: [].}
proc `-=`(d1: var Dim; d2: Dim) {...}{.inline, raises: [], tags: [].}
proc `*`(d1, d2: Dim): Dim {...}{.inline, raises: [], tags: [].}
proc `*=`(d1: var Dim; d2: Dim) {...}{.inline, raises: [], tags: [].}
proc `/`(d1, d2: Dim): Dim {...}{.inline, raises: [], tags: [].}
proc `/=`(d1: var Dim; d2: Dim) {...}{.inline, raises: [], tags: [].}
proc `+`(d: Dim; v: int): Dim {...}{.inline, raises: [], tags: [].}
proc `+=`(d: var Dim; v: int) {...}{.inline, raises: [], tags: [].}
proc `-`(d: Dim; v: int): Dim {...}{.inline, raises: [], tags: [].}
proc `-=`(d: var Dim; v: int) {...}{.inline, raises: [], tags: [].}
proc `*`(d: Dim; v: int): Dim {...}{.inline, raises: [], tags: [].}
proc `*=`(d: var Dim; v: int) {...}{.inline, raises: [], tags: [].}
proc `/`(d: Dim; v: int): Dim {...}{.inline, raises: [], tags: [].}
proc `/=`(d: var Dim; v: int): Dim {...}{.inline, raises: [], tags: [].}

Converters

converter toSeq[T](s: Slice[T]): seq[T]
converter toUint32(c: Color): uint32 {...}{.raises: [], tags: [].}
Color(r, g, b, a) to 0xRRGGBBAA
converter toColor(u: uint32): Color {...}{.raises: [], tags: [].}
0xRRGGBBAA to Color(r, g, b, a)
converter toDim(c: Coord): Dim {...}{.raises: [], tags: [].}
converter toDim(c: CoordInt): Dim {...}{.raises: [], tags: [].}
converter toCoord(d: Dim): Coord {...}{.raises: [], tags: [].}

Templates

template neg(c: Color): Color
Return negative to color c.
template `+`(v: float; c: Coord): Coord
template `-`(v: float; c: Coord): Coord
template `*`(v: float; c: Coord): Coord
template `+`(v: int; c: CoordInt): CoordInt
template `-`(v: int; c: CoordInt): CoordInt
template `*`(v: int; c: CoordInt): CoordInt
template `*`(transform: Transform; point: Coord): Coord
template local(transform: Transform): Transform
================================================ FILE: docs/docs/typewriter.html ================================================ typewriter

typewriter

Types

Typewriter = ref object of Entity
  fText: seq[char]             ## typewriter's queue
  fRemainder: float            ## internal timer (in seconds)
  rate*: float                 ## typewriter's rate (in seconds)
  width*: int                  ## line width limit, no limit if `0` (default)
  

Procs

proc newTypewriter(text: TextGraphic; rate: float): Typewriter {...}{.raises: [Exception],
    tags: [RootEffect].}
proc add(tw: Typewriter; text: string) {...}{.inline, raises: [], tags: [].}
Add new text to the typewriter's queue.
proc dump(tw: Typewriter): string {...}{.inline, raises: [], tags: [].}
Return the text awaiting in the typewriter's queue.
proc clear(tw: Typewriter) {...}{.inline, raises: [], tags: [].}
Delete the text awaiting in the typewriter's queue.
proc force(tw: Typewriter; text: string = "") {...}{.raises: [Exception], tags: [RootEffect].}
Add new text to the typewriter's queue and then output it all immediately.
proc updateTypewriter(tw: Typewriter; elapsed: float) {...}{.raises: [Exception],
    tags: [RootEffect].}

Methods

method update(tw: Typewriter; elapsed: float) {...}{.raises: [Exception], tags: [RootEffect].}
================================================ FILE: docs/docs/utils.html ================================================ utils

utils

Types

Counter = ref object
  counter, current, interval: int
  time: uint64

Procs

proc distance(a, b: Coord): float {...}{.inline, raises: [], tags: [].}
Return distance between two coordinates.
proc distanceToLine(a, d1, d2: Coord): float {...}{.raises: [], tags: [].}
Return distance between point a and line d1-d2.
proc direction(a, b: Coord): Angle {...}{.raises: [], tags: [].}
Return angle direction from coordinate a to b (in degrees).
proc rotate(a: Coord; angle: Angle): Coord {...}{.raises: [], tags: [].}
Rotate point a by the given angle (in degrees).
proc rotate(point, offset: Coord; angle: Angle): Coord {...}{.raises: [], tags: [].}

Rotate point by the given angle and with given offset.

offset Offset coordinate (parent position) point Point to rotate angle Angle of rotation (in degrees)

proc loadSurface(file: string): Surface {...}{.raises: [], tags: [].}

Load an image file to the sdl.Surface.

Return the surface on success, or nil otherwise.

proc loadSurface(src: ptr RWops; freeSrc: bool = true): Surface {...}{.raises: [], tags: [].}

Load src RWops to the sdl.Surface.

Return the surface on success, or nil otherwise.

proc textureFormats(renderer: Renderer): tuple[num: uint32,
    formats: array[16, uint32]] {...}{.raises: [], tags: [].}
Return number and array of available texture formats from the renderer.
proc textureFormat(renderer: Renderer; n: uint32 = 0): uint32 {...}{.raises: [], tags: [].}
Return n'th texture format from the renderer.
proc readAll(src: ptr RWops): string {...}{.raises: [Exception], tags: [RootEffect].}
proc loadCSV[T](file: string; parse: proc (input: string): T; separator = ',';
               quote = '\"'; escape = '\x00'; skipInitialSpace = true): seq[seq[T]]

Load data from a CSV file.

Return a two-dimensional sequence of values from the file, or empty sequence (@[]) otherwise.

proc loadCSV[T](src: ptr RWops; file: string; parse: proc (input: string): T;
               separator = ','; quote = '\"'; escape = '\x00'; skipInitialSpace = true;
               freeSrc = true): seq[seq[T]]

Load data from src RWops.

file is only used for nice error messages.

Return a two-dimensional sequence of values from the file, or empty sequence (@[]) otherwise.

proc loadPalette(palette: var indexedimage.Palette; file: string; separator = ' ';
                quote = '\"'; escape = '\x00'; skipInitialSpace = true) {...}{.
    raises: [CsvError, Exception, OverflowError, ValueError, IndexError],
    tags: [ReadIOEffect].}

Load palette color data from a file.

palette Target palette. If palette is nil, allocates a new palette, otherwise the palette will be freed.

Data file should be in a format of:

rrr ggg bbb aaa ...

or

rrr ggg bbb

where rrr, ggg, bbb, and aaa is in 0..`255` range.

Other types of lines are ignored.

proc loadPalette(palette: var indexedimage.Palette; src: ptr RWops; file: string;
                separator = ' '; quote = '\"'; escape = '\x00'; skipInitialSpace = true;
                freeSrc = true) {...}{.raises: [Exception, CsvError, OverflowError,
                                       ValueError, IndexError],
                               tags: [RootEffect, ReadIOEffect].}
proc random[T](max: T; exclude: seq[T]): T {...}{.deprecated.}

Return a random number in the range 0..<max, except values in the exclude.

Deprecated: Use rand instead.

proc rand[T](max: T; exclude: seq[T]): T
Return a random number in the range 0..``max``, except values in the exclude.
proc rand[T](max: T; exclude: openArray[T]): T {...}{.inline.}
proc random[T](x, exclude: seq[T]): T {...}{.deprecated.}

Return a random number in the sequence x, except values in the exclude.

Deprecated: use rand instaead.

proc rand[T](x, exclude: seq[T]): T
Return a random number in the sequence x, except values in the exclude.
proc rand[T](x, exclude: openArray[T]): T {...}{.inline.}
proc random[T](x: Slice[T]; exclude: seq[T]): T {...}{.deprecated.}

Return a random number in the range min..<max, except values in the exclude.

Deprecated: use rand instead.

proc rand[T](x: Slice[T]; exclude: seq[T]): T
Return a random number in the range min..``max``, except values in the exclude.
proc rand[T](x: Slice[T]; exclude: openArray[T]): T {...}{.inline.}
proc random[T](x: set[T]): T {...}{.deprecated.}

Return a random member of set x.

Deprecated: use rand instead.

proc rand[T](x: set[T]): T
Return a random member of set x.
proc randomBool(chance: float = 0.5): bool {...}{.deprecated, raises: [], tags: [].}
Return true or false, based on the chance value (from 0.0 to 1.0).
proc randBool(chance: float = 0.5): bool {...}{.inline, raises: [], tags: [].}
proc randomSign(chance: float = 0.5): int {...}{.raises: [], tags: [].}
Return 1 or -1, based on the chance value (from 0.0 to 1.0).
proc randSign(chance: float = 0.5): int {...}{.inline, raises: [], tags: [].}
proc randomWeighted[T](weights: openArray[T]): int

Return a random integer, based on the weights array.

E.g., call of randomWeighted([2, 3, 5]) will have a 20% chance of returning 0, 30% chance of returning 1, and 50% chance of returning 2.

proc randWeighted[T](weights: openArray[T]): int {...}{.inline.}
proc newCounter(interval: int = 1000): Counter {...}{.raises: [], tags: [].}
proc update(counter: Counter) {...}{.raises: [], tags: [].}
proc value(counter: Counter): int {...}{.inline, raises: [], tags: [].}

Iterators

iterator atlasValues(file: string; separator = ','; quote = '\"'; escape = '\x00';
                    skipInitialSpace = true): tuple[name: string, rect: Rect] {...}{.
    raises: [CsvError, Exception, OverflowError, ValueError], tags: [ReadIOEffect].}

Load and iterate over atlas mapping file.

Mapping should be in a format of:

name, x, y, w, h ...

iterator atlasValues(src: ptr RWops; file: string; separator = ','; quote = '\"';
                    escape = '\x00'; skipInitialSpace = true; freeSrc = true): tuple[
    name: string, rect: Rect] {...}{.raises: [Exception, CsvError, OverflowError, ValueError],
                            tags: [RootEffect, ReadIOEffect].}

Templates

template rad(a: Angle): Angle
Convert degrees to radians.
template deg(a: Angle): Angle
Convert radians to degrees.
template random[T](max: T; exclude: openArray[T]): T {...}{.deprecated.}
template random[T](x, exclude: openArray[T]): T {...}{.deprecated.}
template random[T](x: Slice[T]; exclude: openArray[T]): T {...}{.deprecated.}
template timeDiff(first, second: untyped): untyped

first, second two results of sdl.getPerformanceCounter().

Return time difference between two time stamps (in ms).

template msToSec(ms: int): float
template secToMs(sec: float): int
================================================ FILE: docs/docs.html ================================================ Nimgame 2

DOCUMENTATION

================================================ FILE: docs/index.html ================================================ Nimgame 2

Nimgame 2 is a simple 2D game engine for Nim language.


Status: v0.6.1 alpha.

About: The engine is written in Nim, and built on top of SDL2 library through the SDL2_nim wrapper.

The purpose of Nimgame 2 is to provide a comfort layer over the SDL2 procedures, creating a minimalist and simple to understand 2D game engine.

Changelog


Checklist of features

  • scene/entity system
  • assets manager
  • audio
    • sound
    • music
    • playlists
  • camera
  • colliders
  • drawing
  • emitters
  • fonts
    • bitmap
    • TrueType
  • GUI
    • buttons
    • progress bar
    • radio groups and buttons
    • text input
  • indexed images (palette manipulation)
  • input
    • keyboard
    • mouse
    • joysticks
    • gamepads
  • mosaic
  • parallax
  • perspective images (perspective manipulation)
  • simple physics
    • default ("space")
    • platformer
  • texture atlas
  • tilemaps
  • typewriter (text animation effect)
  • tweens
  • window management
  • plugins
    • MPEG video support
    • TAR archive support
    • ZIP archive support

Screenshots

Two-Button Knight screenshot
Two-Button Knight
Glorious Glacier Grotto screenshot
Glorious Glacier Grotto
Planetoids screenshot
Planetoids
Platformer tutorial screenshot
Platformer tutorial
Demo14 screenshot
Demo14, using sprites, tilemaps, tweens, and emitters
================================================ FILE: docs/links.html ================================================ Nimgame 2
================================================ FILE: docs/snippets.html ================================================ Nimgame 2

SNIPPETS

Engine Initialization

  # mygame.nim

  import
      nimgame2 / [
        nimgame,
        settings,
      ]
      mainscene # your first scene


  game = newGame()
  if game.init(w = 640, h = 480, title = "My Awesome Game"):
      game.scene = newMainScene() # your scene constructor
      game.run()

Scene Initialization

  # mainscene.nim

  import
    nimgame2 / [
      nimgame,
      entity,
      scene,
      settings,
      texturegraphic,
      types
    ]


  type
    MainScene = ref object of Scene
      myGraphic: TextureGraphic
      myEntity: Entity


  proc init*(scene: MainScene) =
    # don't forget the parent initialization!
    Scene(scene).init()

    # create the graphic
    scene.myGraphic = newTextureGraphic()
    # load graphic file
    discard scene.myGraphic.load("data/gfx/my_image.png")

    # create the entity
    scene.myEntity = newEntity()
    # assign the graphic to the entity
    scene.myEntity.graphic = scene.myGraphic

    # add your entity to the scene
    scene.add(scene.myEntity)


  proc free*(scene: MainScene) =
    # free the texture
    scene.myGraphic.free()


  proc newMainScene*(): MainScene =
    # scene constructor
    new result, free
    result.init()


  method event*(scene: MainScene, event: Event) =
    # call it if your entities have their own event handlers
    scene.eventScene(event)
    # if you want to handle some events manually, you do it here
    if event.kind == KeyDown:
      case event.key.keysym.scancode:
      of ScancodeEscape:
        # stop the engine (see nimgame2/settings.nim)
        gameRunning = false
      else: discard


  method render*(scene: MainScene) =
    # don't forget to call the parent render!
    scene.renderScene()
    # if you want to draw something on top of a rendered scene,
    # you do it here


  method update*(scene: MainScene, elapsed: float) =
    # don't forget to call the parent update!
    scene.updateScene(elapsed)
    # scene-level logic goes here

Entity Initialization

  # myentity.nim

  import
    nimgame2 / [
      nimgame,
      entity,
      texturegraphic,
    ]


  type
    MyEntity* = ref object of Entity


  proc init*(entity: MyEntity, graphic: TextureGraphic) =
    # don't forget to call the parent initialization!
    entity.initEntity()
    # assign the graphic
    entity.graphic = graphic
    # set the center point
    entity.centrify()
    # assign the physics only if you need it
    entity.physics = defaultPhysics


  proc newMyEntity*(graphic: TextureGraphic): MyEntity =
    # entity constructor
    new result
    result.init(graphic)


  method update*(entity: MyEntity, elapsed: float) =
    # don't forget to call the parent update!
    entity.updateEntity(elapsed)
    # entity-level logic goes here

Keyboard Input

  # somewhere in the update method

    let move = 100 * elapsed
    if ScancodeLeft.down: scene.player.pos.x -= move
    if ScancodeRight.down: scene.player.pos.x += move
    # the key was pressed
    if ScancodeSpace.pressed: scene.player.startCharging()
    # the key was relased
    if ScancodeSpace.released: scene.player.discharge()

Mouse Input

  # somewhere in the update method

    let mousePos = mouse.abs
    if Button.left.down: scene.player.fireTo(mousePos)
    # Mouse buttons (Button enum): left, middle, right, x1, x2

Joystick Input

  # somewhere in the initialization routine

    for i in 0..<numJoysticks():
      discard openJoystick(i)

    scene.joy = 0

  # somewhere in the update method

    let move = 100 * elapsed / JoyAxis.high.float
    scene.player.pos.x += scene.joy.joyAxis(0).float * move
    scene.player.pos.y += scene.joy.joyAxis(1).float * move

    # the button was pressed
    if scene.joy.joyPressed(0): scene.player.startCharging()
    # the button was released
    if scene.joy.joyReleased(0): scene.player.discharge()

Sprite Initialization

  # somewhere in the entity initialization routine

    # assign the graphic
    entity.graphic = graphic
    # set the sprite dimensions and offset
    # (if the graphic has a border)
    entity.initSprite((24, 48), offset = (16, 16))

    # add animations
    discard scene.d.addAnimation(
      "run_right", [0, 1, 2, 3])
    discard scene.d.addAnimation(
      "run_left", [0, 1, 2, 3], flip = Flip.horizontal)

    # or, if your frames are in order,
    # use toSeq() from types.nim
    discard scene.d.addAnimation(
      "jump_right", toSeq(4..7))
    discard scene.d.addAnimation(
      "jump_left", toSeq(4..7), flip = Flip.horizontal)

Collider Initialization

  # somewhere in the entity initialization routine

    entity.collider = newBoxCollider(entity, (0, 0), entity.graphic.dim)

TextGraphic Usage

  # somewhere in the scene initialization routine

    # BitmapFont

    # create a bitmap font
    scene.bitmapFont = newBitmapFont()
    # load the font file, giving the dimensions of a single character
    discard scene.bitmapFont.load("data/font/bitmap.png", (8, 16))
    # create a text graphic
    scene.bitmapText = newTextGraphic()
    # assign the font
    scene.bitmapText.font = scene.bitmapFont
    # set the text
    scene.bitmapText.lines =
      [ "Text line 1",
        "Text line 2"]
    # create an entity
    scene.bitmapEntity = newEntity()
    # assign the graphic
    scene.bitmapEntity.graphic = scene.bitmapText
    # add to the scene
    scene.add(scene.bitmapEntity)

    # TrueTypeFont

    # create a TrueType font
    scene.trueTypeFont = newTrueTypeFont()
    # load the font file, giving the font size
    discard scene.trueTypeFont.load("data/font/truetype.ttf", 16)
    # create a text graphic
    scene.trueTypeText = newTextGraphic()
    # assign the font
    scene.trueTypeText.font = scene.trueTypeFont
    # set the text
    scene.trueTypeText.lines =
      [ "Text line 1",
        "Text line 2"]
    # create an entity
    scene.trueTypeEntity = newEntity()
    # assign the graphic
    scene.trueTypeEntity.graphic = scene.trueTypeText
    # add to the scene
    scene.add(scene.trueTypeEntity)

ProcGraphic Usage

  # somewhere in the initialization routine

  proc customProc(graphic: ProcGraphic,
                  pos: Coord,
                  angle: Angle,
                  scale: Scale,
                  center: Coord,
                  flip: Flip,
                  region: Rect) =
    # your custom drawing routine goes here


  proc init*(scene: MyScene) =
    Scene(scene).init()
    # create a ProcGraphic
    scene.customGraphic = newProcGraphic()
    # assign the procedure
    scene.customGraphic.procedure = customProc
    # create an entity
    scene.myEntity = newEntity
    # assign the graphic
    scene.myEntity.graphic = scene.customGraphic
    # add to the scene
    scene.add(scene.myEntity)

IndexedImage Usage

# somewhere in the initialization routine

  let myImage = newIndexedImage("data/gfx/unit.gif")
  var color = myImage.palette[8] # get palette color
  color.r = 255
  color.g = 0
  color.b = 0
  myImage.palette[8] = color # set palette color

  # generate graphic
  let myGraphic = newTextureGraphic()
  discard myGraphic.assignTexture myImage.render()

PerspectiveImage Usage

# somewhere in the initialization routine

  let myImage = newPerspectiveImage("data/gfx/pimage.png")
  let myGraphic = newTextureGraphic()
  # render with distortion
  myGraphic.assignTexture myImage.render(pdHor, 64, 32)
  let myEntity = newEntity()
  myEntith.graphic = myGrapghic
  scene.add(myEntity)

TextureAtlas Usage

# somewhere in the initialization routine

  let myAtlas = newTextureAtlas("data/gfx/atlas.png", "data/csv/atlas.csv")
  entity1.graphic = myAtlas["image1"]
  entity2.graphic = myAtlas["image2"]

Tween Usage

  let tween = newTween[Entity,Coord](
    target = myEntity,
    get = proc(t: Entity): Coord = t.pos,
    set = proc(t: Entity, val: Coord) = t.pos = val
  )
  tween.procedure = inQuad
  tween.setup(
    start = myEnttiy.pos,
    finish = myEntityPos + (100.0, 0.0),
    duration = 3.0,
    loops = -1
  )
  tween.play()

Emitter Usage

  # somewhere in the initialization routine
    # init emitter
    myEmitter = newEmitter(myScene)
    myEmitter.randomVel = (10.0, 10.0)
    myEmitter.randomAcc = (5.0, 5.0)
    myEmitter.randomTTL = 5.0
    myScene.add(myEmitter)
    # init emitter particle
    myEmitter.particle = newParticle()
    myEmitter.particle.graphic = myParticleGraphic
    myEmitter.particle.initSprite((5, 5))
    myEmitter.particle.centrify()
    discard myEmitter.particle.addAnimation("play", toSeq(0..4), 1/5)
    myEmitter.particle.play("play", 1, kill = true)

  # somewhere in the update routine
    if emitCondition:
      myEmitter.emit(5) # emit 5 particles

TileMap Usage

  # somewhere in the initialization routine

    # tiles
    scene.tilesGraphic = newTextureGraphic()
    discard scene.tilesGraphic.load("data/gfx/tile.png")

    # map
    scene.map = newTileMap(scaleFix = true)
    scene.map.graphic = scene.tilesGraphic
    scene.map.initSprite((64, 64), offset = (0, 0))
    scene.map.map = loadCSV[int](
        "data/csv/map.csv",
        proc(input: string): int = discard parseInt(input, result)
    )
    scene.map.passable.add(0)
    scene.add(scene.map)

TileMap Collision List

  # checking specific tile collisions
  let
    collider = TilemapCollider(map.collider)
    collisions = collider.collisionList(myEntity.collider)
    for tile in collisions:
      echo
        "Collided with " & $tile.value & " at " & $tile.mapx & ":" & $tile.mapy

Camera Usage

  # somewhere in the initialization routine

    scene.camera = newEntity()

    scene.map = newMyMap()
    scene.map.parent = scene.camera # this entity is bound to the camera
    scene.add(scene.map)

    scene.player = newMyPlayer()
    scene.player.parent = scene.map # this entity is bound to the map
    scene.add(scene.player)

    # this entity isn't bound to the camera
    scene.ui = newUI()
    scene.add(scene.ui)

    # boud camera to this entity
    scene.cameraBond = scene.player
    # place camera bond entity at the center
    scene.cameraBondOffset = game.size / 2

  # somewhere in the update routine

    if scene.cameraBond == nil:
        if ScancodeRight.down: scene.camera.pos.x += step
        # ...
    else:
        if ScancodeRight.down: scene.player.pos.x += step
        # ...

Sound Usage

  # somewhere in the initialization routine

    # load a sound file
    scene.soundEffect = newSound("data/sfx/effect.wav")
    # set the volume
    scene.soundEffect.volume = Volume.high div 2

  # somewhere else

    # the call
    scene.soundEffect.play()

Music Playlist Usage

  # somewhere in the initialization routine

    # load all music files
    var musicData: Assets[Music]
    musicData = newAssets[Music]("data/music",
                                 proc(file: string): Music = newMusic(file))
    # global playlist
    playlist = newPlaylist()
    # fill the playlist
    for track in musicData.values:
      playlist.list.add(track)

  # somewhere else

    # next random track
    discard playlist.play()

  # somewhere in the update routine

    playlist.update()

GUI: Buttons

# mybutton.nim

import
  nimgame2 / [
    graphic,
    input,
    gui/button,
  ]

type
  MyButton* = ref object of GuiButton

proc init*(btn: MyButton, graphic: Graphic, image: Graphic = nil) =
  GuiButton(btn).init(graphic, image)

proc newMyButton*(graphic: Graphic, image: Graphic = nil): MyButton =
  new result
  result.init(graphic, image)

method onClick*(btn: MyButton, mb: MouseButton) =
  echo "clicked my button"


# somewhere in the initialization routine
  # skin loading
  let mySkin = newTextureGraphic()
  discard mySkin.load("data/gfx/button_skin.png")

  # button initialization
  myBtn = newMyButton(mySkin)
  scene.add(myBtn)

GUI: Actions

# action procedure
proc myBtnAction(widget: GuiWidget) =
  echo "clicked my button"

# somewhere in the initialization routine
  # skin loading
  let mySkin = newTextureGraphic()
  discard mySkin.load("data/gfx/button_skin.png")

  # button initialization
  myBtn = newGuiButton(mySkin)
  myBtn.action = myBtnAction
  scene.add(myBtn)

GUI: Text Input (+ Mosaic)

import
  nimgame2 / [
    scene,
    mosaic,
    texturegraphic,
    truetypefont,
    gui/widget,
    gui/textinput,
  ]

# somewhere in the initialization routine

  # mosaic creation
  let myMosaic = newMosaic("data/gfx/textinput_skin.png")
  let mySkin = newTextureGraphic()
  discard mySkin.assignTexture myMosaic.render(patternStretchBorder(16, 1))

  # text input initialization
  myTextInput = newGuiTextInput(mySkin, myFont)
  myTextInput.text.limit = 16 # set text length limit
  scene.add(myTextInput)

GUI: Radio Groups

import
  nimgame2 / [
    scene,
    texturegraphic,
    truetypefont,
    gui/widget,
    gui/radio,
  ]

type
  MyScene = ref object of Scene
    radioButtons: array[3, GuiRadioButton]
    radioGroup: GuiRadioGroup

# somewhere in the initialization routine

  scene.radioGroup = newGuiRadioGroup() # create group

  # init each button
  for i in 0..scene.radioButtons.high:
    scene.radioButtons[i] = newGuiRadioButton(scene.radioGroup, scene.mySkin)

  scene.radioButtons[0].toggled = true # toggle the first button

  # add to the scene
  scene.add(scene.radioGroup)
  for btn in scene.radioButtons:
    scene.add(btn)

GUI: ProgressBar

# somewhere in the initialization routine
  scene.bar = newProgressBar((200, 50), 0xFF0000FF'u32, 0xFF0000FF'u32, myFont)
  scene.bar.min = 0
  scene.bar.max = 100
  scene.bar.direction = Direction.leftRight
  scene.bar.outline = (1, 1) # one pixel outline
  scene.add(scene.bar)

# on update
  scene.bar.value = newValue
================================================ FILE: docs/structure.js ================================================ // STRUCTURE /** * Create favicon link tag. */ function createFavicon() { var icon = document.createElement('link'); icon.rel = 'shortcut icon'; icon.href = 'favicon.ico'; icon.type = "image/x-icon"; document.querySelector('head').appendChild(icon); } /** * Create a header link object. * * @param name Link name (without extension). * * @param disabled If true - the link is disabled. * * @return an object with a link to the @param link. */ function headerLink(name, disabled) { var a = document.createElement('a'); if(disabled) a.classList.add('disabled'); a.href = name + '.html'; a.classList.add('menu'); a.innerHTML = name.toUpperCase(); var result = document.createElement('span'); result.appendChild(a); return result; } /** * Fill the
of the current html-file. * * @param title Header title. * * @param logo Path to the logo image (without extension). */ function createHeader(title, logo) { var img = document.createElement('img'); img.src = logo + '.png'; var logoLink = document.createElement('a'); logoLink.href = 'index.html'; logoLink.target = '_self'; logoLink.appendChild(img); var logo = document.createElement('div'); logo.classList.add('logo'); logo.appendChild(logoLink); var headerTitle = document.createElement('h1'); headerTitle.innerHTML = title; var headerLinks = [ headerLink('index'), headerLink('demos'), headerLink('tutorials'), headerLink('snippets'), headerLink('docs'), headerLink('links'), ]; var menu = document.createElement('div'); for(var i = 0; i < headerLinks.length; i++) { menu.appendChild(headerLinks[i]); } var titleDiv = document.createElement('div'); titleDiv.appendChild(headerTitle); titleDiv.appendChild(menu); var logoR = document.createElement('div'); logoR.classList.add('logo'); var headerDiv = document.createElement('div'); headerDiv.appendChild(logo); headerDiv.appendChild(titleDiv); headerDiv.appendChild(logoR); var header = document.querySelector('header'); header.appendChild(headerDiv); header.appendChild(document.createElement('hr')); } /** * Fill the