├── .gitmodules ├── .travis.yml ├── CMakeLists.txt ├── COPYING ├── README.md ├── data ├── M484SpaceSoldier.png ├── M484SpaceSoldier.png.COPYRIGHT ├── Vera.ttf └── Vera.ttf.COPYRIGHT ├── lesson00.cc ├── lesson01.cc ├── lesson02.cc ├── lesson03.cc ├── lesson04.cc ├── lesson05.cc ├── lesson06.cc ├── lesson07.cc └── screenshots └── lesson07.png /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "SDL2pp"] 2 | path = SDL2pp 3 | url = https://github.com/libSDL2pp/libSDL2pp.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | compiler: 3 | - gcc 4 | - clang 5 | before_install: 6 | - sudo add-apt-repository --yes ppa:zoogie/sdl2-snapshots 7 | - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test 8 | - sudo apt-get update -qq 9 | - sudo apt-get install -qq cmake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev g++-4.8 10 | - if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi 11 | script: 12 | - cmake . && make 13 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SDL2pp tutorial 2 | # 3 | # Written in 2015 by Dmitry Marakasiv 4 | # 5 | # To the extent possible under law, the author(s) have dedicated all copyright 6 | # and related and neighboring rights to this software to the public domain 7 | # worldwide. This software is distributed without any warranty. 8 | # 9 | # You should have received a copy of the CC0 Public Domain Dedication along with 10 | # this software. If not, see . 11 | 12 | cmake_minimum_required(VERSION 3.16 FATAL_ERROR) 13 | project(SDL2pp-tutorial LANGUAGES CXX) 14 | 15 | # set up SDL2pp library 16 | set(SDL2PP_WITH_IMAGE YES) 17 | set(SDL2PP_WITH_TTF YES) 18 | add_subdirectory(SDL2pp) 19 | 20 | # add compilation flags 21 | set(CMAKE_CXX_STANDARD 17) 22 | add_definitions(-DDATA_PATH="${PROJECT_SOURCE_DIR}/data") 23 | include_directories(${SDL2PP_INCLUDE_DIRS}) 24 | 25 | # define targets 26 | add_executable(lesson00 lesson00.cc) 27 | target_link_libraries(lesson00 PUBLIC SDL2pp) 28 | 29 | add_executable(lesson01 lesson01.cc) 30 | target_link_libraries(lesson01 PUBLIC SDL2pp) 31 | 32 | add_executable(lesson02 lesson02.cc) 33 | target_link_libraries(lesson02 PUBLIC SDL2pp) 34 | 35 | add_executable(lesson03 lesson03.cc) 36 | target_link_libraries(lesson03 PUBLIC SDL2pp) 37 | 38 | add_executable(lesson04 lesson04.cc) 39 | target_link_libraries(lesson04 PUBLIC SDL2pp) 40 | 41 | add_executable(lesson05 lesson05.cc) 42 | target_link_libraries(lesson05 PUBLIC SDL2pp) 43 | 44 | add_executable(lesson06 lesson06.cc) 45 | target_link_libraries(lesson06 PUBLIC SDL2pp) 46 | 47 | add_executable(lesson07 lesson07.cc) 48 | target_link_libraries(lesson07 PUBLIC SDL2pp) 49 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # libSDL2pp tutorial 2 | 3 | [![Build Status](https://travis-ci.org/libSDL2pp/libSDL2pp-tutorial.svg?branch=master)](https://travis-ci.org/libSDL2pp/libSDL2pp-tutorial) 4 | 5 | --- 6 | 7 | ![Screenshot](screenshots/lesson07.png) 8 | 9 | Here's tutorial for [libSDL2pp](https://github.com/libSDL2pp/libSDL2pp), 10 | C++11 bindings/wrapper for SDL2. It covers core functionality of 11 | the library, including initialization and window construction, 12 | loading image files, sprite and text rendering, animation, and event 13 | handling trying to demonstate library features in as little code 14 | as possible. 15 | 16 | ## Lessons 17 | 18 | The tutorial is split into lessons, which demonstrate gradual 19 | development of a simple application resembling a platformer game. 20 | 21 | * **[lesson00](lesson00.cc)**: SDL library initialization, window creation, image loading and rendering 22 | * **[lesson01](lesson01.cc)**: picking specific sprite from an image atlas 23 | * **[lesson02](lesson02.cc)**: main loop, event processing 24 | * **[lesson03](lesson03.cc)**: timing and animation 25 | * **[lesson04](lesson04.cc)**: keyboard control 26 | * **[lesson05](lesson05.cc)**: texture generation 27 | * **[lesson06](lesson06.cc)**: alpha blending and color modulation 28 | * **[lesson07](lesson07.cc)**: text rendering 29 | 30 | Each lesson adds some lines to the code and, thus, functionality 31 | to the application. You can explore these lessons sequentially 32 | starting from the first one (in which you might find e.g. ```git 33 | diff lesson00.cc lesson01.cc``` helpful to see what was added by 34 | the next lesson), or just jump straight to the last one and see 35 | all bits at once. 36 | 37 | ## Building 38 | 39 | To build executables from these lessons, you need **cmake**, **SDL2**, 40 | **SDL2_image** and **SDL2_ttf** libraries and corresponding development 41 | files. 42 | 43 | To build the tutorial, run 44 | 45 | cmake . && make 46 | 47 | which will produce a set of binaries: lesson00 .. lesson07. 48 | 49 | ## Author 50 | 51 | * [Dmitry Marakasov](https://github.com/AMDmi3) 52 | 53 | ## License 54 | 55 | Lesson code is licensed under [CC0](COPYING). Bundled data files 56 | have separate licenses, see COPYRIGHT files under data/. 57 | -------------------------------------------------------------------------------- /data/M484SpaceSoldier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libSDL2pp/libSDL2pp-tutorial/371c5073b00e51e3761c688f79a56f32e3f7a83a/data/M484SpaceSoldier.png -------------------------------------------------------------------------------- /data/M484SpaceSoldier.png.COPYRIGHT: -------------------------------------------------------------------------------- 1 | Space Soldier by Master484 2 | 3 | Public domain 4 | 5 | http://opengameart.org/content/space-soldier-m484-games 6 | http://m484games.ucoz.com/ 7 | -------------------------------------------------------------------------------- /data/Vera.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libSDL2pp/libSDL2pp-tutorial/371c5073b00e51e3761c688f79a56f32e3f7a83a/data/Vera.ttf -------------------------------------------------------------------------------- /data/Vera.ttf.COPYRIGHT: -------------------------------------------------------------------------------- 1 | Bitstream Vera Fonts Copyright 2 | 3 | The fonts have a generous copyright, allowing derivative works (as 4 | long as "Bitstream" or "Vera" are not in the names), and full 5 | redistribution (so long as they are not *sold* by themselves). They 6 | can be be bundled, redistributed and sold with any software. 7 | 8 | The fonts are distributed under the following copyright: 9 | 10 | Copyright 11 | ========= 12 | 13 | Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream 14 | Vera is a trademark of Bitstream, Inc. 15 | 16 | Permission is hereby granted, free of charge, to any person obtaining 17 | a copy of the fonts accompanying this license ("Fonts") and associated 18 | documentation files (the "Font Software"), to reproduce and distribute 19 | the Font Software, including without limitation the rights to use, 20 | copy, merge, publish, distribute, and/or sell copies of the Font 21 | Software, and to permit persons to whom the Font Software is furnished 22 | to do so, subject to the following conditions: 23 | 24 | The above copyright and trademark notices and this permission notice 25 | shall be included in all copies of one or more of the Font Software 26 | typefaces. 27 | 28 | The Font Software may be modified, altered, or added to, and in 29 | particular the designs of glyphs or characters in the Fonts may be 30 | modified and additional glyphs or characters may be added to the 31 | Fonts, only if the fonts are renamed to names not containing either 32 | the words "Bitstream" or the word "Vera". 33 | 34 | This License becomes null and void to the extent applicable to Fonts 35 | or Font Software that has been modified and is distributed under the 36 | "Bitstream Vera" names. 37 | 38 | The Font Software may be sold as part of a larger software package but 39 | no copy of one or more of the Font Software typefaces may be sold by 40 | itself. 41 | 42 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 43 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 44 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 45 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL 46 | BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR 47 | OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, 48 | OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR 49 | OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT 50 | SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. 51 | 52 | Except as contained in this notice, the names of Gnome, the Gnome 53 | Foundation, and Bitstream Inc., shall not be used in advertising or 54 | otherwise to promote the sale, use or other dealings in this Font 55 | Software without prior written authorization from the Gnome Foundation 56 | or Bitstream Inc., respectively. For further information, contact: 57 | fonts at gnome dot org. 58 | 59 | Copyright FAQ 60 | ============= 61 | 62 | 1. I don't understand the resale restriction... What gives? 63 | 64 | Bitstream is giving away these fonts, but wishes to ensure its 65 | competitors can't just drop the fonts as is into a font sale system 66 | and sell them as is. It seems fair that if Bitstream can't make money 67 | from the Bitstream Vera fonts, their competitors should not be able to 68 | do so either. You can sell the fonts as part of any software package, 69 | however. 70 | 71 | 2. I want to package these fonts separately for distribution and 72 | sale as part of a larger software package or system. Can I do so? 73 | 74 | Yes. A RPM or Debian package is a "larger software package" to begin 75 | with, and you aren't selling them independently by themselves. 76 | See 1. above. 77 | 78 | 3. Are derivative works allowed? 79 | Yes! 80 | 81 | 4. Can I change or add to the font(s)? 82 | Yes, but you must change the name(s) of the font(s). 83 | 84 | 5. Under what terms are derivative works allowed? 85 | 86 | You must change the name(s) of the fonts. This is to ensure the 87 | quality of the fonts, both to protect Bitstream and Gnome. We want to 88 | ensure that if an application has opened a font specifically of these 89 | names, it gets what it expects (though of course, using fontconfig, 90 | substitutions could still could have occurred during font 91 | opening). You must include the Bitstream copyright. Additional 92 | copyrights can be added, as per copyright law. Happy Font Hacking! 93 | 94 | 6. If I have improvements for Bitstream Vera, is it possible they might get 95 | adopted in future versions? 96 | 97 | Yes. The contract between the Gnome Foundation and Bitstream has 98 | provisions for working with Bitstream to ensure quality additions to 99 | the Bitstream Vera font family. Please contact us if you have such 100 | additions. Note, that in general, we will want such additions for the 101 | entire family, not just a single font, and that you'll have to keep 102 | both Gnome and Jim Lyles, Vera's designer, happy! To make sense to add 103 | glyphs to the font, they must be stylistically in keeping with Vera's 104 | design. Vera cannot become a "ransom note" font. Jim Lyles will be 105 | providing a document describing the design elements used in Vera, as a 106 | guide and aid for people interested in contributing to Vera. 107 | 108 | 7. I want to sell a software package that uses these fonts: Can I do so? 109 | 110 | Sure. Bundle the fonts with your software and sell your software 111 | with the fonts. That is the intent of the copyright. 112 | 113 | 8. If applications have built the names "Bitstream Vera" into them, 114 | can I override this somehow to use fonts of my choosing? 115 | 116 | This depends on exact details of the software. Most open source 117 | systems and software (e.g., Gnome, KDE, etc.) are now converting to 118 | use fontconfig (see www.fontconfig.org) to handle font configuration, 119 | selection and substitution; it has provisions for overriding font 120 | names and subsituting alternatives. An example is provided by the 121 | supplied local.conf file, which chooses the family Bitstream Vera for 122 | "sans", "serif" and "monospace". Other software (e.g., the XFree86 123 | core server) has other mechanisms for font substitution. 124 | 125 | -------------------------------------------------------------------------------- /lesson00.cc: -------------------------------------------------------------------------------- 1 | // 2 | // SDL2pp tutorial 3 | // 4 | // Written in 2015 by Dmitry Marakasiv 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright 7 | // and related and neighboring rights to this software to the public domain 8 | // worldwide. This software is distributed without any warranty. 9 | // 10 | // You should have received a copy of the CC0 Public Domain Dedication along with 11 | // this software. If not, see . 12 | // 13 | 14 | // 15 | // Lesson 00: 16 | // 17 | // - Initialize SDL library 18 | // - Create window 19 | // - Load image from file 20 | // - Display it in a window 21 | // 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | using namespace SDL2pp; 29 | 30 | int main() try { 31 | // Initialize SDL library 32 | SDL sdl(SDL_INIT_VIDEO); 33 | 34 | // Create main window: 640x480 dimensions, resizable, "SDL2pp demo" title 35 | Window window("SDL2pp demo", 36 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 37 | 640, 480, 38 | SDL_WINDOW_RESIZABLE); 39 | 40 | // Create accelerated video renderer with default driver 41 | Renderer renderer(window, -1, SDL_RENDERER_ACCELERATED); 42 | 43 | // Load sprites image as a new texture 44 | Texture sprites(renderer, DATA_PATH "/M484SpaceSoldier.png"); 45 | 46 | // Clear screen 47 | renderer.Clear(); 48 | 49 | // Render our image, stretching it to the whole window 50 | renderer.Copy(sprites); 51 | 52 | // Show rendered frame 53 | renderer.Present(); 54 | 55 | // 5 second delay 56 | SDL_Delay(5000); 57 | 58 | // Here all resources are automatically released and library deinitialized 59 | return 0; 60 | } catch (std::exception& e) { 61 | // If case of error, print it and exit with error 62 | std::cerr << e.what() << std::endl; 63 | return 1; 64 | } 65 | -------------------------------------------------------------------------------- /lesson01.cc: -------------------------------------------------------------------------------- 1 | // 2 | // SDL2pp tutorial 3 | // 4 | // Written in 2015 by Dmitry Marakasiv 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright 7 | // and related and neighboring rights to this software to the public domain 8 | // worldwide. This software is distributed without any warranty. 9 | // 10 | // You should have received a copy of the CC0 Public Domain Dedication along with 11 | // this software. If not, see . 12 | // 13 | 14 | // 15 | // Lesson 01: 16 | // 17 | // - Pick single sprite to draw 18 | // 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | using namespace SDL2pp; 26 | 27 | int main() try { 28 | // Initialize SDL library 29 | SDL sdl(SDL_INIT_VIDEO); 30 | 31 | // Create main window: 640x480 dimensions, resizable, "SDL2pp demo" title 32 | Window window("SDL2pp demo", 33 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 34 | 640, 480, 35 | SDL_WINDOW_RESIZABLE); 36 | 37 | // Create accelerated video renderer with default driver 38 | Renderer renderer(window, -1, SDL_RENDERER_ACCELERATED); 39 | 40 | // Load sprites image as a new texture 41 | Texture sprites(renderer, DATA_PATH "/M484SpaceSoldier.png"); 42 | 43 | int vcenter = renderer.GetOutputHeight() / 2; // Y coordinate of window center 44 | 45 | // Clear screen 46 | renderer.Clear(); 47 | 48 | // Draw player sprite 49 | renderer.Copy( 50 | sprites, 51 | Rect(8, 11, 50, 50), 52 | Rect(0, vcenter - 50, 50, 50) 53 | ); 54 | 55 | // Show rendered frame 56 | renderer.Present(); 57 | 58 | // 5 second delay 59 | SDL_Delay(5000); 60 | 61 | // Here all resources are automatically released and library deinitialized 62 | return 0; 63 | } catch (std::exception& e) { 64 | // If case of error, print it and exit with error 65 | std::cerr << e.what() << std::endl; 66 | return 1; 67 | } 68 | -------------------------------------------------------------------------------- /lesson02.cc: -------------------------------------------------------------------------------- 1 | // 2 | // SDL2pp tutorial 3 | // 4 | // Written in 2015 by Dmitry Marakasiv 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright 7 | // and related and neighboring rights to this software to the public domain 8 | // worldwide. This software is distributed without any warranty. 9 | // 10 | // You should have received a copy of the CC0 Public Domain Dedication along with 11 | // this software. If not, see . 12 | // 13 | 14 | // 15 | // Lesson 02: 16 | // 17 | // - Main loop 18 | // - Event processing 19 | // 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | using namespace SDL2pp; 27 | 28 | int main() try { 29 | // Initialize SDL library 30 | SDL sdl(SDL_INIT_VIDEO); 31 | 32 | // Create main window: 640x480 dimensions, resizable, "SDL2pp demo" title 33 | Window window("SDL2pp demo", 34 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 35 | 640, 480, 36 | SDL_WINDOW_RESIZABLE); 37 | 38 | // Create accelerated video renderer with default driver 39 | Renderer renderer(window, -1, SDL_RENDERER_ACCELERATED); 40 | 41 | // Load sprites image as a new texture 42 | Texture sprites(renderer, DATA_PATH "/M484SpaceSoldier.png"); 43 | 44 | // Main loop 45 | while (1) { 46 | // Event processing: 47 | // - If window is closed, or Q or Escape buttons are pressed, 48 | // quit the application 49 | SDL_Event event; 50 | while (SDL_PollEvent(&event)) { 51 | if (event.type == SDL_QUIT) { 52 | return 0; 53 | } else if (event.type == SDL_KEYDOWN) { 54 | switch (event.key.keysym.sym) { 55 | case SDLK_ESCAPE: case SDLK_q: 56 | return 0; 57 | } 58 | } 59 | } 60 | 61 | int vcenter = renderer.GetOutputHeight() / 2; // Y coordinate of window center 62 | 63 | // Clear screen 64 | renderer.Clear(); 65 | 66 | // Draw player sprite 67 | renderer.Copy( 68 | sprites, 69 | Rect(8, 11, 50, 50), 70 | Rect(0, vcenter - 50, 50, 50) 71 | ); 72 | 73 | // Show rendered frame 74 | renderer.Present(); 75 | 76 | // Frame limiter: sleep for a little bit to not eat 100% of CPU 77 | SDL_Delay(1); 78 | } 79 | 80 | // Here all resources are automatically released and library deinitialized 81 | return 0; 82 | } catch (std::exception& e) { 83 | // If case of error, print it and exit with error 84 | std::cerr << e.what() << std::endl; 85 | return 1; 86 | } 87 | -------------------------------------------------------------------------------- /lesson03.cc: -------------------------------------------------------------------------------- 1 | // 2 | // SDL2pp tutorial 3 | // 4 | // Written in 2015 by Dmitry Marakasiv 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright 7 | // and related and neighboring rights to this software to the public domain 8 | // worldwide. This software is distributed without any warranty. 9 | // 10 | // You should have received a copy of the CC0 Public Domain Dedication along with 11 | // this software. If not, see . 12 | // 13 | 14 | // 15 | // Lesson 03: 16 | // 17 | // - Timing and animation 18 | // 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | using namespace SDL2pp; 26 | 27 | int main() try { 28 | // Initialize SDL library 29 | SDL sdl(SDL_INIT_VIDEO); 30 | 31 | // Create main window: 640x480 dimensions, resizable, "SDL2pp demo" title 32 | Window window("SDL2pp demo", 33 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 34 | 640, 480, 35 | SDL_WINDOW_RESIZABLE); 36 | 37 | // Create accelerated video renderer with default driver 38 | Renderer renderer(window, -1, SDL_RENDERER_ACCELERATED); 39 | 40 | // Load sprites image as a new texture 41 | Texture sprites(renderer, DATA_PATH "/M484SpaceSoldier.png"); 42 | 43 | // Game state 44 | int run_phase = -1; // run animation phase 45 | float position = 0.0; // player position 46 | 47 | unsigned int prev_ticks = SDL_GetTicks(); 48 | // Main loop 49 | while (1) { 50 | // Timing: calculate difference between this and previous frame 51 | // in milliseconds 52 | unsigned int frame_ticks = SDL_GetTicks(); 53 | unsigned int frame_delta = frame_ticks - prev_ticks; 54 | prev_ticks = frame_ticks; 55 | 56 | // Event processing: 57 | // - If window is closed, or Q or Escape buttons are pressed, 58 | // quit the application 59 | SDL_Event event; 60 | while (SDL_PollEvent(&event)) { 61 | if (event.type == SDL_QUIT) { 62 | return 0; 63 | } else if (event.type == SDL_KEYDOWN) { 64 | switch (event.key.keysym.sym) { 65 | case SDLK_ESCAPE: case SDLK_q: 66 | return 0; 67 | } 68 | } 69 | } 70 | 71 | // Update game state for this frame: 72 | // if character is runnung, move it to the right 73 | position += frame_delta * 0.2; 74 | run_phase = (frame_ticks / 100) % 8; 75 | 76 | // If player passes past the right side of the window, wrap him 77 | // to the left side 78 | if (position > renderer.GetOutputWidth()) 79 | position = -50; 80 | 81 | int vcenter = renderer.GetOutputHeight() / 2; // Y coordinate of window center 82 | 83 | // Clear screen 84 | renderer.Clear(); 85 | 86 | // Pick sprite from running animantion sequence 87 | int src_x = 8 + 51 * run_phase, src_y = 67; 88 | 89 | // Draw player sprite 90 | renderer.Copy( 91 | sprites, 92 | Rect(src_x, src_y, 50, 50), 93 | Rect((int)position, vcenter - 50, 50, 50) 94 | ); 95 | 96 | // Show rendered frame 97 | renderer.Present(); 98 | 99 | // Frame limiter: sleep for a little bit to not eat 100% of CPU 100 | SDL_Delay(1); 101 | } 102 | 103 | // Here all resources are automatically released and library deinitialized 104 | return 0; 105 | } catch (std::exception& e) { 106 | // If case of error, print it and exit with error 107 | std::cerr << e.what() << std::endl; 108 | return 1; 109 | } 110 | -------------------------------------------------------------------------------- /lesson04.cc: -------------------------------------------------------------------------------- 1 | // 2 | // SDL2pp tutorial 3 | // 4 | // Written in 2015 by Dmitry Marakasiv 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright 7 | // and related and neighboring rights to this software to the public domain 8 | // worldwide. This software is distributed without any warranty. 9 | // 10 | // You should have received a copy of the CC0 Public Domain Dedication along with 11 | // this software. If not, see . 12 | // 13 | 14 | // 15 | // Lesson 04: 16 | // 17 | // - Keyboard control 18 | // 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | using namespace SDL2pp; 26 | 27 | int main() try { 28 | // Initialize SDL library 29 | SDL sdl(SDL_INIT_VIDEO); 30 | 31 | // Create main window: 640x480 dimensions, resizable, "SDL2pp demo" title 32 | Window window("SDL2pp demo", 33 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 34 | 640, 480, 35 | SDL_WINDOW_RESIZABLE); 36 | 37 | // Create accelerated video renderer with default driver 38 | Renderer renderer(window, -1, SDL_RENDERER_ACCELERATED); 39 | 40 | // Load sprites image as a new texture 41 | Texture sprites(renderer, DATA_PATH "/M484SpaceSoldier.png"); 42 | 43 | // Game state 44 | bool is_running = false; // whether the character is currently running 45 | int run_phase = -1; // run animation phase 46 | float position = 0.0; // player position 47 | 48 | unsigned int prev_ticks = SDL_GetTicks(); 49 | // Main loop 50 | while (1) { 51 | // Timing: calculate difference between this and previous frame 52 | // in milliseconds 53 | unsigned int frame_ticks = SDL_GetTicks(); 54 | unsigned int frame_delta = frame_ticks - prev_ticks; 55 | prev_ticks = frame_ticks; 56 | 57 | // Event processing: 58 | // - If window is closed, or Q or Escape buttons are pressed, 59 | // quit the application 60 | // - If Right key is pressed, character would run 61 | // - If Right key is released, character would stop 62 | SDL_Event event; 63 | while (SDL_PollEvent(&event)) { 64 | if (event.type == SDL_QUIT) { 65 | return 0; 66 | } else if (event.type == SDL_KEYDOWN) { 67 | switch (event.key.keysym.sym) { 68 | case SDLK_ESCAPE: case SDLK_q: 69 | return 0; 70 | case SDLK_RIGHT: is_running = true; break; 71 | } 72 | } else if (event.type == SDL_KEYUP) { 73 | switch (event.key.keysym.sym) { 74 | case SDLK_RIGHT: is_running = false; break; 75 | } 76 | } 77 | } 78 | 79 | // Update game state for this frame: 80 | // if character is runnung, move it to the right 81 | if (is_running) { 82 | position += frame_delta * 0.2; 83 | run_phase = (frame_ticks / 100) % 8; 84 | } else { 85 | run_phase = 0; 86 | } 87 | 88 | // If player passes past the right side of the window, wrap him 89 | // to the left side 90 | if (position > renderer.GetOutputWidth()) 91 | position = -50; 92 | 93 | int vcenter = renderer.GetOutputHeight() / 2; // Y coordinate of window center 94 | 95 | // Clear screen 96 | renderer.Clear(); 97 | 98 | // Pick sprite from sprite atlas based on whether 99 | // player is running and run animation phase 100 | int src_x = 8, src_y = 11; // by default, standing sprite 101 | if (is_running) { 102 | // one of 8 run animation sprites 103 | src_x = 8 + 51 * run_phase; 104 | src_y = 67; 105 | } 106 | 107 | // Draw player sprite 108 | renderer.Copy( 109 | sprites, 110 | Rect(src_x, src_y, 50, 50), 111 | Rect((int)position, vcenter - 50, 50, 50) 112 | ); 113 | 114 | // Show rendered frame 115 | renderer.Present(); 116 | 117 | // Frame limiter: sleep for a little bit to not eat 100% of CPU 118 | SDL_Delay(1); 119 | } 120 | 121 | // Here all resources are automatically released and library deinitialized 122 | return 0; 123 | } catch (std::exception& e) { 124 | // If case of error, print it and exit with error 125 | std::cerr << e.what() << std::endl; 126 | return 1; 127 | } 128 | -------------------------------------------------------------------------------- /lesson05.cc: -------------------------------------------------------------------------------- 1 | // 2 | // SDL2pp tutorial 3 | // 4 | // Written in 2015 by Dmitry Marakasiv 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright 7 | // and related and neighboring rights to this software to the public domain 8 | // worldwide. This software is distributed without any warranty. 9 | // 10 | // You should have received a copy of the CC0 Public Domain Dedication along with 11 | // this software. If not, see . 12 | // 13 | 14 | // 15 | // Lesson 05: 16 | // 17 | // - Texture generation 18 | // 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | using namespace SDL2pp; 27 | 28 | int main() try { 29 | // Initialize SDL library 30 | SDL sdl(SDL_INIT_VIDEO); 31 | 32 | // Create main window: 640x480 dimensions, resizable, "SDL2pp demo" title 33 | Window window("SDL2pp demo", 34 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 35 | 640, 480, 36 | SDL_WINDOW_RESIZABLE); 37 | 38 | // Create accelerated video renderer with default driver 39 | Renderer renderer(window, -1, SDL_RENDERER_ACCELERATED); 40 | 41 | // Load sprites image as a new texture 42 | Texture sprites(renderer, DATA_PATH "/M484SpaceSoldier.png"); 43 | 44 | // Gradient texture to be generated 45 | Texture gradient(renderer, SDL_PIXELFORMAT_BGR888, SDL_TEXTUREACCESS_STATIC, 1, 256); 46 | { 47 | // Array holding RGB values for 256 pixels 48 | unsigned char grad[256 * 3]; 49 | int n = 0; // counter 50 | 51 | // Fill array with fading gray values from white to black; its contents will be 52 | // 255,255,255, 254,254,254, 253,253,253 ... 1,1,1, 0,0,0 53 | std::generate(grad, grad + sizeof(grad), [&](){ return 255 - n++ / 3; }); 54 | 55 | // Update texture with our raw color data 56 | gradient.Update(NullOpt, grad, 3); 57 | } 58 | 59 | // Game state 60 | bool is_running = false; // whether the character is currently running 61 | int run_phase = -1; // run animation phase 62 | float position = 0.0; // player position 63 | 64 | unsigned int prev_ticks = SDL_GetTicks(); 65 | // Main loop 66 | while (1) { 67 | // Timing: calculate difference between this and previous frame 68 | // in milliseconds 69 | unsigned int frame_ticks = SDL_GetTicks(); 70 | unsigned int frame_delta = frame_ticks - prev_ticks; 71 | prev_ticks = frame_ticks; 72 | 73 | // Event processing: 74 | // - If window is closed, or Q or Escape buttons are pressed, 75 | // quit the application 76 | // - If Right key is pressed, character would run 77 | // - If Right key is released, character would stop 78 | SDL_Event event; 79 | while (SDL_PollEvent(&event)) { 80 | if (event.type == SDL_QUIT) { 81 | return 0; 82 | } else if (event.type == SDL_KEYDOWN) { 83 | switch (event.key.keysym.sym) { 84 | case SDLK_ESCAPE: case SDLK_q: 85 | return 0; 86 | case SDLK_RIGHT: is_running = true; break; 87 | } 88 | } else if (event.type == SDL_KEYUP) { 89 | switch (event.key.keysym.sym) { 90 | case SDLK_RIGHT: is_running = false; break; 91 | } 92 | } 93 | } 94 | 95 | // Update game state for this frame: 96 | // if character is runnung, move it to the right 97 | if (is_running) { 98 | position += frame_delta * 0.2; 99 | run_phase = (frame_ticks / 100) % 8; 100 | } else { 101 | run_phase = 0; 102 | } 103 | 104 | // If player passes past the right side of the window, wrap him 105 | // to the left side 106 | if (position > renderer.GetOutputWidth()) 107 | position = -50; 108 | 109 | int vcenter = renderer.GetOutputHeight() / 2; // Y coordinate of window center 110 | 111 | // Clear screen 112 | renderer.Clear(); 113 | 114 | // Copy our gradient texture, stretching it to the whole window 115 | renderer.Copy( 116 | gradient, 117 | NullOpt, 118 | Rect(0, vcenter, renderer.GetOutputWidth(), renderer.GetOutputHeight() / 2) 119 | ); 120 | 121 | // Pick sprite from sprite atlas based on whether 122 | // player is running and run animation phase 123 | int src_x = 8, src_y = 11; // by default, standing sprite 124 | if (is_running) { 125 | // one of 8 run animation sprites 126 | src_x = 8 + 51 * run_phase; 127 | src_y = 67; 128 | } 129 | 130 | // Draw player sprite 131 | renderer.Copy( 132 | sprites, 133 | Rect(src_x, src_y, 50, 50), 134 | Rect((int)position, vcenter - 50, 50, 50) 135 | ); 136 | 137 | // Draw the same sprite, below the first one, vertically flipped. 138 | // It'll look like reflection in the mirror 139 | renderer.Copy( 140 | sprites, 141 | Rect(src_x, src_y, 50, 50), 142 | Rect((int)position, vcenter, 50, 50), 143 | 0.0, // don't rotate 144 | NullOpt, // rotation center - not needed 145 | SDL_FLIP_VERTICAL // vertical flip 146 | ); 147 | 148 | // Show rendered frame 149 | renderer.Present(); 150 | 151 | // Frame limiter: sleep for a little bit to not eat 100% of CPU 152 | SDL_Delay(1); 153 | } 154 | 155 | // Here all resources are automatically released and library deinitialized 156 | return 0; 157 | } catch (std::exception& e) { 158 | // If case of error, print it and exit with error 159 | std::cerr << e.what() << std::endl; 160 | return 1; 161 | } 162 | -------------------------------------------------------------------------------- /lesson06.cc: -------------------------------------------------------------------------------- 1 | // 2 | // SDL2pp tutorial 3 | // 4 | // Written in 2015 by Dmitry Marakasiv 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright 7 | // and related and neighboring rights to this software to the public domain 8 | // worldwide. This software is distributed without any warranty. 9 | // 10 | // You should have received a copy of the CC0 Public Domain Dedication along with 11 | // this software. If not, see . 12 | // 13 | 14 | // 15 | // Lesson 06: 16 | // 17 | // - Alpha blending and color modulation 18 | // 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | using namespace SDL2pp; 27 | 28 | int main() try { 29 | // Initialize SDL library 30 | SDL sdl(SDL_INIT_VIDEO); 31 | 32 | // Create main window: 640x480 dimensions, resizable, "SDL2pp demo" title 33 | Window window("SDL2pp demo", 34 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 35 | 640, 480, 36 | SDL_WINDOW_RESIZABLE); 37 | 38 | // Create accelerated video renderer with default driver 39 | Renderer renderer(window, -1, SDL_RENDERER_ACCELERATED); 40 | 41 | // Load sprites image as a new texture; since there's no alpha channel 42 | // but we need transparency, use helper surface for which set color key 43 | // to color index 0 -> black background on image will be transparent on our 44 | // texture 45 | Texture sprites(renderer, Surface(DATA_PATH "/M484SpaceSoldier.png") 46 | .SetColorKey(true, 0)); 47 | 48 | // Enable alpha blending for the sprites 49 | sprites.SetBlendMode(SDL_BLENDMODE_BLEND); 50 | 51 | // Gradient texture to be generated 52 | Texture gradient(renderer, SDL_PIXELFORMAT_BGR888, SDL_TEXTUREACCESS_STATIC, 1, 256); 53 | { 54 | // Array holding RGB values for 256 pixels 55 | unsigned char grad[256 * 3]; 56 | int n = 0; // counter 57 | 58 | // Fill array with fading gray values from white to black; its contents will be 59 | // 255,255,255, 254,254,254, 253,253,253 ... 1,1,1, 0,0,0 60 | std::generate(grad, grad + sizeof(grad), [&](){ return 255 - n++ / 3; }); 61 | 62 | // Update texture with our raw color data, enable blending and set color 63 | // and alpha modulation, so when rendered our texture will be dark cyan 64 | gradient.Update(NullOpt, grad, 3) 65 | .SetBlendMode(SDL_BLENDMODE_BLEND) 66 | .SetColorMod(0, 255, 255) 67 | .SetAlphaMod(85); 68 | } 69 | 70 | // Game state 71 | bool is_running = false; // whether the character is currently running 72 | int run_phase = -1; // run animation phase 73 | float position = 0.0; // player position 74 | 75 | unsigned int prev_ticks = SDL_GetTicks(); 76 | // Main loop 77 | while (1) { 78 | // Timing: calculate difference between this and previous frame 79 | // in milliseconds 80 | unsigned int frame_ticks = SDL_GetTicks(); 81 | unsigned int frame_delta = frame_ticks - prev_ticks; 82 | prev_ticks = frame_ticks; 83 | 84 | // Event processing: 85 | // - If window is closed, or Q or Escape buttons are pressed, 86 | // quit the application 87 | // - If Right key is pressed, character would run 88 | // - If Right key is released, character would stop 89 | SDL_Event event; 90 | while (SDL_PollEvent(&event)) { 91 | if (event.type == SDL_QUIT) { 92 | return 0; 93 | } else if (event.type == SDL_KEYDOWN) { 94 | switch (event.key.keysym.sym) { 95 | case SDLK_ESCAPE: case SDLK_q: 96 | return 0; 97 | case SDLK_RIGHT: is_running = true; break; 98 | } 99 | } else if (event.type == SDL_KEYUP) { 100 | switch (event.key.keysym.sym) { 101 | case SDLK_RIGHT: is_running = false; break; 102 | } 103 | } 104 | } 105 | 106 | // Update game state for this frame: 107 | // if character is runnung, move it to the right 108 | if (is_running) { 109 | position += frame_delta * 0.2; 110 | run_phase = (frame_ticks / 100) % 8; 111 | } else { 112 | run_phase = 0; 113 | } 114 | 115 | // If player passes past the right side of the window, wrap him 116 | // to the left side 117 | if (position > renderer.GetOutputWidth()) 118 | position = -50; 119 | 120 | int vcenter = renderer.GetOutputHeight() / 2; // Y coordinate of window center 121 | 122 | // Clear screen 123 | renderer.Clear(); 124 | 125 | // Copy our gradient texture, stretching it to the whole window 126 | renderer.Copy( 127 | gradient, 128 | NullOpt, 129 | Rect(0, vcenter, renderer.GetOutputWidth(), renderer.GetOutputHeight() / 2) 130 | ); 131 | 132 | // Pick sprite from sprite atlas based on whether 133 | // player is running and run animation phase 134 | int src_x = 8, src_y = 11; // by default, standing sprite 135 | if (is_running) { 136 | // one of 8 run animation sprites 137 | src_x = 8 + 51 * run_phase; 138 | src_y = 67; 139 | } 140 | 141 | // Draw player sprite 142 | sprites.SetAlphaMod(255); // sprite is fully opaque 143 | renderer.Copy( 144 | sprites, 145 | Rect(src_x, src_y, 50, 50), 146 | Rect((int)position, vcenter - 50, 50, 50) 147 | ); 148 | 149 | // Draw the same sprite, below the first one, 50% transparent and 150 | // vertically flipped. It'll look like reflection in the mirror 151 | sprites.SetAlphaMod(127); // 50% transparent 152 | renderer.Copy( 153 | sprites, 154 | Rect(src_x, src_y, 50, 50), 155 | Rect((int)position, vcenter, 50, 50), 156 | 0.0, // don't rotate 157 | NullOpt, // rotation center - not needed 158 | SDL_FLIP_VERTICAL // vertical flip 159 | ); 160 | 161 | // Show rendered frame 162 | renderer.Present(); 163 | 164 | // Frame limiter: sleep for a little bit to not eat 100% of CPU 165 | SDL_Delay(1); 166 | } 167 | 168 | // Here all resources are automatically released and library deinitialized 169 | return 0; 170 | } catch (std::exception& e) { 171 | // If case of error, print it and exit with error 172 | std::cerr << e.what() << std::endl; 173 | return 1; 174 | } 175 | -------------------------------------------------------------------------------- /lesson07.cc: -------------------------------------------------------------------------------- 1 | // 2 | // SDL2pp tutorial 3 | // 4 | // Written in 2015 by Dmitry Marakasiv 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright 7 | // and related and neighboring rights to this software to the public domain 8 | // worldwide. This software is distributed without any warranty. 9 | // 10 | // You should have received a copy of the CC0 Public Domain Dedication along with 11 | // this software. If not, see . 12 | // 13 | 14 | // 15 | // Lesson 07: 16 | // 17 | // - Text rendering 18 | // 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | using namespace SDL2pp; 28 | 29 | int main() try { 30 | // Initialize SDL library 31 | SDL sdl(SDL_INIT_VIDEO); 32 | 33 | // Initialize SDL_ttf library 34 | SDLTTF ttf; 35 | 36 | // Create main window: 640x480 dimensions, resizable, "SDL2pp demo" title 37 | Window window("SDL2pp demo", 38 | SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 39 | 640, 480, 40 | SDL_WINDOW_RESIZABLE); 41 | 42 | // Create accelerated video renderer with default driver 43 | Renderer renderer(window, -1, SDL_RENDERER_ACCELERATED); 44 | 45 | // Load sprites image as a new texture; since there's no alpha channel 46 | // but we need transparency, use helper surface for which set color key 47 | // to color index 0 -> black background on image will be transparent on our 48 | // texture 49 | Texture sprites(renderer, Surface(DATA_PATH "/M484SpaceSoldier.png") 50 | .SetColorKey(true, 0)); 51 | 52 | // Enable alpha blending for the sprites 53 | sprites.SetBlendMode(SDL_BLENDMODE_BLEND); 54 | 55 | // Gradient texture to be generated 56 | Texture gradient(renderer, SDL_PIXELFORMAT_BGR888, SDL_TEXTUREACCESS_STATIC, 1, 256); 57 | { 58 | // Array holding RGB values for 256 pixels 59 | unsigned char grad[256 * 3]; 60 | int n = 0; // counter 61 | 62 | // Fill array with fading gray values from white to black; its contents will be 63 | // 255,255,255, 254,254,254, 253,253,253 ... 1,1,1, 0,0,0 64 | std::generate(grad, grad + sizeof(grad), [&](){ return 255 - n++ / 3; }); 65 | 66 | // Update texture with our raw color data, enable blending and set color 67 | // and alpha modulation, so when rendered our texture will be dark cyan 68 | gradient.Update(NullOpt, grad, 3) 69 | .SetBlendMode(SDL_BLENDMODE_BLEND) 70 | .SetColorMod(0, 255, 255) 71 | .SetAlphaMod(85); 72 | } 73 | 74 | // Load font, 12pt size 75 | Font font(DATA_PATH "/Vera.ttf", 12); 76 | 77 | // Game state 78 | bool is_running = false; // whether the character is currently running 79 | int run_phase = -1; // run animation phase 80 | float position = 0.0; // player position 81 | 82 | unsigned int prev_ticks = SDL_GetTicks(); 83 | // Main loop 84 | while (1) { 85 | // Timing: calculate difference between this and previous frame 86 | // in milliseconds 87 | unsigned int frame_ticks = SDL_GetTicks(); 88 | unsigned int frame_delta = frame_ticks - prev_ticks; 89 | prev_ticks = frame_ticks; 90 | 91 | // Event processing: 92 | // - If window is closed, or Q or Escape buttons are pressed, 93 | // quit the application 94 | // - If Right key is pressed, character would run 95 | // - If Right key is released, character would stop 96 | SDL_Event event; 97 | while (SDL_PollEvent(&event)) { 98 | if (event.type == SDL_QUIT) { 99 | return 0; 100 | } else if (event.type == SDL_KEYDOWN) { 101 | switch (event.key.keysym.sym) { 102 | case SDLK_ESCAPE: case SDLK_q: 103 | return 0; 104 | case SDLK_RIGHT: is_running = true; break; 105 | } 106 | } else if (event.type == SDL_KEYUP) { 107 | switch (event.key.keysym.sym) { 108 | case SDLK_RIGHT: is_running = false; break; 109 | } 110 | } 111 | } 112 | 113 | // Update game state for this frame: 114 | // if character is runnung, move it to the right 115 | if (is_running) { 116 | position += frame_delta * 0.2; 117 | run_phase = (frame_ticks / 100) % 8; 118 | } else { 119 | run_phase = 0; 120 | } 121 | 122 | // If player passes past the right side of the window, wrap him 123 | // to the left side 124 | if (position > renderer.GetOutputWidth()) 125 | position = -50; 126 | 127 | int vcenter = renderer.GetOutputHeight() / 2; // Y coordinate of window center 128 | 129 | // Clear screen 130 | renderer.Clear(); 131 | 132 | // Copy our gradient texture, stretching it to the whole window 133 | renderer.Copy( 134 | gradient, 135 | NullOpt, 136 | Rect(0, vcenter, renderer.GetOutputWidth(), renderer.GetOutputHeight() / 2) 137 | ); 138 | 139 | // Pick sprite from sprite atlas based on whether 140 | // player is running and run animation phase 141 | int src_x = 8, src_y = 11; // by default, standing sprite 142 | if (is_running) { 143 | // one of 8 run animation sprites 144 | src_x = 8 + 51 * run_phase; 145 | src_y = 67; 146 | } 147 | 148 | // Draw player sprite 149 | sprites.SetAlphaMod(255); // sprite is fully opaque 150 | renderer.Copy( 151 | sprites, 152 | Rect(src_x, src_y, 50, 50), 153 | Rect((int)position, vcenter - 50, 50, 50) 154 | ); 155 | 156 | // Draw the same sprite, below the first one, 50% transparent and 157 | // vertically flipped. It'll look like reflection in the mirror 158 | sprites.SetAlphaMod(127); // 50% transparent 159 | renderer.Copy( 160 | sprites, 161 | Rect(src_x, src_y, 50, 50), 162 | Rect((int)position, vcenter, 50, 50), 163 | 0.0, // don't rotate 164 | NullOpt, // rotation center - not needed 165 | SDL_FLIP_VERTICAL // vertical flip 166 | ); 167 | 168 | // Create text string to render 169 | std::string text = 170 | "Position: " 171 | + std::to_string((int)position) 172 | + ", running: " 173 | + (is_running ? "true" : "false"); 174 | 175 | // Render the text into new texture. Note that SDL_ttf render 176 | // text into Surface, which is converted into texture on the fly 177 | Texture text_sprite( 178 | renderer, 179 | font.RenderText_Blended(text, SDL_Color{255, 255, 255, 255}) 180 | ); 181 | 182 | // Copy texture into top-left corner of the window 183 | renderer.Copy(text_sprite, NullOpt, Rect(0, 0, text_sprite.GetWidth(), text_sprite.GetHeight())); 184 | 185 | // Show rendered frame 186 | renderer.Present(); 187 | 188 | // Frame limiter: sleep for a little bit to not eat 100% of CPU 189 | SDL_Delay(1); 190 | } 191 | 192 | // Here all resources are automatically released and libraries deinitialized 193 | return 0; 194 | } catch (std::exception& e) { 195 | // If case of error, print it and exit with error 196 | std::cerr << e.what() << std::endl; 197 | return 1; 198 | } 199 | -------------------------------------------------------------------------------- /screenshots/lesson07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libSDL2pp/libSDL2pp-tutorial/371c5073b00e51e3761c688f79a56f32e3f7a83a/screenshots/lesson07.png --------------------------------------------------------------------------------