Compare commits

219 Commits

Author SHA1 Message Date
zv0n 9617499ab8 SDLPP: add constant rotation 2023-04-08 20:19:22 +02:00
zv0n 5a0cb397b1 Gitignore: ignore vscode dir 2023-04-08 19:53:16 +02:00
zv0n 2e8132b458 Mario: turtle blocks initial version 2023-04-08 19:51:27 +02:00
zv0n d41c77ab96 Mario: enable death from bounce for Goomba 2023-04-08 19:43:36 +02:00
zv0n b175e58714 Mario: fix scrolling in load scene 2023-04-08 19:16:46 +02:00
zv0n f0182cf4d4 Mario: add turtle enemy 2023-03-10 16:45:26 +01:00
zv0n fd96a1c2cc SDLPP: don't colide with self 2023-03-10 16:45:10 +01:00
zv0n c453c2fe9a Formatting 2022-11-19 23:10:33 +01:00
zv0n 411f00e468 Fix linux build 2022-11-19 23:02:13 +01:00
zv0n 9402f2afa2 Teleportation in editor 2022-11-19 22:53:24 +01:00
zv0n 6ac2726a94 Editor: slightly less hardcoded teleport map 2022-11-13 20:56:20 +01:00
zv0n c5283000c7 Mario: teleport to hardcoded level 2022-11-13 19:52:39 +01:00
zv0n 41ba43ed93 Mario: fix Mario getting stuck in the floor when eating a mushroom 2022-11-12 21:42:25 +01:00
zv0n 92a30b8c51 SDLPP: don't hide objects on destroy, wait for next render to be killed 2022-11-12 21:32:47 +01:00
zv0n 7bd652f4e9 Mario: Fireball works 2022-11-12 21:32:18 +01:00
zv0n 3cde73d1ed Add fire mario mode 2022-11-11 19:47:35 +01:00
zv0n d89712ebab Mario: change size and texture when Mario eats a mushroom 2022-10-25 19:33:09 +02:00
zv0n 1462c2211b CI: only send notification on failure or change of status 2022-09-28 14:48:22 +02:00
zv0n 938958b709 Test different 'from' format for notification 2022-09-28 14:46:44 +02:00
zv0n e5641f3bfd Notify with arm version of the container 2022-09-28 14:32:19 +02:00
zv0n e6df794618 Try notification 2022-09-28 14:18:37 +02:00
zv0n f137f6609f Formatting 2022-09-28 13:57:13 +02:00
zv0n 59e09f77fd Fix CI/CD build 2022-09-28 13:56:29 +02:00
zv0n 4109cfe1af Mario: add basic big mario logic 2022-09-25 19:44:28 +02:00
zv0n 09cb13195c Mario: stop movement when entering main menu, check there was a movement before reversing it 2022-09-24 22:54:03 +02:00
zv0n 9e4cc97f79 SDLPP: Add scene pause function 2022-09-24 22:51:32 +02:00
zv0n aa5043a811 Mario: disable bouncing on some blocks 2022-09-24 20:45:21 +02:00
zv0n f9a32bdb72 Mario: add arrow key controls 2022-09-24 20:44:52 +02:00
zv0n 45ab92c31f Editor: warn if map isn't saved when quitting 2022-09-24 20:33:15 +02:00
zv0n 31f00ed5d0 gitignore: ignore code workspace 2022-09-24 20:01:56 +02:00
zv0n 3437aa6b47 Mario: end of level logic 2022-09-23 16:46:50 +02:00
zv0n 6211e8c756 Formatting 2022-09-22 20:40:09 +02:00
zv0n a1afaf427a Mario: Add restart and background color for menus 2022-09-22 20:16:46 +02:00
zv0n 8b9ef16929 Editor: Save map on CTRL+S or CMD+S 2022-09-21 22:26:45 +02:00
zv0n 5201d10e20 Game main menu/retry scenes 2022-09-19 22:56:50 +02:00
zv0n 65edc9e8a0 Mario: fix apple build 2022-08-22 22:38:45 +02:00
zv0n 4477c39524 Mario Editor: add option to select a level to load 2022-07-24 20:22:45 +02:00
zv0n 6cee97059c SDLPP TextRenderer: add function 2022-07-24 20:22:07 +02:00
zv0n 70f30b6767 Mario Editor: save to filename entered in editor 2022-07-22 22:18:01 +02:00
zv0n c505915fd2 Mario Editor: add level input field 2022-07-22 18:48:06 +02:00
zv0n fffa56706d Mario Editor: add keyboard control to menu 2022-07-22 13:26:23 +02:00
zv0n ab6dcccbac Mario: OK dialog 2022-07-22 12:55:09 +02:00
zv0n 98c5b5b0dc Remove old TODO 2022-07-22 12:33:49 +02:00
zv0n fa60a0f163 Mario: added Yes/No dialog 2022-07-22 12:23:16 +02:00
zv0n 2a2467ccc2 Mario: remove deleted file from CMake 2022-07-21 20:19:53 +02:00
zv0n 58fd1a37a8 Mario: formatting 2022-07-21 20:17:24 +02:00
zv0n 6558329547 Mario: deleted useless files 2022-07-21 20:17:12 +02:00
zv0n 3a80fab3dd Editor: testing out text input 2022-07-21 20:08:16 +02:00
zv0n 4414ee6ff7 SDLPP: don't cause an exception when TextRenderer has an empty string 2022-07-21 20:07:56 +02:00
zv0n 4143af9962 Mario Editor: add save/load functionality 2022-07-21 19:26:50 +02:00
zv0n 92ffac0edf Mario: add basic main menu to editor, separate scenes from main game loop 2022-06-26 15:13:06 +02:00
zv0n c59851b490 Ensure arrows are enabled/disabled even when moving tools with wsad 2022-06-24 21:51:47 +02:00
zv0n 38dfa533c4 Button update function 2022-06-24 21:50:30 +02:00
zv0n 194415500d Move map/tool controls to new button API 2022-06-23 10:31:58 +02:00
zv0n 94d24e37fa Playing around with buttons 2022-06-22 21:42:57 +02:00
zv0n 2402567330 Added generic button 2022-06-21 14:53:10 +02:00
zv0n a3a1e900b5 Filesystem library 2022-06-21 14:50:39 +02:00
zv0n b98d283d09 Make Goomba hitbox larger 2022-06-21 08:52:21 +02:00
zv0n c8e749a145 Fix goomba movements 2022-06-21 08:50:43 +02:00
zv0n e87495db2e Map versioning 2022-06-21 08:23:36 +02:00
zv0n edb8444d7d Update drone settings 2022-05-23 22:57:04 +02:00
zv0n 2dff727934 Change drone config to use kubernetes 2022-01-07 00:47:48 +01:00
zv0n 0d855ed218 Mario: formatting 2021-10-18 10:10:43 +02:00
zv0n 303490a619 CI: fix formatting check 2021-10-18 10:10:28 +02:00
zv0n f4a067fe23 CI: bump up cppbuilder image 2021-10-18 09:54:07 +02:00
zv0n 8ca70fa11e Mario: formatting 2021-10-18 09:08:35 +02:00
zv0n f3062464d2 CI: better checking of formatting 2021-10-18 09:08:21 +02:00
zv0n d60dc07e10 Update clang-format 2021-10-18 09:07:57 +02:00
zv0n f6cf68f71f Make mario a bit faster 2021-10-17 15:56:10 +02:00
zv0n 7e06da5fc0 CI/CD changes 2021-10-17 13:36:20 +02:00
zv0n ca39b7edc9 New CI/CD image 2021-10-17 13:30:10 +02:00
zv0n 3bf086f48a CI/CD 2021-10-17 13:18:28 +02:00
zv0n 28d7e208fc Mario: add goomba into moving_objects 2021-08-08 21:45:50 +02:00
zv0n edeeadb232 Mario: add Goomba 2021-08-08 21:45:05 +02:00
zv0n e31c4bb2db Mario: change mushroom coliders IDs to NPC specific ones 2021-08-08 21:41:02 +02:00
zv0n 94bf4fc39d Mario: mario detects enemies and bounces when he kills them/dies when they kill him 2021-08-08 21:40:00 +02:00
zv0n 45ac4dad64 Mario: support the new modifier object IDs in maploader 2021-08-08 21:36:47 +02:00
zv0n a01b6070f3 Mario: change modifier IDs to start with 0x6000 2021-08-08 21:34:51 +02:00
zv0n c183e58f6e Blocks.cpp: add character support to 2021-08-08 21:22:44 +02:00
zv0n c7309d56a3 Editor: add character support 2021-08-08 21:22:00 +02:00
zv0n f3c4380bfb Mario: add enemies textures 2021-08-08 21:19:26 +02:00
zv0n 4f65dba2e0 Mario: only visit objects if they entered screen at least once 2021-08-07 22:25:32 +02:00
zv0n f7002f0f38 Mario: better mushroom movement 2021-08-07 22:17:27 +02:00
zv0n a194bfb86e Mario: destroy moving objects once they leave left side of screen, remove destroyed objects from moving_objects 2021-08-07 22:10:09 +02:00
zv0n e283b36229 Mario: set scene's background objects 2021-08-07 21:59:06 +02:00
zv0n 0608202483 SDLPP: add option to specify background objects in scene and move Z index of objects just above those background objects 2021-08-07 21:58:53 +02:00
zv0n f35aa095f3 Mario: remove useless debug outputs 2021-08-07 21:43:27 +02:00
zv0n f04dc1e23b Mario: mushroom interaction with Mario 2021-08-07 21:42:51 +02:00
zv0n 7b2adac922 Mario: add mushroom block 2021-08-07 21:41:15 +02:00
zv0n a7aa86c8e3 Mario: simple blocks formatting 2021-08-07 21:39:54 +02:00
zv0n 4742f3dd02 Mario: add travelToPos function to blocks 2021-08-07 21:39:15 +02:00
zv0n 7cb3f95e44 Mario: loop through all moving objects in doInput 2021-08-07 21:38:00 +02:00
zv0n 6238022ed2 Mario: fix modifier deletion 2021-08-07 12:13:23 +02:00
zv0n 7b1ef25f37 SDLPP: slight code cleanup 2021-08-07 12:13:03 +02:00
zv0n d4393ef179 Mario: better handling of screen resize, when showing FPS consider input handling as well 2021-08-06 18:50:31 +02:00
zv0n 4728056b76 SDLPP: add != for vector, add << for vector 2021-08-06 18:50:31 +02:00
zv0n b87318f44d SDLPP: add function that returns absolute position 2021-08-06 18:50:31 +02:00
zv0n 7d9763443a Mario: update cmake to include brew libraries 2021-08-05 21:21:25 +02:00
zv0n d267402ec5 Make cmake work on windows 2021-08-05 19:16:12 +02:00
zv0n 8e566ddb03 Mario: add sdlpp as a subdirectory instead of ExternalProject 2021-08-05 18:00:47 +02:00
zv0n 509e5e36c2 Sdlpp: move to cmake 2021-08-05 17:55:55 +02:00
zv0n fe157494ec Ignore build dir everywhere 2021-08-05 17:55:16 +02:00
zv0n 040b3b63c2 Move to CMake 2021-08-05 00:33:55 +02:00
zv0n bfe658618e Mario: prepartations for multiple moving objects 2021-08-05 00:32:54 +02:00
zv0n 37f7bab63e sdlpp_renderobject: getMovement is const 2021-08-04 23:29:18 +02:00
zv0n e67cf508a2 Add coin animation 2021-07-24 20:50:24 +02:00
zv0n 130a01feda Forgot to add coineditorblock 2021-07-24 20:48:37 +02:00
zv0n d638108223 Remove redundant functions from blocks.cpp, fix editor problem with pagination 2021-07-24 19:59:25 +02:00
zv0n 3be728843a Refactor to use objects for terrain/mod creation, added coin modifier 2021-07-23 00:08:05 +02:00
zv0n 79d9f266b4 SDLPP: add function to change texture while keeping SRC rect 2021-07-23 00:05:40 +02:00
zv0n 0e71dfa7d5 SDLPP: make text change only happen in render() 2021-07-23 00:05:13 +02:00
zv0n 76f5c43197 Mod texture image 2021-06-24 20:54:18 +02:00
zv0n 2617156833 Mod texture 2021-06-24 20:53:58 +02:00
zv0n b423ac7b8c Mario: add option to make a block collision-less 2021-06-21 19:40:29 +02:00
zv0n a54d079fd2 Mario: add MapObject and use that instead of tuples 2021-06-07 23:48:28 +02:00
zv0n 76f55fd98c Mario Editor: fix highlighting 2021-06-04 14:49:24 +02:00
zv0n 301c4f3142 Mario Editor: initialize empty map with correct column size 2021-06-04 14:39:23 +02:00
zv0n 0475f4967b Mario Editor: smaller block size 2021-06-01 10:18:33 +02:00
zv0n 243c1d9d04 Mario: add a dictionary of flags for each block 2021-05-31 18:54:59 +02:00
zv0n af3954cb61 Mario: merge mapLoader functions into one 2021-05-31 18:54:43 +02:00
zv0n 0b3689b0ae SDLPP: add option to remove collisions 2021-05-31 18:54:17 +02:00
zv0n 78c9b9feb0 Mario: fix function name 2021-05-31 17:28:26 +02:00
zv0n 57a573783d Mario Editor: change function name 2021-05-31 16:10:19 +02:00
zv0n 2b405c5d31 Mario Editor: change edit boxes' indexing to 1-based
As the left map arrow is on position 0 * BLOCK_SIZE and the first edit
box is on position 1 * BLOCK_SIZE, indexing them from 1 causes slightly
more readable code
2021-05-31 16:08:14 +02:00
zv0n 26cbdd0f8e Mario: add block's land type when creating block 2021-05-31 16:07:55 +02:00
zv0n 808f392119 Mario: silence some warnings 2021-05-31 14:30:28 +02:00
zv0n 5d20757d43 Mario Editor: formatting 2021-05-31 14:04:28 +02:00
zv0n cd0a301e52 Mario Editor: add land type switching 2021-05-31 14:03:11 +02:00
zv0n af94cc0e03 SDLPP: add option to get SRC rect of texture 2021-05-31 14:01:11 +02:00
zv0n 3bef592cb1 Mario Editor: formatting 2021-05-29 19:24:47 +02:00
zv0n 58974f8a7e Mario Editor: add tool highlighting + WSAD controls 2021-05-29 19:17:45 +02:00
zv0n 3cb36fe180 Mario Editor: add tool populating function 2021-05-29 13:21:01 +02:00
zv0n 5b8c0f88bb Mario Editor: turn grid/arrow creation into a function 2021-05-29 11:38:45 +02:00
zv0n a55a9142af Mario: slight editor UI update 2021-05-28 20:00:15 +02:00
zv0n be638591c8 Mario: remove debug outputs from editor 2021-05-28 19:53:30 +02:00
zv0n 9d9068091b Mario: slightly better editor UI 2021-05-28 19:51:02 +02:00
zv0n af3588501a Mario: reflect fixed sdlpp collisions 2021-05-27 18:09:58 +02:00
zv0n db338fd544 SDLPP colidesWith: only add id once
Before this change collision id was added for every collision it was a
part of, but we only want that id once (the collider collided, that's all
that matters)
2021-05-27 18:08:48 +02:00
zv0n 757a03568d Mario: Fix bug of being teleported after landing from jump
In rare cases Mario was teleported when landing from a high jump as a
visitor could've been fired in the wrong moment (before Mario's Y was
reset to be standing on the ground) and left/right detect would trigger
and teleport mario 1 block away
2021-05-27 16:57:21 +02:00
zv0n b8c56c06fd Mario: better side collision handling 2021-05-27 16:33:00 +02:00
zv0n 6e61eb03b9 Mario: check before bouncing 2021-05-26 18:24:09 +02:00
zv0n 734b0b58cb Mario: fix floor detect and top movement helper 2021-05-26 17:48:33 +02:00
zv0n d2bc497070 Mario: set mario pointer when loading map for editor 2021-05-26 14:18:39 +02:00
zv0n 19c29b261c Windows compatibility fixes 2021-05-26 14:17:07 +02:00
zv0n 49bceafe0b Mario: fix bounce return position 2021-05-26 09:29:12 +02:00
zv0n 55f88a547c Mario: completely remove dynamic sdlpp 2021-05-26 09:28:59 +02:00
zv0n c2fb78b0a6 Mario: added destructible modifier to editor 2021-05-26 00:46:19 +02:00
zv0n 6fe283bb34 Mario: add bouncing 2021-05-25 22:05:50 +02:00
zv0n 0c4f2482c7 SDLPP: Allow changing coliders' position
Requires `updateSizeAndPosition` to be run on the parent container
2021-05-25 22:05:00 +02:00
zv0n 79d5f348c4 SDLPP: allow using shared pointers when adding collisions 2021-05-25 22:04:38 +02:00
zv0n bd8a841e6f Don't updateSizeAndPosition on setPos as it might change texture and that isn't threadsafe 2021-05-25 20:21:26 +02:00
zv0n 670d5b7c1b Mario: added fps counter 2021-05-25 20:21:02 +02:00
zv0n cc6f3f838b Updated gitignore 2021-05-25 16:35:46 +02:00
zv0n 91df7c3f63 Mario: use .a library instead of dynamic 2021-05-25 16:34:44 +02:00
zv0n df61983f55 SDLPP: add .a library target 2021-05-25 16:34:21 +02:00
zv0n f0df1cc3b2 Mario: remove destructible used for testing 2021-05-25 12:27:26 +02:00
zv0n 7ed8b0f4e1 Mario: destroy blocks 1 at a time, if jumping and would hit only with small side, move Mario a bit so the jump is successful 2021-05-25 12:26:04 +02:00
zv0n 7390f684f5 SDLPP: rectcolider now has min height/width property 2021-05-25 12:18:03 +02:00
zv0n b75b44201a Mario: destructible blocks 2021-05-24 00:07:40 +02:00
zv0n bea479bf72 Mario: top collision detection 2021-05-23 23:57:29 +02:00
zv0n 8672830db8 Mario: jumping sprite + head bump colider 2021-05-23 23:45:45 +02:00
zv0n 088fb4d15a Jumping experiment 2021-05-23 23:32:15 +02:00
zv0n 930875ccf8 Mario: simple jump 2021-05-22 23:54:01 +02:00
zv0n d9a88f2de2 Mario: custom mario class 2021-05-22 23:13:26 +02:00
zv0n 0358aa36c7 Mario: proper position when standing on ground 2021-05-22 22:36:53 +02:00
zv0n d04cbea02d Mario: editor - move all global vars into a single struct 2021-05-22 22:13:22 +02:00
zv0n d80ae9a4e2 Mario editor: more refactoring 2021-05-09 20:45:52 +02:00
zv0n ede8bbbe8b Mario Editor: refactoring 2021-05-09 20:21:53 +02:00
zv0n 83cda5f860 Mario editor: formatting 2021-05-09 00:46:10 +02:00
zv0n b54ba5034c Mario editor: started refactoring 2021-05-09 00:43:53 +02:00
zv0n 7b4c3c9697 Mario: add Roboto font to git 2021-05-07 23:17:49 +02:00
zv0n c849895c72 Mario editor: more terrain, can place Mario 2021-05-07 23:17:05 +02:00
zv0n 85807ca962 Mario editor: added more terrain blocks 2021-05-07 10:36:45 +02:00
zv0n 900382bfce Mario editor: fix tool selection 2021-05-07 10:36:31 +02:00
zv0n e084ed6f86 Mario editor: can paginate blocks now 2021-05-07 10:08:41 +02:00
zv0n f89d36c177 Mario Editor: Tool selection alpha 2021-05-07 09:43:57 +02:00
zv0n c383654349 Mario editor: add + button for columns 2021-05-07 08:49:46 +02:00
zv0n 7b0f72e273 Mario map: initial map has 18 columns 2021-05-07 08:35:01 +02:00
zv0n ad7f737e16 Mario editor: don't delete characters when changing terrain 2021-05-02 14:43:15 +02:00
zv0n 8b8f3b7f06 Mario editor: switching between blocks 2021-05-02 14:28:17 +02:00
zv0n 96857a99af Mario editor: use visitors 2021-05-02 14:14:11 +02:00
zv0n 34324d3054 SDLPP: get/set id in visitor 2021-05-02 14:03:43 +02:00
zv0n e84284e613 SDLPP: can set minimal width/height on rectangle renderer 2021-05-02 14:03:26 +02:00
zv0n 61e45e89a5 Basic editor functionality arrived!
Terrible code, must be changed!!!
2021-05-01 21:55:43 +02:00
zv0n 183bd53b66 Mario: saving map as binary file v1.0 2021-04-30 23:12:53 +02:00
zv0n d4991ea3a7 Starting Mario Editor project 2021-04-30 21:02:14 +02:00
zv0n 1927b71629 Preparation for different types of terrain 2021-04-30 09:10:58 +02:00
zv0n 5562ca4d82 Tetris: mouse proof-of-concept 2021-04-29 19:49:04 +02:00
zv0n 4e81ac6562 SDLPP: if one object is entirely contained within another, it is a collision 2021-04-29 19:48:45 +02:00
zv0n 4f20274f11 SDLPP: mouse position functions 2021-04-29 19:48:05 +02:00
zv0n 90dc26251b Tetris: use new API 2021-04-29 13:25:55 +02:00
zv0n b52dee267b Mario: flip texture according to movement direction 2021-04-29 13:08:08 +02:00
zv0n ff741dd882 SDLPP: add texture flipping/rotation 2021-04-29 13:06:37 +02:00
zv0n b611e2479a Mario: detect left/right collision 2021-04-29 12:33:31 +02:00
zv0n e8e9e12b58 Ignore clangd files 2021-04-29 12:33:06 +02:00
zv0n 7c38e122d0 Mario: use object alignment 2021-04-27 15:58:01 +02:00
zv0n e5d0610f6d SDLPP: add option to specify render object alignment 2021-04-27 15:58:01 +02:00
zv0n fc1d06a2b8 Added README 2021-04-26 22:21:50 +02:00
zv0n 0f1e44615c Mario: include testmap in git 2021-04-26 22:16:53 +02:00
zv0n 5d03da3131 Mario: remove linux-specific includes 2021-04-26 22:16:25 +02:00
zv0n b0b84101a2 Mario: don't let Mario go left 2021-04-26 21:59:21 +02:00
zv0n dd6f37264c SDLPP: add collider IDs 2021-04-26 21:57:31 +02:00
zv0n 19e66bf34a Mario: initial commit 2021-04-25 22:42:55 +02:00
zv0n 7206dbf7c3 SDLPP: Scene - add visitCollisions function 2021-04-25 16:07:46 +02:00
zv0n 5b96de0d9d SDLPP: Scene - add function to bring objet to the front or back of Z 2021-04-25 15:54:16 +02:00
zv0n 1f5e3a999c SDLPP: add header files to sdlpp.hpp 2021-04-25 14:09:14 +02:00
zv0n 87970bfc4b SDLPP: Visitor pattern 2021-04-25 13:57:33 +02:00
zv0n ee82430f82 SDLPP: animation/movement chagnes 2021-04-24 23:26:27 +02:00
zv0n 6cfe2046d4 SDLPP: Formatting 2021-03-15 14:50:40 +01:00
zv0n 4cd351c7a3 SDLPP: Texture - use SDL_Color 2021-03-15 14:48:48 +01:00
zv0n 8540573455 SDLPP: RenderObject - use Vec2D 2021-03-15 14:43:56 +01:00
zv0n 6ecdb6d90d SDLPP: Renderer/Scene - use Vec2D instead of std::pair 2021-03-15 14:37:53 +01:00
zv0n aaae85a932 SDLPP: LineRenderer - use new features 2021-03-15 14:30:01 +01:00
zv0n 8b3eee0673 SDLPP: Split fontconfiguration into 2 files 2021-03-15 14:18:41 +01:00
zv0n 406186d8bb TETRIS: Fix restart 2021-03-14 17:02:41 +01:00
zv0n 594316dcea Tetris: formatting 2021-03-13 18:37:23 +01:00
zv0n 2f20661b5b SDLPP: formatting, make compileable on Linux 2021-03-13 18:36:29 +01:00
zv0n d2cf54556e New collision detection 2021-03-13 15:05:16 +01:00
zv0n 258ce51cfe Trying to switch to more object-oriented 2021-03-12 22:33:46 +01:00
120 changed files with 10808 additions and 669 deletions
+4 -4
View File
@@ -12,10 +12,10 @@ SortIncludes: 'false'
SpaceBeforeAssignmentOperators: 'true'
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: 'false'
SpacesInAngles: 'true'
SpacesInCStyleCastParentheses: 'true'
SpacesInContainerLiterals: 'true'
SpacesInParentheses: 'true'
SpacesInAngles: 'false'
SpacesInCStyleCastParentheses: 'false'
SpacesInContainerLiterals: 'false'
SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'
Standard: Cpp11
TabWidth: '4'
+38
View File
@@ -0,0 +1,38 @@
---
kind: pipeline
type: kubernetes
name: mario-build
platform:
os: linux
arch: arm64
steps:
- name: build
image: docker.zvon.tech/cppbuilder:v0.06
commands:
- cd mario
- mkdir build
- cd build
- cmake ..
- make
- name: formatting-check
image: docker.zvon.tech/cppbuilder:v0.06
commands:
- cd mario
- find . -path "./build" -prune -or -path "./.cache" -prune -or -iname "*.cpp" -or -iname "*.hpp" -print | xargs -P0 -I{} clang-format -style=file --dry-run -Werror {}
when:
status:
- failure
- success
- name: notify
image: docker.zvon.tech/drone-email:v0.01
settings:
host: mail.zvon.tech
username:
from_secret: email_user
password:
from_secret: email_password
port: 465
from: Drone <drone@zvon.tech>
when:
status: [ changed, failure ]
+7
View File
@@ -1,6 +1,7 @@
*.png
*.bmp
*.o
*.a
*.so
*.so.*
*.dylib
@@ -14,3 +15,9 @@ Release
demo
test
tetris/tetris
.cache
compile_commands.json
.DS_Store
*.bak
build
*.code-workspace
+56 -16
View File
@@ -1,25 +1,65 @@
CXX ?= g++
CFLAGS ?= -O2 -Wall -Wextra -g
PREFIX ?= /usr/local/bin
ifeq ($(OS),Windows_NT)
UNAME_S := Windows
CXX = cl
CXXFLAGS = -MD -EHsc
OBJEXT = obj
LDFLAGS =
OUTPUTFLAG = -Fo
else
UNAME_S := $(shell uname -s)
CXX ?= g++
CXXFLAGS = -std=c++14 -Wall -Wextra -pedantic -O2 -DDEBUG -DFEATURE # -g -fsanitize=address
OBJEXT = o
LDFLAGS ?= -lSDL2 -lSDL2_image -lSDL2_gfx -lSDL2_ttf -pthread
OUTPUTFLAG = -o
endif
TEST_OBJECTS = test.${OBJEXT}
ifeq ($(UNAME_S),Linux)
TEST_OBJECTS += libsdlpp.so
endif
ifeq ($(UNAME_S),Darwin)
TEST_OBJECTS += libsdlpp.dylib
endif
ifeq ($(UNAME_S),Windows)
TEST_OBJECTS += sdlpp/SDL2/SDL2_framerate.c sdlpp/SDL2/SDL2_gfxPrimitives.c sdlpp/SDL2/SDL2_imageFilter.c sdlpp/SDL2/SDL2_rotozoom.c
SDLLIB = libsdlpp.dll
endif
.PHONY: default
default: demo
default: test
demo: main.o sdlpp.o
$(CXX) $(CFLAGS) -o $@ $^ ${LDFLAGS}
test: test.o sdlpp.o
$(CXX) $(CFLAGS) -o $@ $^ ${LDFLAGS}
ifeq ($(UNAME_S),Windows)
test: ${TEST_OBJECTS} ${SDLLIB}
$(CXX) $(CXXFLAGS) -Fe"$@" ${TEST_OBJECTS} /link sdlpp\SDL2.lib sdlpp\SDL2_ttf.lib sdlpp\SDL2_image.lib libsdlpp.lib
main.o: main.cpp sdlpp.hpp
$(CXX) $(CFLAGS) -c -o $@ $<
sdlpp.o: sdlpp.cpp sdlpp.hpp
$(CXX) $(CFLAGS) -c -o $@ $<
test.o: tests/test.cpp sdlpp.hpp tests/catch.hpp
$(CXX) $(CFLAGS) -c -o $@ $<
else
test: ${TEST_OBJECTS}
$(CXX) $(CXXFLAGS) -o $@ $^ ${LDFLAGS} -L $(shell pwd) -lsdlpp
endif
windows_tetris: sdlpp.hpp sdlpp.cpp tetris/tetris.cpp tetris/config.cpp tetris/global_vars.cpp tetris/scenes.cpp tetris/functions.cpp tetris/config.hpp tetris/global_vars.hpp tetris/scenes.hpp tetris/functions.hpp
cl -MD -EHsc -Fe"Tetris" sdlpp.cpp tetris/tetris.cpp tetris/config.cpp tetris/global_vars.cpp tetris/scenes.cpp tetris/functions.cpp SDL2/SDL2_framerate.c SDL2/SDL2_gfxPrimitives.c SDL2/SDL2_imageFilter.c SDL2/SDL2_rotozoom.c /link SDL2.lib SDL2_ttf.lib SDL2_image.lib
test.${OBJEXT}: test.cpp
$(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $<
libsdlpp.so: sdlpp
$(MAKE) clean -C sdlpp
$(MAKE) -C sdlpp
cp sdlpp/libsdlpp.so .
ln -sf libsdlpp.so libsdlpp.so.1
libsdlpp.dylib: sdlpp
$(MAKE) clean -C sdlpp
$(MAKE) -C sdlpp
cp sdlpp/libsdlpp.dylib .
libsdlpp.dll: ../sdlpp
$(MAKE) clean -C sdlpp
$(MAKE) -C sdlpp
cp sdlpp/libsdlpp.dll .
cp sdlpp/libsdlpp.lib .
start:
LD_LIBRARY_PATH=$$(pwd) ./test
clean:
rm -Rf *.o test demo
rm -Rf *.${OBJEXT} test
+13 -13
View File
@@ -1,4 +1,4 @@
#include "sdlpp.hpp"
#include "sdlpp/sdlpp.hpp"
#include <thread>
#include <chrono>
#include <SDL2/SDL2_framerate.h>
@@ -78,8 +78,8 @@ public:
}
if ( jump_ < 0 || jump_ > jump_speed )
jump_ = 0;
og_y += grav * time_portion;
og_y -= jump_ * time_portion;
double addition = grav * time_portion - jump_ * time_portion;
original += {0, addition};
}
private:
@@ -135,7 +135,7 @@ void addStuff( SDLPP::Scene &scene, std::shared_ptr< SDLPP::Renderer > &r ) {
while ( posx < 3 ) {
stone =
std::make_shared< Destroyable >( posx, 0.5, 0.15, 0.1, r, 1000 );
stone->addCollision( SDLPP::Rect( 0, 0, 1, 1 ) );
stone->addCollision( SDLPP::RectColider( 0, 0, 1, 1 ) );
stone->setColor( "#222222FF" );
stone->setId( STONE_ID );
stone->setColiderColor( "FF0000" );
@@ -143,24 +143,24 @@ void addStuff( SDLPP::Scene &scene, std::shared_ptr< SDLPP::Renderer > &r ) {
posx += 0.45;
}
auto x = std::make_shared< Player >( 0, 0, 0.2, 0.2, r );
x->addCollision( SDLPP::Rect( 0.3, 0.7, 0.05, 0.31 ) );
x->addCollision( SDLPP::Rect( 0.65, 0.7, 0.05, 0.31 ) );
x->addCollision( SDLPP::Rect( 0.2, 0.3, 0.6, 0.45 ) );
x->addCollision( SDLPP::Circle( 0.5, 0.15, 0.3 ) );
x->addCollision( SDLPP::RectColider( 0.3, 0.7, 0.05, 0.31 ) );
x->addCollision( SDLPP::RectColider( 0.65, 0.7, 0.05, 0.31 ) );
x->addCollision( SDLPP::RectColider( 0.2, 0.3, 0.6, 0.45 ) );
x->addCollision( SDLPP::CircleColider( 0.5, 0.15, 0.3 ) );
x->setColor( "E164B7" );
x->setId( PLAYER_ID );
x->setColiderColor( "00FF00" );
scene.addObject( x );
player = x;
auto z = std::make_shared< SDLPP::RectangleRender >( 0, 2.5, 0, 0, r );
auto z_col = SDLPP::Rect( -1, 0, -1, -1 );
auto z_col = SDLPP::RectColider( -1, 0, -1, -1 );
z_col.setInfinite();
z->addCollision( z_col );
z->setId( DEATH );
z->setColiderColor( "FF00FF" );
scene.addObject( z );
auto y = std::make_shared< SDLPP::TextRenderer >( 0, 0, 0.2, 0.1, r );
y->setText( *font, "DEMO", "#FFFFFF", "#000000", 5 );
y->setText( font, "DEMO", "#FFFFFF", "#000000", 5 );
y->setPermanent( true );
y->setId( 123 );
scene.addObject( y );
@@ -173,20 +173,20 @@ void addPause( SDLPP::Scene &scene, std::shared_ptr< SDLPP::Renderer > &r ) {
bg->setPermanent( true );
scene.addObject( bg );
auto y = std::make_shared< SDLPP::TextRenderer >( 0.25, 0.1, 0.5, 0.3, r );
y->setText( *font, "PAUSED", "#FFFFFF", "#000000", 5 );
y->setText( font, "PAUSED", "#FFFFFF", "#000000", 5 );
y->setId( 0 );
y->centerX();
scene.addObject( y );
auto resume =
std::make_shared< SDLPP::TextRenderer >( 0.4, 0.5, 0.2, 0.1, r );
resume->setText( *font, "Resume", "#FFFFFF", "#000000", 5 );
resume->setText( font, "Resume", "#FFFFFF", "#000000", 5 );
resume->setColor( "#FFFFFF40" );
resume->centerX();
scene.addObject( resume );
pause_options.push_back( resume );
auto quit =
std::make_shared< SDLPP::TextRenderer >( 0.4, 0.7, 0.2, 0.1, r );
quit->setText( *font, "Quit Game", "#FFFFFF", "#000000", 5 );
quit->setText( font, "Quit Game", "#FFFFFF", "#000000", 5 );
quit->centerX();
scene.addObject( quit );
pause_options.push_back( quit );
+8
View File
@@ -0,0 +1,8 @@
sprites
*txt
mario
editor
.DS_Store
*bin
build
.vscode
+114
View File
@@ -0,0 +1,114 @@
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
enable_language(CXX)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
project(Mario)
if(APPLE)
include_directories(/opt/homebrew/include)
link_directories(/opt/homebrew/lib)
endif()
list(APPEND CommonFiles
global_vars.cpp
sprites.cpp
maploader.cpp
mapobject.cpp
blocks/simpleblocks.cpp
mario.cpp
blocks.cpp
)
list(APPEND SDLLibs
sdlpp)
if(WIN32)
list(APPEND CommonFiles
filesystem/windows/filesystem.cpp)
list(APPEND CommonFiles
../sdlpp/SDL2/SDL2_framerate.c
../sdlpp/SDL2/SDL2_gfxPrimitives.c
../sdlpp/SDL2/SDL2_imageFilter.c
../sdlpp/SDL2/SDL2_rotozoom.c
)
add_library(SDL2_m STATIC IMPORTED)
set_target_properties(SDL2_m PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../sdlpp/SDL2.lib)
add_library(SDL2_ttf_m STATIC IMPORTED)
set_target_properties(SDL2_ttf_m PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../sdlpp/SDL2_ttf.lib)
add_library(SDL2_image_m STATIC IMPORTED)
set_target_properties(SDL2_image_m PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../sdlpp/SDL2_image.lib)
add_executable(mario WIN32)
add_executable(editor WIN32)
list(APPEND SDLLibs
SDL2_m
SDL2_image_m
SDL2_ttf_m
)
else()
list(APPEND CommonFiles
filesystem/unix/filesystem.cpp)
add_executable(mario)
add_executable(editor)
list(APPEND SDLLibs
SDL2
SDL2_image
SDL2_ttf
SDL2_gfx
)
endif()
add_subdirectory(../sdlpp sdlpp)
target_sources(mario
PRIVATE ${CommonFiles}
PRIVATE main.cpp
PRIVATE visitors/mario_visitor.cpp
PRIVATE visitors/mushroom_visitor.cpp
PRIVATE visitors/goomba_visitor.cpp
PRIVATE visitors/turtle_visitor.cpp
PRIVATE visitors/bounce_visitor.cpp
PRIVATE visitors/visitor_generator.cpp
PRIVATE visitors/projectile_visitor.cpp
PRIVATE blocks/coinblock.cpp
PRIVATE blocks/mushroomblock.cpp
PRIVATE blocks/goombablock.cpp
PRIVATE blocks/turtleblock.cpp
PRIVATE blocks/fireball.cpp
PRIVATE scenes/load_scene.cpp
PRIVATE scenes/game_main_menu.cpp
PRIVATE editor_visitor.cpp # TODO
PRIVATE edit_box.cpp # TODO
PRIVATE tool_box.cpp # TODO
)
target_sources(editor
PRIVATE ${CommonFiles}
PRIVATE blocks/coineditorblock.cpp
PRIVATE blocks/goombablock.cpp
PRIVATE blocks/turtleblock.cpp
PRIVATE editor.cpp
PRIVATE edit_box.cpp
PRIVATE tool_box.cpp
PRIVATE editor_visitor.cpp
PRIVATE scenes/editor_main.cpp
PRIVATE scenes/editor_main_menu.cpp
PRIVATE scenes/yes_no_scene.cpp
PRIVATE scenes/ok_scene.cpp
PRIVATE scenes/load_scene.cpp
PRIVATE scenes/text_scene.cpp
)
target_compile_definitions(editor PUBLIC EDITOR)
target_link_libraries(mario PRIVATE ${SDLLibs} Threads::Threads)
target_link_libraries(editor PRIVATE ${SDLLibs} Threads::Threads)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/testfont.ttf ${CMAKE_CURRENT_SOURCE_DIR}/sprites DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+11
View File
@@ -0,0 +1,11 @@
# Mario
This is my recreation of first Super Mario Bros. level in my engine
I don't think I can share Nintendo sprites, so you'll have to provide them
yourself. I've downloaded mine from here:
https://www.spriters-resource.com/nes/supermariobros/sheet/50365/ - sprites/mario.png
https://www.spriters-resource.com/nes/supermariobros/sheet/52570/ - sprites/enemies.png
https://www.spriters-resource.com/nes/supermariobros/sheet/52569/ - sprites/items.png
https://www.spriters-resource.com/nes/supermariobros/sheet/52571/ - sprites/terrain.png
+703
View File
@@ -0,0 +1,703 @@
#include "blocks.hpp"
#include "global_vars.hpp"
#include "maploader.hpp"
#include "objectids.hpp"
#include "sprites.hpp"
#include "editor_visitor.hpp"
#include <memory>
#include <unordered_map>
#include "visitors/mario_visitor.hpp"
#include "visitors/bounce_visitor.hpp"
#include "blocks/simpleblocks.hpp"
#include "blocks/coineditorblock.hpp"
#include "blocks/coinblock.hpp"
#include "blocks/mushroomblock.hpp"
#include "blocks/goombablock.hpp"
#include "blocks/turtleblock.hpp"
#include "mario.hpp"
#define CAN_BE_DESTROYED_FLAG 0x0000000000000001
#define HAS_COLLISION 0x0000000000000002
MarioBlock::MarioBlock(int x, int y,
const std::shared_ptr<SDLPP::Renderer> &renderer,
std::shared_ptr<SDLPP::Texture> texture, SDL_Rect src,
bool can_be_destroyed, bool destructible)
: RectangleRender(x * BLOCK_SIZE, 1 - (16 - y) * BLOCK_SIZE, BLOCK_SIZE,
BLOCK_SIZE, renderer, texture, src) {
_can_be_destroyed = can_be_destroyed;
_destructible = can_be_destroyed && destructible;
setMovementSpeed(1);
_coins = 0;
_mushroom = false;
_base_src = src;
}
void MarioBlock::visit(SDLPP::Visitor &visitor) {
#ifdef EDITOR
if (!_tool && _terrain &&
visitor.getVisitorType() == VisitorType::Terrain) {
destroy();
}
if (!_tool && !_terrain &&
(visitor.getVisitorType() == VisitorType::Modifier ||
visitor.getVisitorType() == VisitorType::Character)) {
destroy();
}
#else
if (visitor.getFromId() == MARIO_TOP_DETECT) {
auto &mario_visitor = dynamic_cast<MarioVisitor &>(visitor);
if (mario_visitor.canDestroy()) {
if ((_destructible && !hasCoin() && !hasMushroom()) || (_can_be_destroyed && mario_visitor.isBig() && !hasCoin() && !hasMushroom())) {
destroy();
} else if (_bouncable) {
BounceVisitor bv;
bv.setVisitorType(VisitorType::Terrain);
setPos(getPos() - SDLPP::Vec2D<double>(0, BLOCK_SIZE));
if (getCollisions().size() < 2)
addCollision(
SDLPP::RectColider(0.1, 0.1, 0.8, 0.8, BOUNCE_COLLISION));
updateSizeAndPosition();
g_playground->visitCollisions(*this, bv);
setPos(getPos() + SDLPP::Vec2D<double>(0, BLOCK_SIZE));
updateSizeAndPosition();
if (bv.canBounce())
bounce();
}
if (hasCoin()) {
removeCoin();
auto coin =
createTerrainBlock(COIN_ID, LandType::OVERWORLD, renderer);
coin->setPos(getPos());
std::dynamic_pointer_cast<CoinBlock>(coin)->setParent(this);
dynamic_cast<MarioVisitor &>(visitor).setCoin();
dynamic_cast<MarioVisitor &>(visitor).setCoinBlock(coin);
}
if (hasMushroom()) {
removeMushroom();
auto mushroom =
createTerrainBlock(MUSHROOM_ID, LandType::OVERWORLD, renderer);
mushroom->setPos(getPos());
std::dynamic_pointer_cast<MushroomBlock>(mushroom)->setParent(this);
std::dynamic_pointer_cast<MushroomBlock>(mushroom)->setFireFlower(mario_visitor.isBig());
dynamic_cast<MarioVisitor &>(visitor).setMushroomBlock(mushroom);
if(mario_visitor.isBig()) {
harden();
}
}
}
}
#endif
visitor.visit(*this);
}
void MarioBlock::setTool(bool tool) {
_tool = tool;
}
void MarioBlock::setTerrain(bool terrain) {
_terrain = terrain;
}
void MarioBlock::bounce() {
if (_bouncing) {
return;
}
_bouncing = true;
og_pos = getPos();
ticks_to_bounce = bounce_ticks;
setMovement(0, -bounce_speed);
}
void MarioBlock::travelToPos(const SDLPP::Vec2D<double> &target) {
if (_traveling) {
return;
}
_traveling = true;
_target = target;
auto movement = (_target - getPos());
auto abs_mov_x = movement.getX();
if (abs_mov_x < 0) {
abs_mov_x *= -1;
}
auto abs_mov_y = movement.getY();
if (abs_mov_y < 0) {
abs_mov_y *= -1;
}
movement = movement / (abs_mov_x > abs_mov_y ? abs_mov_x : abs_mov_y);
movement = movement * travel_speed;
setMovement(movement.getX(), movement.getY());
}
void MarioBlock::gravity(int ticks) {
if (_on_ground) {
return;
}
_ticks_till_gravity -= ticks;
if (_ticks_till_gravity < 0) {
addMovement(0, _gravity_acceleration);
_ticks_till_gravity = _base_gravity_ticks;
}
}
bool MarioBlock::isBouncing() const {
return _bouncing;
}
bool MarioBlock::isTraveling() const {
return _traveling;
}
void MarioBlock::custom_move(int ticks) {
SDLPP::RectangleRender::custom_move(ticks);
if (!_bouncing && !_traveling) {
return;
}
if (_bouncing) {
if (getMovement().getY() < 0) {
ticks_to_bounce -= ticks;
if (ticks_to_bounce < 0) {
setMovement(0, bounce_speed);
ticks_to_bounce = bounce_ticks;
}
} else {
if (getPos().getY() >= og_pos.getY()) {
setMovement(0, 0);
setPos(getPos().getX(), og_pos.getY());
_bouncing = false;
}
}
}
if (_traveling) {
bool overshot_x =
(getMovement().getX() < 0 && getPos().getX() <= _target.getX()) ||
(getMovement().getX() > 0 && getPos().getX() >= _target.getX());
bool overshot_y =
(getMovement().getY() < 0 && getPos().getY() <= _target.getY()) ||
(getMovement().getY() > 0 && getPos().getY() >= _target.getY());
if (overshot_x) {
setPos(_target.getX(), getPos().getY());
setMovement(0, getMovement().getY());
}
if (overshot_y) {
setPos(getPos().getX(), _target.getY());
setMovement(getMovement().getX(), 0);
}
if (getMovement() == SDLPP::Vec2D<double>(0, 0)) {
_traveling = false;
}
}
}
void MarioBlock::setType(LandType::Value type) {
_type = type;
setWorldTypeSrc(_type);
}
LandType::Value MarioBlock::getType() const {
return _type;
}
bool MarioBlock::hasCoin() {
return _coins > 0;
}
bool MarioBlock::hasMushroom() {
return _mushroom;
}
bool MarioBlock::hasTeleport() {
return !_teleport_level.empty();
}
void MarioBlock::removeCoin() {
_coins--;
}
void MarioBlock::removeMushroom() {
_mushroom = false;
}
void MarioBlock::addMushroom() {
_mushroom = true;
}
void MarioBlock::setCoinCount(int coins) {
_coins = coins;
}
void MarioBlock::setTeleportLevel(const std::string &level) {
_teleport_level = level;
}
void MarioBlock::setDestructible(bool destructible) {
_destructible = destructible;
}
void MarioBlock::ensureCollision() {
if (getCollisions().size() == 0) {
addCollision(SDLPP::RectColider(0, 0, 1, 1));
}
}
void MarioBlock::setWorldTypeSrc(LandType::Value world) {
auto rect = _base_src;
switch (world) {
case LandType::OVERWORLD:
rect.x += OVERWORLD_SHIFT.getX();
rect.y += OVERWORLD_SHIFT.getY();
break;
case LandType::UNDERWORLD:
rect.x += UNDERWORLD_SHIFT.getX();
rect.y += UNDERWORLD_SHIFT.getY();
break;
case LandType::WATER:
rect.x += WATER_SHIFT.getX();
rect.y += WATER_SHIFT.getY();
break;
case LandType::BOWSER:
rect.x += BOWSER_SHIFT.getX();
rect.y += BOWSER_SHIFT.getY();
break;
}
setTextureSourceRect(rect);
}
const std::vector<uint64_t> possibleBlocks = {
FLOOR_ID,
STEP_ID,
HILL_TOP_ID,
HILL_DOTS_LEFT_ID,
HILL_FILL_ID,
HILL_INCLINE_ID,
HILL_DOTS_RIGHT_ID,
HILL_DECLINE_ID,
CLOUD_LEFT_TOP_ID,
CLOUD_MIDDLE_TOP_ID,
CLOUD_RIGHT_TOP_ID,
VINE_TOP_ID,
CLOUD_LEFT_BOTTOM_ID,
CLOUD_MIDDLE_BOTTOM_ID,
CLOUD_RIGHT_BOTTOM_ID,
VINE_BOTTOM_ID,
BRICK_TOP_ID,
BRICK_ID,
FLAG_ID,
WATER_TOP_ID,
BUSH_LEFT_ID,
BUSH_MIDDLE_ID,
BUSH_RIGHT_ID,
WATER_FILL_ID,
PIPE_LEFT_TOP_ID,
PIPE_RIGHT_TOP_ID,
CASTLE_TOWER_ID,
CASTLE_TOWER_FILLED_ID,
PIPE_LEFT_BOTTOM_ID,
PIPE_RIGHT_BOTTOM_ID,
CASTLE_LEFT_ID,
CASTLE_RIGHT_ID,
POLE_TOP_ID,
CASTLE_ENTRY_ID,
SIDEWAY_PIPE_END_TOP_ID,
SIDEWAY_PIPE_MIDDLE_TOP_ID,
POLE_BOTTOM_ID,
CASTLE_BLACK_ID,
SIDEWAY_PIPE_END_BOTTOM_ID,
SIDEWAY_PIPE_MIDDLE_BOTTOM_ID,
SIDEWAY_PIPE_CONNECTOR_TOP_ID,
TREE_PLATFORM_TOP_LEFT_ID,
TREE_PLATFORM_TOP_MIDDLE_ID,
TREE_PLATFORM_TOP_RIGHT_ID,
SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID,
MUSHROOM_PLATFORM_TOP_LEFT_ID,
MUSHROOM_PLATFORM_TOP_MIDDLE_ID,
MUSHROOM_PLATFORM_TOP_RIGHT_ID,
TREE_PLATFORM_BARK_ID,
MUSHROOM_PLATFORM_BARK_TOP_ID,
TREE_LEAVES_TOP_ID,
TREE_LEAVES_SMALL_ID,
CANNON_TOWER_ID,
MUSHROOM_PLATFORM_BARK_BOTTOM_ID,
TREE_LEAVES_BOTTOM_ID,
TREE_BARK_ID,
CANNON_PEDESTAL_ID,
CANNON_ID,
};
const std::vector<uint64_t> possibleMods = {
DESTRUCTIBLE_MODIFIER_ID,
BACKGROUND_MODIFIER_ID,
COIN_MODIFIER_ID,
MUSHROOM_MODIFIER_ID,
TELEPORT_MODIFIER_ID,
};
const std::vector<uint64_t> possibleCharacters = {
MARIO_ID,
GOOMBA_ID,
TURTLE_ID,
};
const std::vector<LandType::Value> possibleLands = {
LandType::OVERWORLD, LandType::UNDERWORLD, LandType::WATER, LandType::BOWSER
};
std::shared_ptr<MarioBlock>
createBlockById(uint64_t id, int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer) {
std::shared_ptr<MarioBlock> result = nullptr;
switch (id) {
case FLOOR_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<FloorBlock>(x, y, renderer));
break;
case HILL_INCLINE_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<HillInclineBlock>(x, y, renderer));
break;
case HILL_DECLINE_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<HillDeclineBlock>(x, y, renderer));
break;
case HILL_DOTS_RIGHT_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<HillDotsRightBlock>(x, y, renderer));
break;
case HILL_DOTS_LEFT_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<HillDotsLeftBlock>(x, y, renderer));
break;
case HILL_FILL_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<HillFillBlock>(x, y, renderer));
break;
case HILL_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<HillTopBlock>(x, y, renderer));
break;
case BUSH_LEFT_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<BushLeftBlock>(x, y, renderer));
break;
case BUSH_MIDDLE_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<BushMiddleBlock>(x, y, renderer));
break;
case BUSH_RIGHT_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<BushRightBlock>(x, y, renderer));
break;
case CLOUD_LEFT_BOTTOM_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CloudLeftBottomBlock>(x, y, renderer));
break;
case CLOUD_MIDDLE_BOTTOM_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CloudMiddleBottomBlock>(x, y, renderer));
break;
case CLOUD_RIGHT_BOTTOM_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CloudRightBottomBlock>(x, y, renderer));
break;
case CLOUD_LEFT_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CloudLeftTopBlock>(x, y, renderer));
break;
case CLOUD_MIDDLE_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CloudMiddleTopBlock>(x, y, renderer));
break;
case CLOUD_RIGHT_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CloudRightTopBlock>(x, y, renderer));
break;
case PIPE_LEFT_BOTTOM_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<PipeLeftBottomBlock>(x, y, renderer));
break;
case PIPE_RIGHT_BOTTOM_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<PipeRightBottomBlock>(x, y, renderer));
break;
case PIPE_LEFT_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<PipeLeftTopBlock>(x, y, renderer));
break;
case PIPE_RIGHT_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<PipeRightTopBlock>(x, y, renderer));
break;
case CASTLE_LEFT_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CastleLeftBlock>(x, y, renderer));
break;
case CASTLE_RIGHT_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CastleRightBlock>(x, y, renderer));
break;
case CASTLE_BLACK_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CastleBlackBlock>(x, y, renderer));
break;
case CASTLE_ENTRY_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CastleEntryBlock>(x, y, renderer));
break;
case CASTLE_TOWER_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CastleTowerBlock>(x, y, renderer));
break;
case CASTLE_TOWER_FILLED_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CastleTowerFilledBlock>(x, y, renderer));
break;
case VINE_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<VineTopBlock>(x, y, renderer));
break;
case VINE_BOTTOM_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<VineBottomBlock>(x, y, renderer));
break;
case POLE_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<PoleTopBlock>(x, y, renderer));
break;
case POLE_BOTTOM_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<PoleBottomBlock>(x, y, renderer));
break;
case FLAG_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<FlagBlock>(x, y, renderer));
break;
case STEP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<StepBlock>(x, y, renderer));
break;
case BRICK_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<BrickBlock>(x, y, renderer));
break;
case BRICK_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<BrickTopBlock>(x, y, renderer));
break;
case SIDEWAY_PIPE_END_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<SidewayPipeEndTopBlock>(x, y, renderer));
break;
case SIDEWAY_PIPE_END_BOTTOM_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<SidewayPipeEndBottomBlock>(x, y, renderer));
break;
case SIDEWAY_PIPE_MIDDLE_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<SidewayPipeMiddleTopBlock>(x, y, renderer));
break;
case SIDEWAY_PIPE_MIDDLE_BOTTOM_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<SidewayPipeMiddleBottomBlock>(x, y, renderer));
break;
case SIDEWAY_PIPE_CONNECTOR_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<SidewayPipeConnectorTopBlock>(x, y, renderer));
break;
case SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<SidewayPipeConnectorBottomBlock>(x, y, renderer));
break;
case TREE_PLATFORM_TOP_LEFT_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<TreePlatformTopLeftBlock>(x, y, renderer));
break;
case TREE_PLATFORM_TOP_MIDDLE_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<TreePlatformTopMiddleBlock>(x, y, renderer));
break;
case TREE_PLATFORM_TOP_RIGHT_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<TreePlatformTopRightBlock>(x, y, renderer));
break;
case TREE_PLATFORM_BARK_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<TreePlatformBarkBlock>(x, y, renderer));
break;
case WATER_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<WaterTopBlock>(x, y, renderer));
break;
case WATER_FILL_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<WaterFillBlock>(x, y, renderer));
break;
case MUSHROOM_PLATFORM_TOP_LEFT_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<MushroomPlatformTopLeftBlock>(x, y, renderer));
break;
case MUSHROOM_PLATFORM_TOP_MIDDLE_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<MushroomPlatformTopMiddleBlock>(x, y, renderer));
break;
case MUSHROOM_PLATFORM_TOP_RIGHT_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<MushroomPlatformTopRightBlock>(x, y, renderer));
break;
case MUSHROOM_PLATFORM_BARK_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<MushroomPlatformBarkTopBlock>(x, y, renderer));
break;
case MUSHROOM_PLATFORM_BARK_BOTTOM_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<MushroomPlatformBarkBottomBlock>(x, y, renderer));
break;
case TREE_BARK_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<TreeBarkBlock>(x, y, renderer));
break;
case TREE_LEAVES_SMALL_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<TreeLeavesSmallBlock>(x, y, renderer));
break;
case TREE_LEAVES_TOP_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<TreeLeavesTopBlock>(x, y, renderer));
break;
case TREE_LEAVES_BOTTOM_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<TreeLeavesBottomBlock>(x, y, renderer));
break;
case CANNON_TOWER_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CannonTowerBlock>(x, y, renderer));
break;
case CANNON_PEDESTAL_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CannonPedestalBlock>(x, y, renderer));
break;
case CANNON_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CannonBlock>(x, y, renderer));
break;
case MARIO_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<Mario>(x, y, renderer, nullptr));
break;
case GOOMBA_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<GoombaBlock>(x, y, renderer));
break;
case TURTLE_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<TurtleBlock>(x, y, renderer));
break;
#ifdef EDITOR
case DESTRUCTIBLE_MODIFIER_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<DestructibleModifierBlock>(x, y, renderer));
break;
case BACKGROUND_MODIFIER_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<BackgroundModifierBlock>(x, y, renderer));
break;
case COIN_MODIFIER_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CoinEditorBlock>(x, y, renderer));
break;
case MUSHROOM_MODIFIER_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<MushroomModifierBlock>(x, y, renderer));
break;
case TELEPORT_MODIFIER_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<TeleportModifierBlock>(x, y, renderer));
break;
#endif
#ifndef EDITOR
case COIN_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<CoinBlock>(x, y, renderer));
break;
case MUSHROOM_ID:
result = std::static_pointer_cast<MarioBlock>(
std::make_shared<MushroomBlock>(x, y, renderer));
break;
#endif
}
return result;
}
std::shared_ptr<MarioBlock>
createBlock(std::shared_ptr<SDLPP::Renderer> &renderer, int x, int y,
uint64_t id, LandType::Value land_type, bool destructible,
bool editor) {
auto block = createBlockById(id, x, y, renderer);
if (block == nullptr) {
return nullptr;
}
block->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
block->setStatic();
block->setType(land_type);
if (destructible) {
block->setDestructible();
}
if (editor) {
block->ensureCollision();
}
return block;
}
// TODO coin count
std::shared_ptr<MarioBlock>
createTerrainBlock(uint64_t block_id, LandType::Value type,
std::shared_ptr<SDLPP::Renderer> &renderer, int x, int y,
bool destructible, bool editor) {
return createBlock(renderer, x, y, block_id, type, destructible, editor);
}
std::shared_ptr<MarioBlock>
createTerrainBlock(uint64_t block_id, LandType::Value type,
std::shared_ptr<SDLPP::Renderer> &renderer,
bool destructible, bool editor) {
return createTerrainBlock(block_id, type, renderer, 0, 0, destructible,
editor);
}
std::shared_ptr<MarioBlock>
createMario(LandType::Value type, std::shared_ptr<SDLPP::Renderer> &renderer,
int x, int y, bool editor) {
// TODO add type additions
auto mario = createBlock(renderer, x, y, MARIO_ID, type, false, true);
if (editor) {
mario->setTerrain(false);
mario->removeCollisions();
mario->ensureCollision();
}
return mario;
}
enum BlockRole::Value getBlockRole(uint64_t id) {
if (id >= 0x7000)
return BlockRole::TERRAIN;
if (id == MARIO_ID)
return BlockRole::MARIO;
if (id < MARIO_ID)
return BlockRole::CHARACTER;
return BlockRole::MODIFIER;
}
void MarioBlock::setBaseRect(SDL_Rect rect) {
_base_src = rect;
setType(getType());
}
void MarioBlock::checkVisibility(double rightmost_x) {
// we assume that object's X > 0 as otherwise it would be destroyed
if (!getHidden() && getAbsolutePos().getX() < rightmost_x) {
_was_visible = true;
}
}
bool MarioBlock::wasVisible() const {
return _was_visible;
}
void MarioBlock::harden() {
_can_be_destroyed = false;
setDestructible(false);
setBouncable(false);
setTextureSourceRect(HARD_SRC);
}
const std::string &MarioBlock::getTeleportLevel() {
return _teleport_level;
}
+132
View File
@@ -0,0 +1,132 @@
#ifndef BLOCKS_H
#define BLOCKS_H
#include "../sdlpp/sdlpp_rectrenderer.hpp"
#include <SDL2/SDL_rect.h>
#include <memory>
struct LandType {
enum Value { OVERWORLD = 0, UNDERWORLD = 1, WATER = 2, BOWSER = 4 };
};
class MarioBlock : public SDLPP::RectangleRender {
public:
MarioBlock(int x, int y, const std::shared_ptr<SDLPP::Renderer> &renderer,
std::shared_ptr<SDLPP::Texture> texture, SDL_Rect src,
bool can_be_destroyed = false, bool destructible = false);
void visit(SDLPP::Visitor &visitor) override;
void setTool(bool tool = true);
void setTerrain(bool terrain = true);
void bounce();
void travelToPos(const SDLPP::Vec2D<double> &target);
void custom_move(int ticks) override;
void setType(LandType::Value type);
LandType::Value getType() const;
virtual void onScrollUp() {}
virtual void onScrollDown() {}
virtual uint8_t getData() const {
return 0;
}
virtual void setData(uint8_t /*UNUSED*/) {}
// handle own visitor
virtual void handleVisitor(SDLPP::Visitor &visitor) {}
bool hasCoin();
bool hasMushroom();
bool hasTeleport();
void removeCoin();
void removeMushroom();
void addMushroom();
void setCoinCount(int coins);
void setTeleportLevel(const std::string &level);
void setDestructible(bool destructible = true);
void ensureCollision();
bool isBouncing() const;
bool isTraveling() const;
void setBaseRect(SDL_Rect rect);
void checkVisibility(double rightmost_x);
bool wasVisible() const;
void harden();
const std::string &getTeleportLevel();
protected:
double bounce_speed = 0.5;
int bounce_ticks = 100;
double travel_speed = bounce_speed;
void gravity(int ticks);
void setOnGround(bool on_ground = true) {
_on_ground = on_ground;
if (on_ground) {
setMovement(getMovement().getX(), 0);
}
}
bool isOnGround() const {
return _on_ground;
}
void setGravityTicks(int ticks) {
_base_gravity_ticks = ticks;
}
virtual void setWorldTypeSrc(LandType::Value world);
bool isBouncable() {
return _bouncable;
}
void setBouncable(bool bouncable = true) {
_bouncable = bouncable;
}
private:
bool _tool = false;
bool _terrain = true;
bool _destructible = false;
bool _can_be_destroyed = false;
bool _bouncing = false;
bool _traveling = false;
int _coins = 0;
bool _mushroom = false;
std::string _teleport_level = "";
bool _release_coin = false;
int ticks_to_bounce = 0;
SDLPP::Vec2D<double> og_pos = {};
LandType::Value _type;
SDL_Rect _base_src;
SDLPP::Vec2D<double> _target = { 0, 0 };
bool _on_ground = true;
int _base_gravity_ticks = 1000 / 60;
int _ticks_till_gravity = 0;
double _gravity_acceleration = 1.0 / (64.0 / 7.0);
bool _was_visible = false;
bool _bouncable = true;
};
extern const std::vector<uint64_t> possibleBlocks;
extern const std::vector<uint64_t> possibleMods;
extern const std::vector<uint64_t> possibleCharacters;
extern const std::vector<LandType::Value> possibleLands;
struct BlockRole {
enum Value {
TERRAIN,
MODIFIER,
CHARACTER,
MARIO,
};
};
std::shared_ptr<MarioBlock>
createTerrainBlock(uint64_t block_id, LandType::Value type,
std::shared_ptr<SDLPP::Renderer> &renderer,
bool destructible = false, bool editor = false);
std::shared_ptr<MarioBlock>
createTerrainBlock(uint64_t block_id, LandType::Value type,
std::shared_ptr<SDLPP::Renderer> &renderer, int x, int y,
bool destructible = false, bool editor = false);
std::shared_ptr<MarioBlock>
createMario(LandType::Value type, std::shared_ptr<SDLPP::Renderer> &renderer,
int x, int y, bool editor = false);
enum BlockRole::Value getBlockRole(uint64_t id);
#endif
+26
View File
@@ -0,0 +1,26 @@
#include "coinblock.hpp"
#include "../sprites.hpp"
#include "../global_vars.hpp"
CoinBlock::CoinBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, COIN_SRC, true, true) {
setHidden(true);
bounce_speed = 0.75;
bounce_ticks = 150;
}
void CoinBlock::custom_move(int ticks) {
if (_parent != nullptr && !_parent->isBouncing() && !isBouncing()) {
setHidden(false);
bounce();
_parent = nullptr;
} else if (_parent == nullptr && !isBouncing()) {
setHidden(true);
destroy();
}
MarioBlock::custom_move(ticks);
}
void CoinBlock::setParent(MarioBlock *parent) {
_parent = parent;
}
+16
View File
@@ -0,0 +1,16 @@
#ifndef COIN_BLOCK_HPP
#define COIN_BLOCK_HPP
#include "../blocks.hpp"
class CoinBlock : public MarioBlock {
public:
CoinBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
void custom_move(int ticks) override;
void setParent(MarioBlock *parent);
private:
MarioBlock *_parent = nullptr;
};
#endif
+75
View File
@@ -0,0 +1,75 @@
#include "coineditorblock.hpp"
#include "../objectids.hpp"
CoinEditorBlock::CoinEditorBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> renderer)
: MarioBlock(x, y, renderer, g_translucent_mod_texture, MOD_COIN_SRC,
false, false) {
setId(COIN_MODIFIER_ID);
auto mypos = getDoubleRect();
auto size = mypos.second.getX() / size_divisor;
_amount_text = std::make_shared<SDLPP::TextRenderer>(
mypos.first.getX() + mypos.second.getX() - size,
mypos.first.getY() + mypos.second.getX() - size, size, size, renderer,
"1", g_text_config);
setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
_amount_text->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
}
void CoinEditorBlock::render() {
MarioBlock::render();
if (_amount_text != nullptr && !hidden) {
_amount_text->render();
}
}
void CoinEditorBlock::updateSizeAndPosition() {
MarioBlock::updateSizeAndPosition();
auto block_size = getDoubleRect().second;
_amount_text->setPos(getPos() + block_size - block_size / size_divisor);
_amount_text->updateSizeAndPosition();
}
void CoinEditorBlock::addOne() {
if (_amount < max_amount) {
_amount++;
updateText();
}
}
void CoinEditorBlock::subtractOne() {
if (_amount > 1) {
_amount--;
updateText();
}
}
void CoinEditorBlock::setAmount(int amount) {
if (amount < 1) {
amount = 1;
} else if (amount > max_amount) {
amount = max_amount;
}
_amount = amount;
updateText();
}
void CoinEditorBlock::updateText() {
_amount_text->changeText(std::to_string(_amount));
}
void CoinEditorBlock::onScrollUp() {
addOne();
}
void CoinEditorBlock::onScrollDown() {
subtractOne();
}
uint8_t CoinEditorBlock::getData() const {
return _amount;
}
void CoinEditorBlock::setData(uint8_t data) {
setAmount(data);
}
+30
View File
@@ -0,0 +1,30 @@
#ifndef COIN_BLOCK_H
#define COIN_BLOCK_H
#include "../blocks.hpp"
#include "../global_vars.hpp"
#include "../sprites.hpp"
#include "../../sdlpp/sdlpp_textrenderer.hpp"
class CoinEditorBlock : public MarioBlock {
public:
CoinEditorBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> renderer);
void render() override;
void updateSizeAndPosition() override;
void addOne();
void subtractOne();
void setAmount(int amount);
void onScrollUp() override;
void onScrollDown() override;
uint8_t getData() const override;
void setData(uint8_t data) override;
private:
void updateText();
int _amount = 1;
std::shared_ptr<SDLPP::TextRenderer> _amount_text;
constexpr static double size_divisor = 1.5;
constexpr static uint8_t max_amount = 15;
};
#endif
+70
View File
@@ -0,0 +1,70 @@
#include "fireball.hpp"
#include "../sprites.hpp"
#include "../global_vars.hpp"
#include "../objectids.hpp"
#include "../visitors/projectile_visitor.hpp"
Fireball::Fireball(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_items_texture, FIRE_BALL_ANIM[3]) {
setHidden(true);
ensureCollision();
setSize({BLOCK_SIZE/2, BLOCK_SIZE/2});
setId(FIREBALL_ID);
setBouncable(true);
setAnimationFrames(FIRE_BALL_ANIM);
setAnimationSpeed(16);
resumeAnimation();
setOnGround(false);
auto bottom_detect = SDLPP::RectColider(0.2, 1, 0.6, 0, NPC_FLOOR_DETECT);
bottom_detect.setColor("#FF0000");
bottom_detect.setOutlineColor("#FF0000");
bottom_detect.setMinHeight(1);
addCollision(bottom_detect);
addCollision(SDLPP::RectColider(0, 0.25, 0.1, 0.6, NPC_LEFT_SIDE_DETECT));
addCollision(
SDLPP::RectColider(0.9, 0.25, 0.1, 0.6, NPC_RIGHT_SIDE_DETECT));
jump_movement = movementSpeed;
}
void Fireball::custom_move(int ticks) {
ticks_till_death -= ticks;
if (ticks_till_death <= 0) {
destroy();
}
gravity(ticks);
MarioBlock::custom_move(ticks);
}
void Fireball::setMovementDir(bool left) {
setMovement(movementSpeed / 2 * (left ? -1 : 1), 0);
}
void Fireball::handleVisitor(SDLPP::Visitor &visitor) {
#ifndef EDITOR
// TODO -
// https://web.archive.org/web/20130807122227/http://i276.photobucket.com/albums/kk21/jdaster64/smb_playerphysics.png
auto &p_visitor = dynamic_cast<ProjectileVisitor &>(visitor);
// handle gravity
setOnGround(p_visitor.isOnGround());
if(p_visitor.isOnGround() && jump_movement > movementSpeed/16) {
setMovement(getMovement().getX(), -jump_movement);
setPos(getPos() - SDLPP::Vec2D<double>(0, jump_movement * BLOCK_SIZE));
jump_movement /= 2;
setOnGround(false);
}
if (p_visitor.canGoLeft() != p_visitor.canGoRight()) {
if(p_visitor.canGoLeft()) {
// we only want to be the size of the fireball left of the blockage
setPos(-1 * getDoubleRect().second.getX() + p_visitor.getMovementBlockage().getX(), getPos().getY());
} else {
// we want to be size of the blockage away from the blockage
setPos(BLOCK_SIZE + p_visitor.getMovementBlockage().getX(), getPos().getY());
}
setMovementDir(getMovement().getX() > 0);
}
if (p_visitor.getDeath()) {
destroy();
}
#endif
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef FIREBALL_HPP
#define FIREBALL_HPP
#include "../blocks.hpp"
class Fireball : public MarioBlock {
public:
Fireball(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
void custom_move(int ticks) override;
void handleVisitor(SDLPP::Visitor &visitor) override;
void setMovementDir(bool left);
private:
double jump_movement;
bool jumping = false;
long ticks_till_death = 3100;
};
#endif
+86
View File
@@ -0,0 +1,86 @@
#include "goombablock.hpp"
#include "../sprites.hpp"
#include "../global_vars.hpp"
#include "../objectids.hpp"
#include "../visitors/goomba_visitor.hpp"
GoombaBlock::GoombaBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_enemies_texture, GOOMBA_WALK_ANIM[0],
false, false) {
#ifndef EDITOR
setAnimationFrames(GOOMBA_WALK_ANIM);
setAnimationSpeed(12.5);
resumeAnimation();
#endif
setId(GOOMBA_ID);
auto bottom_detect = SDLPP::RectColider(0.2, 1, 0.6, 0, NPC_FLOOR_DETECT);
bottom_detect.setMinHeight(1);
addCollision(bottom_detect);
addCollision(SDLPP::RectColider(0, 0.25, 0.1, 0.6, NPC_LEFT_SIDE_DETECT));
addCollision(
SDLPP::RectColider(0.9, 0.25, 0.1, 0.6, NPC_RIGHT_SIDE_DETECT));
addCollision(std::make_shared<SDLPP::RectColider>(0.35, 0, 0.3, 0.15,
NPC_TOP_DETECT));
setBouncable(false);
#ifndef EDITOR
setMovement(-0.19, 0);
#endif
}
void GoombaBlock::move(int ticks) {
#ifndef EDITOR
if (wasVisible()) {
MarioBlock::move(ticks);
}
#else
MarioBlock::move(ticks);
#endif
}
void GoombaBlock::custom_move(int ticks) {
#ifndef EDITOR
if (death_started) {
death_countdown -= ticks;
if (death_countdown <= 0) {
destroy();
}
} else {
gravity(ticks);
}
#endif
MarioBlock::custom_move(ticks);
}
void GoombaBlock::handleVisitor(SDLPP::Visitor &visitor) {
#ifndef EDITOR
auto &g_visitor = dynamic_cast<GoombaVisitor &>(visitor);
setOnGround(g_visitor.isOnGround());
if (isOnGround()) {
setPos(getPos().getX(), g_visitor.getGroundY() - BLOCK_SIZE);
}
if ((!g_visitor.canGoLeft() && getMovement().getX() < 0) ||
(!g_visitor.canGoRight() && getMovement().getX() > 0)) {
setPos(g_visitor.getValidXPos(), getPos().getY());
setMovement(-getMovement().getX(), getMovement().getY());
}
if (g_visitor.shouldBounce()) {
setMovement(getMovement().getX(), -0.5);
}
if (g_visitor.isDead()) {
removeCollisions();
pauseAnimation();
setBaseRect(GOOMBA_DEATH_SRC);
setMovement(0, getMovement().getY());
startDeath();
// destroy();
}
if (g_visitor.instantDeath()) {
destroy();
}
#endif
}
void GoombaBlock::startDeath() {
death_started = true;
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef GOOMBA_BLOCK_HPP
#define GOOMBA_BLOCK_HPP
#include "../blocks.hpp"
class GoombaBlock : public MarioBlock {
public:
GoombaBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
void custom_move(int ticks) override;
void move(int ticks) override;
void handleVisitor(SDLPP::Visitor &visitor) override;
private:
void startDeath();
int death_countdown = 100;
bool death_started = false;
};
#endif
+64
View File
@@ -0,0 +1,64 @@
#include "mushroomblock.hpp"
#include "../sprites.hpp"
#include "../global_vars.hpp"
#include "../objectids.hpp"
#include "../visitors/mushroom_visitor.hpp"
MushroomBlock::MushroomBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, MUSHROOM_SRC, true,
true) {
setHidden(true);
ensureCollision();
setId(MUSHROOM_ID);
auto bottom_detect = SDLPP::RectColider(0.2, 1, 0.6, 0, NPC_FLOOR_DETECT);
bottom_detect.setColor("#FF0000");
bottom_detect.setOutlineColor("#FF0000");
bottom_detect.setMinHeight(1);
addCollision(bottom_detect);
addCollision(SDLPP::RectColider(0, 0.25, 0.1, 0.6, NPC_LEFT_SIDE_DETECT));
addCollision(
SDLPP::RectColider(0.9, 0.25, 0.1, 0.6, NPC_RIGHT_SIDE_DETECT));
}
void MushroomBlock::custom_move(int ticks) {
if (_parent != nullptr && !_parent->isBouncing() && !isTraveling()) {
setHidden(false);
travelToPos(_parent->getPos() - SDLPP::Vec2D<double>(0, BLOCK_SIZE));
_parent = nullptr;
} else if (_parent == nullptr && !isTraveling() && !_started_movement) {
_started_movement = true;
if(!_fire_flower) {
setMovement(movementSpeed / 4, 0);
}
}
gravity(ticks);
MarioBlock::custom_move(ticks);
}
void MushroomBlock::setParent(MarioBlock *parent) {
_parent = parent;
}
void MushroomBlock::handleVisitor(SDLPP::Visitor &visitor) {
auto &m_visitor = dynamic_cast<MushroomVisitor &>(visitor);
if (m_visitor.getDeath()) {
destroy();
}
if (!_started_movement) {
return;
}
setOnGround(m_visitor.isOnGround());
if (isOnGround()) {
setPos(getPos().getX(), m_visitor.getGroundY() - BLOCK_SIZE);
}
if (!m_visitor.canGoLeft() || !m_visitor.canGoRight()) {
setPos(m_visitor.getValidXPos(), getPos().getY());
setMovement(-getMovement().getX(), getMovement().getY());
}
}
void MushroomBlock::setFireFlower(bool fire_flower) {
setTextureSourceRect(fire_flower ? FIRE_FLOWER_SRC : MUSHROOM_SRC);
_fire_flower = fire_flower;
}
+20
View File
@@ -0,0 +1,20 @@
#ifndef MUSHROOM_BLOCK_HPP
#define MUSHROOM_BLOCK_HPP
#include "../blocks.hpp"
class MushroomBlock : public MarioBlock {
public:
MushroomBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
void custom_move(int ticks) override;
void setParent(MarioBlock *parent);
void handleVisitor(SDLPP::Visitor &visitor) override;
void setFireFlower(bool fire_flower);
private:
MarioBlock *_parent = nullptr;
bool _started_movement = false;
bool _fire_flower = false;
};
#endif
+472
View File
@@ -0,0 +1,472 @@
#include "simpleblocks.hpp"
#include "../global_vars.hpp"
#include "../sprites.hpp"
#include "../objectids.hpp"
FloorBlock::FloorBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, FLOOR_SRC, true) {
ensureCollision();
setId(FLOOR_ID);
}
HillInclineBlock::HillInclineBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, HILL_INCLINE_SRC,
false) {
setId(HILL_INCLINE_ID);
}
HillDeclineBlock::HillDeclineBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, HILL_DECLINE_SRC,
false) {
setId(HILL_INCLINE_ID);
}
HillDotsRightBlock::HillDotsRightBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, HILL_DOTS_RIGHT_SRC,
false) {
setId(HILL_DOTS_RIGHT_ID);
}
HillDotsLeftBlock::HillDotsLeftBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, HILL_DOTS_LEFT_SRC,
false) {
setId(HILL_DOTS_LEFT_ID);
}
HillFillBlock::HillFillBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, HILL_FILL_SRC, false) {
setId(HILL_FILL_ID);
}
HillTopBlock::HillTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, HILL_TOP_SRC, false) {
setId(HILL_TOP_ID);
}
BushLeftBlock::BushLeftBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, BUSH_LEFT_SRC, false) {
setId(BUSH_LEFT_ID);
}
BushMiddleBlock::BushMiddleBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, BUSH_MIDDLE_SRC,
false) {
setId(BUSH_MIDDLE_ID);
}
BushRightBlock::BushRightBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, BUSH_RIGHT_SRC, false) {
setId(BUSH_RIGHT_ID);
}
CloudLeftBottomBlock::CloudLeftBottomBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CLOUD_LEFT_BOTTOM_SRC,
false) {
setId(CLOUD_LEFT_BOTTOM_ID);
}
CloudMiddleBottomBlock::CloudMiddleBottomBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CLOUD_MIDDLE_BOTTOM_SRC,
false) {
setId(CLOUD_MIDDLE_BOTTOM_ID);
}
CloudRightBottomBlock::CloudRightBottomBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CLOUD_RIGHT_BOTTOM_SRC,
false) {
setId(CLOUD_RIGHT_BOTTOM_ID);
}
CloudLeftTopBlock::CloudLeftTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CLOUD_LEFT_TOP_SRC,
false) {
setId(CLOUD_LEFT_TOP_ID);
}
CloudMiddleTopBlock::CloudMiddleTopBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CLOUD_MIDDLE_TOP_SRC,
false) {
setId(CLOUD_MIDDLE_TOP_ID);
}
CloudRightTopBlock::CloudRightTopBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CLOUD_RIGHT_TOP_SRC,
false) {
setId(CLOUD_RIGHT_TOP_ID);
}
PipeLeftBottomBlock::PipeLeftBottomBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, PIPE_LEFT_BOTTOM_SRC,
false) {
ensureCollision();
setId(PIPE_LEFT_BOTTOM_ID);
}
PipeRightBottomBlock::PipeRightBottomBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, PIPE_RIGHT_BOTTOM_SRC,
false) {
ensureCollision();
setId(PIPE_RIGHT_BOTTOM_ID);
}
PipeLeftTopBlock::PipeLeftTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, PIPE_LEFT_TOP_SRC,
false) {
ensureCollision();
setId(PIPE_LEFT_TOP_ID);
}
PipeRightTopBlock::PipeRightTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, PIPE_RIGHT_TOP_SRC,
false) {
ensureCollision();
setId(PIPE_RIGHT_TOP_ID);
}
CastleLeftBlock::CastleLeftBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CASTLE_LEFT_SRC,
false) {
setId(CASTLE_LEFT_ID);
}
CastleRightBlock::CastleRightBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CASTLE_RIGHT_SRC,
false) {
setId(CASTLE_RIGHT_ID);
}
CastleBlackBlock::CastleBlackBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CASTLE_BLACK_SRC,
false) {
setId(CASTLE_BLACK_ID);
}
CastleEntryBlock::CastleEntryBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CASTLE_ENTRY_SRC,
false) {
setId(CASTLE_ENTRY_ID);
}
CastleTowerBlock::CastleTowerBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CASTLE_TOWER_SRC,
false) {
setId(CASTLE_TOWER_ID);
}
CastleTowerFilledBlock::CastleTowerFilledBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CASTLE_TOWER_FILLED_SRC,
false) {
setId(CASTLE_TOWER_FILLED_ID);
}
VineTopBlock::VineTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, VINE_TOP_SRC, false) {
ensureCollision();
setId(VINE_TOP_ID);
setBouncable(false);
}
VineBottomBlock::VineBottomBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, VINE_BOTTOM_SRC,
false) {
ensureCollision();
setId(VINE_BOTTOM_ID);
setBouncable(false);
}
PoleTopBlock::PoleTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, POLE_TOP_SRC, false) {
ensureCollision();
setId(POLE_TOP_ID);
setBouncable(false);
}
PoleBottomBlock::PoleBottomBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, POLE_BOTTOM_SRC,
false) {
ensureCollision();
setId(POLE_BOTTOM_ID);
setBouncable(false);
}
FlagBlock::FlagBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, FLAG_SRC, false) {
setId(FLAG_ID);
setBouncable(false);
}
StepBlock::StepBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, STEP_SRC, true) {
ensureCollision();
setId(STEP_ID);
}
BrickBlock::BrickBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, BRICK_SRC, true) {
ensureCollision();
setId(BRICK_ID);
}
BrickTopBlock::BrickTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, BRICK_TOP_SRC, true) {
ensureCollision();
setId(BRICK_TOP_ID);
}
SidewayPipeEndTopBlock::SidewayPipeEndTopBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
SIDEWAY_PIPE_END_TOP_SRC, false) {
ensureCollision();
setId(SIDEWAY_PIPE_END_TOP_ID);
}
SidewayPipeEndBottomBlock::SidewayPipeEndBottomBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
SIDEWAY_PIPE_END_BOTTOM_SRC, false) {
ensureCollision();
setId(SIDEWAY_PIPE_END_BOTTOM_ID);
}
SidewayPipeMiddleTopBlock::SidewayPipeMiddleTopBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
SIDEWAY_PIPE_MIDDLE_TOP_SRC, false) {
ensureCollision();
setId(SIDEWAY_PIPE_MIDDLE_TOP_ID);
}
SidewayPipeMiddleBottomBlock::SidewayPipeMiddleBottomBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
SIDEWAY_PIPE_MIDDLE_BOTTOM_SRC, false) {
ensureCollision();
setId(SIDEWAY_PIPE_MIDDLE_BOTTOM_ID);
}
SidewayPipeConnectorTopBlock::SidewayPipeConnectorTopBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
SIDEWAY_PIPE_CONNECTOR_TOP_SRC, false) {
ensureCollision();
setId(SIDEWAY_PIPE_CONNECTOR_TOP_ID);
}
SidewayPipeConnectorBottomBlock::SidewayPipeConnectorBottomBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
SIDEWAY_PIPE_CONNECTOR_BOTTOM_SRC, false) {
ensureCollision();
setId(SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID);
}
TreePlatformTopLeftBlock::TreePlatformTopLeftBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
TREE_PLATFORM_TOP_LEFT_SRC, false) {
ensureCollision();
setId(TREE_PLATFORM_TOP_LEFT_ID);
setBouncable(false);
}
TreePlatformTopMiddleBlock::TreePlatformTopMiddleBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
TREE_PLATFORM_TOP_MIDDLE_SRC, false) {
ensureCollision();
setId(TREE_PLATFORM_TOP_MIDDLE_ID);
setBouncable(false);
}
TreePlatformTopRightBlock::TreePlatformTopRightBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
TREE_PLATFORM_TOP_RIGHT_SRC, false) {
ensureCollision();
setId(TREE_PLATFORM_TOP_RIGHT_ID);
setBouncable(false);
}
TreePlatformBarkBlock::TreePlatformBarkBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, TREE_PLATFORM_BARK_SRC,
false) {
ensureCollision();
setId(TREE_PLATFORM_BARK_ID);
setBouncable(false);
}
WaterTopBlock::WaterTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, WATER_TOP_SRC, false) {
ensureCollision();
setId(WATER_TOP_ID);
setBouncable(false);
}
WaterFillBlock::WaterFillBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, WATER_FILL_SRC, false) {
ensureCollision();
setId(WATER_FILL_ID);
setBouncable(false);
}
MushroomPlatformTopLeftBlock::MushroomPlatformTopLeftBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
MUSHROOM_PLATFORM_TOP_LEFT_SRC, false) {
ensureCollision();
setId(MUSHROOM_PLATFORM_TOP_LEFT_ID);
setBouncable(false);
}
MushroomPlatformTopMiddleBlock::MushroomPlatformTopMiddleBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
MUSHROOM_PLATFORM_TOP_MIDDLE_SRC, false) {
ensureCollision();
setId(MUSHROOM_PLATFORM_TOP_MIDDLE_ID);
setBouncable(false);
}
MushroomPlatformTopRightBlock::MushroomPlatformTopRightBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
MUSHROOM_PLATFORM_TOP_RIGHT_SRC, false) {
ensureCollision();
setId(MUSHROOM_PLATFORM_TOP_RIGHT_ID);
setBouncable(false);
}
MushroomPlatformBarkTopBlock::MushroomPlatformBarkTopBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
MUSHROOM_PLATFORM_BARK_TOP_SRC, false) {
ensureCollision();
setId(MUSHROOM_PLATFORM_BARK_TOP_ID);
setBouncable(false);
}
MushroomPlatformBarkBottomBlock::MushroomPlatformBarkBottomBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture,
MUSHROOM_PLATFORM_BARK_BOTTOM_SRC, false) {
ensureCollision();
setId(MUSHROOM_PLATFORM_BARK_BOTTOM_ID);
setBouncable(false);
}
TreeBarkBlock::TreeBarkBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, TREE_BARK_SRC, false) {
ensureCollision();
setId(TREE_BARK_ID);
setBouncable(false);
}
TreeLeavesSmallBlock::TreeLeavesSmallBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, TREE_LEAVES_SMALL_SRC,
false) {
ensureCollision();
setId(TREE_LEAVES_SMALL_ID);
setBouncable(false);
}
TreeLeavesTopBlock::TreeLeavesTopBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, TREE_LEAVES_TOP_SRC,
false) {
ensureCollision();
setId(TREE_LEAVES_TOP_ID);
setBouncable(false);
}
TreeLeavesBottomBlock::TreeLeavesBottomBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, TREE_LEAVES_BOTTOM_SRC,
false) {
ensureCollision();
setId(TREE_LEAVES_BOTTOM_ID);
setBouncable(false);
}
CannonTowerBlock::CannonTowerBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CANNON_TOWER_SRC,
false) {
ensureCollision();
setId(CANNON_TOWER_ID);
}
CannonPedestalBlock::CannonPedestalBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CANNON_PEDESTAL_SRC,
false) {
ensureCollision();
setId(CANNON_PEDESTAL_ID);
}
CannonBlock::CannonBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, CANNON_SRC, false) {
ensureCollision();
setId(CANNON_ID);
}
DestructibleModifierBlock::DestructibleModifierBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_mod_texture, MOD_DESTRUCTIBLE_SRC,
false) {
setId(DESTRUCTIBLE_MODIFIER_ID);
}
BackgroundModifierBlock::BackgroundModifierBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_mod_texture, MOD_BACKGROUND_SRC, false) {
setId(BACKGROUND_MODIFIER_ID);
}
MushroomModifierBlock::MushroomModifierBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_mod_texture, MOD_MUSHROOM_SRC, false) {
setId(MUSHROOM_MODIFIER_ID);
}
TeleportModifierBlock::TeleportModifierBlock(
int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_mod_texture, MOD_TELEPORT_SRC, false) {
setId(TELEPORT_MODIFIER_ID);
}
+349
View File
@@ -0,0 +1,349 @@
#ifndef SIMPLE_BLOCKS_HPP
#define SIMPLE_BLOCKS_HPP
#include "../blocks.hpp"
class FloorBlock : public MarioBlock {
public:
FloorBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class HillInclineBlock : public MarioBlock {
public:
HillInclineBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class HillDeclineBlock : public MarioBlock {
public:
HillDeclineBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class HillDotsRightBlock : public MarioBlock {
public:
HillDotsRightBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class HillDotsLeftBlock : public MarioBlock {
public:
HillDotsLeftBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class HillFillBlock : public MarioBlock {
public:
HillFillBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class HillTopBlock : public MarioBlock {
public:
HillTopBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class BushLeftBlock : public MarioBlock {
public:
BushLeftBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class BushMiddleBlock : public MarioBlock {
public:
BushMiddleBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class BushRightBlock : public MarioBlock {
public:
BushRightBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CloudLeftBottomBlock : public MarioBlock {
public:
CloudLeftBottomBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CloudMiddleBottomBlock : public MarioBlock {
public:
CloudMiddleBottomBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CloudRightBottomBlock : public MarioBlock {
public:
CloudRightBottomBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CloudLeftTopBlock : public MarioBlock {
public:
CloudLeftTopBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CloudMiddleTopBlock : public MarioBlock {
public:
CloudMiddleTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CloudRightTopBlock : public MarioBlock {
public:
CloudRightTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class PipeLeftBottomBlock : public MarioBlock {
public:
PipeLeftBottomBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class PipeRightBottomBlock : public MarioBlock {
public:
PipeRightBottomBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class PipeLeftTopBlock : public MarioBlock {
public:
PipeLeftTopBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class PipeRightTopBlock : public MarioBlock {
public:
PipeRightTopBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CastleLeftBlock : public MarioBlock {
public:
CastleLeftBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CastleRightBlock : public MarioBlock {
public:
CastleRightBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CastleBlackBlock : public MarioBlock {
public:
CastleBlackBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CastleEntryBlock : public MarioBlock {
public:
CastleEntryBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CastleTowerBlock : public MarioBlock {
public:
CastleTowerBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CastleTowerFilledBlock : public MarioBlock {
public:
CastleTowerFilledBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class VineTopBlock : public MarioBlock {
public:
VineTopBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class VineBottomBlock : public MarioBlock {
public:
VineBottomBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class PoleTopBlock : public MarioBlock {
public:
PoleTopBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class PoleBottomBlock : public MarioBlock {
public:
PoleBottomBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class FlagBlock : public MarioBlock {
public:
FlagBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class StepBlock : public MarioBlock {
public:
StepBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class BrickBlock : public MarioBlock {
public:
BrickBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class BrickTopBlock : public MarioBlock {
public:
BrickTopBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class SidewayPipeEndTopBlock : public MarioBlock {
public:
SidewayPipeEndTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class SidewayPipeEndBottomBlock : public MarioBlock {
public:
SidewayPipeEndBottomBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class SidewayPipeMiddleTopBlock : public MarioBlock {
public:
SidewayPipeMiddleTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class SidewayPipeMiddleBottomBlock : public MarioBlock {
public:
SidewayPipeMiddleBottomBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class SidewayPipeConnectorTopBlock : public MarioBlock {
public:
SidewayPipeConnectorTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class SidewayPipeConnectorBottomBlock : public MarioBlock {
public:
SidewayPipeConnectorBottomBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class TreePlatformTopLeftBlock : public MarioBlock {
public:
TreePlatformTopLeftBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class TreePlatformTopMiddleBlock : public MarioBlock {
public:
TreePlatformTopMiddleBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class TreePlatformTopRightBlock : public MarioBlock {
public:
TreePlatformTopRightBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class TreePlatformBarkBlock : public MarioBlock {
public:
TreePlatformBarkBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class WaterTopBlock : public MarioBlock {
public:
WaterTopBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class WaterFillBlock : public MarioBlock {
public:
WaterFillBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class MushroomPlatformTopLeftBlock : public MarioBlock {
public:
MushroomPlatformTopLeftBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class MushroomPlatformTopMiddleBlock : public MarioBlock {
public:
MushroomPlatformTopMiddleBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class MushroomPlatformTopRightBlock : public MarioBlock {
public:
MushroomPlatformTopRightBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class MushroomPlatformBarkTopBlock : public MarioBlock {
public:
MushroomPlatformBarkTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class MushroomPlatformBarkBottomBlock : public MarioBlock {
public:
MushroomPlatformBarkBottomBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class TreeBarkBlock : public MarioBlock {
public:
TreeBarkBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class TreeLeavesSmallBlock : public MarioBlock {
public:
TreeLeavesSmallBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class TreeLeavesTopBlock : public MarioBlock {
public:
TreeLeavesTopBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class TreeLeavesBottomBlock : public MarioBlock {
public:
TreeLeavesBottomBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CannonTowerBlock : public MarioBlock {
public:
CannonTowerBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CannonPedestalBlock : public MarioBlock {
public:
CannonPedestalBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class CannonBlock : public MarioBlock {
public:
CannonBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
};
//------------------ MODS------------------------------------------------------
class DestructibleModifierBlock : public MarioBlock {
public:
DestructibleModifierBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class BackgroundModifierBlock : public MarioBlock {
public:
BackgroundModifierBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class MushroomModifierBlock : public MarioBlock {
public:
MushroomModifierBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
class TeleportModifierBlock : public MarioBlock {
public:
TeleportModifierBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer);
};
#endif
+116
View File
@@ -0,0 +1,116 @@
#include "turtleblock.hpp"
#include "../sprites.hpp"
#include "../global_vars.hpp"
#include "../objectids.hpp"
#include "../visitors/turtle_visitor.hpp"
TurtleBlock::TurtleBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y-1, renderer, g_enemies_texture, TURTLE_WALK_ANIM[0],
false, false) {
setSize({BLOCK_SIZE, 2*BLOCK_SIZE});
#ifndef EDITOR
setAnimationFrames(TURTLE_WALK_ANIM);
setAnimationSpeed(12.5);
resumeAnimation();
#endif
setId(TURTLE_ID);
auto bottom_detect = SDLPP::RectColider(0.2, 1, 0.6, 0, NPC_FLOOR_DETECT);
bottom_detect.setMinHeight(1);
addCollision(bottom_detect);
addCollision(SDLPP::RectColider(0, 0.5, 0.1, 0.35, NPC_LEFT_SIDE_DETECT));
addCollision(
SDLPP::RectColider(0.9, 0.5, 0.1, 0.35, NPC_RIGHT_SIDE_DETECT));
addCollision(std::make_shared<SDLPP::RectColider>(0, 0.25, 1, 0.15,
NPC_TOP_DETECT));
setBouncable(false);
#ifndef EDITOR
setMovement(-0.19, 0);
#endif
}
void TurtleBlock::move(int ticks) {
#ifndef EDITOR
if (wasVisible()) {
MarioBlock::move(ticks);
}
#else
MarioBlock::move(ticks);
#endif
}
void TurtleBlock::custom_move(int ticks) {
#ifndef EDITOR
if (death_started) {
death_countdown -= ticks;
if (death_countdown <= 0) {
destroy();
}
} else {
gravity(ticks);
}
#endif
MarioBlock::custom_move(ticks);
}
void TurtleBlock::handleVisitor(SDLPP::Visitor &visitor) {
#ifndef EDITOR
switched_after_turtle = false;
auto &t_visitor = dynamic_cast<TurtleVisitor &>(visitor);
setOnGround(t_visitor.isOnGround());
if (isOnGround()) {
setPos(getPos().getX(), t_visitor.getGroundY() - BLOCK_SIZE*(isShell() ? 1 : 2));
}
if ((!t_visitor.canGoLeft() && getMovement().getX() < 0) ||
(!t_visitor.canGoRight() && getMovement().getX() > 0)) {
setPos(t_visitor.getValidXPos(), getPos().getY());
setMovement(-getMovement().getX(), getMovement().getY());
flipHorizontally();
}
if (t_visitor.shouldBounce()) {
setMovement(getMovement().getX(), -0.5);
}
if (t_visitor.isDead()) {
if(!isShell()) {
setShell();
// pauseAnimation();
setAnimationFrames(TURTLE_SHELL_ANIM);
setAnimationSpeed(4);
next_movement = -2 * getMovement().getX();
setMovement(0, 0);
setSize({BLOCK_SIZE, BLOCK_SIZE});
setPos(getPos().getX(), getPos().getY() + BLOCK_SIZE);
} else {
if(getMovement().getX() == 0) {
resumeAnimation();
setMovement(next_movement, 0);
} else {
pauseAnimation();
next_movement = -next_movement;
setMovement(0, 0);
setTextureSourceRect(TURTLE_SHELL_ANIM[2]);
}
}
}
if (t_visitor.instantDeath()) {
destroy();
}
if (t_visitor.switchMovement()) {
if (isShell()) {
switched_after_turtle = true;
if(getMovement().getX() == 0) {
setMovement(t_visitor.getNextMovement(), getMovement().getY());
} else {
setMovement(-getMovement().getX(), getMovement().getY());
}
setPos(t_visitor.getTurtleHitValidPos(), getPos().getY());
} else {
destroy();
}
}
#endif
}
void TurtleBlock::startDeath() {
death_started = true;
}
+35
View File
@@ -0,0 +1,35 @@
#ifndef TURTLE_BLOCK_HPP
#define TURTLE_BLOCK_HPP
#include "../blocks.hpp"
class TurtleBlock : public MarioBlock {
public:
TurtleBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer);
void custom_move(int ticks) override;
void move(int ticks) override;
void handleVisitor(SDLPP::Visitor &visitor) override;
bool isShell() const {
return is_shell;
}
void setShell(bool shell = true) {
is_shell = shell;
}
double getMovementAfterSwitch() const {
if(switched_after_turtle) {
return -getMovement().getX();
} else {
return getMovement().getX();
}
}
private:
void startDeath();
int death_countdown = 100;
bool death_started = false;
bool is_shell = false;
double next_movement = 0;
bool switched_after_turtle = false;
};
#endif
+26
View File
@@ -0,0 +1,26 @@
#include "edit_box.hpp"
#include "objectids.hpp"
#include "blocks.hpp"
#include "sprites.hpp"
EditBox::EditBox(int x, int y, float start_x, float start_y, int map_width,
int map_height, std::shared_ptr<SDLPP::Renderer> renderer)
: SDLPP::RectangleRender(start_x + x * BLOCK_SIZE,
start_y + y * BLOCK_SIZE, BLOCK_SIZE,
BLOCK_SIZE, renderer) {
_x = x;
_y = y;
setId(EDITOR_EDIT_SQUARE);
setColiderColor("#FF00AA");
setPermanent();
setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
addCollision(SDLPP::RectColider(0, 0, 1, 1));
}
SDLPP::Vec2D<int> EditBox::getIndexes() const {
return { _x, _y };
}
void EditBox::visit(SDLPP::Visitor &visitor) {
visitor.visit(*this);
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef EDIT_BOX_H
#define EDIT_BOX_H
#include "../sdlpp/sdlpp.hpp"
class EditBox : public SDLPP::RectangleRender {
public:
EditBox(int x, int y, float start_x, float start_y, int map_width,
int map_height, std::shared_ptr<SDLPP::Renderer> renderer);
virtual SDLPP::Vec2D<int> getIndexes() const;
virtual void visit(SDLPP::Visitor &visitor) override;
private:
int _x;
int _y;
};
#endif
+117
View File
@@ -0,0 +1,117 @@
#include "../sdlpp/sdlpp.hpp"
#include "global_vars.hpp"
#include "gui/gui.hpp"
#include "sprites.hpp"
#include <memory>
#ifdef _WIN32
#include "../sdlpp/SDL2/SDL2_framerate.h"
#include <ctime>
#include <string>
#include <windows.h>
#else
#include <SDL2/SDL2_framerate.h>
#endif // UNIX
#include <array>
#include <thread>
#include <mutex>
#include "objectids.hpp"
#include "blocks.hpp"
#include "maploader.hpp"
#include "../sdlpp/sdlpp_mouse.hpp"
#include "edit_box.hpp"
#include "editor_visitor.hpp"
#include "tool_box.hpp"
#include "blocks/coineditorblock.hpp"
#include "scenes/editor_scenes.hpp"
std::vector<SceneStruct> game_scenes{};
void doInput() {
FPSmanager gFPS;
SDL_initFramerate(&gFPS);
SDL_setFramerate(&gFPS, 200);
while (!g_quit) {
SDL_framerateDelay(&gFPS);
game_scenes.back().doInput(game_scenes.back().scene);
game_scenes.back().scene->updateScene();
}
}
#ifdef _WIN32
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR szCmdLine, int nCmdShow) {
#else
int main() {
#endif
SDLPP::init();
SDLPP::Window w("Mario editor!");
w.setResizable(true);
BLOCK_SIZE = 1.0 / 26;
auto font = std::make_shared<SDLPP::Font>("testfont.ttf", 36);
g_text_config = std::make_shared<SDLPP::FontConfiguration>(font, "#FFFFFF",
"#000000", 0.15);
auto renderer = std::make_shared<SDLPP::Renderer>(w);
renderer->setBlendMode(SDL_BLENDMODE_BLEND);
// prepare global vars
g_terrain_texture = std::make_shared<SDLPP::Texture>(
renderer, "sprites/terrain.png", MARIO_OVERWORLD_COLORKEY);
g_mario_texture = std::make_shared<SDLPP::Texture>(
renderer, "sprites/mario.png", MARIO_OVERWORLD_COLORKEY);
g_mod_texture =
std::make_shared<SDLPP::Texture>(renderer, "sprites/mods.png");
g_enemies_texture = std::make_shared<SDLPP::Texture>(
renderer, "sprites/enemies.png", MARIO_OVERWORLD_COLORKEY);
g_translucent_terrain_texture = std::make_shared<SDLPP::Texture>(
renderer, "sprites/terrain.png", MARIO_OVERWORLD_COLORKEY);
g_translucent_terrain_texture->setAlpha(100);
g_translucent_mod_texture =
std::make_shared<SDLPP::Texture>(renderer, "sprites/mods.png");
g_translucent_mod_texture->setAlpha(100);
g_translucent_enemies_texture = std::make_shared<SDLPP::Texture>(
renderer, "sprites/enemies.png", MARIO_OVERWORLD_COLORKEY);
g_translucent_enemies_texture->setAlpha(100);
game_scenes.push_back(createEditorScene(renderer));
auto base = SDL_GetTicks();
int frames = 0;
std::thread inputThread(doInput);
SDL_PumpEvents();
game_scenes.back().scene->updateSizeAndPosition();
game_scenes.back().scene->renderScene();
renderer->presentRenderer();
FPSmanager gFPS;
SDL_initFramerate(&gFPS);
SDL_setFramerate(&gFPS, 60);
while (!g_quit) {
SDL_framerateDelay(&gFPS);
SDL_PumpEvents();
std::lock_guard<std::mutex> lock(render_mutex);
auto max_game_scenes = game_scenes.size();
for (size_t i = 0; i < max_game_scenes; i++) {
game_scenes[i].additionalRender(game_scenes[i].scene);
// additional renderer can remove scene from game_scenes, better
// check
if (i < game_scenes.size()) {
game_scenes[i].scene->renderScene(false);
}
}
renderer->presentRenderer();
frames++;
if (SDL_GetTicks() - base >= 1000) {
std::cout << "FPS: " << frames << std::endl;
frames = 0;
base = SDL_GetTicks();
}
}
inputThread.join();
return 0;
}
+132
View File
@@ -0,0 +1,132 @@
#include "editor_visitor.hpp"
#include "../sdlpp/sdlpp_renderobject.hpp"
#include "blocks.hpp"
#include "objectids.hpp"
#include "edit_box.hpp"
#include "tool_box.hpp"
#include <memory>
#define SELECTED_LEFT_MAP 0x00000001
#define SELECTED_RIGHT_MAP 0x00000002
#define SELECTED_REMOVE_BLOCK 0x00000004
#define SELECTED_REMOVE_MODIFIER 0x00000008
#define SELECTED_RIGHT_TOOL 0x00000010
#define SELECTED_LEFT_TOOL 0x00000020
#define SELECTED_RIGHT_MOD 0x00000040
#define SELECTED_LEFT_MOD 0x00000080
#define SELECTED_RIGHT_CHARACTER 0x00000100
#define SELECTED_LEFT_CHARACTER 0x00000200
#define SELECTED_BUTTON 0x00000400
void MouseVisitor::visit(const SDLPP::RenderObject &obj) {
auto id = obj.getId();
switch (id) {
case EDITOR_LEFT_MAP_ID:
select_flags |= SELECTED_LEFT_MAP;
break;
case EDITOR_RIGHT_MAP_ID:
select_flags |= SELECTED_RIGHT_MAP;
break;
case EDITOR_LEFT_TOOL_ID:
select_flags |= SELECTED_LEFT_TOOL;
break;
case EDITOR_RIGHT_TOOL_ID:
select_flags |= SELECTED_RIGHT_TOOL;
break;
case EDITOR_LEFT_MOD_ID:
select_flags |= SELECTED_LEFT_MOD;
break;
case EDITOR_RIGHT_MOD_ID:
select_flags |= SELECTED_RIGHT_MOD;
break;
case EDITOR_LEFT_CHARACTER_ID:
select_flags |= SELECTED_LEFT_CHARACTER;
break;
case EDITOR_RIGHT_CHARACTER_ID:
select_flags |= SELECTED_RIGHT_CHARACTER;
break;
case EDITOR_EDIT_SQUARE:
edit_box = true;
edit_box_location = dynamic_cast<const EditBox &>(obj).getIndexes();
break;
case EDITOR_TOOL_ID:
tool_box = true;
tool_box_location = dynamic_cast<const ToolBox &>(obj).getIndexes();
tool_box_type = dynamic_cast<const ToolBox &>(obj).getType();
break;
case BUTTON_ID:
select_flags |= SELECTED_BUTTON;
cur_button = reinterpret_cast<const Button*>(&obj)->getButtonIndex();
break;
default:
break;
}
}
bool MouseVisitor::moveMapLeft(uint64_t flags) {
return flags & SELECTED_LEFT_MAP;
}
bool MouseVisitor::moveMapRight(uint64_t flags) {
return flags & SELECTED_RIGHT_MAP;
}
bool MouseVisitor::moveToolsLeft(uint64_t flags) {
return flags & SELECTED_LEFT_TOOL;
}
bool MouseVisitor::moveToolsRight(uint64_t flags) {
return flags & SELECTED_RIGHT_TOOL;
}
bool MouseVisitor::moveModsLeft(uint64_t flags) {
return flags & SELECTED_LEFT_MOD;
}
bool MouseVisitor::moveModsRight(uint64_t flags) {
return flags & SELECTED_RIGHT_MOD;
}
bool MouseVisitor::moveCharactersLeft(uint64_t flags) {
return flags & SELECTED_LEFT_CHARACTER;
}
bool MouseVisitor::moveCharactersRight(uint64_t flags) {
return flags & SELECTED_RIGHT_CHARACTER;
}
bool MouseVisitor::button(uint64_t flags) {
return flags & SELECTED_BUTTON;
}
void ToolVisitor::visit(const SDLPP::RenderObject &obj) {
auto id = obj.getCollisions()[0]->getId();
switch (id) {
case EDITOR_TERRAIN_ID: {
const auto &m_obj = dynamic_cast<const MarioBlock &>(obj);
remove_block = true;
if (obj.getId() == source_id &&
((m_obj.getType() == source_type &&
getVisitorType() == VisitorType::Terrain) ||
(m_obj.getData() == _data &&
getVisitorType() == VisitorType::Modifier))) {
add_block = false;
}
} break;
case EDITOR_CHARACTER_ID: {
const auto &m_obj = dynamic_cast<const MarioBlock &>(obj);
remove_block = true;
if (obj.getId() == source_id && m_obj.getType() == source_type &&
getVisitorType() == VisitorType::Character) {
add_block = false;
}
}
default:
break;
}
}
bool ToolVisitor::addBlock() const {
return add_block;
}
bool ToolVisitor::removeBlock() const {
return remove_block;
}
+109
View File
@@ -0,0 +1,109 @@
#ifndef EDITOR_VISITOR_H
#define EDITOR_VISITOR_H
#include "../sdlpp/sdlpp_visitor.hpp"
#include "../sdlpp/sdlpp_geometry.hpp"
#include "blocks.hpp"
#include "gui/gui.hpp"
#include <memory>
struct VisitorType {
enum Value {
Terrain = 0xE001,
Modifier = 0xE002,
Character = 0xE003,
};
};
class MouseVisitor : public SDLPP::Visitor {
public:
MouseVisitor() = default;
void visit(const SDLPP::RenderObject &obj) override;
void setFromId(uint64_t /*UNUSED*/) override {}
uint64_t getFromId() const override {
return 0;
}
uint64_t getFlags() const {
return select_flags;
}
bool foundEditBox() const {
return edit_box;
}
const SDLPP::Vec2D<int> &getEditBoxIndexes() const {
return edit_box_location;
}
bool foundToolBox() const {
return tool_box;
}
const SDLPP::Vec2D<int> &getToolBoxIndexes() const {
return tool_box_location;
}
void setVisitorType(uint64_t type) override {
_type = type;
}
uint64_t getVisitorType() const override {
return _type;
}
uint64_t getToolType() const {
return tool_box_type;
}
uint64_t getCurButton() const {
return cur_button;
}
static bool moveMapLeft(uint64_t flags);
static bool moveMapRight(uint64_t flags);
static bool moveToolsLeft(uint64_t flags);
static bool moveToolsRight(uint64_t flags);
static bool moveModsLeft(uint64_t flags);
static bool moveModsRight(uint64_t flags);
static bool moveCharactersLeft(uint64_t flags);
static bool moveCharactersRight(uint64_t flags);
static bool button(uint64_t flags);
private:
uint64_t select_flags = 0;
bool edit_box = false;
bool tool_box = false;
SDLPP::Vec2D<int> edit_box_location = { -1, -1 };
SDLPP::Vec2D<int> tool_box_location = { -1, -1 };
uint64_t _type{};
uint64_t tool_box_type = 0;
uint64_t cur_button = -1;
};
class ToolVisitor : public SDLPP::Visitor {
public:
ToolVisitor() = default;
void visit(const SDLPP::RenderObject &obj) override;
void setFromId(uint64_t id) override {
source_id = id;
}
uint64_t getFromId() const override {
return source_id;
}
void setVisitorType(uint64_t type) override {
_type = type;
}
uint64_t getVisitorType() const override {
return _type;
}
void setSourceType(LandType::Value type) {
source_type = type;
}
void setSourceData(const uint64_t &data) {
_data = data;
}
bool addBlock() const;
bool removeBlock() const;
private:
bool remove_block = false;
bool add_block = true;
uint64_t source_id = 0;
uint64_t _type = 0;
uint64_t _data = 0;
LandType::Value source_type{};
};
#endif
+127
View File
@@ -0,0 +1,127 @@
#ifndef FSLIB_H
#define FSLIB_H
#include <string>
#ifdef _WIN32
#include <Windows.h>
using string = std::wstring;
using char_t = wchar_t;
#else
#include <dirent.h>
using string = std::string;
using char_t = char;
#endif
// windows version stolen from
// http://www.martinbroadhurst.com/list-the-files-in-a-directory-in-c.html
namespace FSLib {
bool exists(const string &path);
bool isDirectory(const string &path);
bool rename(const string &file_a, const string &file_b);
bool deleteFile(const string &file);
string canonical(const string &path);
bool createDirectoryFull(const string &path);
string getContainingDirectory(const string &path);
string getFileName(const string &path);
string getFileExtension(const string &path);
extern char dir_divisor;
class Directory {
public:
Directory() = delete;
explicit Directory(const string &path_);
explicit Directory(const Directory &d) = default;
explicit Directory(Directory &&d) = default;
class Iterator {
public:
explicit Iterator(const Directory &d_);
~Iterator();
#ifdef _WIN32
explicit Iterator(bool ended_);
#else
Iterator(const Directory &d_, const struct dirent *current_entry_);
#endif
Iterator() = delete;
Iterator(const Iterator &i) = default;
Iterator(Iterator &&i) = default;
char_t const *operator*() const;
Iterator &operator++();
bool operator==(const Iterator &i_other) const;
Iterator operator++(int) {
Iterator ret(*this);
operator++();
return ret;
}
bool operator!=(const Iterator &i_other) const {
return !(i_other == *this);
}
private:
#ifndef _WIN32
DIR *d{};
const struct dirent *current_entry{};
#else
HANDLE hFind{};
WIN32_FIND_DATA data{};
bool ended{ false };
#endif
};
using iterator = Iterator;
using const_iterator = Iterator;
iterator end();
const_iterator end() const;
iterator begin() {
return Iterator(*this);
}
const_iterator begin() const {
return Iterator(*this);
}
const_iterator cbegin() const {
return begin();
}
const_iterator cend() const {
return end();
}
const char_t *path() const {
return dir_path.c_str();
}
#ifdef _WIN32
const char_t *validPath() const {
return dir_path.substr(0, dir_path.length() - 2).c_str();
}
#endif
private:
string dir_path;
};
} // namespace FSLib
#endif
+169
View File
@@ -0,0 +1,169 @@
#include "../../filesystem.hpp"
#include <cstring>
#include <sys/stat.h>
#include <unistd.h>
#ifdef __APPLE__
#include <sys/syslimits.h>
#endif
#include <stdexcept>
#include <iostream>
char FSLib::dir_divisor = '/';
FSLib::Directory::Directory(const string &path_) : dir_path(path_) {}
FSLib::Directory::Iterator::Iterator(const Directory &d_)
: d(opendir(d_.path())) {
if (!exists(d_.path()) || !isDirectory(d_.path())) {
throw std::runtime_error(std::string("Directory ") + d_.path() +
" either doesn't exist or isn't a directory");
}
current_entry = readdir(d);
// skip "." and ".."
if (current_entry != nullptr && (!strcmp(current_entry->d_name, ".") ||
!strcmp(current_entry->d_name, "..")))
++(*this);
}
FSLib::Directory::Iterator::Iterator(const Directory &d_,
const struct dirent *current_entry_)
: d(opendir(d_.path())), current_entry(current_entry_) {}
FSLib::Directory::Iterator::~Iterator() {
if (d)
closedir(d);
}
bool FSLib::exists(const string &path) {
struct stat path_stat;
return stat(path.c_str(), &path_stat) == 0;
}
string FSLib::canonical(const string &path) {
char_t *canonical_path = new char_t[PATH_MAX];
auto failed = realpath(path.c_str(), canonical_path) == nullptr;
if (failed) {
delete[] canonical_path;
return string();
}
string canonical_string{ canonical_path };
delete[] canonical_path;
return canonical_string;
}
bool FSLib::isDirectory(const string &path) {
struct stat path_stat;
if (stat(path.c_str(), &path_stat) != 0)
return false;
return S_ISDIR(path_stat.st_mode);
}
bool FSLib::rename(const string &file_a, const string &file_b) {
return ::rename(file_a.c_str(), file_b.c_str()) == 0;
}
// TODO do windows version
bool deleteRecursive(const string &dir) {
for (const auto &file : FSLib::Directory(dir)) {
auto path = dir + "/" + file;
if (FSLib::isDirectory(path)) {
if (!deleteRecursive(path)) {
return false;
}
} else if (unlink(path.c_str()) != 0) {
return false;
}
}
return rmdir(dir.c_str()) == 0;
}
bool FSLib::deleteFile(const string &file) {
// TODO log
auto canon = canonical(file);
if (canon.empty()) {
return false;
}
if (isDirectory(canon)) {
return deleteRecursive(canon);
}
return unlink(canon.c_str()) == 0;
}
bool FSLib::createDirectoryFull(const string &path) {
uint64_t pos{};
// go through all directories leading to the last one
// and create them if they don't exist
do {
// get partial directory path
pos = path.find_first_of("/", pos);
if (pos > 0) {
auto dirname = path.substr(0, pos);
// create it if it doesn't exist
if (!FSLib::exists(dirname)) {
if (mkdir(dirname.c_str(),
S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0)
return false;
}
}
pos++;
} while (pos < path.length() && pos != 0);
return true;
}
FSLib::Directory::iterator FSLib::Directory::end() {
return Iterator(*this, nullptr);
}
FSLib::Directory::const_iterator FSLib::Directory::end() const {
return Iterator(*this, nullptr);
}
char_t const *FSLib::Directory::Iterator::operator*() const {
return current_entry->d_name;
}
FSLib::Directory::Iterator &FSLib::Directory::Iterator::operator++() {
if (current_entry == nullptr)
return *this;
current_entry = readdir(d);
// skip . and ..
if (current_entry != nullptr && (!strcmp(current_entry->d_name, ".") ||
!strcmp(current_entry->d_name, "..")))
return operator++();
return *this;
}
bool FSLib::Directory::Iterator::operator==(const Iterator &i_other) const {
return i_other.current_entry == current_entry;
}
string FSLib::getContainingDirectory(const string &path) {
auto pos = path.find_last_of('/');
if (pos == string::npos) {
return ".";
}
return path.substr(0, pos);
}
string FSLib::getFileName(const string &path) {
auto pos = path.find_last_of('/');
if (pos == string::npos) {
return path;
}
return path.substr(pos + 1);
}
string FSLib::getFileExtension(const string &path) {
auto pos = path.find_last_of('.');
if (pos == string::npos) {
return "";
}
return path.substr(pos + 1);
}
+155
View File
@@ -0,0 +1,155 @@
#include "../../filesystem.hpp"
#include <Shlwapi.h>
#include <cstring>
#include <stdexcept>
#include <windows.h>
char FSLib::dir_divisor = '\\';
FSLib::Directory::Directory(const string &path_) : dir_path(path_) {
// need to append \\* for windows to search files in directory
dir_path.append(L"\\*");
}
FSLib::Directory::Iterator::Iterator(const Directory &d_) {
if (!exists(d_.validPath()) || !isDirectory(d_.validPath())) {
throw std::runtime_error(
"Directory either doesn't exist or isn't a directory");
}
hFind = FindFirstFileW(d_.path(), &data);
if (hFind != INVALID_HANDLE_VALUE) {
if (!wcscmp(data.cFileName, L".") || !wcscmp(data.cFileName, L"..")) {
++(*this);
}
} else {
ended = true;
}
}
FSLib::Directory::Iterator::~Iterator() {
if (hFind)
FindClose(hFind);
}
// this is definitely not a good way to create the "end" iterator
// but it was the only way I thought of with my limited knowledge of
// windows.h
FSLib::Directory::Iterator::Iterator(bool ended_) : ended(ended_) {}
bool FSLib::exists(const string &path) {
struct _stat path_stat;
return _wstat(path.c_str(), &path_stat) == 0;
}
string FSLib::canonical(const string &path) {
char_t *full_path = new char_t[MAX_PATH];
char_t *canonical_path = new char_t[MAX_PATH];
auto failed = !GetFullPathName(path.c_str(), MAX_PATH, full_path, NULL);
if (failed) {
delete[] canonical_path;
delete[] full_path;
return string();
}
failed = !PathCanonicalizeW(canonical_path, full_path);
delete[] full_path;
if (failed) {
delete[] canonical_path;
return string();
}
string canonical_string{ canonical_path };
delete[] canonical_path;
return canonical_string;
}
bool FSLib::isDirectory(const string &path) {
struct _stat path_stat;
if (_wstat(path.c_str(), &path_stat) != 0)
return false;
return path_stat.st_mode & _S_IFDIR;
}
bool FSLib::rename(const string &file_a, const string &file_b) {
return MoveFileExW(file_a.c_str(), file_b.c_str(),
MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING);
}
bool FSLib::createDirectoryFull(const string &path) {
uint64_t pos = path.find_first_of(L":", 0) + 2;
if (pos == string::npos)
pos = 0;
// go through all directories leading to the last one
// and create them if they don't exist
do {
// get partial directory path
pos = path.find_first_of(L"\\", pos);
auto dirname = path.substr(0, pos);
// create it if it doesn't exist
if (!FSLib::exists(dirname)) {
if (!CreateDirectoryW(dirname.c_str(), NULL))
return false;
}
pos++;
} while (pos < path.length() && pos != 0);
return true;
}
FSLib::Directory::iterator FSLib::Directory::end() {
return Iterator(true);
}
FSLib::Directory::const_iterator FSLib::Directory::end() const {
return Iterator(true);
}
char_t const *FSLib::Directory::Iterator::operator*() const {
return data.cFileName;
}
FSLib::Directory::Iterator &FSLib::Directory::Iterator::operator++() {
if (ended == true)
return *this;
// skip . and ..
if (FindNextFileW(hFind, &data) == 0) {
ended = true;
} else if (!wcscmp(data.cFileName, L".") ||
!wcscmp(data.cFileName, L"..")) {
return operator++();
}
return *this;
}
bool FSLib::Directory::Iterator::operator==(const Iterator &i_other) const {
return i_other.ended == ended;
}
string FSLib::getContainingDirectory(const string &path) {
auto pos = path.find_last_of('\\');
if (pos == string::npos) {
return ".";
}
return path.substr(0, pos);
}
string FSLib::getFileName(const string &path) {
auto pos = path.find_last_of('\\');
if (pos == string::npos) {
return path;
}
return path.substr(pos + 1);
}
string FSLib::getFileExtension(const string &path) {
auto pos = path.find_last_of('.');
if (pos == string::npos) {
return "";
}
return path.substr(pos + 1);
}
+15
View File
@@ -0,0 +1,15 @@
#include "global_vars.hpp"
#include "../sdlpp/sdlpp_texture.hpp"
std::shared_ptr<SDLPP::Texture> g_terrain_texture{};
std::shared_ptr<SDLPP::Texture> g_mario_texture{};
std::shared_ptr<SDLPP::Texture> g_mod_texture{};
std::shared_ptr<SDLPP::Texture> g_enemies_texture{};
std::shared_ptr<SDLPP::Texture> g_items_texture{};
std::shared_ptr<SDLPP::Texture> g_translucent_terrain_texture{};
std::shared_ptr<SDLPP::Texture> g_translucent_mod_texture{};
std::shared_ptr<SDLPP::Texture> g_translucent_enemies_texture;
std::shared_ptr<SDLPP::Scene> g_playground{};
std::shared_ptr<SDLPP::FontConfiguration> g_text_config{};
bool g_quit = false;
bool g_death = false;
+19
View File
@@ -0,0 +1,19 @@
#ifndef GLOBAL_VARS_H
#define GLOBAL_VARS_H
#include "../sdlpp/sdlpp.hpp"
extern std::shared_ptr<SDLPP::Texture> g_terrain_texture;
extern std::shared_ptr<SDLPP::Texture> g_mario_texture;
extern std::shared_ptr<SDLPP::Texture> g_mod_texture;
extern std::shared_ptr<SDLPP::Texture> g_enemies_texture;
extern std::shared_ptr<SDLPP::Texture> g_items_texture;
extern std::shared_ptr<SDLPP::Texture> g_translucent_terrain_texture;
extern std::shared_ptr<SDLPP::Texture> g_translucent_mod_texture;
extern std::shared_ptr<SDLPP::Texture> g_translucent_enemies_texture;
extern std::shared_ptr<SDLPP::Scene> g_playground;
extern std::shared_ptr<SDLPP::FontConfiguration> g_text_config;
extern bool g_quit;
extern bool g_death;
#endif
+195
View File
@@ -0,0 +1,195 @@
#ifndef GUIELEMENTS
#define GUIELEMENTS
#include "../../sdlpp/sdlpp.hpp"
#include "../global_vars.hpp"
#include "../objectids.hpp"
#include <functional>
#include <utility>
enum ButtonState {
NORMAL,
HIGHLIGHTED,
DISABLED,
};
struct ButtonConfig {
std::string font_color;
std::string font_outline_color;
std::string bg_color;
std::string font_color_highlight;
std::string font_outline_color_highlight;
std::string bg_color_highlight;
std::string font_color_disabled;
std::string font_outline_color_disabled;
std::string bg_color_disabled;
double outline;
};
class Button : public SDLPP::TextRenderer {
public:
Button() = delete;
Button(double x, double y, double w, double h,
std::shared_ptr<SDLPP::Renderer> &r, const std::string &text,
const ButtonConfig &config,
std::function<void(void *, Button *)> click_fun, void *input)
: TextRenderer(x, y, w, h, r, g_text_config->getFont(), text,
config.font_color, config.font_outline_color,
config.outline),
click_fun(std::move(click_fun)), func_input(input),
config(config), button_text(text) {
setColor(config.bg_color);
setId(BUTTON_ID);
addCollision(SDLPP::RectColider(0, 0, 1, 1));
state = NORMAL;
}
void setButtonText(const std::string &text) {
button_text = text;
should_update_text = true;
}
void setFontColor(const std::string &color) {
config.font_color = color;
if (!highlighted && !disabled) {
should_update_color = true;
}
}
void setFontColorHighlight(const std::string &color) {
config.font_color_highlight = color;
if (highlighted && !disabled) {
should_update_color = true;
}
}
void setFontColorDisabled(const std::string &color) {
config.font_color_disabled = color;
if (disabled) {
should_update_color = true;
}
}
void setFontOutlineColor(const std::string &color) {
config.font_outline_color = color;
if (!highlighted && !disabled) {
should_update_color = true;
}
}
void setFontOutlineColorHighlight(const std::string &color) {
config.font_outline_color_highlight = color;
if (highlighted && !disabled) {
should_update_color = true;
}
}
void setFontOutlineColorDisabled(const std::string &color) {
config.font_outline_color_disabled = color;
if (disabled) {
should_update_color = true;
}
}
void setBackgroundColor(const std::string &color) {
config.bg_color = color;
if (!highlighted && !disabled) {
setColor(color);
}
}
void setBackgroundColorHighlight(const std::string &color) {
config.bg_color_highlight = color;
if (highlighted && !disabled) {
setColor(color);
}
}
void setBackgroundColorDisabled(const std::string &color) {
config.bg_color_disabled = color;
if (disabled) {
setColor(color);
}
}
void performFunction() {
if (!disabled) {
click_fun(func_input, this);
}
}
uint64_t getButtonIndex() const {
return _id;
}
void setButtonIndex(uint64_t id) {
_id = id;
}
void setHighlight() {
if (!disabled) {
setColor(config.bg_color_highlight);
should_update_color = true;
state = HIGHLIGHTED;
}
highlighted = true;
}
void unsetHighlight() {
if (!disabled) {
setColor(config.bg_color);
should_update_color = true;
state = NORMAL;
}
highlighted = false;
}
void disable() {
setColor(config.bg_color_disabled);
should_update_color = true;
state = DISABLED;
disabled = true;
}
void enable() {
if (!highlighted) {
setColor(config.bg_color);
should_update_color = true;
state = NORMAL;
} else {
setColor(config.bg_color_highlight);
should_update_color = true;
state = HIGHLIGHTED;
}
disabled = false;
}
void update() {
if (should_update_color) {
switch (state) {
case NORMAL:
setTextColor(g_text_config->getFont(), config.font_color,
config.font_outline_color, config.outline);
break;
case HIGHLIGHTED:
setTextColor(
g_text_config->getFont(), config.font_color_highlight,
config.font_outline_color_highlight, config.outline);
break;
case DISABLED:
setTextColor(
g_text_config->getFont(), config.font_color_disabled,
config.font_outline_color_disabled, config.outline);
default:
break;
}
}
if (should_update_text) {
changeText(button_text);
}
}
private:
std::function<void(void *, Button *)> click_fun;
void *func_input;
uint64_t _id{};
ButtonConfig config{};
bool highlighted = false;
bool disabled = false;
std::string button_text;
ButtonState state = NORMAL;
bool should_update_color = false;
bool should_update_text = false;
};
/*std::shared_ptr<SDLPP::RectangleRender>
createButton(double x, double y, double w, double h,
std::shared_ptr<SDLPP::Renderer> &r, const std::string &text,
const std::string &color, const std::string &outline_color,
const std::string &background_color,
std::function<void(void *)> click_fun, void *input);*/
#endif
+513
View File
@@ -0,0 +1,513 @@
#include "../sdlpp/sdlpp.hpp"
#include "SDL2/SDL_keycode.h"
#include "sprites.hpp"
#include <memory>
#ifdef _WIN32
#include "../sdlpp/SDL2/SDL2_framerate.h"
#include <ctime>
#include <string>
#include <windows.h>
#else
#include <SDL2/SDL2_framerate.h>
#endif // UNIX
#include <thread>
#include <mutex>
#include <unordered_set>
#include "global_vars.hpp"
#include "objectids.hpp"
#include "blocks.hpp"
#include "maploader.hpp"
#include "mario.hpp"
#include "visitors/visitor_generator.hpp"
// TODO make shared scenes
#include "scenes/game_scenes.hpp"
bool update = false;
int update_count = 0;
bool newLoaded = false;
std::shared_ptr<Mario> mario = nullptr;
std::shared_ptr<SDLPP::RectangleRender> leftStop = nullptr;
std::shared_ptr<SDLPP::Renderer> renderer = nullptr;
std::shared_ptr<SDLPP::TextRenderer> fps = nullptr;
std::shared_ptr<SDLPP::TextRenderer> coins = nullptr;
int coin_count = 0;
int global_frames = 0;
std::string last_load_level = "";
bool __right_pressed = false;
bool __left_pressed = false;
std::vector<std::shared_ptr<MarioBlock>> moving_objects = {};
std::vector<SceneStruct> game_scenes{};
std::string _teleport_level = "";
std::mutex render_mutex;
std::mutex gamescene_mutex;
void handleKeyDown(SDL_Keycode key, SDLPP::Scene &scene) {
switch (key) {
case SDLK_a:
case SDLK_LEFT:
__left_pressed = true;
mario->walkLeft();
break;
case SDLK_d:
case SDLK_RIGHT:
__right_pressed = true;
mario->walkRight();
break;
case SDLK_SPACE:
case SDLK_w:
case SDLK_UP:
mario->jump();
break;
case SDLK_s:
case SDLK_DOWN:
mario->crouch();
break;
case SDLK_r:
scene.getRenderer().setRenderColiders(
!scene.getRenderer().getRenderColiders());
break;
case SDLK_f:
if (fps) {
fps->setHidden(!fps->getHidden());
}
case SDLK_RETURN:
mario->fire();
break;
default:
break;
}
}
void handleKeyUp(SDL_Keycode key) {
switch (key) {
case SDLK_ESCAPE: {
std::lock_guard<std::mutex> lock(render_mutex);
mario->setMovement(0, mario->getMovement().getY());
game_scenes.back().scene->pauseScene();
__right_pressed = false;
__left_pressed = false;
game_scenes.push_back(
createGameMainMenuScene(renderer, false, true, true));
} break;
case SDLK_a:
case SDLK_LEFT:
if (__left_pressed) {
mario->walkRight();
__left_pressed = false;
}
break;
case SDLK_d:
case SDLK_RIGHT:
if (__right_pressed) {
mario->walkLeft();
__right_pressed = false;
}
break;
case SDLK_SPACE:
case SDLK_w:
case SDLK_UP:
mario->stopJump();
break;
case SDLK_s:
case SDLK_DOWN:
mario->uncrouch();
if(__left_pressed) {
mario->walkLeft();
}
if(__right_pressed) {
mario->walkRight();
}
break;
default:
break;
}
}
void moveToMarioPosition(SDLPP::Scene &scene,
SDLPP::Vec2D<double> &prev_mario) {
auto rendDims = renderer->getDoubleDimensions();
if (leftStop) {
auto left =
rendDims.getX() < 2.0 ? -(rendDims.getX() - 1) / 2.0 - 0.1 : -0.5;
leftStop->setPos(left, 0);
}
auto mario_pos_difference = prev_mario - mario->getAbsolutePos();
// sometimes there is a concurrency problem and prev_pos == cur_pos, in
// that case move everything so Mario is standing on the left edge of the
// screen
if (mario_pos_difference.getX() < 0.01 &&
mario_pos_difference.getX() > -0.01) {
// 0.01 is the width of visible leftStop
scene.moveEverything(-(mario->getAbsolutePos().getX() - 0.01), 0);
} else {
scene.moveEverything(mario_pos_difference.getX(), 0);
}
scene.updateSizeAndPosition();
auto left_stop_rightmost = leftStop->getDoubleRect().first.getX() +
leftStop->getDoubleRect().second.getX();
if (mario->getPos().getX() < left_stop_rightmost) {
mario->setPos(left_stop_rightmost, mario->getPos().getY());
}
}
void pollEvents(SDLPP::Scene &scene) {
SDL_Event event;
while (SDLPP::getSDLEvent(event)) {
switch (event.type) {
case SDL_QUIT:
g_quit = true;
break;
case SDL_KEYDOWN:
if (!event.key.repeat) {
handleKeyDown(event.key.keysym.sym, scene);
}
break;
case SDL_KEYUP:
handleKeyUp(event.key.keysym.sym);
break;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
auto prev_mario_pos = mario->getAbsolutePos();
scene.updateSizeAndPosition();
moveToMarioPosition(scene, prev_mario_pos);
update = true;
update_count = 2;
}
default:
break;
}
}
}
void doInputMainGame(std::shared_ptr<SDLPP::Scene> scene) {
if (newLoaded) {
auto prev_mario_pos = mario->getAbsolutePos();
scene->updateSizeAndPosition();
moveToMarioPosition(*scene, prev_mario_pos);
update = true;
update_count = 2;
newLoaded = false;
}
if (g_death) {
game_scenes.push_back(
createGameMainMenuScene(renderer, true, false, true));
g_death = false;
}
pollEvents(*scene);
std::lock_guard<std::mutex> lock(render_mutex);
scene->updateScene();
auto prev_coin_count = coin_count;
auto rightmost_x = renderer->getDoubleDimensions().getX();
for (size_t i = 0; i < moving_objects.size(); i++) {
moving_objects[i]->checkVisibility(rightmost_x);
if (!moving_objects[i]->wasVisible()) {
continue;
}
auto visitor = getVisitor(*moving_objects[i], *scene,
coin_count, moving_objects);
scene->visitCollisions(*moving_objects[i], *visitor);
moving_objects[i]->handleVisitor(*visitor);
auto rightmost_pos = moving_objects[i]->getAbsolutePos().getX() +
moving_objects[i]->getDoubleRect().second.getX();
if (rightmost_pos < 0 && moving_objects[i] != mario) {
moving_objects[i]->destroy();
}
}
std::vector<uint64_t> killed_indices{};
for (size_t i = 0; i < moving_objects.size(); i++) {
if (moving_objects[i]->getKilled()) {
killed_indices.push_back(i);
}
}
std::reverse(killed_indices.begin(), killed_indices.end());
for (auto &index : killed_indices) {
moving_objects.erase(moving_objects.begin() + index);
}
if (coin_count != prev_coin_count) {
coins->changeText(std::to_string(coin_count) + " COINS");
update = true;
update_count = 2;
}
// if player is > 0.7 of playground, move everything left
auto playerX = mario->getRect().x;
auto width = scene->getWidth();
auto rightBarrier = width * 0.5;
auto rightmostX =
scene->rightmost()->getRect().x + scene->rightmost()->getRect().w;
scene->moveEverything((playerX > rightBarrier && rightmostX > width) *
(rightBarrier - playerX) / width,
0);
update = update || (playerX > rightBarrier && rightmostX > width);
global_frames++;
if (mario->isDead()) {
g_death = true;
}
}
void doInput() {
FPSmanager gFPS;
SDL_initFramerate(&gFPS);
SDL_setFramerate(&gFPS, 200);
while (!g_quit) {
SDL_framerateDelay(&gFPS);
std::lock_guard<std::mutex> lock(gamescene_mutex);
game_scenes.back().doInput(game_scenes.back().scene);
game_scenes.back().scene->updateScene();
}
}
void mainGameAdditional(std::shared_ptr<SDLPP::Scene> & /*UNUSED*/) {
static auto base = SDL_GetTicks();
static int frames = 0;
mario->setStanding();
frames++;
if (SDL_GetTicks() - base >= 1000) {
if (global_frames < frames) {
frames = global_frames;
}
global_frames = 0;
fps->changeText(std::to_string(frames) + " fps");
frames = 0;
base = SDL_GetTicks();
}
}
void addObjectToScene(std::shared_ptr<MarioBlock> &object, bool moving) {
game_scenes.back().scene->addObject(object);
object->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
if(moving) {
moving_objects.push_back(object);
}
}
void addObjectToSceneTop(std::shared_ptr<MarioBlock> &object, bool moving) {
addObjectToScene(object, moving);
game_scenes.back().scene->moveZTop(object);
}
void addObjectToSceneBack(std::shared_ptr<MarioBlock> &object, bool moving) {
addObjectToScene(object, moving);
game_scenes.back().scene->moveZJustAboveBackground(object);
}
SceneStruct mainGameScene(const std::string &level_path) {
auto scene = std::make_shared<SDLPP::Scene>(renderer);
g_playground = scene;
auto bg = std::make_shared<SDLPP::RectangleRender>(
0, 0, 10, 10, renderer, MARIO_OVERWORLD_COLORKEY, true);
bg->setPermanent();
bg->setStatic();
bg->setId(1);
scene->addObject(bg);
mario.reset();
mario = std::make_shared<Mario>(renderer, addObjectToSceneTop);
scene->addObject(mario);
auto defeat =
std::make_shared<SDLPP::RectangleRender>(0, 1.01, 0, 0, renderer);
defeat->setId(DEATH_ID);
defeat->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
defeat->setPermanent();
auto defeatCol = SDLPP::RectColider(-1, 0, -1, -1);
defeatCol.setInfinite();
defeat->addCollision(defeatCol);
scene->addObject(defeat);
leftStop =
std::make_shared<SDLPP::RectangleRender>(-0.1, 0, 0.11, 0, renderer);
leftStop->setId(STOP_MOVEMENT);
leftStop->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
leftStop->setPermanent();
auto leftStopCol = SDLPP::RectColider(0, -1, 1, -1);
leftStopCol.setInfinite();
leftStop->addCollision(leftStopCol);
leftStop->setColiderColor("#FF00FF");
scene->addObject(leftStop);
loadMap(scene, mario, level_path);
auto font = std::make_shared<SDLPP::Font>("testfont.ttf", 36);
fps = std::make_shared<SDLPP::TextRenderer>(
0.2, 0, 0.78, 0.1, renderer, font, "0fps", "#FFFFFF", "#000000", 0.1,
SDLPP_TEXT_RIGHT);
fps->setAlignment(SDLPP::OBJ_END, SDLPP::OBJ_START);
fps->setId(0);
fps->setPermanent();
fps->setHidden(true);
scene->addObject(fps);
coins = std::make_shared<SDLPP::TextRenderer>(
0.2, 0, 0.78, 0.1, renderer, font, "0 COINS", "#FFFFFF", "#000000", 0.1,
SDLPP_TEXT_RIGHT);
coins->setAlignment(SDLPP::OBJ_START, SDLPP::OBJ_START);
coins->setId(0);
coins->setPermanent();
scene->addObject(coins);
scene->moveEverything(-mario->getDoubleRect().first.getX() + 0.2, 0);
std::unordered_set<uint64_t> background_ids = {
HILL_INCLINE_ID, HILL_DECLINE_ID, HILL_DOTS_RIGHT_ID,
HILL_DOTS_LEFT_ID, HILL_FILL_ID, HILL_TOP_ID,
BUSH_LEFT_ID, BUSH_MIDDLE_ID, BUSH_RIGHT_ID,
CLOUD_LEFT_BOTTOM_ID, CLOUD_MIDDLE_BOTTOM_ID, CLOUD_RIGHT_BOTTOM_ID,
CLOUD_LEFT_TOP_ID, CLOUD_MIDDLE_TOP_ID, CLOUD_RIGHT_TOP_ID,
CASTLE_LEFT_ID, CASTLE_RIGHT_ID, CASTLE_BLACK_ID,
CASTLE_ENTRY_ID, CASTLE_TOWER_ID, CASTLE_TOWER_FILLED_ID,
WATER_TOP_ID, WATER_FILL_ID
};
scene->setBackgroundObjectIDs(background_ids);
scene->updateBackgroundObjectZIndex();
// we want mario to be first because visiting isn't perfect
moving_objects.clear();
moving_objects.push_back(mario);
std::unordered_set<int> moving_object_ids = {
GOOMBA_ID,
TURTLE_ID,
};
for (auto &obj : scene->getObjects(moving_object_ids)) {
moving_objects.push_back(std::dynamic_pointer_cast<MarioBlock>(obj));
}
SceneStruct ret{};
ret.scene = scene;
ret.doInput = doInputMainGame;
ret.additionalRender = mainGameAdditional;
return ret;
}
void setTeleportLevelMain(const std::string &level) {
_teleport_level = level;
}
void loadLevel(const std::string &level, bool reset) {
// std::lock_guard<std::mutex> lock(render_mutex);
if(reset) {
coin_count = 0;
}
std::lock_guard<std::mutex> lock(gamescene_mutex);
for (auto &scene : game_scenes) {
scene.scene->resetScene();
}
game_scenes.clear();
int marioBig = 0;
if(!reset) {
if(mario->hasFire()) {
marioBig = 2;
} else if (mario->isBig()) {
marioBig = 1;
}
}
game_scenes.push_back(mainGameScene("levels/" + level));
if(!reset) {
for(int i = 0; i < marioBig; i++) {
mario->setBig();
}
}
game_scenes.back().scene->updateSizeAndPosition();
update = true;
newLoaded = true;
update_count = 2;
if(reset) {
last_load_level = level;
}
g_death = false;
}
void loadLevel(const std::string &level) {
loadLevel(level, true);
}
void loadLastLevel() {
if (last_load_level != "") {
loadLevel(last_load_level);
}
}
#ifdef _WIN32
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR szCmdLine, int nCmdShow) {
#else
int main() {
#endif
SDLPP::init();
SDLPP::Window w("Mario clone!");
w.setResizable(true);
renderer = std::make_shared<SDLPP::Renderer>(w);
renderer->setBlendMode(SDL_BLENDMODE_BLEND);
// prepare global vars
g_terrain_texture = std::make_shared<SDLPP::Texture>(
renderer, "sprites/terrain.png", MARIO_OVERWORLD_COLORKEY);
g_enemies_texture = std::make_shared<SDLPP::Texture>(
renderer, "sprites/enemies.png", MARIO_OVERWORLD_COLORKEY);
g_items_texture = std::make_shared<SDLPP::Texture>(
renderer, "sprites/items.png", MARIO_OVERWORLD_COLORKEY);
g_mario_texture = std::make_shared<SDLPP::Texture>(
renderer, "sprites/mario.png", MARIO_OVERWORLD_COLORKEY);
g_translucent_terrain_texture = std::make_shared<SDLPP::Texture>(
renderer, "sprites/terrain.png", MARIO_OVERWORLD_COLORKEY);
g_translucent_terrain_texture->setAlpha(100);
FPSmanager gFPS;
SDL_initFramerate(&gFPS);
SDL_setFramerate(&gFPS, 60);
auto font = std::make_shared<SDLPP::Font>("testfont.ttf", 36);
g_text_config = std::make_shared<SDLPP::FontConfiguration>(font, "#FFFFFF",
"#000000", 0.15);
game_scenes.push_back(
createGameMainMenuScene(renderer, false, false, false));
std::thread inputThread(doInput);
SDL_PumpEvents();
game_scenes.back().scene->updateSizeAndPosition();
game_scenes.back().scene->renderScene();
renderer->presentRenderer();
update = true;
while (!g_quit) {
SDL_framerateDelay(&gFPS);
SDL_PumpEvents();
std::lock_guard<std::mutex> lock(render_mutex);
if (!_teleport_level.empty()) {
loadLevel(_teleport_level, false);
_teleport_level = "";
}
if (update) {
for (auto &scene : game_scenes) {
scene.scene->updateSizeAndPosition();
}
if (update_count > 0) {
update_count--;
} else {
update = false;
}
}
auto max_game_scenes = game_scenes.size();
renderer->clearRenderer();
for (size_t i = 0; i < max_game_scenes; i++) {
game_scenes[i].additionalRender(game_scenes[i].scene);
// additional renderer can remove scene from game_scenes, better
// check
if (i < game_scenes.size()) {
game_scenes[i].scene->renderScene(false);
}
}
renderer->presentRenderer();
}
inputThread.join();
return 0;
}
+298
View File
@@ -0,0 +1,298 @@
#include "maploader.hpp"
#include "../sdlpp/sdlpp_rectrenderer.hpp"
#include <array>
#include <fstream>
#include <functional>
#include "mario.hpp"
#include "sprites.hpp"
#include "blocks.hpp"
#include "objectids.hpp"
#include "global_vars.hpp"
#include "filesystem.hpp"
#define TERRAIN_TYPE_HAS_ADDITIONAL 0x8
#define WIDE_TERRAIN_HAS_ADDITIONAL 0x8000
#define ADDITIONAL_IS_MOD 0x80
#define FILE_VERSION 0x01
void loadMapV01(std::shared_ptr<SDLPP::Scene> &scene,
std::shared_ptr<SDLPP::RenderObject> &mario,
std::ifstream &map_file, std::vector<mapColumnType> &objects,
bool editor, size_t editor_width,
std::shared_ptr<SDLPP::Renderer> &renderer);
void loadMap(std::shared_ptr<SDLPP::Scene> &scene,
std::shared_ptr<SDLPP::RenderObject> mario,
const std::string &file) {
std::vector<mapColumnType> tmp = {};
loadMap(scene, mario, file, tmp, false);
scene->moveZTop(mario);
}
uint8_t read8Bits(std::ifstream &file) {
uint8_t data;
file.read((char *)&data, sizeof(uint8_t) / sizeof(char));
return data;
}
std::string readString(std::ifstream &file) {
std::string res = "";
char tmp{};
file.read(&tmp, 1);
while (tmp != '\0') {
res += tmp;
file.read(&tmp, 1);
}
return res;
}
void write8Bits(std::ofstream &file, uint8_t data) {
file.write((char *)&data, sizeof(uint8_t) / sizeof(char));
}
void writeString(std::ofstream &file, const std::string &text) {
file.write(text.c_str(), text.size() + 1);
}
uint16_t read16Bits(std::ifstream &file) {
uint16_t data;
file.read((char *)&data, sizeof(uint16_t) / sizeof(char));
return data;
}
void write16Bits(std::ofstream &file, uint16_t data) {
file.write((char *)&data, sizeof(uint16_t) / sizeof(char));
}
std::pair<uint16_t, uint8_t> separateWideTerrain(uint16_t wide_terrain) {
uint8_t terrain_type = (wide_terrain & 0xF000) >> 12;
uint16_t terrain_id = (wide_terrain & 0x0FFF) | BLOCK_PREFIX;
return { terrain_id, terrain_type };
}
std::pair<uint8_t, uint8_t> separateAdditionalData(uint8_t data) {
auto id = data & 0x0F;
auto type = (data & 0xF0) >> 4;
return { id, type };
}
uint16_t combineTerrain(uint16_t id, uint8_t type) {
uint16_t wide_terrain = type;
wide_terrain = wide_terrain << 12;
wide_terrain |= 0x0FFF & id;
return wide_terrain;
}
uint8_t combineAdditionalData(uint8_t id, uint8_t type) {
return type << 4 | id;
}
MapObject parseBlock(std::ifstream &map_file) {
uint8_t character_type = 0;
uint8_t character_id = 0;
uint32_t modifier_id = 0;
uint8_t modifier_data = 0;
std::string modifier_text = "";
uint16_t wide_terrain = read16Bits(map_file);
auto terrain = separateWideTerrain(wide_terrain);
uint16_t terrain_id = terrain.first;
uint8_t terrain_type = terrain.second;
if (terrain_type & TERRAIN_TYPE_HAS_ADDITIONAL) {
uint8_t additional_data = read8Bits(map_file);
terrain_type &= ~TERRAIN_TYPE_HAS_ADDITIONAL;
if (additional_data & ADDITIONAL_IS_MOD) {
additional_data &= ~ADDITIONAL_IS_MOD;
auto modifier = separateAdditionalData(additional_data);
modifier_id = modifier.first | 0x6000;
modifier_data = modifier.second;
if(modifier_id == TELEPORT_MODIFIER_ID) {
modifier_text = readString(map_file);
}
} else {
// character
auto character = separateAdditionalData(additional_data);
character_id = character.first;
character_type = character.second;
}
}
return MapObject(terrain_id, terrain_type, character_id, character_type,
modifier_id, modifier_data, modifier_text);
}
void loadEmptyMap(std::vector<mapColumnType> &objects, size_t editor_width) {
objects.resize(editor_width);
}
// editor loader
// TODO catch exception in calling functions
void loadMap(std::shared_ptr<SDLPP::Scene> &scene,
std::shared_ptr<SDLPP::RenderObject> &mario,
const std::string &file, std::vector<mapColumnType> &objects,
bool editor, size_t editor_width) {
if (!FSLib::exists(file)) {
// create empty array large enough for initial editor window
loadEmptyMap(objects, editor_width);
return;
}
auto renderer = scene->getRendererShared();
std::ifstream map_file;
map_file.open(file, std::ios::in | std::ios::binary);
uint16_t version;
map_file.read((char *)&version, sizeof(uint16_t) / sizeof(char));
switch (version) {
case 0x01:
loadMapV01(scene, mario, map_file, objects, editor, editor_width,
renderer);
break;
default:
throw "Invalid file version";
}
}
void loadMapV01(std::shared_ptr<SDLPP::Scene> &scene,
std::shared_ptr<SDLPP::RenderObject> &mario,
std::ifstream &map_file, std::vector<mapColumnType> &objects,
bool editor, size_t editor_width,
std::shared_ptr<SDLPP::Renderer> &renderer) {
uint16_t cols;
map_file.read((char *)&cols, sizeof(uint16_t) / sizeof(char));
if (editor) {
objects.resize(cols);
}
mapColumnType *col = nullptr;
for (uint16_t i = 0; i < cols; i++) {
if (editor) {
col = &objects[i];
}
for (int j = 0; j < 16; j++) {
auto block = parseBlock(map_file);
if (editor) {
col->at(j) = block;
}
bool destructible = false;
bool removeCollisions = false;
int coinCount = 0;
bool mushroom = false;
std::string teleport_level = "";
if (!editor && block.getModifierId() == DESTRUCTIBLE_MODIFIER_ID) {
destructible = true;
}
if (!editor && block.getModifierId() == BACKGROUND_MODIFIER_ID) {
destructible = false;
removeCollisions = true;
}
if (!editor && block.getModifierId() == COIN_MODIFIER_ID) {
coinCount = block.getModifierData();
}
if (!editor && block.getModifierId() == MUSHROOM_MODIFIER_ID) {
mushroom = true;
}
if (!editor && block.getModifierId() == TELEPORT_MODIFIER_ID) {
teleport_level = block.getModifierText();
}
// TODO add modifiers to createTerrainBlock
if (block.getTerrainId() != 0) {
auto obj = createTerrainBlock(block.getTerrainId(),
block.getTerrainType(), renderer,
i, j, destructible, editor);
if (obj != nullptr) {
obj->setCoinCount(coinCount);
if (mushroom) {
obj->addMushroom();
}
if (!teleport_level.empty()) {
obj->setTeleportLevel(teleport_level);
}
if (removeCollisions) {
obj->removeCollisions();
}
if (obj != nullptr) {
if (editor) {
obj->getCollisions()[0]->setId(EDITOR_TERRAIN_ID);
}
scene->addObject(obj);
}
}
}
if (block.hasCharacter()) {
if (block.getCharacterId() == MARIO_ID) {
if (editor) {
auto mario2 = createMario(block.getCharacterType(),
renderer, i, j, true);
scene->addObject(mario2);
#ifndef EDITOR
std::dynamic_pointer_cast<Mario>(mario2)->setAddObjFunc(std::dynamic_pointer_cast<Mario>(mario)->getAddObjFunc());
#endif
mario = mario2;
} else {
mario->setPos(i * BLOCK_SIZE,
1 - (16 - j) * BLOCK_SIZE);
}
} else {
auto obj = createTerrainBlock(
block.getCharacterId(), block.getCharacterType(),
renderer, i, j, destructible, editor);
dynamic_cast<MarioBlock *>(obj.get())->setTerrain(false);
if (editor) {
obj->getCollisions()[0]->setId(EDITOR_CHARACTER_ID);
}
scene->addObject(obj);
}
}
if (editor && block.hasModifier()) {
// TODO createModifierBlock with data
auto mod = createTerrainBlock(block.getModifierId(),
LandType::OVERWORLD, renderer, i,
j, false, editor);
mod->setData(block.getModifierData());
mod->setTextureKeepSRC(g_translucent_mod_texture);
mod->getCollisions()[0]->setId(EDITOR_TERRAIN_ID);
dynamic_cast<MarioBlock *>(mod.get())->setTerrain(false);
scene->addObject(mod);
}
}
}
if (editor && objects.size() < editor_width) {
objects.resize(editor_width);
}
}
// TODO catch exception in calling func
void saveMap(const std::string &file, std::vector<mapColumnType> &objects) {
std::ofstream output_file;
output_file.open(file, std::ios::out | std::ios::binary);
if (!output_file.is_open()) {
throw "Could not open file '" + file + "'";
}
const uint16_t version = FILE_VERSION;
output_file.write((char *)&version, sizeof(uint16_t) / sizeof(char));
const uint16_t cols = objects.size();
output_file.write((char *)&cols, sizeof(uint16_t) / sizeof(char));
for (auto &col : objects) {
for (int i = 0; i < 16; i++) {
auto &block = col[i];
auto wide_terrain =
combineTerrain(block.getTerrainId(), block.getTerrainType());
// if block has additional data it needs to indicate it
if (block.hasCharacter() || block.hasModifier()) {
wide_terrain |= WIDE_TERRAIN_HAS_ADDITIONAL;
}
write16Bits(output_file, wide_terrain);
uint8_t additional_data = 0;
if (block.hasCharacter()) {
additional_data = combineAdditionalData(
block.getCharacterId(), block.getCharacterType());
} else if (block.hasModifier()) {
// we have IDs like 0x600X but only X is useful data, the 0x6 at
// the beginning is to differentiate mods from characters
additional_data = combineAdditionalData(
block.getModifierId() & 0x000F, block.getModifierData());
additional_data |= ADDITIONAL_IS_MOD;
}
if (additional_data) {
write8Bits(output_file, additional_data);
if(additional_data & ADDITIONAL_IS_MOD && additional_data & !block.getModifierText().empty()) {
writeString(output_file, block.getModifierText());
}
}
}
}
output_file.close();
}
+20
View File
@@ -0,0 +1,20 @@
#ifndef MAPLOADER_H
#define MAPLOADER_H
#include "../sdlpp/sdlpp_scene.hpp"
#include "../sdlpp/sdlpp_rectrenderer.hpp"
#include "mapobject.hpp"
typedef std::array<MapObject, 16> mapColumnType;
void loadMap(std::shared_ptr<SDLPP::Scene> &scene,
std::shared_ptr<SDLPP::RenderObject> mario,
const std::string &file);
void loadMap(std::shared_ptr<SDLPP::Scene> &scene,
std::shared_ptr<SDLPP::RenderObject> &mario,
const std::string &file, std::vector<mapColumnType> &objects,
bool editor = false, size_t editor_width = 0);
void loadEmptyMap(std::vector<mapColumnType> &objects, size_t editor_width);
void saveMap(const std::string &file, std::vector<mapColumnType> &objects);
#endif
+111
View File
@@ -0,0 +1,111 @@
#include "mapobject.hpp"
MapObject::MapObject(uint16_t terrain_id, LandType::Value terrain_type,
uint8_t character_id, LandType::Value character_type,
uint32_t modifier_id, uint8_t modifier_data, const std::string &modifier_text) {
setTerrain(terrain_id, terrain_type);
if (character_id != 0)
setCharacter(character_id, character_type);
if (modifier_id != 0) {
if(!modifier_text.empty()) {
setModifier(modifier_id, modifier_text);
} else {
setModifier(modifier_id, modifier_data);
}
}
}
MapObject::MapObject(uint16_t terrain_id, uint8_t terrain_type,
uint8_t character_id, uint8_t character_type,
uint32_t modifier_id, uint8_t modifier_data, const std::string &modifier_text)
: MapObject(terrain_id, static_cast<LandType::Value>(terrain_type),
character_id, static_cast<LandType::Value>(character_type),
modifier_id, modifier_data, modifier_text) {}
void MapObject::setTerrain(uint16_t id, LandType::Value land_type) {
terrain_id = id;
terrain_type = land_type;
}
void MapObject::setTerrain(uint16_t id, uint8_t land_type) {
setTerrain(id, static_cast<LandType::Value>(land_type));
}
void MapObject::setCharacter(uint8_t id, LandType::Value land_type) {
character_id = id;
character_type = land_type;
if (hasModifier()) {
modifier_id = 0;
modifier_data = 0;
}
}
void MapObject::setCharacter(uint8_t id, uint8_t land_type) {
setCharacter(id, static_cast<LandType::Value>(land_type));
}
void MapObject::setModifier(uint32_t id, uint8_t data) {
modifier_id = id;
modifier_data = data;
if (hasCharacter()) {
character_id = 0;
character_type = LandType::OVERWORLD;
}
}
void MapObject::setModifier(uint32_t id, const std::string &text) {
setModifier(id, 0);
modifier_text = text;
}
const std::string &MapObject::getModifierText() {
return modifier_text;
}
void MapObject::unsetTerrain() {
setTerrain(0, 0);
}
void MapObject::unsetModifier() {
if (hasModifier()) {
setModifier(0, 0);
}
}
void MapObject::unsetCharacter() {
if (hasCharacter()) {
setCharacter(0, 0);
}
}
bool MapObject::hasCharacter() {
return character_id != 0;
}
bool MapObject::hasModifier() {
return modifier_id != 0;
}
uint16_t MapObject::getTerrainId() {
return terrain_id;
}
uint8_t MapObject::getCharacterId() {
return character_id;
}
uint32_t MapObject::getModifierId() {
return modifier_id;
}
LandType::Value MapObject::getTerrainType() {
return terrain_type;
}
LandType::Value MapObject::getCharacterType() {
return character_type;
}
uint8_t MapObject::getModifierData() {
return modifier_data;
}
+46
View File
@@ -0,0 +1,46 @@
#ifndef MAP_OBJECT_H
#define MAP_OBJECT_H
#include "blocks.hpp"
class MapObject {
public:
MapObject() = default;
MapObject(uint16_t terrain_id, uint8_t terrain_type, uint8_t character_id,
uint8_t character_type, uint32_t modifier_id,
uint8_t modifier_data, const std::string &modifier_text);
MapObject(uint16_t terrain_id, LandType::Value terrain_type,
uint8_t character_id, LandType::Value character_type,
uint32_t modifier_id, uint8_t modifier_data,
const std::string &modifier_text);
void setTerrain(uint16_t id, LandType::Value land_type);
void setTerrain(uint16_t id, uint8_t land_type);
void setCharacter(uint8_t id, LandType::Value land_type);
void setCharacter(uint8_t id, uint8_t land_type);
void setModifier(uint32_t id, uint8_t data);
void setModifier(uint32_t id, const std::string &text);
void unsetTerrain();
void unsetModifier();
void unsetCharacter();
bool hasCharacter();
bool hasModifier();
uint16_t getTerrainId();
uint8_t getCharacterId();
uint32_t getModifierId();
LandType::Value getTerrainType();
LandType::Value getCharacterType();
uint8_t getModifierData();
const std::string &getModifierText();
private:
LandType::Value terrain_type = LandType::OVERWORLD;
uint16_t terrain_id = 0;
LandType::Value character_type = LandType::OVERWORLD;
uint8_t character_id = 0;
uint32_t modifier_id = 0;
uint8_t modifier_data = 0;
std::string modifier_text = "";
};
#endif
+292
View File
@@ -0,0 +1,292 @@
#include "mario.hpp"
#include "blocks.hpp"
#include "global_vars.hpp"
#include "objectids.hpp"
#include "sprites.hpp"
#include "visitors/mario_visitor.hpp"
#include "blocks/fireball.hpp"
Mario::Mario(int x, int y, const std::shared_ptr<SDLPP::Renderer> &renderer, std::function<void(std::shared_ptr<MarioBlock>&, bool)> addObject)
: MarioBlock(x, y, renderer, g_mario_texture, MARIO_STANDING_SRC), _addObject(addObject) {
setAnimationFrames(*walk_anim);
setId(MARIO_ID);
setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
setAnimationSpeed(12.5);
pauseAnimation();
setMovement(0, 0);
setMovementSpeed(1);
auto bottom_detect = SDLPP::RectColider(0.2, 1, 0.6, 0, MARIO_FLOOR_DETECT);
bottom_detect.setColor("#FF0000");
bottom_detect.setOutlineColor("#FF0000");
bottom_detect.setMinHeight(1);
addCollision(bottom_detect);
addCollision(SDLPP::RectColider(0, 0.25, 0.1, 0.6, MARIO_LEFT_SIDE_DETECT));
addCollision(
SDLPP::RectColider(0.9, 0.25, 0.1, 0.6, MARIO_RIGHT_SIDE_DETECT));
addCollision(SDLPP::RectColider(0, 0, 0.1, 0.1, MARIO_TOP_LEFT_DETECT));
addCollision(SDLPP::RectColider(0.9, 0, 0.1, 0.1, MARIO_TOP_LEFT_DETECT));
top_collision = std::make_shared<SDLPP::RectColider>(0.5, 0, 0.2, 0.15,
MARIO_TOP_DETECT);
addCollision(top_collision);
addCollision(SDLPP::RectColider(0, 1, 1, 0.2, MARIO_ENEMY_DETECT));
setColiderColor("#FF0000");
setStatic(false);
bounce_speed *= 4;
}
Mario::Mario(const std::shared_ptr<SDLPP::Renderer> &renderer, std::function<void(std::shared_ptr<MarioBlock>&, bool)> addObject)
: Mario(0, 0, renderer, addObject) {}
void Mario::walkLeft() {
if (!controllable || isCrouching()) {
return;
}
if (on_ground)
resumeAnimation();
addMovement(-side_movement, 0);
if (getMovement().getX() < 0 && faces_right) {
flipHorizontally();
top_collision->setPos(0.3, 0);
updateSizeAndPosition();
faces_right = false;
}
}
void Mario::walkRight() {
if (!controllable || isCrouching()) {
return;
}
if (on_ground)
resumeAnimation();
addMovement(side_movement, 0);
if (getMovement().getX() > 0 && !faces_right) {
flipHorizontally();
top_collision->setPos(0.5, 0);
updateSizeAndPosition();
faces_right = true;
}
}
void Mario::setStanding() {
if (getMovement().getX() == 0) {
pauseAnimation();
}
}
void setTeleportLevelMain(const std::string &level);
void Mario::handleVisitor(SDLPP::Visitor &visitor) {
#ifndef EDITOR
// TODO -
// https://web.archive.org/web/20130807122227/http://i276.photobucket.com/albums/kk21/jdaster64/smb_playerphysics.png
auto &m_visitor = dynamic_cast<MarioVisitor &>(visitor);
// handle gravity
on_ground = m_visitor.isOnGround();
if (!jumping && on_ground) {
resetMovementY();
setBaseRect(*standing_src);
if (!controllable) {
setDeath();
}
if (getMovement().getX() != 0)
resumeAnimation();
// for some reason falling of the edge causes on_ground to be true, but
// visitor ground_y is 0
if (m_visitor.getGroundY() != 0) {
setPos(getPos().getX(),
m_visitor.getGroundY() - getDoubleRect().second.getY());
}
}
// if we just left ground gravity didn't work in custom_move
if (!on_ground && !jumping && getMovement().getY() == 0) {
addMovement(0, 2 * gravity_add_falling);
}
if (m_visitor.topBlock() && getMovement().getY() < 0) {
resetMovementY();
stop_jump = true;
}
if (m_visitor.shouldBounce() && getMovement().getY() > 0) {
addMovement(0, -bounce_speed);
}
// make sure Mario isn't stuck inside a wall
// TODO more readable function names
if (m_visitor.isStopped()) {
setPos(m_visitor.getStopX(), getPos().getY());
} else if (m_visitor.canGoLeft() != m_visitor.canGoRight()) {
// only stop mario on ground if the block obstructs at least half of him
// (important for bug when mario lands from a high jump and is
// teleported if visitor is fired at wrong moment)
SDLPP::Vec2D<double> next_pos = {
m_visitor.getMovementBlockage().getX() +
(m_visitor.canGoLeft() * -1 + m_visitor.canGoRight() * 1) *
BLOCK_SIZE,
getPos().getY()
};
setPos(next_pos);
} else if (m_visitor.moveTop() && jumping && !stop_jump) {
auto objPos = m_visitor.getRightLeftPos();
if (objPos.getX() < getPos().getX()) {
setPos(objPos.getX() + BLOCK_SIZE, getPos().getY());
} else {
setPos(objPos.getX() - BLOCK_SIZE, getPos().getY());
}
}
if (m_visitor.hasMushroom()) {
setBig();
}
if (m_visitor.hasTeleport() && (
(m_visitor.teleportBottom() && isCrouching()) || (!m_visitor.teleportBottom() && walkingRight())
)) {
setTeleportLevelMain(m_visitor.getTeleportLevel());
}
if (m_visitor.levelEnd() && controllable) {
if (std::abs(getPos().getX() - m_visitor.getEndPos().getX()) <
BLOCK_SIZE / 8) {
setPos(m_visitor.getEndPos().getX(), getPos().getY());
stopMovement();
}
}
if (m_visitor.isDead()) {
handleDeath();
}
if (m_visitor.isInstantDead()) {
setDeath();
}
#endif
}
void Mario::handleDeath() {
if (isBig() && ticks_till_vulnurable <= 0) {
unsetBig();
ticks_till_vulnurable = base_vulnurable_ticks;
} else if (ticks_till_vulnurable <= 0) {
setDeath();
}
}
void Mario::jump() {
if (!controllable || isCrouching()) {
return;
}
if (!on_ground)
return;
jumping = true;
stop_jump = false;
max_jump = getPos().getY() - 3 * BLOCK_SIZE;
min_jump = getPos().getY() - 1 * BLOCK_SIZE;
slow_jump = getPos().getY() - 2 * BLOCK_SIZE;
addMovement(0, -jump_movement);
ticks_till_gravity = base_gravity_ticks;
setBaseRect(*jump_src);
pauseAnimation();
}
void Mario::crouch() {
if(walkingLeft()) {
walkRight();
} else if(walkingRight()) {
walkLeft();
}
_crouching = true;
}
void Mario::uncrouch() {
_crouching = false;
}
#ifndef EDITOR
void Mario::fire() {
if (!hasFire()) {
return;
}
auto fireball = std::make_shared<Fireball>(0, 0, renderer);
fireball->setPos(getPos() + SDLPP::Vec2D<double>((faces_right ? 1 : -1) * BLOCK_SIZE, BLOCK_SIZE));
fireball->setMovementDir(!faces_right);
auto fireball_m = std::static_pointer_cast<MarioBlock>(fireball);
fireball->setHidden(false);
_addObject(fireball_m, true);
}
void Mario::setAddObjFunc(std::function<void(std::shared_ptr<MarioBlock>&, bool)> func) {
_addObject = func;
}
std::function<void(std::shared_ptr<MarioBlock>&, bool)> Mario::getAddObjFunc() {
return _addObject;
}
#endif
void Mario::stopJump() {
stop_jump = true;
}
void Mario::custom_move(int ticks) {
if (ticks_till_vulnurable > 0) {
ticks_till_vulnurable -= ticks;
}
MarioBlock::custom_move(ticks);
if (!jumping && on_ground)
return;
if (getMovement().getY() >= 1.0625 * jump_movement)
return;
ticks_till_gravity -= ticks;
if (ticks_till_gravity < 0) {
if (getMovement().getY() > 0) {
jumping = false;
addMovement(0, gravity_add_jumping);
} else {
if (stop_jump) {
addMovement(0, gravity_add_falling);
} else {
addMovement(0, gravity_add_jumping);
}
}
ticks_till_gravity += base_gravity_ticks;
}
}
void Mario::visit(SDLPP::Visitor &visitor) {
// TODO
visitor.visit(*this);
}
void Mario::setWorldTypeSrc(LandType::Value /*UNUSED*/) {
MarioBlock::setWorldTypeSrc(LandType::OVERWORLD);
// TODO
}
void Mario::stopMovement() {
controllable = false;
setMovement(0, getMovement().getY());
}
void Mario::setBig() {
if (isBig()) {
setFireFlag();
} else {
setBigFlag();
setSize({ BLOCK_SIZE, 2 * BLOCK_SIZE });
setPos(getPos() - SDLPP::Vec2D<double>(0, BLOCK_SIZE));
}
setBaseRect(isJumping()
? (hasFire() ? MARIO_JUMP_FIRE_SRC : MARIO_JUMP_BIG_SRC)
: (hasFire() ? MARIO_STANDING_FIRE_SRC
: MARIO_STANDING_BIG_SRC));
setAnimationFrames(hasFire() ? MARIO_WALK_FIRE_ANIM : MARIO_WALK_BIG_ANIM);
standing_src = hasFire() ? &MARIO_STANDING_FIRE_SRC : &MARIO_STANDING_BIG_SRC;
death_src = hasFire() ? &MARIO_DEATH_FIRE_SRC : &MARIO_DEATH_BIG_SRC;
change_dir_src = hasFire() ? &MARIO_CHANGE_DIR_FIRE_SRC : &MARIO_CHANGE_DIR_BIG_SRC;
jump_src = hasFire() ? &MARIO_JUMP_FIRE_SRC : &MARIO_JUMP_BIG_SRC;
walk_anim = hasFire() ? &MARIO_WALK_FIRE_ANIM : &MARIO_WALK_BIG_ANIM;
}
void Mario::unsetBig() {
if (hasFire()) {
unsetFireFlag();
} else {
unsetBigFlag();
setSize({ BLOCK_SIZE, BLOCK_SIZE });
setBaseRect(isJumping() ? MARIO_JUMP_SRC : MARIO_STANDING_SRC);
setAnimationFrames(MARIO_WALK_ANIM);
standing_src = &MARIO_STANDING_SRC;
death_src = &MARIO_DEATH_SRC;
change_dir_src = &MARIO_CHANGE_DIR_SRC;
jump_src = &MARIO_JUMP_SRC;
walk_anim = &MARIO_WALK_ANIM;
}
}
+126
View File
@@ -0,0 +1,126 @@
#ifndef MARIO_H
#define MARIO_H
#include "../sdlpp/sdlpp_rectrenderer.hpp"
#include "sprites.hpp"
#include "blocks.hpp"
#include <functional>
#define BIG_FLAG 0x0001
#define FIRE_FLAG 0x0002
#define STAR_FLAG 0x0004
class Mario : public MarioBlock {
public:
Mario(int x, int y, const std::shared_ptr<SDLPP::Renderer> &renderer,
std::function<void(std::shared_ptr<MarioBlock> &, bool)> addObject);
Mario(const std::shared_ptr<SDLPP::Renderer> &renderer,
std::function<void(std::shared_ptr<MarioBlock> &, bool)> addObject);
void walkLeft();
void walkRight();
void setStanding();
void handleVisitor(SDLPP::Visitor &visitor) override;
void jump();
void crouch();
void uncrouch();
#ifndef EDITOR
void fire();
void setAddObjFunc(
std::function<void(std::shared_ptr<MarioBlock> &, bool)> func);
std::function<void(std::shared_ptr<MarioBlock> &, bool)> getAddObjFunc();
#endif
void stopJump();
void custom_move(int ticks) override;
void visit(SDLPP::Visitor &visitor) override;
bool isDead() {
return _death;
}
void handleDeath();
void setBig();
void unsetBig();
void setStar() {
setStarFlag();
}
void unsetStar() {
unsetStarFlag();
}
bool isBig() const {
return special_flags & BIG_FLAG;
}
bool hasFire() const {
return special_flags & FIRE_FLAG;
}
bool hasStar() const {
return special_flags & STAR_FLAG;
}
bool isJumping() const {
return jumping;
}
bool isCrouching() const {
return _crouching;
}
bool walkingLeft() const {
return getMovement().getX() < 0;
}
bool walkingRight() const {
return getMovement().getX() > 0;
}
private:
std::function<void(std::shared_ptr<MarioBlock> &, bool)> _addObject;
void setDeath(bool dead = true) {
_death = dead;
}
bool _death = false;
bool controllable = true;
bool faces_right = true;
double side_movement = 0.3;
double jump_movement = 1.0;
bool jumping = false;
bool stop_jump = false;
bool _crouching = false;
double max_jump = 0;
double min_jump = 0;
double slow_jump = 0;
bool on_ground = true;
int ticks_till_gravity = 0;
int ticks_till_vulnurable = 0;
// gravity should be added every frame in 60fps game
const int base_gravity_ticks = 1000 / 60;
const int base_vulnurable_ticks = 1000;
const double gravity_add_jumping = jump_movement / 32.0;
const double gravity_add_falling = jump_movement / (64.0 / 7.0);
std::shared_ptr<SDLPP::RectColider> top_collision = nullptr;
void setWorldTypeSrc(LandType::Value world) override;
void stopMovement();
uint8_t special_flags = 0;
// SRCs
const SDL_Rect *standing_src = &MARIO_STANDING_SRC;
const SDL_Rect *death_src = &MARIO_DEATH_SRC;
const SDL_Rect *change_dir_src = &MARIO_CHANGE_DIR_SRC;
const SDL_Rect *jump_src = &MARIO_JUMP_SRC;
const std::vector<SDL_Rect> *walk_anim = &MARIO_WALK_ANIM;
void setBigFlag() {
special_flags = special_flags | BIG_FLAG;
}
void setFireFlag() {
special_flags = special_flags | FIRE_FLAG;
}
void setStarFlag() {
special_flags = special_flags | STAR_FLAG;
}
void unsetBigFlag() {
special_flags = special_flags & ~BIG_FLAG;
}
void unsetFireFlag() {
special_flags = special_flags & ~FIRE_FLAG;
}
void unsetStarFlag() {
special_flags = special_flags & ~STAR_FLAG;
}
};
#endif
+122
View File
@@ -0,0 +1,122 @@
#ifndef OBJECTIDS_H
#define OBJECTIDS_H
// terrain
#define BLOCK_PREFIX 0x7000
#define FLOOR_ID 0x7001
#define HILL_INCLINE_ID 0x7002
#define HILL_DECLINE_ID 0x7003
#define HILL_DOTS_RIGHT_ID 0x7004
#define HILL_DOTS_LEFT_ID 0x7005
#define HILL_FILL_ID 0x7006
#define HILL_TOP_ID 0x7007
#define BUSH_LEFT_ID 0x7008
#define BUSH_MIDDLE_ID 0x7009
#define BUSH_RIGHT_ID 0x700A
#define CLOUD_LEFT_BOTTOM_ID 0x700B
#define CLOUD_MIDDLE_BOTTOM_ID 0x700C
#define CLOUD_RIGHT_BOTTOM_ID 0x700D
#define CLOUD_LEFT_TOP_ID 0x700E
#define CLOUD_MIDDLE_TOP_ID 0x700F
#define CLOUD_RIGHT_TOP_ID 0x7010
#define PIPE_LEFT_BOTTOM_ID 0x7011
#define PIPE_LEFT_TOP_ID 0x7012
#define PIPE_RIGHT_BOTTOM_ID 0x7013
#define PIPE_RIGHT_TOP_ID 0x7014
#define CASTLE_LEFT_ID 0x7015
#define CASTLE_RIGHT_ID 0x7016
#define CASTLE_BLACK_ID 0x7017
#define CASTLE_ENTRY_ID 0x7018
#define CASTLE_TOWER_ID 0x7019
#define CASTLE_TOWER_FILLED_ID 0x701A
#define VINE_TOP_ID 0x701B
#define VINE_BOTTOM_ID 0x701C
#define POLE_TOP_ID 0x701D
#define POLE_BOTTOM_ID 0x701E
#define FLAG_ID 0x701F
#define STEP_ID 0x7020
#define BRICK_ID 0x7021
#define BRICK_TOP_ID 0x7022
#define SIDEWAY_PIPE_END_TOP_ID 0x7023
#define SIDEWAY_PIPE_END_BOTTOM_ID 0x7024
#define SIDEWAY_PIPE_MIDDLE_TOP_ID 0x7025
#define SIDEWAY_PIPE_MIDDLE_BOTTOM_ID 0x7026
#define SIDEWAY_PIPE_CONNECTOR_TOP_ID 0x7027
#define SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID 0x7028
#define TREE_PLATFORM_TOP_LEFT_ID 0x7029
#define TREE_PLATFORM_TOP_MIDDLE_ID 0x702A
#define TREE_PLATFORM_TOP_RIGHT_ID 0x702B
#define TREE_PLATFORM_BARK_ID 0x702C
#define WATER_TOP_ID 0x702D
#define WATER_FILL_ID 0x702E
#define MUSHROOM_PLATFORM_TOP_LEFT_ID 0x702F
#define MUSHROOM_PLATFORM_TOP_MIDDLE_ID 0x7030
#define MUSHROOM_PLATFORM_TOP_RIGHT_ID 0x7031
#define MUSHROOM_PLATFORM_BARK_TOP_ID 0x7032
#define MUSHROOM_PLATFORM_BARK_BOTTOM_ID 0x7033
#define TREE_BARK_ID 0x7034
#define TREE_LEAVES_SMALL_ID 0x7035
#define TREE_LEAVES_TOP_ID 0x7036
#define TREE_LEAVES_BOTTOM_ID 0x7037
#define CANNON_TOWER_ID 0x7038
#define CANNON_PEDESTAL_ID 0x7039
#define CANNON_ID 0x703A
#define COIN_ID 0x703B
#define MUSHROOM_ID 0x703C
// modifiers
#define DESTRUCTIBLE_MODIFIER_ID 0x6001
#define BACKGROUND_MODIFIER_ID 0x6002
#define COIN_MODIFIER_ID 0x6003
#define MUSHROOM_MODIFIER_ID 0x6004
#define TELEPORT_MODIFIER_ID 0x6005
// character IDs
#define MARIO_ID 0x0F
#define GOOMBA_ID 0x0E
#define TURTLE_ID 0x0D
#define DEATH_ID 0x1001
#define STOP_MOVEMENT 0x2000
#define MARIO_FLOOR_DETECT 0x2001
#define MARIO_LEFT_SIDE_DETECT 0x2002
#define MARIO_RIGHT_SIDE_DETECT 0x2003
#define MARIO_TOP_DETECT 0x2004
#define MARIO_TOP_LEFT_DETECT 0x2005
#define MARIO_TOP_RIGHT_DETECT 0x2006
#define MARIO_ENEMY_DETECT 0x2007
#define NPC_FLOOR_DETECT 0x2008
#define NPC_LEFT_SIDE_DETECT 0x2009
#define NPC_RIGHT_SIDE_DETECT 0x200A
#define NPC_TOP_DETECT 0x200B
// projectiles
#define FIREBALL_ID 0x3001
// GUI
#define BUTTON_ID 0xA000
#define EDITOR_EDIT_SQUARE 0xF001
#define EDITOR_MOUSE_ID 0xF002
#define EDITOR_LEFT_MAP_ID 0xF003
#define EDITOR_RIGHT_MAP_ID 0xF004
#define EDITOR_TERRAIN_ID 0xF005
#define EDITOR_TOOL_ID 0xF006
#define EDITOR_LEFT_TOOL_ID 0xF007
#define EDITOR_RIGHT_TOOL_ID 0xF008
#define EDITOR_CHARACTER_ID 0xF009
#define EDITOR_LEFT_MOD_ID 0xF00A
#define EDITOR_RIGHT_MOD_ID 0xF00B
#define EDITOR_LEFT_CHARACTER_ID 0xF00C
#define EDITOR_RIGHT_CHARACTER_ID 0xF00D
#define EDITOR_WORLD_CHANGE_ID 0xF00E
#define MOUSE_VISITOR_TYPE 0xE003
#define MARIO_VISITOR_TYPE 0xE004
// Collisions
#define BOUNCE_COLLISION 0x0045
#endif
File diff suppressed because it is too large Load Diff
+241
View File
@@ -0,0 +1,241 @@
#include "editor_scenes.hpp"
#include "../../sdlpp/sdlpp.hpp"
#include "../../sdlpp/sdlpp_mouse.hpp"
#include "../global_vars.hpp"
#include "../objectids.hpp"
#include "../editor_visitor.hpp"
bool __update_scenes_main_menu = false;
bool __quit_scenes_main_menu = false;
bool __started_main_menu = false;
bool *__quit_flag = nullptr;
uint64_t __cur_button_index_main_menu = -1;
uint64_t __cur_button_index_main_menu_down = -1;
std::vector<std::shared_ptr<Button>> __buttons_main_menu{};
std::shared_ptr<SDLPP::RectangleRender> __mouse_main_menu{};
void quitMainMenu() {
game_scenes.pop_back();
if (__quit_flag != nullptr) {
*__quit_flag = true;
} else {
g_quit = true;
}
}
void resumeMainMenu() {
__quit_scenes_main_menu = true;
}
void quitMainMenuCallback(void * /*UNUSED*/, Button * /*UNUSED*/) {
quitMainMenu();
}
void resumeMainMenuCallback(void * /*UNUSED*/, Button * /*UNUSED*/) {
resumeMainMenu();
}
void loadFinished(const std::string level_name) {
__quit_scenes_main_menu = true;
loadMapDialogCallback(level_name);
}
void showLoadMenu(void * /*UNUSED*/, Button * /*UNUSED*/) {
// TODO levels
auto loadMenu = createLoadScene(__buttons_main_menu.back()->getRenderer(),
"levels", loadFinished);
game_scenes.push_back(loadMenu);
}
void __updateSelectedButton_MainMenu(uint64_t new_index) {
if (new_index != __cur_button_index_main_menu &&
new_index != (uint64_t)-1) {
__buttons_main_menu[new_index]->setHighlight();
if (__cur_button_index_main_menu != (uint64_t)-1) {
__buttons_main_menu[__cur_button_index_main_menu]->unsetHighlight();
}
__cur_button_index_main_menu = new_index;
}
}
void resetGlobals() {
__update_scenes_main_menu = false;
__quit_scenes_main_menu = false;
__cur_button_index_main_menu_down = -1;
__mouse_main_menu->setPos(0, 0);
}
void handleKeyUpMainMenu(SDL_Keycode key, SDLPP::Scene & /*UNUSED*/) {
switch (key) {
case SDLK_ESCAPE:
resumeMainMenu();
break;
case SDLK_DOWN:
case SDLK_s:
if (__cur_button_index_main_menu == __buttons_main_menu.size() - 1) {
__updateSelectedButton_MainMenu(0);
} else {
__updateSelectedButton_MainMenu(__cur_button_index_main_menu + 1);
}
break;
case SDLK_UP:
case SDLK_w:
if (__cur_button_index_main_menu == 0) {
__updateSelectedButton_MainMenu(__buttons_main_menu.size() - 1);
} else {
__updateSelectedButton_MainMenu(__cur_button_index_main_menu - 1);
}
break;
case SDLK_RETURN:
if (__cur_button_index_main_menu >= 0 &&
__cur_button_index_main_menu < __buttons_main_menu.size()) {
__buttons_main_menu[__cur_button_index_main_menu]
->performFunction();
}
break;
default:
break;
}
}
std::shared_ptr<SDLPP::Scene>
createSceneMainMenu(std::shared_ptr<SDLPP::Renderer> &renderer) {
auto scene = std::make_shared<SDLPP::Scene>(renderer);
auto bg = std::make_shared<SDLPP::RectangleRender>(0, 0, 10, 10, renderer,
"#00000088", true);
bg->setPermanent();
bg->setId(1);
scene->addObject(bg);
__mouse_main_menu =
std::make_shared<SDLPP::RectangleRender>(0.01, 0.01, 0, 0, renderer);
__mouse_main_menu->setMinWidth(1);
__mouse_main_menu->setMinHeight(1);
__mouse_main_menu->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
__mouse_main_menu->setId(EDITOR_MOUSE_ID);
__mouse_main_menu->setColiderColor("#00FF00");
__mouse_main_menu->addCollision(SDLPP::RectColider({ 0, 0 }, { 1, 1 }));
scene->addObject(__mouse_main_menu);
ButtonConfig default_button_theme{};
default_button_theme.bg_color = "#FFFFFF88";
default_button_theme.bg_color_highlight = "#FFFFFFBB";
default_button_theme.bg_color_disabled = "#AAAAAA88";
default_button_theme.font_color = "#000000";
default_button_theme.font_color_highlight = "#000000";
default_button_theme.font_color_disabled = "#555555";
default_button_theme.font_outline_color = "#FFFFFF88";
default_button_theme.font_outline_color_highlight = "#FFFFFFAA";
default_button_theme.font_outline_color_disabled = "#787878";
default_button_theme.outline = 0.1;
// buttons
__buttons_main_menu.emplace_back(std::make_shared<Button>(
0.2, 0.25, 0.6, 0.1, renderer, "SAVE", default_button_theme,
saveMapCallback, nullptr));
__buttons_main_menu.back()->setAlignment(SDLPP::OBJ_CENTER,
SDLPP::OBJ_CENTER);
__buttons_main_menu.back()->setPermanent();
__buttons_main_menu.back()->setButtonIndex(__buttons_main_menu.size() - 1);
__buttons_main_menu.emplace_back(
std::make_shared<Button>(0.2, 0.4, 0.6, 0.1, renderer, "LOAD",
default_button_theme, showLoadMenu, nullptr));
__buttons_main_menu.back()->setAlignment(SDLPP::OBJ_CENTER,
SDLPP::OBJ_CENTER);
__buttons_main_menu.back()->setPermanent();
__buttons_main_menu.back()->setButtonIndex(__buttons_main_menu.size() - 1);
__buttons_main_menu.emplace_back(std::make_shared<Button>(
0.2, 0.55, 0.6, 0.1, renderer, "RESUME", default_button_theme,
resumeMainMenuCallback, nullptr));
__buttons_main_menu.back()->setAlignment(SDLPP::OBJ_CENTER,
SDLPP::OBJ_CENTER);
__buttons_main_menu.back()->setPermanent();
__buttons_main_menu.back()->setButtonIndex(__buttons_main_menu.size() - 1);
__buttons_main_menu.emplace_back(std::make_shared<Button>(
0.2, 0.7, 0.6, 0.1, renderer, "QUIT", default_button_theme,
quitMainMenuCallback, nullptr));
__buttons_main_menu.back()->setAlignment(SDLPP::OBJ_CENTER,
SDLPP::OBJ_CENTER);
__buttons_main_menu.back()->setPermanent();
__buttons_main_menu.back()->setButtonIndex(__buttons_main_menu.size() - 1);
for (auto &button : __buttons_main_menu) {
scene->addObject(button);
}
return scene;
}
void additionalRenderMainMenu(std::shared_ptr<SDLPP::Scene> & /*UNUSED*/) {
if (__update_scenes_main_menu) {
for (auto &_scene : game_scenes) {
_scene.scene->updateSizeAndPosition();
}
if (__started_main_menu) {
__update_scenes_main_menu = false;
} else {
__started_main_menu = true;
}
}
if (__quit_scenes_main_menu) {
game_scenes.pop_back();
resetGlobals();
}
}
void getMousePositionFlagsMainMenu(SDLPP::Scene &scene) {
auto mouse = scene.getObjects({ EDITOR_MOUSE_ID })[0];
// move mouse colider to mouse position
mouse->setPos(SDLPP::Mouse::getMousePositionDouble(
scene.getRenderer(), SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER));
MouseVisitor visitor;
scene.visitCollisions(*mouse, visitor);
__updateSelectedButton_MainMenu(visitor.getCurButton());
}
void pollEventsMainMenu(std::shared_ptr<SDLPP::Scene> &scene) {
SDL_Event event;
while (SDLPP::getSDLEvent(event)) {
switch (event.type) {
case SDL_QUIT:
quitMainMenu();
break;
case SDL_KEYUP:
handleKeyUpMainMenu(event.key.keysym.sym, *scene);
break;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
__update_scenes_main_menu = true;
}
break;
case SDL_MOUSEMOTION:
getMousePositionFlagsMainMenu(*scene);
break;
case SDL_MOUSEBUTTONUP:
if (__cur_button_index_main_menu_down ==
__cur_button_index_main_menu &&
__cur_button_index_main_menu != (uint64_t)-1) {
__buttons_main_menu[__cur_button_index_main_menu]
->performFunction();
}
break;
case SDL_MOUSEBUTTONDOWN:
// store current mouse flags in previous mouse flags
__cur_button_index_main_menu_down = __cur_button_index_main_menu;
break;
default:
break;
}
}
}
SceneStruct
createEditorMainMenuScene(std::shared_ptr<SDLPP::Renderer> &renderer,
bool *quit_flag) {
SceneStruct ret{};
ret.scene = createSceneMainMenu(renderer);
ret.additionalRender = additionalRenderMainMenu;
ret.doInput = pollEventsMainMenu;
__update_scenes_main_menu = true;
__updateSelectedButton_MainMenu(0);
__quit_flag = quit_flag;
return ret;
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef EDITOR_SCENES_HPP
#define EDITOR_SCENES_HPP
#include "../../sdlpp/sdlpp_scene.hpp"
#include "../gui/gui.hpp"
#include <functional>
#include "shared_scenes.hpp"
extern std::mutex render_mutex;
extern std::vector<SceneStruct> game_scenes;
void saveMapCallback(void *input, Button *caller);
void loadMapDialogCallback(const std::string &level_name);
SceneStruct createEditorScene(std::shared_ptr<SDLPP::Renderer> &renderer);
SceneStruct
createEditorMainMenuScene(std::shared_ptr<SDLPP::Renderer> &renderer,
bool *quit_flag);
SceneStruct
createEditorFileChoiceScene(std::shared_ptr<SDLPP::Renderer> &renderer);
SceneStruct createTextScene(std::shared_ptr<SDLPP::Renderer> renderer,
std::function<void(const std::string &)> finalizer);
#endif
+269
View File
@@ -0,0 +1,269 @@
#include "editor_scenes.hpp"
#include "../../sdlpp/sdlpp.hpp"
#include "../../sdlpp/sdlpp_mouse.hpp"
#include "../global_vars.hpp"
#include "../objectids.hpp"
#include "../editor_visitor.hpp"
#include <functional>
#include "../sprites.hpp"
bool __update_scenes_main_menu = false;
bool __quit_scenes_main_menu = false;
bool __restart_scenes_main_menu = false;
bool __started_main_menu = false;
bool __include_resume = false;
uint64_t __cur_button_index_main_menu = -1;
uint64_t __cur_button_index_main_menu_down = -1;
std::vector<std::shared_ptr<Button>> __buttons_main_menu{};
std::shared_ptr<SDLPP::RectangleRender> __mouse_main_menu{};
extern void loadLevel(const std::string &level);
extern void loadLastLevel();
void quitMainMenu() {
g_quit = true;
}
void resumeMainMenu() {
__quit_scenes_main_menu = true;
}
void restartMainMenu() {
__quit_scenes_main_menu = true;
__restart_scenes_main_menu = true;
}
void quitMainMenuCallback(void * /*UNUSED*/, Button * /*UNUSED*/) {
quitMainMenu();
}
void resumeMainMenuCallback(void * /*UNUSED*/, Button * /*UNUSED*/) {
resumeMainMenu();
}
void restartMainMenuCallback(void * /*UNUSED*/, Button * /*UNUSED*/) {
restartMainMenu();
}
void resetGlobals() {
__update_scenes_main_menu = false;
__quit_scenes_main_menu = false;
__restart_scenes_main_menu = false;
__started_main_menu = false;
__cur_button_index_main_menu_down = -1;
__mouse_main_menu.reset();
__buttons_main_menu.clear();
}
void showLoadMenu(void * /*UNUSED*/, Button * /*UNUSED*/) {
auto loadMenu = createLoadScene(__buttons_main_menu.back()->getRenderer(),
"levels", loadLevel, false, false);
std::lock_guard<std::mutex> lock(render_mutex);
game_scenes.pop_back();
resetGlobals();
game_scenes.push_back(loadMenu);
}
void __updateSelectedButton_MainMenu(uint64_t new_index) {
if (new_index != (uint64_t)-1) {
__buttons_main_menu[new_index]->setHighlight();
if (__cur_button_index_main_menu != (uint64_t)-1 &&
new_index != __cur_button_index_main_menu) {
__buttons_main_menu[__cur_button_index_main_menu]->unsetHighlight();
}
__cur_button_index_main_menu = new_index;
}
}
void handleKeyUpMainMenu(SDL_Keycode key, SDLPP::Scene & /*UNUSED*/) {
switch (key) {
case SDLK_ESCAPE:
if (__include_resume) {
resumeMainMenu();
} else {
quitMainMenu();
}
break;
case SDLK_DOWN:
case SDLK_s:
if (__cur_button_index_main_menu == __buttons_main_menu.size() - 1) {
__updateSelectedButton_MainMenu(0);
} else {
__updateSelectedButton_MainMenu(__cur_button_index_main_menu + 1);
}
break;
case SDLK_UP:
case SDLK_w:
if (__cur_button_index_main_menu == 0) {
__updateSelectedButton_MainMenu(__buttons_main_menu.size() - 1);
} else {
__updateSelectedButton_MainMenu(__cur_button_index_main_menu - 1);
}
break;
case SDLK_RETURN:
if (__cur_button_index_main_menu >= 0 &&
__cur_button_index_main_menu < __buttons_main_menu.size()) {
__buttons_main_menu[__cur_button_index_main_menu]
->performFunction();
}
break;
default:
break;
}
}
std::shared_ptr<SDLPP::Scene>
createSceneMainMenu(std::shared_ptr<SDLPP::Renderer> &renderer,
bool include_restart, bool include_resume,
bool transparent_bg) {
auto scene = std::make_shared<SDLPP::Scene>(renderer);
auto bg = std::make_shared<SDLPP::RectangleRender>(
0, 0, 10, 10, renderer,
transparent_bg ? "#00000088" : MARIO_OVERWORLD_COLORKEY, true);
bg->setPermanent();
bg->setId(1);
scene->addObject(bg);
__mouse_main_menu =
std::make_shared<SDLPP::RectangleRender>(0.01, 0.01, 0, 0, renderer);
__mouse_main_menu->setMinWidth(1);
__mouse_main_menu->setMinHeight(1);
__mouse_main_menu->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
__mouse_main_menu->setId(EDITOR_MOUSE_ID);
__mouse_main_menu->setColiderColor("#00FF00");
__mouse_main_menu->addCollision(SDLPP::RectColider({ 0, 0 }, { 1, 1 }));
scene->addObject(__mouse_main_menu);
ButtonConfig default_button_theme{};
default_button_theme.bg_color = "#FFFFFF88";
default_button_theme.bg_color_highlight = "#FFFFFFBB";
default_button_theme.bg_color_disabled = "#AAAAAA88";
default_button_theme.font_color = "#000000";
default_button_theme.font_color_highlight = "#000000";
default_button_theme.font_color_disabled = "#555555";
default_button_theme.font_outline_color = "#FFFFFF88";
default_button_theme.font_outline_color_highlight = "#FFFFFFAA";
default_button_theme.font_outline_color_disabled = "#787878";
default_button_theme.outline = 0.1;
// buttons
if (include_resume) {
__buttons_main_menu.emplace_back(std::make_shared<Button>(
0.2, 0.25, 0.6, 0.1, renderer, "RESUME", default_button_theme,
resumeMainMenuCallback, nullptr));
__buttons_main_menu.back()->setAlignment(SDLPP::OBJ_CENTER,
SDLPP::OBJ_CENTER);
__buttons_main_menu.back()->setPermanent();
__buttons_main_menu.back()->setButtonIndex(__buttons_main_menu.size() -
1);
}
if (include_restart || include_resume) {
__buttons_main_menu.emplace_back(std::make_shared<Button>(
0.2, 0.4, 0.6, 0.1, renderer, "RESTART", default_button_theme,
restartMainMenuCallback, nullptr));
__buttons_main_menu.back()->setAlignment(SDLPP::OBJ_CENTER,
SDLPP::OBJ_CENTER);
__buttons_main_menu.back()->setPermanent();
__buttons_main_menu.back()->setButtonIndex(__buttons_main_menu.size() -
1);
}
__buttons_main_menu.emplace_back(
std::make_shared<Button>(0.2, 0.55, 0.6, 0.1, renderer, "LOAD",
default_button_theme, showLoadMenu, nullptr));
__buttons_main_menu.back()->setAlignment(SDLPP::OBJ_CENTER,
SDLPP::OBJ_CENTER);
__buttons_main_menu.back()->setPermanent();
__buttons_main_menu.back()->setButtonIndex(__buttons_main_menu.size() - 1);
__buttons_main_menu.emplace_back(std::make_shared<Button>(
0.2, 0.85, 0.6, 0.1, renderer, "QUIT", default_button_theme,
quitMainMenuCallback, nullptr));
__buttons_main_menu.back()->setAlignment(SDLPP::OBJ_CENTER,
SDLPP::OBJ_CENTER);
__buttons_main_menu.back()->setPermanent();
__buttons_main_menu.back()->setButtonIndex(__buttons_main_menu.size() - 1);
for (auto &button : __buttons_main_menu) {
scene->addObject(button);
}
return scene;
}
void additionalRenderMainMenu(std::shared_ptr<SDLPP::Scene> & /*UNUSED*/) {
if (__update_scenes_main_menu) {
for (auto &_scene : game_scenes) {
_scene.scene->updateSizeAndPosition();
}
if (__started_main_menu) {
__update_scenes_main_menu = false;
} else {
__started_main_menu = true;
}
}
if (__quit_scenes_main_menu) {
game_scenes.pop_back();
game_scenes.back().scene->unpauseScene();
if (__restart_scenes_main_menu) {
loadLastLevel();
}
resetGlobals();
}
}
void getMousePositionFlagsMainMenu(SDLPP::Scene &scene) {
auto mouse = scene.getObjects({ EDITOR_MOUSE_ID })[0];
// move mouse colider to mouse position
mouse->setPos(SDLPP::Mouse::getMousePositionDouble(
scene.getRenderer(), SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER));
MouseVisitor visitor;
scene.visitCollisions(*mouse, visitor);
__updateSelectedButton_MainMenu(visitor.getCurButton());
}
void pollEventsMainMenu(std::shared_ptr<SDLPP::Scene> &scene) {
SDL_Event event;
while (SDLPP::getSDLEvent(event)) {
switch (event.type) {
case SDL_QUIT:
quitMainMenu();
break;
case SDL_KEYUP:
handleKeyUpMainMenu(event.key.keysym.sym, *scene);
break;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
__update_scenes_main_menu = true;
}
break;
case SDL_MOUSEMOTION:
getMousePositionFlagsMainMenu(*scene);
break;
case SDL_MOUSEBUTTONUP:
if (__cur_button_index_main_menu_down ==
__cur_button_index_main_menu &&
__cur_button_index_main_menu != (uint64_t)-1) {
__buttons_main_menu[__cur_button_index_main_menu]
->performFunction();
}
break;
case SDL_MOUSEBUTTONDOWN:
// store current mouse flags in previous mouse flags
__cur_button_index_main_menu_down = __cur_button_index_main_menu;
break;
default:
break;
}
}
}
SceneStruct createGameMainMenuScene(std::shared_ptr<SDLPP::Renderer> &renderer,
bool include_restart, bool include_resume,
bool transparent_background) {
__include_resume = include_resume;
SceneStruct ret{};
ret.scene = createSceneMainMenu(renderer, include_restart, include_resume,
transparent_background);
ret.additionalRender = additionalRenderMainMenu;
ret.doInput = pollEventsMainMenu;
__update_scenes_main_menu = true;
__updateSelectedButton_MainMenu(0);
return ret;
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef GAME_SCENES_HPP
#define GAME_SCENES_HPP
#include "../../sdlpp/sdlpp_scene.hpp"
#include "../gui/gui.hpp"
#include <functional>
#include "shared_scenes.hpp"
extern std::mutex render_mutex;
extern std::vector<SceneStruct> game_scenes;
SceneStruct createGameMainMenuScene(std::shared_ptr<SDLPP::Renderer> &renderer,
bool include_restart = true,
bool include_resume = true,
bool transparent_background = true);
SceneStruct createGameRetryScene(std::shared_ptr<SDLPP::Renderer> &renderer);
#endif
+277
View File
@@ -0,0 +1,277 @@
#include <utility>
#include "SDL2/SDL_keycode.h"
#include "editor_scenes.hpp"
#include "../../sdlpp/sdlpp.hpp"
#include "../../sdlpp/sdlpp_mouse.hpp"
#include "../global_vars.hpp"
#include "../objectids.hpp"
#include "../editor_visitor.hpp"
#include "../filesystem.hpp"
#include "../sprites.hpp"
bool __update_scenes_load_dialog = false;
bool __quit_scenes_load_dialog = false;
bool __started_load_dialog = false;
bool __pop_at_finish_load_dialog = false;
uint64_t __cur_button_index_load_dialog = -1;
uint64_t __cur_button_index_load_dialog_down = -1;
std::vector<std::shared_ptr<Button>> __buttons_load_dialog{};
std::shared_ptr<SDLPP::RectangleRender> __mouse_load_dialog{};
std::function<void(const std::string &)> __load_dialog_finalizer;
std::string __selected_level_load_dialog = "";
void __quitLoadDialog() {
__quit_scenes_load_dialog = true;
}
void __updateSelectedButton_LoadDialog(uint64_t new_index) {
if (new_index != __cur_button_index_load_dialog &&
new_index != (uint64_t)-1) {
__buttons_load_dialog[new_index]->setHighlight();
if (__cur_button_index_load_dialog != (uint64_t)-1) {
__buttons_load_dialog[__cur_button_index_load_dialog]
->unsetHighlight();
}
__cur_button_index_load_dialog = new_index;
}
}
void __quitCallback_LoadDialog(void * /*UNUSED*/, Button *btn) {
__selected_level_load_dialog = btn->getText();
__quitLoadDialog();
}
void __moveButtons(double movement) {
for (auto &button : __buttons_load_dialog) {
button->setPos(button->getPos() + SDLPP::Vec2D<double>(0, movement));
}
__update_scenes_load_dialog = true;
}
void __selectUpperButton() {
if (__cur_button_index_load_dialog > 0) {
__updateSelectedButton_LoadDialog(__cur_button_index_load_dialog - 1);
if (__buttons_load_dialog[__cur_button_index_load_dialog]
->getPos()
.getY() < 0.49) {
__moveButtons(0.25);
}
}
}
void __selectLowerButton() {
if (__cur_button_index_load_dialog < __buttons_load_dialog.size() - 1) {
__updateSelectedButton_LoadDialog(__cur_button_index_load_dialog + 1);
auto pos =
__buttons_load_dialog[__cur_button_index_load_dialog]->getPos();
if (__buttons_load_dialog[__cur_button_index_load_dialog]
->getPos()
.getY() > 0.99) {
__moveButtons(-0.25);
}
}
}
void __handleKeyUp_LoadDialog(SDL_Keycode key, SDLPP::Scene & /*UNUSED*/) {
switch (key) {
case SDLK_ESCAPE:
__selected_level_load_dialog = "";
__quitLoadDialog();
break;
case SDLK_RETURN:
__buttons_load_dialog[__cur_button_index_load_dialog]
->performFunction();
break;
case SDLK_UP:
case SDLK_w:
__selectUpperButton();
break;
case SDLK_DOWN:
case SDLK_s:
__selectLowerButton();
break;
default:
break;
}
}
void addLevelButton(const std::string &path, const std::string &file,
double &start_height, const int initial_path_len,
std::shared_ptr<SDLPP::Renderer> &renderer,
ButtonConfig &button_theme) {
if (FSLib::isDirectory(path + FSLib::dir_divisor + file)) {
for (const auto &file_rec :
FSLib::Directory(path + FSLib::dir_divisor + file)) {
addLevelButton(path + FSLib::dir_divisor + file, file_rec,
start_height, initial_path_len, renderer,
button_theme);
}
} else {
__buttons_load_dialog.emplace_back(std::make_shared<Button>(
0.3, start_height, 0.4, 0.2, renderer,
(path + FSLib::dir_divisor + file).substr(initial_path_len),
button_theme, __quitCallback_LoadDialog, nullptr));
__buttons_load_dialog.back()->setAlignment(SDLPP::OBJ_CENTER,
SDLPP::OBJ_CENTER);
__buttons_load_dialog.back()->setPermanent();
__buttons_load_dialog.back()->setButtonIndex(
__buttons_load_dialog.size() - 1);
start_height += 0.25;
}
}
std::shared_ptr<SDLPP::Scene>
createSceneLoadDialog(std::shared_ptr<SDLPP::Renderer> &renderer,
const std::string &path, bool transparent_bg) {
auto scene = std::make_shared<SDLPP::Scene>(renderer);
auto bg = std::make_shared<SDLPP::RectangleRender>(0, 0, 10, 10, renderer,
transparent_bg ? "#000000BB" : MARIO_OVERWORLD_COLORKEY, true);
bg->setPermanent();
bg->setId(1);
scene->addObject(bg);
__mouse_load_dialog =
std::make_shared<SDLPP::RectangleRender>(0.01, 0.01, 0, 0, renderer);
__mouse_load_dialog->setMinWidth(1);
__mouse_load_dialog->setMinHeight(1);
__mouse_load_dialog->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
__mouse_load_dialog->setId(EDITOR_MOUSE_ID);
__mouse_load_dialog->setColiderColor("#00FF00");
__mouse_load_dialog->addCollision(SDLPP::RectColider({ 0, 0 }, { 1, 1 }));
scene->addObject(__mouse_load_dialog);
ButtonConfig default_button_theme{};
default_button_theme.bg_color = "#FFFFFF88";
default_button_theme.bg_color_highlight = "#FFFFFFBB";
default_button_theme.bg_color_disabled = "#AAAAAA88";
default_button_theme.font_color = "#000000";
default_button_theme.font_color_highlight = "#000000";
default_button_theme.font_color_disabled = "#555555";
default_button_theme.font_outline_color = "#FFFFFF88";
default_button_theme.font_outline_color_highlight = "#FFFFFFAA";
default_button_theme.font_outline_color_disabled = "#787878";
default_button_theme.outline = 0.1;
// buttons
double start_height = 0.5;
for (const auto &file : FSLib::Directory(path)) {
addLevelButton(path, file, start_height, path.length() + 1, renderer,
default_button_theme);
}
for (auto &button : __buttons_load_dialog) {
scene->addObject(button);
}
auto font_config = std::make_shared<SDLPP::FontConfiguration>(
g_text_config->getFont(), "#000000", "#FFFFFFAA", 0.05);
auto dialog_text = std::make_shared<SDLPP::TextRenderer>(
0.1, 0.15, 0.8, 0.3, renderer, "LEVELS", font_config,
SDLPP_TEXT_CENTER);
dialog_text->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
dialog_text->setPermanent();
scene->addObject(dialog_text);
return scene;
}
void __resetGlobals_LoadDialog() {
__update_scenes_load_dialog = false;
__quit_scenes_load_dialog = false;
__started_load_dialog = false;
__pop_at_finish_load_dialog = false;
__cur_button_index_load_dialog = -1;
__cur_button_index_load_dialog_down = -1;
__buttons_load_dialog.clear();
__mouse_load_dialog.reset();
__selected_level_load_dialog = "";
}
void __additionalRender_LoadDialog(std::shared_ptr<SDLPP::Scene> & /*UNUSED*/) {
if (__update_scenes_load_dialog) {
for (auto &_scene : game_scenes) {
_scene.scene->updateSizeAndPosition();
}
if (__started_load_dialog) {
__update_scenes_load_dialog = false;
} else {
__started_load_dialog = true;
}
}
if (__quit_scenes_load_dialog) {
__load_dialog_finalizer(__selected_level_load_dialog);
if(__pop_at_finish_load_dialog) {
game_scenes.pop_back();
}
__resetGlobals_LoadDialog();
}
}
void __getMousePositionFlags_LoadDialog(SDLPP::Scene &scene) {
auto mouse = scene.getObjects({ EDITOR_MOUSE_ID })[0];
// move mouse colider to mouse position
mouse->setPos(SDLPP::Mouse::getMousePositionDouble(
scene.getRenderer(), SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER));
MouseVisitor visitor;
scene.visitCollisions(*mouse, visitor);
__updateSelectedButton_LoadDialog(visitor.getCurButton());
//__cur_button_index_load_dialog = visitor.getCurButton();
}
void __pollEvents_LoadDialog(std::shared_ptr<SDLPP::Scene> &scene) {
SDL_Event event;
while (SDLPP::getSDLEvent(event)) {
switch (event.type) {
case SDL_QUIT:
__quitLoadDialog();
break;
case SDL_KEYUP:
__handleKeyUp_LoadDialog(event.key.keysym.sym, *scene);
break;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
__update_scenes_load_dialog = true;
}
break;
case SDL_MOUSEMOTION:
__getMousePositionFlags_LoadDialog(*scene);
break;
case SDL_MOUSEBUTTONUP:
if (__cur_button_index_load_dialog_down ==
__cur_button_index_load_dialog &&
__cur_button_index_load_dialog != (uint64_t)-1) {
__buttons_load_dialog[__cur_button_index_load_dialog]
->performFunction();
}
break;
case SDL_MOUSEBUTTONDOWN:
// store current mouse flags in previous mouse flags
__cur_button_index_load_dialog_down =
__cur_button_index_load_dialog;
break;
case SDL_MOUSEWHEEL:
if (event.wheel.y < 0) {
__moveButtons(-0.02);
} else if (event.wheel.y < 0) {
__moveButtons(0.02);
}
break;
default:
break;
}
}
}
SceneStruct
createLoadScene(std::shared_ptr<SDLPP::Renderer> renderer,
const std::string &path,
std::function<void(const std::string &)> finalizer,
bool pop_at_finish, bool transparent_bg) {
__load_dialog_finalizer = std::move(finalizer);
__pop_at_finish_load_dialog = pop_at_finish;
SceneStruct ret{};
ret.scene = createSceneLoadDialog(renderer, path, transparent_bg);
ret.additionalRender = __additionalRender_LoadDialog;
ret.doInput = __pollEvents_LoadDialog;
__update_scenes_load_dialog = true;
__updateSelectedButton_LoadDialog(0);
return ret;
}
+175
View File
@@ -0,0 +1,175 @@
#include "SDL2/SDL_keycode.h"
#include "editor_scenes.hpp"
#include "../../sdlpp/sdlpp.hpp"
#include "../../sdlpp/sdlpp_mouse.hpp"
#include "../global_vars.hpp"
#include "../objectids.hpp"
#include "../editor_visitor.hpp"
bool __update_scenes_ok_dialog = false;
bool __quit_scenes_ok_dialog = false;
bool __started_ok_dialog = false;
uint64_t __cur_button_index_ok_dialog = -1;
uint64_t __cur_button_index_ok_dialog_down = -1;
std::vector<std::shared_ptr<Button>> __buttons_ok_dialog{};
std::shared_ptr<SDLPP::RectangleRender> __mouse_ok_dialog{};
std::function<void()> __ok_dialog_finalizer;
void __quitOkDialog() {
__quit_scenes_ok_dialog = true;
}
void __quitCallback_OkDialog(void * /*UNUSED*/, Button * /*UNUSED*/) {
__quitOkDialog();
}
void __handleKeyUp_OkDialog(SDL_Keycode key, SDLPP::Scene & /*UNUSED*/) {
switch (key) {
case SDLK_ESCAPE:
case SDLK_RETURN:
__quitOkDialog();
break;
default:
break;
}
}
std::shared_ptr<SDLPP::Scene>
createSceneOkDialog(std::shared_ptr<SDLPP::Renderer> &renderer,
const std::string &text) {
auto scene = std::make_shared<SDLPP::Scene>(renderer);
auto bg = std::make_shared<SDLPP::RectangleRender>(0, 0, 10, 10, renderer,
"#00000088", true);
bg->setPermanent();
bg->setId(1);
scene->addObject(bg);
__mouse_ok_dialog =
std::make_shared<SDLPP::RectangleRender>(0.01, 0.01, 0, 0, renderer);
__mouse_ok_dialog->setMinWidth(1);
__mouse_ok_dialog->setMinHeight(1);
__mouse_ok_dialog->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
__mouse_ok_dialog->setId(EDITOR_MOUSE_ID);
__mouse_ok_dialog->setColiderColor("#00FF00");
__mouse_ok_dialog->addCollision(SDLPP::RectColider({ 0, 0 }, { 1, 1 }));
scene->addObject(__mouse_ok_dialog);
ButtonConfig default_button_theme{};
default_button_theme.bg_color = "#FFFFFF88";
default_button_theme.bg_color_highlight = "#FFFFFFBB";
default_button_theme.bg_color_disabled = "#AAAAAA88";
default_button_theme.font_color = "#000000";
default_button_theme.font_color_highlight = "#000000";
default_button_theme.font_color_disabled = "#555555";
default_button_theme.font_outline_color = "#FFFFFF88";
default_button_theme.font_outline_color_highlight = "#FFFFFFAA";
default_button_theme.font_outline_color_disabled = "#787878";
default_button_theme.outline = 0.1;
// buttons
__buttons_ok_dialog.emplace_back(std::make_shared<Button>(
0.3, 0.5, 0.4, 0.2, renderer, "OK", default_button_theme,
__quitCallback_OkDialog, nullptr));
__buttons_ok_dialog.back()->setAlignment(SDLPP::OBJ_CENTER,
SDLPP::OBJ_CENTER);
__buttons_ok_dialog.back()->setPermanent();
__buttons_ok_dialog.back()->setButtonIndex(__buttons_ok_dialog.size() - 1);
__buttons_ok_dialog.back()->setHighlight();
for (auto &button : __buttons_ok_dialog) {
scene->addObject(button);
}
auto font_config = std::make_shared<SDLPP::FontConfiguration>(
g_text_config->getFont(), "#000000", "#282828", 0.05);
auto dialog_text = std::make_shared<SDLPP::TextRenderer>(
0.1, 0.15, 0.8, 0.3, renderer, text, font_config, SDLPP_TEXT_CENTER);
dialog_text->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
dialog_text->setPermanent();
scene->addObject(dialog_text);
return scene;
}
void __resetGlobals_OkDialog() {
__update_scenes_ok_dialog = false;
__quit_scenes_ok_dialog = false;
__started_ok_dialog = false;
__cur_button_index_ok_dialog = -1;
__cur_button_index_ok_dialog_down = -1;
__buttons_ok_dialog.clear();
__mouse_ok_dialog.reset();
}
void __additionalRender_OkDialog(std::shared_ptr<SDLPP::Scene> & /*UNUSED*/) {
if (__update_scenes_ok_dialog) {
for (auto &_scene : game_scenes) {
_scene.scene->updateSizeAndPosition();
}
if (__started_ok_dialog) {
__update_scenes_ok_dialog = false;
} else {
__started_ok_dialog = true;
}
}
if (__quit_scenes_ok_dialog) {
__ok_dialog_finalizer();
game_scenes.pop_back();
__resetGlobals_OkDialog();
}
}
void __getMousePositionFlags_OkDialog(SDLPP::Scene &scene) {
auto mouse = scene.getObjects({ EDITOR_MOUSE_ID })[0];
// move mouse colider to mouse position
mouse->setPos(SDLPP::Mouse::getMousePositionDouble(
scene.getRenderer(), SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER));
MouseVisitor visitor;
scene.visitCollisions(*mouse, visitor);
__cur_button_index_ok_dialog = visitor.getCurButton();
}
void __pollEvents_OkDialog(std::shared_ptr<SDLPP::Scene> &scene) {
SDL_Event event;
while (SDLPP::getSDLEvent(event)) {
switch (event.type) {
case SDL_QUIT:
__quitOkDialog();
break;
case SDL_KEYUP:
__handleKeyUp_OkDialog(event.key.keysym.sym, *scene);
break;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
__update_scenes_ok_dialog = true;
}
break;
case SDL_MOUSEMOTION:
__getMousePositionFlags_OkDialog(*scene);
break;
case SDL_MOUSEBUTTONUP:
if (__cur_button_index_ok_dialog_down ==
__cur_button_index_ok_dialog &&
__cur_button_index_ok_dialog != (uint64_t)-1) {
__buttons_ok_dialog[__cur_button_index_ok_dialog]
->performFunction();
}
break;
case SDL_MOUSEBUTTONDOWN:
// store current mouse flags in previous mouse flags
__cur_button_index_ok_dialog_down = __cur_button_index_ok_dialog;
break;
default:
break;
}
}
}
SceneStruct createOkScene(std::shared_ptr<SDLPP::Renderer> renderer,
const std::string &text,
std::function<void()> finalizer) {
__ok_dialog_finalizer = finalizer;
SceneStruct ret{};
ret.scene = createSceneOkDialog(renderer, text);
ret.additionalRender = __additionalRender_OkDialog;
ret.doInput = __pollEvents_OkDialog;
__update_scenes_ok_dialog = true;
return ret;
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef SHARED_SCENES_HPP
#define SHARED_SCENES_HPP
#include "../../sdlpp/sdlpp_scene.hpp"
#include <functional>
struct SceneStruct {
std::shared_ptr<SDLPP::Scene> scene;
std::function<void(std::shared_ptr<SDLPP::Scene> &)> doInput;
std::function<void(std::shared_ptr<SDLPP::Scene> &)> additionalRender;
};
SceneStruct createYesNoScene(std::shared_ptr<SDLPP::Renderer> renderer,
const std::string &text,
std::function<void(bool)> finalizer);
SceneStruct createOkScene(std::shared_ptr<SDLPP::Renderer> renderer,
const std::string &text,
std::function<void()> finalizer);
SceneStruct createLoadScene(std::shared_ptr<SDLPP::Renderer> renderer,
const std::string &path,
std::function<void(const std::string &)> finalizer,
bool pop_at_finish = true,
bool transparent_bg = true);
#endif
+216
View File
@@ -0,0 +1,216 @@
#include "SDL2/SDL_keycode.h"
#include "editor_scenes.hpp"
#include "../../sdlpp/sdlpp.hpp"
#include "../../sdlpp/sdlpp_mouse.hpp"
#include "../global_vars.hpp"
#include "../objectids.hpp"
#include "../editor_visitor.hpp"
bool __update_scenes_text_dialog = false;
bool __quit_scenes_text_dialog = false;
bool __started_text_dialog = false;
bool __update_text = false;
uint64_t __cur_button_index_text_dialog = -1;
uint64_t __cur_button_index_text_dialog_down = -1;
std::vector<std::shared_ptr<Button>> __buttons_text_dialog{};
std::shared_ptr<SDLPP::RectangleRender> __mouse_text_dialog{};
std::shared_ptr<SDLPP::TextRenderer> __level_name_object{};
std::string __level_name_text = "LEVEL NAME";
std::function<void(const std::string &)> __text_dialog_finalizer;
void __quitTextDialog() {
__quit_scenes_text_dialog = true;
}
void __quitCallback_TextDialog(void * /*UNUSED*/, Button * /*UNUSED*/) {
__quitTextDialog();
}
void __handleKeyUp_TextDialog(SDL_Keycode key, SDLPP::Scene & /*UNUSED*/) {
switch (key) {
case SDLK_ESCAPE:
__level_name_text = "";
// fallthrough
case SDLK_RETURN:
__quitTextDialog();
break;
default:
break;
}
}
std::shared_ptr<SDLPP::Scene>
createSceneTextDialog(std::shared_ptr<SDLPP::Renderer> &renderer) {
auto scene = std::make_shared<SDLPP::Scene>(renderer);
auto bg = std::make_shared<SDLPP::RectangleRender>(0, 0, 10, 10, renderer,
"#00000088", true);
bg->setPermanent();
bg->setId(1);
scene->addObject(bg);
__mouse_text_dialog =
std::make_shared<SDLPP::RectangleRender>(0.01, 0.01, 0, 0, renderer);
__mouse_text_dialog->setMinWidth(1);
__mouse_text_dialog->setMinHeight(1);
__mouse_text_dialog->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
__mouse_text_dialog->setId(EDITOR_MOUSE_ID);
__mouse_text_dialog->setColiderColor("#00FF00");
__mouse_text_dialog->addCollision(SDLPP::RectColider({ 0, 0 }, { 1, 1 }));
scene->addObject(__mouse_text_dialog);
ButtonConfig default_button_theme{};
default_button_theme.bg_color = "#FFFFFF88";
default_button_theme.bg_color_highlight = "#FFFFFFBB";
default_button_theme.bg_color_disabled = "#AAAAAA88";
default_button_theme.font_color = "#000000";
default_button_theme.font_color_highlight = "#000000";
default_button_theme.font_color_disabled = "#555555";
default_button_theme.font_outline_color = "#FFFFFF88";
default_button_theme.font_outline_color_highlight = "#FFFFFFAA";
default_button_theme.font_outline_color_disabled = "#787878";
default_button_theme.outline = 0.1;
// buttons
__buttons_text_dialog.emplace_back(std::make_shared<Button>(
0.3, 0.7, 0.4, 0.2, renderer, "OK", default_button_theme,
__quitCallback_TextDialog, nullptr));
__buttons_text_dialog.back()->setAlignment(SDLPP::OBJ_CENTER,
SDLPP::OBJ_CENTER);
__buttons_text_dialog.back()->setPermanent();
__buttons_text_dialog.back()->setButtonIndex(__buttons_text_dialog.size() - 1);
__buttons_text_dialog.back()->setHighlight();
for (auto &button : __buttons_text_dialog) {
scene->addObject(button);
}
auto font_config = std::make_shared<SDLPP::FontConfiguration>(
g_text_config->getFont(), "#000000", "#282828", 0.05);
// level name
__level_name_object = std::make_shared<SDLPP::TextRenderer>(
0.1, 0.4, 0.8, 0.2, renderer, __level_name_text,
font_config, SDLPP_TEXT_LEFT);
__level_name_object->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
__level_name_object->setPermanent();
__level_name_object->setColor("#FFFFFF88");
scene->addObject(__level_name_object);
return scene;
}
void __resetGlobals_TextDialog() {
__update_scenes_text_dialog = false;
__quit_scenes_text_dialog = false;
__started_text_dialog = false;
__cur_button_index_text_dialog = -1;
__cur_button_index_text_dialog_down = -1;
__buttons_text_dialog.clear();
__mouse_text_dialog.reset();
__level_name_object.reset();
__level_name_text = "LEVEL NAME";
}
void __additionalRender_TextDialog(std::shared_ptr<SDLPP::Scene> & /*UNUSED*/) {
if (__update_text) {
__level_name_object->changeText(__level_name_text);
__update_text = false;
__update_scenes_text_dialog = true;
}
if (__update_scenes_text_dialog) {
for (auto &_scene : game_scenes) {
_scene.scene->updateSizeAndPosition();
}
if (__started_text_dialog) {
__update_scenes_text_dialog = false;
} else {
__started_text_dialog = true;
}
}
if (__quit_scenes_text_dialog) {
SDL_StopTextInput();
if(!__level_name_text.empty() &&
(__level_name_text.size() < 7 || __level_name_text.substr(__level_name_text.size() - 7) != ".marmap")) {
__level_name_text += ".marmap";
}
__text_dialog_finalizer(__level_name_text);
game_scenes.pop_back();
__resetGlobals_TextDialog();
}
}
void __getMousePositionFlags_TextDialog(SDLPP::Scene &scene) {
auto mouse = scene.getObjects({ EDITOR_MOUSE_ID })[0];
// move mouse colider to mouse position
mouse->setPos(SDLPP::Mouse::getMousePositionDouble(
scene.getRenderer(), SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER));
MouseVisitor visitor;
scene.visitCollisions(*mouse, visitor);
__cur_button_index_text_dialog = visitor.getCurButton();
}
bool controlOrCommandPressed();
void __pollEvents_TextDialog(std::shared_ptr<SDLPP::Scene> &scene) {
SDL_Event event;
while (SDLPP::getSDLEvent(event)) {
switch (event.type) {
case SDL_QUIT:
__quitTextDialog();
break;
case SDL_KEYUP:
__handleKeyUp_TextDialog(event.key.keysym.sym, *scene);
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_BACKSPACE &&
!__level_name_text.empty()) {
__level_name_text.pop_back();
__update_text = true;
} else if (event.key.keysym.sym == SDLK_c &&
controlOrCommandPressed()) {
// handle copy
SDL_SetClipboardText(__level_name_text.c_str());
} else if (event.key.keysym.sym == SDLK_v &&
controlOrCommandPressed()) {
// handle paste
__level_name_text += SDL_GetClipboardText();
__update_text = true;
}
break;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
__update_scenes_text_dialog = true;
}
break;
case SDL_MOUSEMOTION:
__getMousePositionFlags_TextDialog(*scene);
break;
case SDL_MOUSEBUTTONUP:
if (__cur_button_index_text_dialog_down ==
__cur_button_index_text_dialog &&
__cur_button_index_text_dialog != (uint64_t)-1) {
__buttons_text_dialog[__cur_button_index_text_dialog]
->performFunction();
}
break;
case SDL_MOUSEBUTTONDOWN:
// store current mouse flags in previous mouse flags
__cur_button_index_text_dialog_down = __cur_button_index_text_dialog;
break;
case SDL_TEXTINPUT:
__level_name_text += event.text.text;
__update_text = true;
break;
default:
break;
}
}
}
SceneStruct createTextScene(std::shared_ptr<SDLPP::Renderer> renderer,
std::function<void(const std::string &)> finalizer) {
__text_dialog_finalizer = finalizer;
SceneStruct ret{};
ret.scene = createSceneTextDialog(renderer);
ret.additionalRender = __additionalRender_TextDialog;
ret.doInput = __pollEvents_TextDialog;
__update_scenes_text_dialog = true;
SDL_StartTextInput();
return ret;
}
+213
View File
@@ -0,0 +1,213 @@
#include "SDL2/SDL_keycode.h"
#include "editor_scenes.hpp"
#include "../../sdlpp/sdlpp.hpp"
#include "../../sdlpp/sdlpp_mouse.hpp"
#include "../global_vars.hpp"
#include "../objectids.hpp"
#include "../editor_visitor.hpp"
bool __update_scenes_yesno_dialog = false;
bool __quit_scenes_yesno_dialog = false;
bool __started_yesno_dialog = false;
uint64_t __cur_button_index_yesno_dialog = -1;
uint64_t __cur_button_index_yesno_dialog_down = -1;
std::vector<std::shared_ptr<Button>> __buttons_yesno_dialog{};
std::shared_ptr<SDLPP::RectangleRender> __mouse_yesno_dialog{};
std::function<void(bool)> __yesno_dialog_finalizer;
void __quitYesNoDialog(bool result = false) {
__yesno_dialog_finalizer(result);
__quit_scenes_yesno_dialog = true;
}
void __updateSelectedButton_YesNoDialog(uint64_t new_index) {
if (new_index != __cur_button_index_yesno_dialog &&
new_index != (uint64_t)-1) {
__buttons_yesno_dialog[new_index]->setHighlight();
if (__cur_button_index_yesno_dialog != (uint64_t)-1) {
__buttons_yesno_dialog[__cur_button_index_yesno_dialog]
->unsetHighlight();
}
__cur_button_index_yesno_dialog = new_index;
}
}
void __handleKeyUp_YesNoDialog(SDL_Keycode key, SDLPP::Scene & /*UNUSED*/) {
switch (key) {
case SDLK_ESCAPE:
__quitYesNoDialog();
break;
case SDLK_LEFT:
case SDLK_a:
__updateSelectedButton_YesNoDialog(0);
break;
case SDLK_RIGHT:
case SDLK_d:
__updateSelectedButton_YesNoDialog(1);
break;
case SDLK_RETURN:
__quitYesNoDialog(__cur_button_index_yesno_dialog == 0);
break;
default:
break;
}
}
void __returnYesCallback_YesNoDialog(void * /*UNUSED*/, Button * /*UNUSED*/) {
__quitYesNoDialog(true);
}
void __returnNoCallback_YesNoDialog(void * /*UNUSED*/, Button * /*UNUSED*/) {
__quitYesNoDialog(false);
}
std::shared_ptr<SDLPP::Scene>
createSceneYesNoDialog(std::shared_ptr<SDLPP::Renderer> &renderer,
const std::string &text) {
auto scene = std::make_shared<SDLPP::Scene>(renderer);
auto bg = std::make_shared<SDLPP::RectangleRender>(0, 0, 10, 10, renderer,
"#00000088", true);
bg->setPermanent();
bg->setId(1);
scene->addObject(bg);
__mouse_yesno_dialog =
std::make_shared<SDLPP::RectangleRender>(0.01, 0.01, 0, 0, renderer);
__mouse_yesno_dialog->setMinWidth(1);
__mouse_yesno_dialog->setMinHeight(1);
__mouse_yesno_dialog->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
__mouse_yesno_dialog->setId(EDITOR_MOUSE_ID);
__mouse_yesno_dialog->setColiderColor("#00FF00");
__mouse_yesno_dialog->addCollision(SDLPP::RectColider({ 0, 0 }, { 1, 1 }));
scene->addObject(__mouse_yesno_dialog);
ButtonConfig default_button_theme{};
default_button_theme.bg_color = "#FFFFFF88";
default_button_theme.bg_color_highlight = "#FFFFFFBB";
default_button_theme.bg_color_disabled = "#AAAAAA88";
default_button_theme.font_color = "#000000";
default_button_theme.font_color_highlight = "#000000";
default_button_theme.font_color_disabled = "#555555";
default_button_theme.font_outline_color = "#FFFFFF88";
default_button_theme.font_outline_color_highlight = "#FFFFFFAA";
default_button_theme.font_outline_color_disabled = "#787878";
default_button_theme.outline = 0.1;
// buttons
__buttons_yesno_dialog.emplace_back(std::make_shared<Button>(
0.1, 0.5, 0.4, 0.2, renderer, "YES", default_button_theme,
__returnYesCallback_YesNoDialog, nullptr));
__buttons_yesno_dialog.back()->setAlignment(SDLPP::OBJ_CENTER,
SDLPP::OBJ_CENTER);
__buttons_yesno_dialog.back()->setPermanent();
__buttons_yesno_dialog.back()->setButtonIndex(
__buttons_yesno_dialog.size() - 1);
__buttons_yesno_dialog.emplace_back(std::make_shared<Button>(
0.55, 0.5, 0.4, 0.2, renderer, "NO", default_button_theme,
__returnNoCallback_YesNoDialog, nullptr));
__buttons_yesno_dialog.back()->setAlignment(SDLPP::OBJ_CENTER,
SDLPP::OBJ_CENTER);
__buttons_yesno_dialog.back()->setPermanent();
__buttons_yesno_dialog.back()->setButtonIndex(
__buttons_yesno_dialog.size() - 1);
for (auto &button : __buttons_yesno_dialog) {
scene->addObject(button);
}
auto font_config = std::make_shared<SDLPP::FontConfiguration>(
g_text_config->getFont(), "#000000", "#FFFFFFAA", 0.10);
auto dialog_text = std::make_shared<SDLPP::TextRenderer>(
0.1, 0.15, 0.8, 0.3, renderer, text, font_config, SDLPP_TEXT_CENTER);
dialog_text->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
dialog_text->setPermanent();
scene->addObject(dialog_text);
return scene;
}
void __resetGlobals_YesNoDialog() {
__update_scenes_yesno_dialog = false;
__quit_scenes_yesno_dialog = false;
__started_yesno_dialog = false;
__cur_button_index_yesno_dialog = -1;
__cur_button_index_yesno_dialog_down = -1;
__buttons_yesno_dialog.clear();
__mouse_yesno_dialog.reset();
}
void __additionalRender_YesNoDialog(
std::shared_ptr<SDLPP::Scene> & /*UNUSED*/) {
if (__update_scenes_yesno_dialog) {
for (auto &_scene : game_scenes) {
_scene.scene->updateSizeAndPosition();
}
if (__started_yesno_dialog) {
__update_scenes_yesno_dialog = false;
} else {
__started_yesno_dialog = true;
}
}
if (__quit_scenes_yesno_dialog) {
game_scenes.pop_back();
__resetGlobals_YesNoDialog();
}
}
void __getMousePositionFlags_YesNoDialog(SDLPP::Scene &scene) {
auto mouse = scene.getObjects({ EDITOR_MOUSE_ID })[0];
// move mouse colider to mouse position
mouse->setPos(SDLPP::Mouse::getMousePositionDouble(
scene.getRenderer(), SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER));
MouseVisitor visitor;
scene.visitCollisions(*mouse, visitor);
__updateSelectedButton_YesNoDialog(visitor.getCurButton());
}
void __pollEvents_YesNoDialog(std::shared_ptr<SDLPP::Scene> &scene) {
SDL_Event event;
while (SDLPP::getSDLEvent(event)) {
switch (event.type) {
case SDL_QUIT:
__quitYesNoDialog();
break;
case SDL_KEYUP:
__handleKeyUp_YesNoDialog(event.key.keysym.sym, *scene);
break;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
__update_scenes_yesno_dialog = true;
}
break;
case SDL_MOUSEMOTION:
__getMousePositionFlags_YesNoDialog(*scene);
break;
case SDL_MOUSEBUTTONUP:
if (__cur_button_index_yesno_dialog_down ==
__cur_button_index_yesno_dialog &&
__cur_button_index_yesno_dialog != (uint64_t)-1) {
__buttons_yesno_dialog[__cur_button_index_yesno_dialog]
->performFunction();
}
break;
case SDL_MOUSEBUTTONDOWN:
// store current mouse flags in previous mouse flags
__cur_button_index_yesno_dialog_down =
__cur_button_index_yesno_dialog;
break;
default:
break;
}
}
}
SceneStruct createYesNoScene(std::shared_ptr<SDLPP::Renderer> renderer,
const std::string &text,
std::function<void(bool)> finalizer) {
__yesno_dialog_finalizer = finalizer;
SceneStruct ret{};
ret.scene = createSceneYesNoDialog(renderer, text);
ret.additionalRender = __additionalRender_YesNoDialog;
ret.doInput = __pollEvents_YesNoDialog;
__update_scenes_yesno_dialog = true;
__updateSelectedButton_YesNoDialog(1);
return ret;
}
+118
View File
@@ -0,0 +1,118 @@
#include "sprites.hpp"
double BLOCK_SIZE = 1.0 / 16;
const std::string MARIO_OVERWORLD_COLORKEY = "#93bbec";
const SDL_Rect MARIO_STANDING_SRC = { 1, 9, 16, 16 };
const SDL_Rect MARIO_DEATH_SRC = { 22, 9, 16, 16 };
const std::vector<SDL_Rect> MARIO_WALK_ANIM = { { 43, 9, 16, 16 },
{ 60, 9, 16, 16 },
{ 77, 9, 16, 16 } };
const SDL_Rect MARIO_CHANGE_DIR_SRC = { 98, 9, 16, 16 };
const SDL_Rect MARIO_JUMP_SRC = { 119, 9, 16, 16 };
const SDL_Rect MARIO_STANDING_BIG_SRC = { 1, 26, 16, 32 };
const SDL_Rect MARIO_DEATH_BIG_SRC = { 22, 26, 16, 32 };
const std::vector<SDL_Rect> MARIO_WALK_BIG_ANIM = { { 43, 26, 16, 32 },
{ 60, 26, 16, 32 },
{ 77, 26, 16, 32 } };
const SDL_Rect MARIO_CHANGE_DIR_BIG_SRC = { 98, 26, 16, 32 };
const SDL_Rect MARIO_JUMP_BIG_SRC = { 119, 26, 16, 32 };
const SDL_Rect MARIO_STANDING_FIRE_SRC = { 1, 157, 16, 32 };
const SDL_Rect MARIO_DEATH_FIRE_SRC = { 22, 157, 16, 32 };
const std::vector<SDL_Rect> MARIO_WALK_FIRE_ANIM = { { 43, 157, 16, 32 },
{ 60, 157, 16, 32 },
{ 77, 157, 16, 32 } };
const SDL_Rect MARIO_CHANGE_DIR_FIRE_SRC = { 98, 157, 16, 32 };
const SDL_Rect MARIO_JUMP_FIRE_SRC = { 119, 157, 16, 32 };
extern const std::vector<SDL_Rect> FIRE_BALL_ANIM = { {96, 144, 8, 8},
{104, 144, 8, 8},
{96, 152, 8, 8},
{104, 152, 8, 8},
};
const SDL_Rect FLOOR_SRC = { 1, 131, 16, 16 };
const SDL_Rect HILL_INCLINE_SRC = { 137, 97, 16, 16 };
const SDL_Rect HILL_DECLINE_SRC = { 205, 97, 16, 16 };
const SDL_Rect HILL_FILL_SRC = { 171, 97, 16, 16 };
const SDL_Rect HILL_DOTS_RIGHT_SRC = { 154, 97, 16, 16 };
const SDL_Rect HILL_DOTS_LEFT_SRC = { 188, 97, 16, 16 };
const SDL_Rect HILL_TOP_SRC = { 171, 63, 16, 16 };
const SDL_Rect BUSH_LEFT_SRC = { 222, 97, 16, 16 };
const SDL_Rect BUSH_MIDDLE_SRC = { 239, 97, 16, 16 };
const SDL_Rect BUSH_RIGHT_SRC = { 256, 97, 16, 16 };
const SDL_Rect CLOUD_LEFT_BOTTOM_SRC = { 222, 80, 16, 16 };
const SDL_Rect CLOUD_MIDDLE_BOTTOM_SRC = { 239, 80, 16, 16 };
const SDL_Rect CLOUD_RIGHT_BOTTOM_SRC = { 256, 80, 16, 16 };
const SDL_Rect CLOUD_LEFT_TOP_SRC = { 222, 63, 16, 16 };
const SDL_Rect CLOUD_MIDDLE_TOP_SRC = { 239, 63, 16, 16 };
const SDL_Rect CLOUD_RIGHT_TOP_SRC = { 256, 63, 16, 16 };
const SDL_Rect PIPE_LEFT_BOTTOM_SRC = { 103, 63, 16, 16 };
const SDL_Rect PIPE_LEFT_TOP_SRC = { 103, 46, 16, 16 };
const SDL_Rect PIPE_RIGHT_BOTTOM_SRC = { 120, 63, 16, 16 };
const SDL_Rect PIPE_RIGHT_TOP_SRC = { 120, 46, 16, 16 };
const SDL_Rect CASTLE_LEFT_SRC = { 69, 131, 16, 16 };
const SDL_Rect CASTLE_RIGHT_SRC = { 103, 131, 16, 16 };
const SDL_Rect CASTLE_BLACK_SRC = { 86, 131, 16, 16 };
const SDL_Rect CASTLE_ENTRY_SRC = { 86, 114, 16, 16 };
const SDL_Rect CASTLE_TOWER_SRC = { 69, 114, 16, 16 };
const SDL_Rect CASTLE_TOWER_FILLED_SRC = { 103, 114, 16, 16 };
const SDL_Rect VINE_TOP_SRC = { 69, 29, 16, 16 };
const SDL_Rect VINE_BOTTOM_SRC = { 69, 46, 16, 16 };
const SDL_Rect POLE_TOP_SRC = { 86, 29, 16, 16 };
const SDL_Rect POLE_BOTTOM_SRC = { 86, 46, 16, 16 };
const SDL_Rect FLAG_SRC = { 137, 46, 16, 16 };
const SDL_Rect STEP_SRC = { 86, 63, 16, 16 };
const SDL_Rect BRICK_SRC = { 35, 97, 16, 16 };
const SDL_Rect BRICK_TOP_SRC = { 18, 97, 16, 16 };
const SDL_Rect SIDEWAY_PIPE_END_TOP_SRC = { 69, 80, 16, 16 };
const SDL_Rect SIDEWAY_PIPE_END_BOTTOM_SRC = { 69, 97, 16, 16 };
const SDL_Rect SIDEWAY_PIPE_MIDDLE_TOP_SRC = { 86, 80, 16, 16 };
const SDL_Rect SIDEWAY_PIPE_MIDDLE_BOTTOM_SRC = { 86, 97, 16, 16 };
const SDL_Rect SIDEWAY_PIPE_CONNECTOR_TOP_SRC = { 103, 80, 16, 16 };
const SDL_Rect SIDEWAY_PIPE_CONNECTOR_BOTTOM_SRC = { 103, 97, 16, 16 };
const SDL_Rect TREE_PLATFORM_TOP_LEFT_SRC = { 137, 12, 16, 16 };
const SDL_Rect TREE_PLATFORM_TOP_MIDDLE_SRC = { 154, 12, 16, 16 };
const SDL_Rect TREE_PLATFORM_TOP_RIGHT_SRC = { 171, 12, 16, 16 };
const SDL_Rect TREE_PLATFORM_BARK_SRC = { 154, 46, 16, 16 };
const SDL_Rect WATER_TOP_SRC = { 171, 29, 16, 16 };
const SDL_Rect WATER_FILL_SRC = { 171, 46, 16, 16 };
const SDL_Rect MUSHROOM_PLATFORM_TOP_LEFT_SRC = { 188, 12, 16, 16 };
const SDL_Rect MUSHROOM_PLATFORM_TOP_MIDDLE_SRC = { 205, 12, 16, 16 };
const SDL_Rect MUSHROOM_PLATFORM_TOP_RIGHT_SRC = { 222, 12, 16, 16 };
const SDL_Rect MUSHROOM_PLATFORM_BARK_TOP_SRC = { 205, 29, 16, 16 };
const SDL_Rect MUSHROOM_PLATFORM_BARK_BOTTOM_SRC = { 205, 46, 16, 16 };
const SDL_Rect TREE_BARK_SRC = { 222, 46, 16, 16 };
const SDL_Rect TREE_LEAVES_SMALL_SRC = { 222, 29, 16, 16 };
const SDL_Rect TREE_LEAVES_TOP_SRC = { 239, 12, 16, 16 };
const SDL_Rect TREE_LEAVES_BOTTOM_SRC = { 239, 29, 16, 16 };
const SDL_Rect CANNON_TOWER_SRC = { 256, 46, 16, 16 };
const SDL_Rect CANNON_PEDESTAL_SRC = { 256, 29, 16, 16 };
const SDL_Rect CANNON_SRC = { 256, 12, 16, 16 };
const SDL_Rect COIN_SRC = { 549, 202, 16, 16 };
const SDL_Rect MUSHROOM_SRC = { 69, 12, 16, 16 };
const SDL_Rect FIRE_FLOWER_SRC = { 1, 12, 16, 16 };
const SDL_Rect HARD_SRC = { 69, 63, 16, 16 };
extern const SDL_Rect MOD_DESTRUCTIBLE_SRC = { 0, 0, 16, 16 };
extern const SDL_Rect MOD_BACKGROUND_SRC = { 16, 0, 16, 16 };
extern const SDL_Rect MOD_COIN_SRC = { 32, 0, 16, 16 };
extern const SDL_Rect MOD_MUSHROOM_SRC = { 48, 0, 16, 16 };
extern const SDL_Rect MOD_TELEPORT_SRC = { 0, 16, 16, 16 };
const SDLPP::Vec2D<uint64_t> OVERWORLD_SHIFT = { 0, 0 };
const SDLPP::Vec2D<uint64_t> UNDERWORLD_SHIFT = { 274, 0 };
const SDLPP::Vec2D<uint64_t> WATER_SHIFT = { 548, 0 };
const SDLPP::Vec2D<uint64_t> BOWSER_SHIFT = { 0, 173 };
const std::vector<SDL_Rect> GOOMBA_WALK_ANIM = { { 1, 28, 16, 16 },
{ 18, 28, 16, 16 } };
const SDL_Rect GOOMBA_DEATH_SRC = { 39, 28, 16, 16 };
const std::vector<SDL_Rect> TURTLE_WALK_ANIM = { { 60, 12, 16, 32 },
{ 77, 12, 16, 32 } };
const std::vector<SDL_Rect> TURTLE_SHELL_ANIM = { { 136, 28, 16, 16},
{ 136, 28, 16, 16},
{ 153, 28, 16, 16} };
+118
View File
@@ -0,0 +1,118 @@
#ifndef SPRITES_H
#define SPRITES_H
#ifndef _WIN32
#include <SDL2/SDL_rect.h>
#else
#include "../sdlpp/SDL2/SDL_rect.h"
#endif
#include <string>
#include <vector>
#include "../sdlpp/sdlpp_vector.hpp"
extern double BLOCK_SIZE;
//------------------ COLORS -------------------------
extern const std::string MARIO_OVERWORLD_COLORKEY;
//------------------ MARIO --------------------------
extern const SDL_Rect MARIO_STANDING_SRC;
extern const SDL_Rect MARIO_DEATH_SRC;
extern const std::vector<SDL_Rect> MARIO_WALK_ANIM;
extern const SDL_Rect MARIO_CHANGE_DIR_SRC;
extern const SDL_Rect MARIO_JUMP_SRC;
//------------------ BIG MARIO ----------------------
extern const SDL_Rect MARIO_STANDING_BIG_SRC;
extern const SDL_Rect MARIO_DEATH_BIG_SRC;
extern const std::vector<SDL_Rect> MARIO_WALK_BIG_ANIM;
extern const SDL_Rect MARIO_CHANGE_DIR_BIG_SRC;
extern const SDL_Rect MARIO_JUMP_BIG_SRC;
//------------------ FIRE MARIO ----------------------
extern const SDL_Rect MARIO_STANDING_FIRE_SRC;
extern const SDL_Rect MARIO_DEATH_FIRE_SRC;
extern const std::vector<SDL_Rect> MARIO_WALK_FIRE_ANIM;
extern const SDL_Rect MARIO_CHANGE_DIR_FIRE_SRC;
extern const SDL_Rect MARIO_JUMP_FIRE_SRC;
//------------------ FIRE BALL ----------------------
extern const std::vector<SDL_Rect> FIRE_BALL_ANIM;
//------------------ TERRAIN ------------------------
extern const SDL_Rect FLOOR_SRC;
extern const SDL_Rect HILL_INCLINE_SRC;
extern const SDL_Rect HILL_DECLINE_SRC;
extern const SDL_Rect HILL_FILL_SRC;
extern const SDL_Rect HILL_DOTS_RIGHT_SRC;
extern const SDL_Rect HILL_DOTS_LEFT_SRC;
extern const SDL_Rect HILL_TOP_SRC;
extern const SDL_Rect BUSH_LEFT_SRC;
extern const SDL_Rect BUSH_MIDDLE_SRC;
extern const SDL_Rect BUSH_RIGHT_SRC;
extern const SDL_Rect CLOUD_LEFT_BOTTOM_SRC;
extern const SDL_Rect CLOUD_MIDDLE_BOTTOM_SRC;
extern const SDL_Rect CLOUD_RIGHT_BOTTOM_SRC;
extern const SDL_Rect CLOUD_LEFT_TOP_SRC;
extern const SDL_Rect CLOUD_MIDDLE_TOP_SRC;
extern const SDL_Rect CLOUD_RIGHT_TOP_SRC;
extern const SDL_Rect PIPE_LEFT_BOTTOM_SRC;
extern const SDL_Rect PIPE_LEFT_TOP_SRC;
extern const SDL_Rect PIPE_RIGHT_BOTTOM_SRC;
extern const SDL_Rect PIPE_RIGHT_TOP_SRC;
extern const SDL_Rect CASTLE_LEFT_SRC;
extern const SDL_Rect CASTLE_RIGHT_SRC;
extern const SDL_Rect CASTLE_BLACK_SRC;
extern const SDL_Rect CASTLE_ENTRY_SRC;
extern const SDL_Rect CASTLE_TOWER_SRC;
extern const SDL_Rect CASTLE_TOWER_FILLED_SRC;
extern const SDL_Rect VINE_TOP_SRC;
extern const SDL_Rect VINE_BOTTOM_SRC;
extern const SDL_Rect POLE_TOP_SRC;
extern const SDL_Rect POLE_BOTTOM_SRC;
extern const SDL_Rect FLAG_SRC;
extern const SDL_Rect STEP_SRC;
extern const SDL_Rect BRICK_SRC;
extern const SDL_Rect BRICK_TOP_SRC;
extern const SDL_Rect SIDEWAY_PIPE_END_TOP_SRC;
extern const SDL_Rect SIDEWAY_PIPE_END_BOTTOM_SRC;
extern const SDL_Rect SIDEWAY_PIPE_MIDDLE_TOP_SRC;
extern const SDL_Rect SIDEWAY_PIPE_MIDDLE_BOTTOM_SRC;
extern const SDL_Rect SIDEWAY_PIPE_CONNECTOR_TOP_SRC;
extern const SDL_Rect SIDEWAY_PIPE_CONNECTOR_BOTTOM_SRC;
extern const SDL_Rect TREE_PLATFORM_TOP_LEFT_SRC;
extern const SDL_Rect TREE_PLATFORM_TOP_MIDDLE_SRC;
extern const SDL_Rect TREE_PLATFORM_TOP_RIGHT_SRC;
extern const SDL_Rect TREE_PLATFORM_BARK_SRC;
extern const SDL_Rect WATER_TOP_SRC;
extern const SDL_Rect WATER_FILL_SRC;
extern const SDL_Rect MUSHROOM_PLATFORM_TOP_LEFT_SRC;
extern const SDL_Rect MUSHROOM_PLATFORM_TOP_MIDDLE_SRC;
extern const SDL_Rect MUSHROOM_PLATFORM_TOP_RIGHT_SRC;
extern const SDL_Rect MUSHROOM_PLATFORM_BARK_TOP_SRC;
extern const SDL_Rect MUSHROOM_PLATFORM_BARK_BOTTOM_SRC;
extern const SDL_Rect TREE_BARK_SRC;
extern const SDL_Rect TREE_LEAVES_SMALL_SRC;
extern const SDL_Rect TREE_LEAVES_TOP_SRC;
extern const SDL_Rect TREE_LEAVES_BOTTOM_SRC;
extern const SDL_Rect CANNON_TOWER_SRC;
extern const SDL_Rect CANNON_PEDESTAL_SRC;
extern const SDL_Rect CANNON_SRC;
extern const SDL_Rect COIN_SRC;
extern const SDL_Rect MUSHROOM_SRC;
extern const SDL_Rect FIRE_FLOWER_SRC;
extern const SDL_Rect HARD_SRC;
//------------------ MODIFIERS ----------------------
extern const SDL_Rect MOD_DESTRUCTIBLE_SRC;
extern const SDL_Rect MOD_BACKGROUND_SRC;
extern const SDL_Rect MOD_COIN_SRC;
extern const SDL_Rect MOD_MUSHROOM_SRC;
extern const SDL_Rect MOD_TELEPORT_SRC;
//------------------ ENEMIES -------------------------
extern const SDL_Rect GOOMBA_DEATH_SRC;
extern const std::vector<SDL_Rect> GOOMBA_WALK_ANIM;
extern const std::vector<SDL_Rect> TURTLE_WALK_ANIM;
extern const std::vector<SDL_Rect> TURTLE_SHELL_ANIM;
extern const SDLPP::Vec2D<uint64_t> OVERWORLD_SHIFT;
extern const SDLPP::Vec2D<uint64_t> UNDERWORLD_SHIFT;
extern const SDLPP::Vec2D<uint64_t> WATER_SHIFT;
extern const SDLPP::Vec2D<uint64_t> BOWSER_SHIFT;
#endif
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.
+28
View File
@@ -0,0 +1,28 @@
#include "tool_box.hpp"
#include "objectids.hpp"
#include "blocks.hpp"
#include "sprites.hpp"
ToolBox::ToolBox(int x, int y, double start_x, double start_y,
std::shared_ptr<SDLPP::Renderer> renderer, bool coliders)
: SDLPP::RectangleRender(start_x + x * BLOCK_SIZE,
start_y + y * BLOCK_SIZE, BLOCK_SIZE,
BLOCK_SIZE, renderer) {
_x = x;
_y = y;
setId(EDITOR_TOOL_ID);
setColiderColor("#FF00AA");
setColor("#FFFFFF88");
setPermanent();
setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
if (coliders)
addCollision(SDLPP::RectColider(0, 0, 1, 1));
}
SDLPP::Vec2D<int> ToolBox::getIndexes() const {
return { _x, _y };
}
void ToolBox::visit(SDLPP::Visitor &visitor) {
visitor.visit(*this);
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef TOOL_BOX_H
#define TOOL_BOX_H
#include "../sdlpp/sdlpp.hpp"
class ToolBox : public SDLPP::RectangleRender {
public:
ToolBox(int x, int y, double start_x, double start_y,
std::shared_ptr<SDLPP::Renderer> renderer, bool coliders = true);
virtual SDLPP::Vec2D<int> getIndexes() const;
virtual void visit(SDLPP::Visitor &visitor) override;
uint64_t getType() const {
return _type;
}
void setType(uint64_t type) {
_type = type;
}
private:
int _x;
int _y;
uint64_t _type;
};
#endif
+17
View File
@@ -0,0 +1,17 @@
#include "bounce_visitor.hpp"
#include "../../sdlpp/sdlpp_renderobject.hpp"
#include "../objectids.hpp"
void BounceVisitor::visit(const SDLPP::RenderObject &obj) {
auto id = obj.getId();
switch (id) {
case FLOOR_ID:
case BRICK_ID:
case BRICK_TOP_ID:
if (from == BOUNCE_COLLISION) {
hits += 1;
}
default:
break;
}
}
+34
View File
@@ -0,0 +1,34 @@
#ifndef BOUNCE_VISITOR_HPP
#define BOUNCE_VISITOR_HPP
#include "../../sdlpp/sdlpp_visitor.hpp"
#include "../../sdlpp/sdlpp_geometry.hpp"
class BounceVisitor : public SDLPP::Visitor {
public:
BounceVisitor() = default;
void visit(const SDLPP::RenderObject &obj) override;
void setFromId(uint64_t id) override {
from = id;
}
uint64_t getFromId() const override {
return from;
}
void setVisitorType(uint64_t type) override {
_type = type;
}
uint64_t getVisitorType() const override {
return _type;
}
bool canBounce() const {
return hits < 2;
}
private:
int hits = 0;
uint64_t from{};
uint64_t _type{};
};
#endif
+81
View File
@@ -0,0 +1,81 @@
#include "goomba_visitor.hpp"
#include "../../sdlpp/sdlpp_renderobject.hpp"
#include "../objectids.hpp"
#include "../sprites.hpp"
#include "../mario.hpp"
#include "../blocks/turtleblock.hpp"
void GoombaVisitor::visit(const SDLPP::RenderObject &obj) {
auto id = obj.getId();
auto marioBlock = reinterpret_cast<const MarioBlock&>(obj);
switch (id) {
case FLOOR_ID:
case BRICK_ID:
case BRICK_TOP_ID:
if(marioBlock.isBouncing()) {
bounce = true;
death = true;
return;
}
case PIPE_LEFT_BOTTOM_ID:
case PIPE_RIGHT_BOTTOM_ID:
case PIPE_LEFT_TOP_ID:
case PIPE_RIGHT_TOP_ID:
case STEP_ID:
case SIDEWAY_PIPE_END_TOP_ID:
case SIDEWAY_PIPE_END_BOTTOM_ID:
case SIDEWAY_PIPE_MIDDLE_BOTTOM_ID:
case SIDEWAY_PIPE_MIDDLE_TOP_ID:
case SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID:
case SIDEWAY_PIPE_CONNECTOR_TOP_ID:
case TREE_PLATFORM_TOP_LEFT_ID:
case TREE_PLATFORM_TOP_RIGHT_ID:
case MUSHROOM_PLATFORM_TOP_MIDDLE_ID:
case MUSHROOM_PLATFORM_TOP_LEFT_ID:
case MUSHROOM_PLATFORM_TOP_RIGHT_ID:
case CANNON_TOWER_ID:
case CANNON_PEDESTAL_ID:
case CANNON_ID:
if (from == NPC_FLOOR_DETECT) {
onGround = true;
groundY = obj.getPos().getY();
} else if (from == NPC_LEFT_SIDE_DETECT) {
if (!left && !right) {
movement_blockage = obj.getPos();
validXPos = movement_blockage.getX() + BLOCK_SIZE;
}
left = true;
} else if (from == NPC_RIGHT_SIDE_DETECT) {
if (!left && !right) {
movement_blockage = obj.getPos();
validXPos = movement_blockage.getX() - BLOCK_SIZE;
}
right = true;
}
break;
case DEATH_ID:
instant_death = true;
break;
case TURTLE_ID:
{
auto &turtle = dynamic_cast<const TurtleBlock &>(obj);
if(turtle.isShell() && turtle.getMovement().getX() != 0) {
death = true;
}
}
break;
case MARIO_ID:
{
auto &mario = dynamic_cast<const Mario &>(obj);
if (from == NPC_TOP_DETECT && obj.getPos().getY() <= goomba_pos.getY() - BLOCK_SIZE && !mario.isJumping()) {
death = true;
}
}
break;
case FIREBALL_ID:
instant_death = true;
break;
default:
break;
}
}
+74
View File
@@ -0,0 +1,74 @@
#ifndef GOOMBA_VISITOR_H
#define GOOMBA_VISITOR_H
#include "../../sdlpp/sdlpp_visitor.hpp"
#include "../../sdlpp/sdlpp_geometry.hpp"
#include "../../sdlpp/sdlpp_scene.hpp"
#include "../blocks.hpp"
class GoombaVisitor : public SDLPP::Visitor {
public:
GoombaVisitor() = delete;
GoombaVisitor(const SDLPP::Vec2D<double> &pos) : goomba_pos(pos) {}
void visit(const SDLPP::RenderObject &obj) override;
bool isOnGround() const {
return onGround;
}
bool isDead() const {
return death;
}
bool instantDeath() const {
return instant_death;
}
void setFromId(uint64_t id) override {
from = id;
}
void setVisitorType(uint64_t type) override {
_type = type;
}
uint64_t getVisitorType() const override {
return _type;
}
uint64_t getFromId() const override {
return from;
}
bool canGoLeft() const {
return !left;
}
bool canGoRight() const {
return !right;
}
double getGroundY() const {
return groundY;
}
bool topBlock() const {
return top_hit;
}
const SDLPP::Vec2D<double> &getMovementBlockage() {
return movement_blockage;
}
double getValidXPos() const {
return validXPos;
}
bool shouldBounce() {
return bounce;
}
private:
bool onGround = false;
double groundY = 0;
uint64_t _type{};
bool death = false;
bool instant_death = false;
bool bounce = false;
uint64_t from = -1;
bool left = false;
bool right = false;
bool top_hit = false;
SDLPP::Vec2D<double> movement_blockage;
double validXPos = 0;
const SDLPP::Vec2D<double> goomba_pos;
};
#endif
+89
View File
@@ -0,0 +1,89 @@
#include "mario_visitor.hpp"
#include "../../sdlpp/sdlpp_renderobject.hpp"
#include "../objectids.hpp"
#include "../sprites.hpp"
void MarioVisitor::visit(const SDLPP::RenderObject &obj) {
auto id = obj.getId();
switch (id) {
case PIPE_LEFT_TOP_ID:
case PIPE_RIGHT_TOP_ID:
teleport_bottom = true;
// fallthrough
case PIPE_LEFT_BOTTOM_ID:
case PIPE_RIGHT_BOTTOM_ID:
{
auto m_obj = dynamic_cast<const MarioBlock &>(obj);
if(m_obj.hasTeleport()) {
setTeleportLevel(m_obj.getTeleportLevel());
}
}
// fallthrough
case FLOOR_ID:
case BRICK_ID:
case BRICK_TOP_ID:
case STEP_ID:
case SIDEWAY_PIPE_END_TOP_ID:
case SIDEWAY_PIPE_END_BOTTOM_ID:
case SIDEWAY_PIPE_MIDDLE_BOTTOM_ID:
case SIDEWAY_PIPE_MIDDLE_TOP_ID:
case SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID:
case SIDEWAY_PIPE_CONNECTOR_TOP_ID:
case TREE_PLATFORM_TOP_LEFT_ID:
case TREE_PLATFORM_TOP_RIGHT_ID:
case MUSHROOM_PLATFORM_TOP_MIDDLE_ID:
case MUSHROOM_PLATFORM_TOP_LEFT_ID:
case MUSHROOM_PLATFORM_TOP_RIGHT_ID:
case CANNON_TOWER_ID:
case CANNON_PEDESTAL_ID:
case CANNON_ID:
if (from == MARIO_FLOOR_DETECT) {
onGround = true;
groundY = obj.getPos().getY();
} else if (from == MARIO_LEFT_SIDE_DETECT) {
if (!left && !right) {
movement_blockage = obj.getPos();
}
left = true;
} else if (from == MARIO_RIGHT_SIDE_DETECT) {
if (!left && !right) {
movement_blockage = obj.getPos();
}
right = true;
} else if (from == MARIO_TOP_DETECT) {
top_hit = true;
} else if (from == MARIO_TOP_LEFT_DETECT ||
from == MARIO_TOP_RIGHT_DETECT) {
rightleftpos = obj.getPos();
top_left_right = true;
}
break;
case DEATH_ID:
_instant_death = true;
break;
case GOOMBA_ID:
case TURTLE_ID:
if (from != MARIO_FLOOR_DETECT && from != MARIO_ENEMY_DETECT) {
_death = true;
} else if (from == MARIO_FLOOR_DETECT || from == MARIO_ENEMY_DETECT) {
_bounce = true;
}
break;
case STOP_MOVEMENT:
stop = true;
newX = obj.getDoubleRect().first.getX() +
obj.getDoubleRect().second.getX();
break;
case MUSHROOM_ID:
mushroom = true;
break;
case POLE_BOTTOM_ID:
case POLE_TOP_ID:
case FLAG_ID:
_end = true;
endPos = obj.getPos();
break;
default:
break;
}
}
+174
View File
@@ -0,0 +1,174 @@
#ifndef MARIO_VISITOR_H
#define MARIO_VISITOR_H
#include "../../sdlpp/sdlpp_visitor.hpp"
#include "../../sdlpp/sdlpp_geometry.hpp"
#include "../../sdlpp/sdlpp_scene.hpp"
#include "../blocks.hpp"
class MarioVisitor : public SDLPP::Visitor {
public:
MarioVisitor(bool is_jumping, SDLPP::Scene &scene, int &coin_count,
std::vector<std::shared_ptr<MarioBlock>> &moving_objects,
bool is_big, bool has_star)
: jumping(is_jumping), _scene(scene), _coin_count(coin_count),
_moving_objects(moving_objects), _is_big(is_big),
_has_star(has_star) {}
void visit(const SDLPP::RenderObject &obj) override;
bool isOnGround() const {
return onGround;
}
bool isDead() const {
return _death;
}
bool isInstantDead() const {
return _instant_death;
}
bool isStopped() const {
return stop;
}
double newXPos() const {
return newX;
}
void setFromId(uint64_t id) override {
from = id;
}
uint64_t getFromId() const override {
return from;
}
void setVisitorType(uint64_t type) override {
_type = type;
}
uint64_t getVisitorType() const override {
return _type;
}
bool canGoLeft() const {
return !left;
}
bool canGoRight() const {
return !right;
}
double getGroundY() const {
return groundY;
}
bool topBlock() const {
return top_hit;
}
bool moveTop() const {
return top_left_right && !top_hit;
}
const SDLPP::Vec2D<double> &getRightLeftPos() {
return rightleftpos;
}
bool canDestroy() const {
return jumping && !top_hit;
}
const SDLPP::Vec2D<double> &getMovementBlockage() {
return movement_blockage;
}
double getStopX() const {
return newX;
}
void setCoin() {
// TODO remove coin?
coin = true;
_coin_count++;
}
bool hasCoin() const {
return coin;
}
void setCoinBlock(std::shared_ptr<MarioBlock> &coin) {
// TODO remove coin_block?
coin_block = coin;
_scene.addObject(coin);
_scene.moveZJustAboveBackground(coin);
}
bool hasCoinBlock() {
return coin_block != nullptr;
}
std::shared_ptr<MarioBlock> &getCoinBlock() {
return coin_block;
}
bool hasMushroom() const {
return mushroom;
}
void setMushroomBlock(std::shared_ptr<MarioBlock> &mushroom) {
_scene.addObject(mushroom);
_scene.moveZJustAboveBackground(mushroom);
_moving_objects.push_back(mushroom);
}
bool shouldBounce() {
return _bounce;
}
bool levelEnd() {
return _end;
}
const SDLPP::Vec2D<double> &getEndPos() {
return endPos;
}
bool isBig() const {
return _is_big;
}
bool hasStar() const {
return _has_star;
}
bool hasTeleport() const {
return !teleport_level.empty();
}
const std::string &getTeleportLevel() const {
return teleport_level;
}
void setTeleportLevel(const std::string &level) {
teleport_level = level;
}
bool teleportBottom() {
return teleport_bottom;
}
private:
bool onGround = false;
double groundY = 0;
bool stop = false;
double newX{};
uint64_t from = -1;
bool left = false;
bool right = false;
uint64_t _type = 0;
bool top_hit = false;
SDLPP::Vec2D<double> rightleftpos;
bool top_left_right = false;
bool jumping;
bool coin = false;
SDLPP::Vec2D<double> movement_blockage;
std::shared_ptr<MarioBlock> coin_block = nullptr;
SDLPP::Scene &_scene;
int &_coin_count;
bool mushroom = false;
std::vector<std::shared_ptr<MarioBlock>> &_moving_objects;
bool _bounce = false;
bool _end = false;
SDLPP::Vec2D<double> endPos;
bool _is_big = false;
bool _has_star = false;
bool _death = false;
bool _instant_death = false;
std::string teleport_level = "";
bool teleport_bottom = false;
};
#endif
+53
View File
@@ -0,0 +1,53 @@
#include "mushroom_visitor.hpp"
#include "../../sdlpp/sdlpp_renderobject.hpp"
#include "../objectids.hpp"
#include "../sprites.hpp"
void MushroomVisitor::visit(const SDLPP::RenderObject &obj) {
auto id = obj.getId();
switch (id) {
case FLOOR_ID:
case BRICK_ID:
case BRICK_TOP_ID:
case PIPE_LEFT_BOTTOM_ID:
case PIPE_RIGHT_BOTTOM_ID:
case PIPE_LEFT_TOP_ID:
case PIPE_RIGHT_TOP_ID:
case STEP_ID:
case SIDEWAY_PIPE_END_TOP_ID:
case SIDEWAY_PIPE_END_BOTTOM_ID:
case SIDEWAY_PIPE_MIDDLE_BOTTOM_ID:
case SIDEWAY_PIPE_MIDDLE_TOP_ID:
case SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID:
case SIDEWAY_PIPE_CONNECTOR_TOP_ID:
case TREE_PLATFORM_TOP_LEFT_ID:
case TREE_PLATFORM_TOP_RIGHT_ID:
case MUSHROOM_PLATFORM_TOP_MIDDLE_ID:
case MUSHROOM_PLATFORM_TOP_LEFT_ID:
case MUSHROOM_PLATFORM_TOP_RIGHT_ID:
case CANNON_TOWER_ID:
case CANNON_PEDESTAL_ID:
case CANNON_ID:
if (from == NPC_FLOOR_DETECT) {
onGround = true;
groundY = obj.getPos().getY();
} else if (from == NPC_LEFT_SIDE_DETECT) {
if (!left && !right) {
movement_blockage = obj.getPos();
validXPos = movement_blockage.getX() + BLOCK_SIZE;
}
left = true;
} else if (from == NPC_RIGHT_SIDE_DETECT) {
if (!left && !right) {
movement_blockage = obj.getPos();
validXPos = movement_blockage.getX() - BLOCK_SIZE;
}
right = true;
}
break;
case MARIO_ID:
death = true;
default:
break;
}
}
+60
View File
@@ -0,0 +1,60 @@
#ifndef MUSHROOM_VISITOR_H
#define MUSHROOM_VISITOR_H
#include "../../sdlpp/sdlpp_visitor.hpp"
#include "../../sdlpp/sdlpp_geometry.hpp"
#include "../../sdlpp/sdlpp_scene.hpp"
#include "../blocks.hpp"
class MushroomVisitor : public SDLPP::Visitor {
public:
MushroomVisitor() = default;
void visit(const SDLPP::RenderObject &obj) override;
bool isOnGround() const {
return onGround;
}
void setFromId(uint64_t id) override {
from = id;
}
uint64_t getFromId() const override {
return from;
}
void setVisitorType(uint64_t type) override {
_type = type;
}
uint64_t getVisitorType() const override {
return _type;
}
bool canGoLeft() const {
return !left;
}
bool canGoRight() const {
return !right;
}
double getGroundY() const {
return groundY;
}
const SDLPP::Vec2D<double> &getMovementBlockage() {
return movement_blockage;
}
bool getDeath() {
return death;
}
double getValidXPos() {
return validXPos;
}
private:
bool onGround = false;
double groundY = 0;
double validXPos = 0;
bool stop = false;
bool left = false;
bool right = false;
SDLPP::Vec2D<double> movement_blockage;
uint64_t from{};
uint64_t _type{};
bool death = false;
};
#endif
+54
View File
@@ -0,0 +1,54 @@
#include "projectile_visitor.hpp"
#include "../../sdlpp/sdlpp_renderobject.hpp"
#include "../objectids.hpp"
#include "../sprites.hpp"
void ProjectileVisitor::visit(const SDLPP::RenderObject &obj) {
auto id = obj.getId();
switch (id) {
case FLOOR_ID:
case BRICK_ID:
case BRICK_TOP_ID:
case PIPE_LEFT_BOTTOM_ID:
case PIPE_RIGHT_BOTTOM_ID:
case PIPE_LEFT_TOP_ID:
case PIPE_RIGHT_TOP_ID:
case STEP_ID:
case SIDEWAY_PIPE_END_TOP_ID:
case SIDEWAY_PIPE_END_BOTTOM_ID:
case SIDEWAY_PIPE_MIDDLE_BOTTOM_ID:
case SIDEWAY_PIPE_MIDDLE_TOP_ID:
case SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID:
case SIDEWAY_PIPE_CONNECTOR_TOP_ID:
case TREE_PLATFORM_TOP_LEFT_ID:
case TREE_PLATFORM_TOP_RIGHT_ID:
case MUSHROOM_PLATFORM_TOP_MIDDLE_ID:
case MUSHROOM_PLATFORM_TOP_LEFT_ID:
case MUSHROOM_PLATFORM_TOP_RIGHT_ID:
case CANNON_TOWER_ID:
case CANNON_PEDESTAL_ID:
case CANNON_ID:
if (from == NPC_FLOOR_DETECT) {
onGround = true;
groundY = obj.getPos().getY();
} else if (from == NPC_LEFT_SIDE_DETECT) {
if (!left && !right) {
movement_blockage = obj.getPos();
validXPos = movement_blockage.getX() + BLOCK_SIZE;
}
left = true;
} else if (from == NPC_RIGHT_SIDE_DETECT) {
if (!left && !right) {
movement_blockage = obj.getPos();
validXPos = movement_blockage.getX() - BLOCK_SIZE;
}
right = true;
}
break;
case GOOMBA_ID:
case TURTLE_ID:
death = true;
default:
break;
}
}
+60
View File
@@ -0,0 +1,60 @@
#ifndef PROJECTILE_VISITOR_H
#define PROJECTILE_VISITOR_H
#include "../../sdlpp/sdlpp_visitor.hpp"
#include "../../sdlpp/sdlpp_geometry.hpp"
#include "../../sdlpp/sdlpp_scene.hpp"
#include "../blocks.hpp"
class ProjectileVisitor : public SDLPP::Visitor {
public:
ProjectileVisitor() = default;
void visit(const SDLPP::RenderObject &obj) override;
bool isOnGround() const {
return onGround;
}
void setFromId(uint64_t id) override {
from = id;
}
uint64_t getFromId() const override {
return from;
}
void setVisitorType(uint64_t type) override {
_type = type;
}
uint64_t getVisitorType() const override {
return _type;
}
bool canGoLeft() const {
return !left;
}
bool canGoRight() const {
return !right;
}
double getGroundY() const {
return groundY;
}
const SDLPP::Vec2D<double> &getMovementBlockage() {
return movement_blockage;
}
bool getDeath() {
return death;
}
double getValidXPos() {
return validXPos;
}
private:
bool onGround = false;
double groundY = 0;
double validXPos = 0;
bool stop = false;
bool left = false;
bool right = false;
SDLPP::Vec2D<double> movement_blockage;
uint64_t from{};
uint64_t _type{};
bool death = false;
};
#endif
+87
View File
@@ -0,0 +1,87 @@
#include "turtle_visitor.hpp"
#include "../../sdlpp/sdlpp_renderobject.hpp"
#include "../objectids.hpp"
#include "../sprites.hpp"
#include "../mario.hpp"
#include "../blocks/turtleblock.hpp"
void TurtleVisitor::visit(const SDLPP::RenderObject &obj) {
auto id = obj.getId();
auto marioBlock = reinterpret_cast<const MarioBlock&>(obj);
switch (id) {
case FLOOR_ID:
case BRICK_ID:
case BRICK_TOP_ID:
if(marioBlock.isBouncing()) {
bounce = true;
instant_death = true;
return;
}
case PIPE_LEFT_BOTTOM_ID:
case PIPE_RIGHT_BOTTOM_ID:
case PIPE_LEFT_TOP_ID:
case PIPE_RIGHT_TOP_ID:
case STEP_ID:
case SIDEWAY_PIPE_END_TOP_ID:
case SIDEWAY_PIPE_END_BOTTOM_ID:
case SIDEWAY_PIPE_MIDDLE_BOTTOM_ID:
case SIDEWAY_PIPE_MIDDLE_TOP_ID:
case SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID:
case SIDEWAY_PIPE_CONNECTOR_TOP_ID:
case TREE_PLATFORM_TOP_LEFT_ID:
case TREE_PLATFORM_TOP_RIGHT_ID:
case MUSHROOM_PLATFORM_TOP_MIDDLE_ID:
case MUSHROOM_PLATFORM_TOP_LEFT_ID:
case MUSHROOM_PLATFORM_TOP_RIGHT_ID:
case CANNON_TOWER_ID:
case CANNON_PEDESTAL_ID:
case CANNON_ID:
if (from == NPC_FLOOR_DETECT) {
onGround = true;
groundY = obj.getPos().getY();
} else if (from == NPC_LEFT_SIDE_DETECT) {
if (!left && !right) {
movement_blockage = obj.getPos();
validXPos = movement_blockage.getX() + BLOCK_SIZE;
}
left = true;
} else if (from == NPC_RIGHT_SIDE_DETECT) {
if (!left && !right) {
movement_blockage = obj.getPos();
validXPos = movement_blockage.getX() - BLOCK_SIZE;
}
right = true;
}
break;
case DEATH_ID:
instant_death = true;
break;
case TURTLE_ID:
{
auto &turtle = dynamic_cast<const TurtleBlock &>(obj);
if ((from == NPC_LEFT_SIDE_DETECT || from == NPC_RIGHT_SIDE_DETECT) && turtle.isShell()) {
switch_movement = true;
next_movement = turtle.getMovementAfterSwitch();
if(from == NPC_LEFT_SIDE_DETECT) {
valid_turtle_hit_pos = obj.getPos().getX() + BLOCK_SIZE;
} else {
valid_turtle_hit_pos = obj.getPos().getX() - BLOCK_SIZE;
}
}
}
break;
case MARIO_ID:
{
auto &mario = dynamic_cast<const Mario &>(obj);
if (from == NPC_TOP_DETECT && obj.getPos().getY() <= turtle_pos.getY() - 0.5*BLOCK_SIZE && !mario.isJumping()) {
death = true;
}
}
break;
case FIREBALL_ID:
instant_death = true;
break;
default:
break;
}
}
+86
View File
@@ -0,0 +1,86 @@
#ifndef TURTLE_VISITOR_H
#define TURTLE_VISITOR_H
#include "../../sdlpp/sdlpp_visitor.hpp"
#include "../../sdlpp/sdlpp_geometry.hpp"
#include "../../sdlpp/sdlpp_scene.hpp"
#include "../blocks.hpp"
class TurtleVisitor : public SDLPP::Visitor {
public:
TurtleVisitor() = delete;
TurtleVisitor(const SDLPP::Vec2D<double> &pos) : turtle_pos(pos) {}
void visit(const SDLPP::RenderObject &obj) override;
bool isOnGround() const {
return onGround;
}
bool isDead() const {
return death;
}
bool instantDeath() const {
return instant_death;
}
void setFromId(uint64_t id) override {
from = id;
}
void setVisitorType(uint64_t type) override {
_type = type;
}
uint64_t getVisitorType() const override {
return _type;
}
uint64_t getFromId() const override {
return from;
}
bool canGoLeft() const {
return !left;
}
bool canGoRight() const {
return !right;
}
double getGroundY() const {
return groundY;
}
bool topBlock() const {
return top_hit;
}
const SDLPP::Vec2D<double> &getMovementBlockage() {
return movement_blockage;
}
double getValidXPos() const {
return validXPos;
}
bool switchMovement() const {
return switch_movement;
}
double getNextMovement() const {
return next_movement;
}
double getTurtleHitValidPos() const {
return valid_turtle_hit_pos;
}
bool shouldBounce() const {
return bounce;
}
private:
bool onGround = false;
double groundY = 0;
uint64_t _type{};
bool death = false;
bool instant_death = false;
uint64_t from = -1;
bool left = false;
bool right = false;
bool top_hit = false;
bool bounce = false;
SDLPP::Vec2D<double> movement_blockage;
double validXPos = 0;
const SDLPP::Vec2D<double> turtle_pos;
bool switch_movement = false;
double next_movement = 0;
double valid_turtle_hit_pos = 0;
};
#endif
+45
View File
@@ -0,0 +1,45 @@
#include "visitor_generator.hpp"
#include "../objectids.hpp"
#include "mario_visitor.hpp"
#include "mushroom_visitor.hpp"
#include "goomba_visitor.hpp"
#include "turtle_visitor.hpp"
#include "projectile_visitor.hpp"
#include "../mario.hpp"
std::shared_ptr<SDLPP::Visitor>
getVisitor(const MarioBlock &block, SDLPP::Scene &scene,
int &coin_count,
std::vector<std::shared_ptr<MarioBlock>> &moving_objects) {
std::shared_ptr<SDLPP::Visitor> result{};
switch (block.getId()) {
case MARIO_ID:
{
auto &mario = dynamic_cast<const Mario &>(block);
result = std::static_pointer_cast<SDLPP::Visitor>(
std::make_shared<MarioVisitor>(block.getMovement().getY() < 0,
scene, coin_count,
moving_objects, mario.isBig(), mario.hasStar()));
}
break;
case MUSHROOM_ID:
result = std::static_pointer_cast<SDLPP::Visitor>(
std::make_shared<MushroomVisitor>());
break;
case GOOMBA_ID:
result = std::static_pointer_cast<SDLPP::Visitor>(
std::make_shared<GoombaVisitor>(block.getPos()));
break;
case TURTLE_ID:
result = std::static_pointer_cast<SDLPP::Visitor>(
std::make_shared<TurtleVisitor>(block.getPos()));
break;
case FIREBALL_ID:
result = std::static_pointer_cast<SDLPP::Visitor>(
std::make_shared<ProjectileVisitor>());
break;
default:
break;
}
return result;
}
+10
View File
@@ -0,0 +1,10 @@
#ifndef MARIO_VISITOR_GENERATOR_HPP
#define MARIO_VISITOR_GENERATOR_HPP
#include "../blocks.hpp"
std::shared_ptr<SDLPP::Visitor>
getVisitor(const MarioBlock &block, SDLPP::Scene &scene, int &coin_count,
std::vector<std::shared_ptr<MarioBlock>> &moving_objects);
#endif
+46
View File
@@ -0,0 +1,46 @@
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(libsdlpp)
list(APPEND SDLPPFiles
sdlpp_circlecolider.cpp
sdlpp_circlerenderer.cpp
sdlpp_collision.cpp
sdlpp_common.cpp
sdlpp_font.cpp
sdlpp_linerenderer.cpp
sdlpp_rectcolider.cpp
sdlpp_rectrenderer.cpp
sdlpp_renderer.cpp
sdlpp_renderobject.cpp
sdlpp_scene.cpp
sdlpp_textrenderer.cpp
sdlpp_texture.cpp
sdlpp_window.cpp
sdlpp_fontconfiguration.cpp
sdlpp_mouse.cpp
)
if(WIN32)
add_library(sdlpp SHARED
${SDLPPFiles}
)
add_library(SDL2 STATIC IMPORTED)
set_target_properties(SDL2 PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/SDL2.lib)
add_library(SDL2_ttf STATIC IMPORTED)
set_target_properties(SDL2_ttf PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/SDL2_ttf.lib)
add_library(SDL2_image STATIC IMPORTED)
set_target_properties(SDL2_image PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/SDL2_image.lib)
target_link_libraries(sdlpp SDL2 SDL2_ttf SDL2_image)
target_compile_definitions(sdlpp PUBLIC DLLEXPORT)
else()
add_library(sdlpp STATIC
${SDLPPFiles}
)
endif()
-63
View File
@@ -1,63 +0,0 @@
MAJOR ?= 1
MINOR ?= 0
RELEASE ?= 0
ifeq ($(OS),Windows_NT)
UNAME_S := Windows
CXX = cl
CXXFLAGS = -MD -EHsc /DDLLEXPORT
OBJEXT = obj
RM = del
else
UNAME_S := $(shell uname -s)
CXX ?= g++
CXXFLAGS = -std=c++14 -Wall -Wextra -pedantic
OBJEXT = o
endif
ifeq ($(UNAME_S),Linux)
SDLPPLIBRARY = libsdlpp.so.${MAJOR}.${MINOR}.${RELEASE}
LIBRARYFLAGS = -fPIC
endif
ifeq ($(UNAME_S),Darwin)
SDLPPLIBRARY = libsdlpp.dylib
LIBRARYFLAGS =
endif
ifeq ($(UNAME_S),Windows)
SDLPPLIBRARY = libsdlpp.dll
LIBRARYFLAGS =
endif
OBJECTFILES = sdlpp_circlecolider.${OBJEXT} sdlpp_circlerenderer.${OBJEXT} sdlpp_collision.${OBJEXT} sdlpp_common.${OBJEXT} sdlpp_font.${OBJEXT} sdlpp_linerenderer.${OBJEXT} sdlpp_rectcolider.${OBJEXT} sdlpp_rectrenderer.${OBJEXT} sdlpp_renderer.${OBJEXT} sdlpp_renderobject.${OBJEXT} sdlpp_scene.${OBJEXT} sdlpp_textrenderer.${OBJEXT} sdlpp_texture.${OBJEXT} sdlpp_window.${OBJEXT}
all: ${SDLPPLIBRARY}
ifeq ($(UNAME_S),Windows)
%.${OBJEXT}: %.cpp
${CXX} ${CXXFLAGS} ${LIBRARYFLAGS} /c $< /Fo"$@"
else
%.${OBJEXT}: %.cpp
${CXX} ${CXXFLAGS} ${LIBRARYFLAGS} -c $< -o $@
endif
ifeq ($(UNAME_S),Linux)
${SDLPPLIBRARY}: ${OBJECTFILES}
${CXX} ${CXXFLAGS} -shared -Wl,-soname,libsdlpp.so.${MAJOR}\
-o ${SDLPPLIBRARY} $^
ln -sf ${SDLPPLIBRARY} libsdlpp.so
ln -sf ${SDLPPLIBRARY} libsdlpp.so.${MAJOR}
endif
ifeq ($(UNAME_S),Darwin)
${SDLPPLIBRARY}: ${OBJECTFILES}
${CXX} ${CXXFLAGS} -dynamiclib -install_name ${SDLPPLIBRARY}\
-current_version ${MAJOR}.${MINOR} $^ -lSDL2 -lSDL2_image -lSDL2_gfx -lSDL2_ttf -o $@
endif
ifeq ($(UNAME_S),Windows)
${SDLPPLIBRARY}: ${OBJECTFILES}
${CXX} /LD $^ /link SDL2.lib SDL2_ttf.lib SDL2_image.lib /OUT:$@ /IMPLIB:libsdlpp.lib
endif
clean:
${RM} *.so* *.${OBJEXT} *.dylib libsdlpp*
.PHONY: all clean test
+7 -1
View File
@@ -7,14 +7,20 @@
#include "sdlpp_circlecolider.hpp"
#include "sdlpp_circlerenderer.hpp"
#include "sdlpp_font.hpp"
#include "sdlpp_fontconfiguration.hpp"
#include "sdlpp_linerenderer.hpp"
#include "sdlpp_scene.hpp"
#include "sdlpp_rectcolider.hpp"
#include "sdlpp_rectrenderer.hpp"
#include "sdlpp_renderer.hpp"
#include "sdlpp_renderobject.hpp"
#include "sdlpp_scene.hpp"
#include "sdlpp_textrenderer.hpp"
#include "sdlpp_texture.hpp"
#include "sdlpp_visitor.hpp"
#include "sdlpp_window.hpp"
#include "sdlpp_line.hpp"
#include "sdlpp_vector.hpp"
#include "sdlpp_geometry.hpp"
#endif
+48 -70
View File
@@ -1,46 +1,41 @@
#include "sdlpp_circlecolider.hpp"
#include "sdlpp_geometry.hpp"
namespace SDLPP {
CircleColider::CircleColider( double x, double y, double rad )
: CollisionPolygon( x, y ) {
original_rad = rad;
: CircleColider( { x, y }, rad ) {}
CircleColider::CircleColider( const Vec2D< double > &center, double rad )
: CollisionPolygon( center ), original_rad( rad ) {}
CircleColider::CircleColider( double x, double y, double rad, uint64_t id )
: CircleColider( { x, y }, rad, id ) {}
CircleColider::CircleColider( const Vec2D< double > &center, double rad,
uint64_t id )
: CircleColider( center, rad ) {
_id = id;
}
bool CircleColider::colidesWith( const SDLPP::CollisionPolygon &other ) const {
if ( other.isCircle() ) {
int otherRad = ( other.rightmost() - other.leftmost() ) / 2;
/* check if distance of centers is lower than radiuses added together */
int otherRad =
dynamic_cast< const SDLPP::CircleColider & >( other ).getRadius();
int thisRad = getRadius();
int totalDist = otherRad + thisRad;
int xdiff = other.leftmost() + otherRad - ( leftmost() + thisRad );
int ydiff = other.topmost() + otherRad - ( topmost() + thisRad );
int xdiff = other.getX() - getX();
int ydiff = other.getY() - getY();
return ( xdiff * xdiff + ydiff * ydiff ) <= totalDist * totalDist;
} else if ( other.isInfinite() ) {
return infinityIntersection( other, *this );
}
int rad = rad_;
int centerx = getX();
int centery = getY();
if ( other.topmost() <= centery && other.bottommost() >= centery ) {
return other.leftmost() <= rightmost() &&
other.rightmost() >= leftmost();
} else if ( other.leftmost() <= centerx && other.rightmost() >= centerx ) {
return other.topmost() <= bottommost() &&
other.bottommost() >= topmost();
/* other is not a circle */
int rad = getRadius();
for ( auto &line : other.getLines() ) {
auto distance = pointLineDistance( position, line );
if ( distance * distance <= rad * rad )
return true;
}
int pointx = 0, pointy = 0;
if ( centerx > other.rightmost() ) {
pointx = other.rightmost();
} else {
pointx = other.leftmost();
}
if ( centery < other.topmost() ) {
pointy = other.topmost();
} else {
pointy = other.bottommost();
}
int distancesquared = ( pointx - centerx ) * ( pointx - centerx ) +
( pointy - centery ) * ( pointy - centery );
return distancesquared <= rad * rad;
return false;
}
bool CircleColider::isCircle() const {
@@ -59,14 +54,15 @@ int CircleColider::rightmost() const {
return getX() + rad_;
}
void CircleColider::updateCollision( int x, int y, int w, int h ) {
position_x = original_x * w + x;
position_y = original_y * h + y;
void CircleColider::updateCollision( int x, int y, int w, int h, uint64_t id ) {
position = Vec2D< int >( original.getX() * w + x, original.getY() * h + y );
rad_ = original_rad * w;
if ( _id == static_cast< uint64_t >( -1 ) )
_id = id;
}
void CircleColider::render( Renderer &renderer,
const std::tuple< int, int, int, int > &color ) {
void CircleColider::render( Renderer &renderer, const SDL_Color &color,
const SDL_Color &outline_color ) {
std::vector< int > rect = { leftmost(), topmost(), rightmost(),
bottommost() };
auto center_x = getX();
@@ -76,14 +72,13 @@ void CircleColider::render( Renderer &renderer,
auto xdiff = center_x - i;
auto xdist = xdiff * xdiff;
auto allowed_rad = sqrt( radsq - xdist );
SDL_SetRenderDrawColor( renderer.getRendererPtr(),
std::get< 0 >( color ), std::get< 1 >( color ),
std::get< 2 >( color ), 0x40 );
SDL_SetRenderDrawColor( renderer.getRendererPtr(), color.r, color.g,
color.b, color.a );
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
center_y - allowed_rad, i, center_y + allowed_rad );
SDL_SetRenderDrawColor( renderer.getRendererPtr(),
std::get< 0 >( color ), std::get< 1 >( color ),
std::get< 2 >( color ), 0x80 );
SDL_SetRenderDrawColor( renderer.getRendererPtr(), outline_color.r,
outline_color.g, outline_color.b,
outline_color.a );
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
center_y - allowed_rad, i,
center_y - allowed_rad + 2 );
@@ -91,39 +86,18 @@ void CircleColider::render( Renderer &renderer,
center_y + allowed_rad, i,
center_y + allowed_rad - 2 );
}
SDL_SetRenderDrawColor( renderer.getRendererPtr(), 0xFF, 0, 0, 0xFF );
SDL_RenderDrawLine( renderer.getRendererPtr(), center_x, center_y,
center_x + rad_, center_y );
SDL_RenderDrawLine( renderer.getRendererPtr(), center_x, center_y, center_x,
center_y + rad_ );
SDL_RenderDrawLine( renderer.getRendererPtr(), center_x, center_y,
center_x - rad_, center_y );
SDL_RenderDrawLine( renderer.getRendererPtr(), center_x, center_y, center_x,
center_y - rad_ );
}
void CircleColider::render( Renderer &renderer, const SDL_Color &color ) {
auto input_color = color;
auto outline_color = color;
input_color.a = 0x40;
outline_color.a = 0x80;
render( renderer, input_color, outline_color );
}
void CircleColider::render( Renderer &renderer ) {
std::vector< int > rect = { leftmost(), topmost(), rightmost(),
bottommost() };
auto center_x = getX();
auto center_y = getY();
auto radsq = rad_ * rad_;
for ( int i = rect[0]; i <= rect[2]; i++ ) {
auto xdiff = center_x - i;
auto xdist = xdiff * xdiff;
auto allowed_rad = sqrt( radsq - xdist );
SDL_SetRenderDrawColor( renderer.getRendererPtr(), sdl_color.r,
sdl_color.g, sdl_color.b, sdl_color.a );
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
center_y - allowed_rad, i, center_y + allowed_rad );
SDL_SetRenderDrawColor( renderer.getRendererPtr(), sdl_outline.r,
sdl_outline.g, sdl_outline.b, sdl_outline.a );
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
center_y - allowed_rad, i,
center_y - allowed_rad + 2 );
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
center_y + allowed_rad, i,
center_y + allowed_rad - 2 );
}
render( renderer, sdl_color, sdl_outline );
}
int CircleColider::getRadius() const {
@@ -133,4 +107,8 @@ int CircleColider::getRadius() const {
std::shared_ptr< CollisionPolygon > CircleColider::copySelf() {
return std::make_shared< CircleColider >( *this );
}
std::vector< Line< int > > CircleColider::getLines() const {
return {};
}
} // namespace SDLPP
+10 -5
View File
@@ -10,6 +10,9 @@ namespace SDLPP {
class SDLPPSCOPE CircleColider : public CollisionPolygon {
public:
CircleColider( double x, double y, double rad );
CircleColider( const Vec2D< double > &center, double rad );
CircleColider( double x, double y, double rad, uint64_t id );
CircleColider( const Vec2D< double > &center, double rad, uint64_t id );
virtual ~CircleColider() {}
virtual bool colidesWith( const CollisionPolygon &other ) const override;
@@ -19,12 +22,14 @@ public:
virtual int leftmost() const override;
virtual int rightmost() const override;
virtual void updateCollision( int x, int y, int w, int h ) override;
virtual void
render( Renderer &renderer,
const std::tuple< int, int, int, int > &color ) override;
virtual void updateCollision( int x, int y, int w, int h,
uint64_t id ) override;
virtual void render( Renderer &renderer, const SDL_Color &color,
const SDL_Color &outline_color ) override;
virtual void render( Renderer &renderer, const SDL_Color &color ) override;
virtual void render( Renderer &renderer ) override;
virtual std::shared_ptr<CollisionPolygon> copySelf() override;
virtual std::shared_ptr< CollisionPolygon > copySelf() override;
virtual std::vector< Line< int > > getLines() const override;
private:
int getRadius() const;
+43 -49
View File
@@ -6,28 +6,41 @@
namespace SDLPP {
CircleRender::CircleRender( double x, double y, double rad,
std::shared_ptr< Renderer > &r )
: RenderObject( r ) {
og_x = x_ = x;
og_y = y_ = y;
og_r = r_ = rad;
}
: CircleRender( { x, y }, rad, r ) {}
CircleRender::CircleRender( double x, double y, double rad,
std::shared_ptr< Renderer > &r,
std::shared_ptr< Texture > &t )
: CircleRender( x, y, rad, r ) {
throw "I don't support textures yet!!!";
}
: CircleRender( { x, y }, rad, r, t ) {}
CircleRender::CircleRender( double x, double y, double rad,
std::shared_ptr< Renderer > &r,
const std::string &img_or_color,
bool is_polygon )
: CircleRender( x, y, rad, r ) {
if(!is_polygon) {
const std::string &img_or_color, bool is_polygon )
: CircleRender( { x, y }, rad, r, img_or_color, is_polygon ) {}
CircleRender::CircleRender( Vec2D< double > center, double rad,
std::shared_ptr< Renderer > &r )
: RenderObject( r ) {
original = center;
current = center;
og_r = r_ = rad;
}
CircleRender::CircleRender( Vec2D< double > center, double rad,
std::shared_ptr< Renderer > &r,
std::shared_ptr< Texture > & /*UNUSED*/ )
: CircleRender( center, rad, r ) {
throw "I don't support textures yet!!!";
}
CircleRender::CircleRender( Vec2D< double > center, double rad,
std::shared_ptr< Renderer > &r,
const std::string &img_or_color, bool is_polygon )
: CircleRender( center, rad, r ) {
if ( !is_polygon ) {
throw "I don't support textures yet!!!";
} else {
setColor(img_or_color);
setColor( img_or_color );
color = img_or_color;
}
}
@@ -36,7 +49,8 @@ void CircleRender::setColor( const std::string &color ) {
if ( !polygon ) {
polygon = std::make_shared< CircleColider >( 0, 0, 1 );
polygon->updateCollision( collisionPushX(), collisionPushY(),
collisionWidth(), collisionHeight() );
collisionWidth(), collisionHeight(),
getId() );
}
polygon->setColor( color );
}
@@ -45,14 +59,16 @@ void CircleRender::setOutlineColor( const std::string &color ) {
if ( !polygon ) {
polygon = std::make_shared< CircleColider >( 0, 0, 1 );
polygon->updateCollision( collisionPushX(), collisionPushY(),
collisionWidth(), collisionHeight() );
collisionWidth(), collisionHeight(),
getId() );
}
polygon->setOutlineColor( color );
}
std::pair< std::pair< double, double >, std::pair< double, double > >
std::pair< Vec2D< double >, Vec2D< double > >
CircleRender::getDoubleRect() const {
return { { og_x - og_r, og_y - og_r }, { 2 * og_r, 2 * og_r } };
return { { original.getX() - og_r, original.getY() - og_r },
{ 2 * og_r, 2 * og_r } };
}
int CircleRender::leftmost() {
@@ -90,16 +106,17 @@ int CircleRender::collisionHeight() {
void CircleRender::updateSizeAndPosition() {
updateXY();
auto dimension = renderer->getSmallerSide();
rect.x = std::round( (x_ - r_) * dimension );
rect.y = std::round( (y_ - r_) * dimension );
rect.w = std::round( ( x_ + r_ ) * dimension ) - rect.x;
rect.h = std::round( ( y_ + r_ ) * dimension ) - rect.y;
rect.x = std::round( ( current.getX() - r_ ) * dimension );
rect.y = std::round( ( current.getY() - r_ ) * dimension );
rect.w = std::round( ( current.getX() + r_ ) * dimension ) - rect.x;
rect.h = std::round( ( current.getY() + r_ ) * dimension ) - rect.y;
if ( polygon )
polygon->updateCollision( collisionPushX(), collisionPushY(),
collisionWidth(), collisionHeight() );
collisionWidth(), collisionHeight(),
getId() );
for ( auto &x : collisions ) {
x->updateCollision( collisionPushX(), collisionPushY(),
collisionWidth(), collisionHeight() );
collisionWidth(), collisionHeight(), getId() );
}
}
@@ -107,40 +124,17 @@ SDL_Rect CircleRender::getRect() {
return rect;
}
void CircleRender::centerX() {
centerx = true;
updateSizeAndPosition();
}
std::shared_ptr< RenderObject > CircleRender::copySelf() {
auto ret = std::make_shared< CircleRender >( *this );
copyTo(ret);
copyTo( ret );
return ret;
}
void CircleRender::copyTo(std::shared_ptr<RenderObject> other) {
RenderObject::copyTo(other);
void CircleRender::copyTo( std::shared_ptr< RenderObject > other ) {
RenderObject::copyTo( other );
}
std::string CircleRender::getColor() const {
return color;
}
void CircleRender::updateXY() {
if ( !centerx ) {
x_ = og_x;
y_ = og_y;
return;
}
auto width = renderer->getWidth();
auto height = renderer->getHeight();
if ( width > height ) {
auto multiplier =
static_cast< double >( width ) / static_cast< double >( height );
x_ = og_x + static_cast< double >( multiplier - 1 ) / 2;
} else {
x_ = og_x;
}
y_ = og_y;
}
} // namespace SDLPP
+21 -10
View File
@@ -11,17 +11,30 @@ class SDLPPSCOPE CircleRender : public RenderObject {
public:
CircleRender() = delete;
virtual ~CircleRender(){};
CircleRender( double x, double y, double rad, std::shared_ptr< Renderer > &r );
CircleRender( double x, double y, double rad, std::shared_ptr< Renderer > &r,
CircleRender( double x, double y, double rad,
std::shared_ptr< Renderer > &r );
CircleRender( double x, double y, double rad,
std::shared_ptr< Renderer > &r,
std::shared_ptr< Texture > &t );
CircleRender( double x, double y, double rad, std::shared_ptr< Renderer > &r,
CircleRender( double x, double y, double rad,
std::shared_ptr< Renderer > &r,
const std::string &img_or_color, bool is_polygon = false );
CircleRender( Vec2D< double > center, double rad,
std::shared_ptr< Renderer > &r );
CircleRender( Vec2D< double > center, double rad,
std::shared_ptr< Renderer > &r,
std::shared_ptr< Texture > &t );
CircleRender( Vec2D< double > center, double rad,
std::shared_ptr< Renderer > &r,
const std::string &img_or_color, bool is_polygon = false );
virtual void setColor( const std::string &color ) override;
virtual void setOutlineColor( const std::string &color ) override;
virtual void specialAction( int /*UNUSED*/ ) override{}
virtual void custom_move( int /*UNUSED*/ ) override{}
virtual std::pair< std::pair< double, double >,
std::pair< double, double > >
virtual void specialAction( int /*UNUSED*/ ) override {}
virtual void custom_move( int ticks ) override {
RenderObject::custom_move(ticks);
}
virtual std::pair< Vec2D< double >, Vec2D< double > >
getDoubleRect() const override;
virtual int leftmost() override;
virtual int topmost() override;
@@ -33,13 +46,11 @@ public:
virtual int collisionHeight() override;
virtual void updateSizeAndPosition() override;
virtual SDL_Rect getRect() override;
virtual void centerX() override;
virtual std::shared_ptr< RenderObject > copySelf() override;
std::string getColor() const;
private:
virtual void copyTo(std::shared_ptr<RenderObject> other) override;
void updateXY();
virtual void copyTo( std::shared_ptr< RenderObject > other ) override;
double og_r;
double r_;
std::string color = "";
+54 -13
View File
@@ -1,11 +1,19 @@
#include "sdlpp_collision.hpp"
#include "sdlpp_geometry.hpp"
namespace SDLPP {
CollisionPolygon::CollisionPolygon( double x, double y ) {
original_x = x;
original_y = y;
position_x = 0;
position_y = 0;
CollisionPolygon::CollisionPolygon( double x, double y )
: CollisionPolygon( Vec2D< double >( x, y ) ) {}
CollisionPolygon::CollisionPolygon( const Vec2D< double > &input ) {
original = input;
position = { 0, 0 };
}
CollisionPolygon::CollisionPolygon( double x, double y, uint64_t id )
: CollisionPolygon( Vec2D< double >( x, y ), id ) {}
CollisionPolygon::CollisionPolygon( const Vec2D< double > &input, uint64_t id )
: CollisionPolygon( input ) {
_id = id;
}
bool CollisionPolygon::isInfinite() const {
@@ -15,16 +23,26 @@ void CollisionPolygon::setInfinite() {
infinite = true;
}
void CollisionPolygon::updateCollision( int x, int y, int w, int h ) {
position_x = original_x * w + x;
position_y = original_y * h + y;
void CollisionPolygon::updateCollision( int x, int y, int w, int h,
uint64_t id ) {
if ( _id == static_cast< uint64_t >( -1 ) )
_id = id;
position = Vec2D< int >( original.getX() * w + x, original.getY() * h + y );
}
void CollisionPolygon::setPos(const Vec2D<double> &pos) {
original = pos;
}
void CollisionPolygon::setPos(double x, double y) {
setPos({x, y});
}
int CollisionPolygon::getX() const {
return position_x;
return position.getX();
}
int CollisionPolygon::getY() const {
return position_y;
return position.getY();
}
void CollisionPolygon::setColor( const std::string &color ) {
@@ -33,6 +51,12 @@ void CollisionPolygon::setColor( const std::string &color ) {
void CollisionPolygon::setOutlineColor( const std::string &color ) {
sdl_outline = getSDLColorHEX( color );
}
void CollisionPolygon::setId( uint64_t id ) {
_id = id;
}
uint64_t CollisionPolygon::getId() {
return _id;
}
bool infinityIntersection( const SDLPP::CollisionPolygon &infinite,
const SDLPP::CollisionPolygon &other ) {
@@ -53,8 +77,25 @@ bool infinityIntersection( const SDLPP::CollisionPolygon &infinite,
bool intersects( const SDLPP::CollisionPolygon &p1,
const SDLPP::CollisionPolygon &p2 ) {
return !(
p1.rightmost() < p2.leftmost() || p2.rightmost() < p1.leftmost() ||
p1.topmost() > p2.bottommost() || p2.topmost() > p1.bottommost() );
if ( p1.rightmost() < p2.leftmost() || p2.rightmost() < p1.leftmost() ||
p1.bottommost() < p2.topmost() || p2.bottommost() < p1.topmost() )
return false;
if ( p1.leftmost() < p2.leftmost() && p1.topmost() < p2.topmost() &&
p1.rightmost() > p2.rightmost() &&
p1.bottommost() > p2.bottommost() ) {
return true;
}
if ( p2.leftmost() < p1.leftmost() && p2.topmost() < p1.topmost() &&
p2.rightmost() > p1.rightmost() &&
p2.bottommost() > p1.bottommost() ) {
return true;
}
for ( auto &line : p1.getLines() ) {
for ( auto &line2 : p2.getLines() ) {
if ( linesCross( line, line2 ) )
return true;
}
}
return false;
}
} // namespace SDLPP
+20 -8
View File
@@ -3,12 +3,18 @@
#include "sdlpp_common.hpp"
#include "sdlpp_renderer.hpp"
#include "sdlpp_vector.hpp"
#include "sdlpp_line.hpp"
#include <memory>
#include <vector>
namespace SDLPP {
class SDLPPSCOPE CollisionPolygon {
public:
CollisionPolygon( double x, double y );
CollisionPolygon( const Vec2D< double > &input );
CollisionPolygon( double x, double y, uint64_t id );
CollisionPolygon( const Vec2D< double > &input, uint64_t id );
virtual ~CollisionPolygon() {}
virtual bool colidesWith( const CollisionPolygon &other ) const = 0;
virtual bool isCircle() const = 0;
@@ -18,24 +24,30 @@ public:
virtual int bottommost() const = 0;
virtual int leftmost() const = 0;
virtual int rightmost() const = 0;
virtual void updateCollision( int x, int y, int w, int h );
virtual void render( Renderer &renderer,
const std::tuple< int, int, int, int > &color ) = 0;
virtual void updateCollision( int x, int y, int w, int h,
uint64_t objectId );
virtual void render( Renderer &renderer, const SDL_Color &color,
const SDL_Color &outline_color ) = 0;
virtual void render( Renderer &renderer, const SDL_Color &color ) = 0;
virtual void render( Renderer &renderer ) = 0;
void setPos(const Vec2D<double> &pos);
void setPos(double x, double y);
int getX() const;
int getY() const;
void setColor( const std::string &color );
void setOutlineColor( const std::string &color );
virtual std::shared_ptr<CollisionPolygon> copySelf() = 0;
virtual std::shared_ptr< CollisionPolygon > copySelf() = 0;
virtual std::vector< Line< int > > getLines() const = 0;
uint64_t getId();
void setId( uint64_t id );
protected:
double original_x;
double original_y;
int position_x;
int position_y;
Vec2D< double > original;
Vec2D< int > position;
bool infinite = false;
SDL_Color sdl_color = { 0, 0, 0, 0 };
SDL_Color sdl_outline = { 0, 0, 0, 0 };
uint64_t _id = -1;
};
SDLPPSCOPE bool infinityIntersection( const SDLPP::CollisionPolygon &infinite,
+2 -2
View File
@@ -1,8 +1,8 @@
#include "sdlpp_font.hpp"
namespace SDLPP {
Font::Font( const std::string &font ) : font_path(font) {}
Font::Font( const std::string &font, int size ) : Font(font) {
Font::Font( const std::string &font ) : font_path( font ) {}
Font::Font( const std::string &font, int size ) : Font( font ) {
original_size = size;
font_ptr = TTF_OpenFont( font_path.c_str(), size );
checkFont();
+37
View File
@@ -0,0 +1,37 @@
#include "sdlpp_fontconfiguration.hpp"
namespace SDLPP {
FontConfiguration::FontConfiguration( std::shared_ptr< Font > font,
const std::string &color,
const std::string &outline_color,
double outline_size ) {
_font = font;
_color = color;
_outline_color = outline_color;
_outline_size = outline_size;
}
const std::shared_ptr< Font > &FontConfiguration::getFont() {
return _font;
}
const std::string &FontConfiguration::getColor() {
return _color;
}
const std::string &FontConfiguration::getOutlineColor() {
return _outline_color;
}
const double &FontConfiguration::getOutlineSize() {
return _outline_size;
}
void FontConfiguration::setColor( const std::string &color ) {
_color = color;
}
void FontConfiguration::setOutlineColor( const std::string &outline_color ) {
_outline_color = outline_color;
}
} // namespace SDLPP
+8 -30
View File
@@ -3,42 +3,20 @@
#include "sdlpp_common.hpp"
#include "sdlpp_font.hpp"
#include <memory>
namespace SDLPP {
class SDLPPSCOPE FontConfiguration {
public:
FontConfiguration() = delete;
FontConfiguration( std::shared_ptr< Font > font, const std::string &color,
const std::string &outline_color, double outline_size ) {
_font = font;
_color = color;
_outline_color = outline_color;
_outline_size = outline_size;
}
const std::shared_ptr< Font > &getFont() {
return _font;
}
const std::string &getColor() {
return _color;
}
const std::string &getOutlineColor() {
return _outline_color;
}
const double &getOutlineSize() {
return _outline_size;
}
void setColor( const std::string &color ) {
_color = color;
}
void setOutlineColor( const std::string &outline_color ) {
_outline_color = outline_color;
}
const std::string &outline_color, double outline_size );
const std::shared_ptr< Font > &getFont();
const std::string &getColor();
const std::string &getOutlineColor();
const double &getOutlineSize();
void setColor( const std::string &color );
void setOutlineColor( const std::string &outline_color );
private:
std::shared_ptr< Font > _font;
+7
View File
@@ -0,0 +1,7 @@
#ifndef SDLPP_HPP_GEOMETRY
#define SDLPP_HPP_GEOMETRY
#include "sdlpp_geometry_vector.hpp"
#include "sdlpp_geometry_line.hpp"
#endif
+71
View File
@@ -0,0 +1,71 @@
#ifndef SDLPP_HPP_GEOMETRY_LINE
#define SDLPP_HPP_GEOMETRY_LINE
#include "sdlpp_common.hpp"
#include "sdlpp_vector.hpp"
#include "sdlpp_line.hpp"
#include <algorithm>
#include <iostream>
namespace SDLPP {
template < typename T >
Vec2D< T > pointProjectionOnLine( const Vec2D< T > &point,
const Line< T > &line ) {
/* from here -
* https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
*/
auto length_squared = line.lengthSquared();
if ( length_squared == 0.0 )
return point;
auto t =
std::max( 0.0, std::min( 1.0, ( ( point - line.getStart() ) *
( line.getEnd() - line.getStart() ) ) /
length_squared ) );
return line.getStart() + t * ( line.getEnd() - line.getStart() );
}
template < typename T >
double pointLineDistance( const Vec2D< T > &point, const Line< T > &line ) {
return vecDistance( point, pointProjectionOnLine( point, line ) );
}
template < typename T >
int _determinant( const Line< T > &line, const Vec2D< T > &point ) {
auto res = ( line.getEnd().getX() - line.getStart().getX() ) *
( point.getY() - line.getStart().getY() ) -
( line.getEnd().getY() - line.getStart().getY() ) *
( point.getX() - line.getStart().getX() );
if ( res < 0 )
return -1;
if ( res > 0 )
return 1;
return 0;
}
template < typename T >
bool linesCross( const Line< T > &a, const Line< T > &b ) {
auto det_a_s = _determinant( a, b.getStart() );
auto det_a_e = _determinant( a, b.getEnd() );
if ( det_a_s == det_a_e && det_a_s != 0 )
return false;
// det_a_s == det_a_e == 0, means that lines have the same vector,
// we need to find out if they overlap
if ( det_a_s == det_a_e ) {
if ( a.getStart().getX() == a.getEnd().getX() ) {
// vertical lines
return a.bottomost().getY() > b.topmost().getY() &&
a.topmost().getY() < b.bottomost().getY();
} else {
// horizontal lines
return a.leftmost().getX() < b.rightmost().getX() &&
a.rightmost().getX() > b.leftmost().getX();
}
}
auto det_b_s = _determinant( b, a.getStart() );
auto det_b_e = _determinant( b, a.getEnd() );
if ( det_b_s == det_b_e )
return false;
return true;
}
} // namespace SDLPP
#endif
+29
View File
@@ -0,0 +1,29 @@
#ifndef SDLPP_HPP_GEOMETRY_VECTOR
#define SDLPP_HPP_GEOMETRY_VECTOR
#include "sdlpp_common.hpp"
#include "sdlpp_vector.hpp"
#include <cmath>
namespace SDLPP {
template < typename T >
double vecDotProduct( const Vec2D< T > &a, const Vec2D< T > &b ) {
return a * b;
}
template < typename T > double vecLengthSquared( const Vec2D< T > &vec ) {
return vecDotProduct( vec, vec );
}
template < typename T > double vecLength( const Vec2D< T > &vec ) {
return std::sqrt( vecLengthSquared( vec ) );
}
template < typename T >
double vecDistanceSquared( const Vec2D< T > &a, const Vec2D< T > &b ) {
return vecLengthSquared( a - b );
}
template < typename T >
double vecDistance( const Vec2D< T > &a, const Vec2D< T > &b ) {
return vecLength( a - b );
}
} // namespace SDLPP
#endif
+102
View File
@@ -0,0 +1,102 @@
#ifndef SDLPP_HPP_LINE
#define SDLPP_HPP_LINE
#include "sdlpp_common.hpp"
#include "sdlpp_vector.hpp"
#include <iostream>
namespace SDLPP {
template < typename T > class SDLPPSCOPE Line {
public:
Line() = delete;
~Line() = default;
Line( const Vec2D< T > &start, const Vec2D< T > &end )
: _start( start ), _end( end ) {
updateMost();
}
Line( T x_1, T y_1, T x_2, T y_2 ) : Line( { x_1, y_1 }, { x_2, y_2 } ) {}
Line( const Vec2D< T > &start, const Vec2D< T > &end, bool infinite )
: Line( start, end ) {
_infinite = infinite;
}
Line( T x_1, T y_1, T x_2, T y_2, bool infinite )
: Line( { x_1, y_1 }, { x_2, y_2 }, infinite ) {}
Line( const Line &input ) : Line( input.getStart(), input.getEnd() ) {}
Line &operator=( const Line &input ) {
_start = input.getStart();
_end = input.getEnd();
updateMost();
return *this;
}
void updateMost() {
if ( _start.getY() < _end.getY() ) {
top = &_start;
bottom = &_end;
} else {
top = &_end;
bottom = &_start;
}
if ( _start.getX() < _end.getX() ) {
left = &_start;
right = &_end;
} else {
left = &_end;
right = &_start;
}
}
const Vec2D< T > &getStart() const {
return _start;
}
const Vec2D< T > &getEnd() const {
return _end;
}
double length() const {
return vecDistance( _start, _end );
}
double lengthSquared() const {
return vecDistanceSquared( _start, _end );
}
void setInfinite( bool infinite ) {
_infinite = infinite;
}
bool isInfinite() {
return _infinite;
}
void add( const Vec2D< T > &vec ) {
_start += vec;
_end += vec;
}
const Vec2D< T > &topmost() const {
return *top;
}
const Vec2D< T > &bottomost() const {
return *bottom;
}
const Vec2D< T > &leftmost() const {
return *left;
}
const Vec2D< T > &rightmost() const {
return *right;
}
private:
Vec2D< T > _start;
Vec2D< T > _end;
Vec2D< T > *top = nullptr;
Vec2D< T > *bottom = nullptr;
Vec2D< T > *left = nullptr;
Vec2D< T > *right = nullptr;
bool _infinite = false;
};
} // namespace SDLPP
#endif
+54 -84
View File
@@ -4,83 +4,73 @@
namespace SDLPP {
LineRenderer::LineRenderer( double x1, double y1, double x2, double y2,
const std::shared_ptr< Renderer > &r )
: RenderObject( r ) {
og_x1 = x1_ = x1;
og_y1 = y1_ = y1;
og_x2 = x2_ = x2;
og_y2 = y2_ = y2;
updateSizeAndPosition();
}
: LineRenderer( { { x1, y1 }, { x2, y2 } }, r ) {}
LineRenderer::LineRenderer( double x1, double y1, double x2, double y2,
const std::shared_ptr< Renderer > &r,
const std::string &color )
: LineRenderer( x1, y1, x2, y2, r ) {
: LineRenderer( { { x1, y1 }, { x2, y2 } }, r, color ) {}
LineRenderer::LineRenderer( const Line< double > &line,
const std::shared_ptr< Renderer > &r )
: RenderObject( r ) {
original = current = line;
updateSizeAndPosition();
}
LineRenderer::LineRenderer( const Line< double > &line,
const std::shared_ptr< Renderer > &r,
const std::string &color )
: LineRenderer( line, r ) {
setColor( color );
}
void LineRenderer::setColor( const std::string &color ) {
_color = getColorsHEX( color );
_color = getSDLColorHEX( color );
}
void LineRenderer::render() {
if ( !getHidden() ) {
SDL_SetRenderDrawColor(
renderer->getRendererPtr(), std::get< 0 >( _color ),
std::get< 1 >( _color ), std::get< 2 >( _color ),
std::get< 3 >( _color ) );
SDL_RenderDrawLine( renderer->getRendererPtr(), pixel_x1, pixel_y1,
pixel_x2, pixel_y2 );
SDL_SetRenderDrawColor( renderer->getRendererPtr(), _color.r, _color.g,
_color.b, _color.a );
SDL_RenderDrawLine(
renderer->getRendererPtr(), pixel_line.getStart().getX(),
pixel_line.getStart().getY(), pixel_line.getEnd().getX(),
pixel_line.getEnd().getY() );
}
if ( hasCollisions() && renderer->getRenderColiders() && !getHidden() ) {
for ( const auto &col : getCollisions() )
col->render( *renderer, colider_color );
}
}
void LineRenderer::move( int ticks ) {
if ( permanent )
return;
auto addx =
static_cast< double >( movementSpeed * movementDirection.first ) *
( static_cast< double >( ticks ) / 1000 );
auto addy =
static_cast< double >( movementSpeed * movementDirection.second ) *
( static_cast< double >( ticks ) / 1000 );
if ( std::isnan( addx ) || std::isnan( addy ) )
return;
og_x1 += addx;
og_x2 += addx;
og_y1 += addy;
og_y2 += addy;
custom_move( ticks );
updateSizeAndPosition();
}
void LineRenderer::setPos( double x, double y ) {
auto diffx = og_x2 - og_x1;
auto diffy = og_y2 - og_y1;
og_x1 = x;
og_y1 = y;
og_x2 = og_x1 + diffx;
og_y2 = og_y1 + diffy;
updateSizeAndPosition();
setPos( Vec2D< double >( x, y ) );
}
void LineRenderer::setPos( const std::pair< double, double > &pos ) {
setPos( pos.first, pos.second );
setPos( Vec2D< double >( pos.first, pos.second ) );
}
std::pair< double, double > LineRenderer::getPos() const {
return { og_x1, og_y1 };
void LineRenderer::setPos( const Vec2D< double > &vec ) {
auto diff = original.getEnd() - original.getStart();
original = { vec, vec + diff };
updateSizeAndPosition();
}
Vec2D< double > LineRenderer::getPos() const {
return original.getStart();
}
int LineRenderer::leftmost() {
return pixel_x1 < pixel_x2 ? pixel_x1 : pixel_x2;
return pixel_line.getStart().getX() < pixel_line.getEnd().getX()
? pixel_line.getStart().getX()
: pixel_line.getEnd().getX();
}
int LineRenderer::topmost() {
return pixel_y1 < pixel_y2 ? pixel_y1 : pixel_y2;
return pixel_line.getStart().getY() < pixel_line.getEnd().getY()
? pixel_line.getStart().getY()
: pixel_line.getEnd().getY();
}
int LineRenderer::rightmost() {
return pixel_x1 > pixel_x2 ? pixel_x1 : pixel_x2;
return pixel_line.getStart().getX() > pixel_line.getEnd().getX()
? pixel_line.getStart().getX()
: pixel_line.getEnd().getX();
}
int LineRenderer::bottommost() {
return pixel_y1 > pixel_y2 ? pixel_y1 : pixel_y2;
return pixel_line.getStart().getY() > pixel_line.getEnd().getY()
? pixel_line.getStart().getY()
: pixel_line.getEnd().getY();
}
int LineRenderer::collisionPushX() {
return leftmost();
@@ -97,57 +87,37 @@ int LineRenderer::collisionHeight() {
void LineRenderer::updateSizeAndPosition() {
updateXY();
auto dimension = renderer->getSmallerSide();
pixel_x1 = std::round( x1_ * dimension );
pixel_x2 = std::round( x2_ * dimension );
pixel_y1 = std::round( y1_ * dimension );
pixel_y2 = std::round( y2_ * dimension );
pixel_line = Line< int >(
Vec2D< int >( std::round( current.getStart().getX() * dimension ),
std::round( current.getStart().getY() * dimension ) ),
Vec2D< int >( std::round( current.getEnd().getX() * dimension ),
std::round( current.getEnd().getY() * dimension ) ) );
for ( auto &x : collisions ) {
x->updateCollision( collisionPushX(), collisionPushY(),
collisionWidth(), collisionHeight() );
collisionWidth(), collisionHeight(), getId() );
}
}
void LineRenderer::centerX() {
centerx = true;
updateSizeAndPosition();
}
std::shared_ptr< RenderObject > LineRenderer::copySelf() {
auto ret = std::make_shared< LineRenderer >( *this );
copyTo(ret);
copyTo( ret );
return ret;
}
void LineRenderer::copyTo(std::shared_ptr<RenderObject> other) {
RenderObject::copyTo(other);
void LineRenderer::copyTo( std::shared_ptr< RenderObject > other ) {
RenderObject::copyTo( other );
}
SDL_Rect LineRenderer::getRect() {
return { leftmost(), topmost(), rightmost() - leftmost(),
bottommost() - topmost() };
}
std::pair< std::pair< double, double >, std::pair< double, double > >
std::pair< Vec2D< double >, Vec2D< double > >
LineRenderer::getDoubleRect() const {
return { { og_x1, og_y1 }, { og_x2 - og_x1, og_y2 - og_y1 } };
return { original.getStart(), original.getEnd() - original.getStart() };
}
void LineRenderer::updateXY() {
if ( !centerx ) {
x1_ = og_x1;
y1_ = og_y1;
x2_ = og_x2;
y2_ = og_y2;
return;
}
auto width = renderer->getWidth();
auto height = renderer->getHeight();
if ( width > height ) {
auto multiplier =
static_cast< double >( width ) / static_cast< double >( height );
x1_ = og_x1 + static_cast< double >( multiplier - 1 ) / 2;
x2_ = og_x2 + static_cast< double >( multiplier - 1 ) / 2;
} else {
x1_ = og_x1;
x2_ = og_x2;
}
y1_ = og_y1;
y2_ = og_y2;
auto additions = computeAlignmentAdditions();
current = { original.getStart() + additions,
original.getEnd() + additions };
}
} // namespace SDLPP
+19 -21
View File
@@ -2,7 +2,9 @@
#define SDLPP_HPP_LINE_RENDERER
#include "sdlpp_common.hpp"
#include "sdlpp_line.hpp"
#include "sdlpp_renderobject.hpp"
#include "sdlpp_vector.hpp"
namespace SDLPP {
class SDLPPSCOPE LineRenderer : public RenderObject {
@@ -14,14 +16,21 @@ public:
LineRenderer( double x1, double y1, double x2, double y2,
const std::shared_ptr< Renderer > &r,
const std::string &color );
LineRenderer( const Line< double > &line,
const std::shared_ptr< Renderer > &r );
LineRenderer( const Line< double > &line,
const std::shared_ptr< Renderer > &r,
const std::string &color );
virtual void setColor( const std::string &color ) override;
virtual void specialAction( int /*UNUSED*/ ) override{};
virtual void render() override;
virtual void move( int ticks ) override;
virtual void custom_move( int /*UNUSED*/ ) override {}
virtual void custom_move( int ticks ) override {
RenderObject::custom_move(ticks);
}
virtual void setPos( double x, double y ) override;
virtual void setPos( const std::pair< double, double > &pos ) override;
virtual std::pair< double, double > getPos() const override;
virtual void setPos( const Vec2D< double > &vec ) override;
virtual Vec2D< double > getPos() const override;
virtual int leftmost() override;
virtual int topmost() override;
virtual int rightmost() override;
@@ -31,32 +40,21 @@ public:
virtual int collisionWidth() override;
virtual int collisionHeight() override;
virtual void updateSizeAndPosition() override;
virtual void centerX() override;
virtual std::shared_ptr< RenderObject > copySelf() override;
virtual SDL_Rect getRect() override;
virtual std::pair< std::pair< double, double >,
std::pair< double, double > >
virtual std::pair< Vec2D< double >, Vec2D< double > >
getDoubleRect() const override;
void setOutlineColor( const std::string & /*UNUSED*/ ) override {}
protected:
virtual void copyTo(std::shared_ptr<RenderObject> other) override;
void updateXY();
double og_x1;
double og_y1;
double x1_;
double y1_;
double og_x2;
double og_y2;
double x2_;
double y2_;
int pixel_x1{};
int pixel_y1{};
int pixel_x2{};
int pixel_y2{};
virtual void copyTo( std::shared_ptr< RenderObject > other ) override;
virtual void updateXY() override;
Line< double > original = { { 0, 0 }, { 0, 0 } };
Line< double > current = { { 0, 0 }, { 0, 0 } };
Line< int > pixel_line = { { 0, 0 }, { 0, 0 } };
bool centerx = false;
std::tuple< int, int, int, int > _color;
SDL_Color _color;
};
} // end of namespace SDLPP
#endif
+40
View File
@@ -0,0 +1,40 @@
#include "sdlpp_mouse.hpp"
#include "sdlpp_renderobject.hpp"
SDLPP::Vec2D< int > SDLPP::Mouse::getMousePosition() {
int x, y;
SDL_GetMouseState( &x, &y );
return { x, y };
}
SDLPP::Vec2D< double >
SDLPP::Mouse::getMousePositionDouble( const SDLPP::Renderer &r,
SDLPP::ObjectAlignment alignment_x,
SDLPP::ObjectAlignment alignment_y ) {
auto pixel_pos = getMousePosition();
auto smaller = r.getSmallerSide();
Vec2D< double > ret = { static_cast< double >( pixel_pos.getX() ) / smaller,
static_cast< double >( pixel_pos.getY() ) /
smaller };
Vec2D< double > additions =
( r.getDoubleDimensions() - Vec2D< double >( 1.0, 1.0 ) ) / 2;
switch ( alignment_x ) {
case SDLPP::OBJ_CENTER:
ret -= { additions.getX(), 0 };
break;
case SDLPP::OBJ_END:
ret -= { 2 * additions.getX(), 0 };
default:
break;
}
switch ( alignment_y ) {
case SDLPP::OBJ_CENTER:
ret -= { 0, additions.getY() };
break;
case SDLPP::OBJ_END:
ret -= { 0, 2 * additions.getY() };
default:
break;
}
return ret;
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef SDLPP_HPP_MOUSE
#define SDLPP_HPP_MOUSE
#include "sdlpp_common.hpp"
#include "sdlpp_renderer.hpp"
#include "sdlpp_renderobject.hpp"
#include "sdlpp_vector.hpp"
namespace SDLPP {
class SDLPPSCOPE Mouse {
public:
static Vec2D< int > getMousePosition();
static Vec2D< double >
getMousePositionDouble( const Renderer &r, ObjectAlignment alignment_x,
ObjectAlignment alignment_y );
};
} // end of namespace SDLPP
#endif
+84 -33
View File
@@ -1,10 +1,44 @@
#include "sdlpp_rectcolider.hpp"
namespace SDLPP {
double RectColider::width() const {
return _size.getX();
}
double RectColider::height() const {
return _size.getY();
}
int RectColider::pixel_width() const {
return _size_pixel.getX();
}
int RectColider::pixel_height() const {
return _size_pixel.getY();
}
void RectColider::setMinWidth( int width ) {
min_size = {width, min_size.getY()};
}
void RectColider::setMinHeight( int height ) {
min_size = {min_size.getX(), height};
}
RectColider::RectColider( double x, double y, double w, double h )
: CollisionPolygon( x, y ) {
w_ = w;
h_ = h;
: RectColider( { x, y }, { w, h } ) {}
RectColider::RectColider( const Vec2D< double > &top_left,
const Vec2D< double > &size )
: CollisionPolygon( top_left ), _size( size ) {}
RectColider::RectColider( double x, double y, double w, double h, uint64_t id )
: RectColider( { x, y }, { w, h }, id ) {}
RectColider::RectColider( const Vec2D< double > &top_left,
const Vec2D< double > &size, uint64_t id )
: RectColider( top_left, size ) {
_id = id;
}
bool RectColider::colidesWith( const SDLPP::CollisionPolygon &other ) const {
@@ -23,55 +57,61 @@ bool RectColider::isCircle() const {
return false;
}
int RectColider::topmost() const {
return ( !isInfinite() || original_y != -1 ) * getY() + isInfinite() * -1;
return ( !isInfinite() || original.getY() != -1 ) * getY() +
isInfinite() * -1;
}
int RectColider::bottommost() const {
return ( !isInfinite() || h_ != -1 ) * ( getY() + pixel_h ) +
return ( !isInfinite() || height() != -1 ) * ( getY() + pixel_height() ) +
isInfinite() * -1;
}
int RectColider::leftmost() const {
return ( !isInfinite() || original_x != -1 ) * getX() + isInfinite() * -1;
return ( !isInfinite() || original.getX() != -1 ) * getX() +
isInfinite() * -1;
}
int RectColider::rightmost() const {
return ( !isInfinite() || w_ != -1 ) * ( getX() + pixel_w ) +
return ( !isInfinite() || width() != -1 ) * ( getX() + pixel_width() ) +
isInfinite() * -1;
}
void RectColider::updateCollision( int x, int y, int w, int h ) {
position_x = original_x * w + x;
position_y = original_y * h + y;
pixel_w = w_ * w;
pixel_h = h_ * h;
void RectColider::updateCollision( int x, int y, int w, int h, uint64_t id ) {
position = Vec2D< int >( original.getX() * w + x, original.getY() * h + y );
_size_pixel = Vec2D< int >( width() * w, height() * h );
if ( _id == static_cast< uint64_t >( -1 ) )
_id = id;
if(_size_pixel.getX() < min_size.getX()) {
_size_pixel = {min_size.getX(), _size_pixel.getY()};
}
if(_size_pixel.getY() < min_size.getY()) {
_size_pixel = {_size_pixel.getX(), min_size.getY()};
}
}
void RectColider::render( Renderer &renderer,
const std::tuple< int, int, int, int > &color ) {
void RectColider::render( Renderer &renderer, const SDL_Color &color,
const SDL_Color &outline_color ) {
auto rect = getRect();
// outline with desired color at 50% opacity
SDL_SetRenderDrawColor( renderer.getRendererPtr(), std::get< 0 >( color ),
std::get< 1 >( color ), std::get< 2 >( color ),
0x80 );
SDL_RenderDrawRect( renderer.getRendererPtr(), &rect );
// fill with desired color at 25% opacity
SDL_SetRenderDrawColor( renderer.getRendererPtr(), std::get< 0 >( color ),
std::get< 1 >( color ), std::get< 2 >( color ),
0x40 );
SDL_SetRenderDrawColor( renderer.getRendererPtr(), color.r, color.g,
color.b, color.a );
SDL_RenderFillRect( renderer.getRendererPtr(), &rect );
SDL_SetRenderDrawColor( renderer.getRendererPtr(), outline_color.r,
outline_color.g, outline_color.b, outline_color.a );
SDL_RenderDrawRect( renderer.getRendererPtr(), &rect );
}
void RectColider::render( Renderer &renderer, const SDL_Color &color ) {
auto input_color = color;
auto outline_color = color;
input_color.a = 0x40;
outline_color.a = 0x80;
render( renderer, input_color, outline_color );
}
void RectColider::render( Renderer &renderer ) {
auto rect = getRect();
SDL_SetRenderDrawColor( renderer.getRendererPtr(), sdl_color.r, sdl_color.g,
sdl_color.b, sdl_color.a );
SDL_RenderFillRect( renderer.getRendererPtr(), &rect );
SDL_SetRenderDrawColor( renderer.getRendererPtr(), sdl_outline.r,
sdl_outline.g, sdl_outline.b, sdl_outline.a );
SDL_RenderDrawRect( renderer.getRendererPtr(), &rect );
render( renderer, sdl_color, sdl_outline );
}
SDL_Rect RectColider::getRect() {
if ( !isInfinite() )
return { leftmost(), topmost(), pixel_w, pixel_h };
return { leftmost(), topmost(), pixel_width(), pixel_height() };
SDL_Rect r = { 0, 0, 0, 0 };
if ( ( r.x = leftmost() ) == -1 )
@@ -81,11 +121,11 @@ SDL_Rect RectColider::getRect() {
if ( rightmost() == -1 )
r.w = std::numeric_limits< int >::max();
else
r.w = pixel_w;
r.w = pixel_width();
if ( bottommost() == -1 )
r.h = std::numeric_limits< int >::max();
else
r.h = pixel_h;
r.h = pixel_height();
return r;
}
@@ -93,4 +133,15 @@ std::shared_ptr< CollisionPolygon > RectColider::copySelf() {
return std::make_shared< RectColider >( *this );
}
std::vector< Line< int > > RectColider::getLines() const {
std::vector< Line< int > > ret{};
ret.emplace_back( position, position + Vec2D< int >( pixel_width(), 0 ) );
ret.emplace_back( position + Vec2D< int >( pixel_width(), 0 ),
position + _size_pixel );
ret.emplace_back( position, position + Vec2D< int >( 0, pixel_height() ) );
ret.emplace_back( position + Vec2D< int >( 0, pixel_height() ),
position + _size_pixel );
return ret;
}
} // namespace SDLPP
+24 -9
View File
@@ -3,13 +3,20 @@
#include "sdlpp_common.hpp"
#include "sdlpp_collision.hpp"
#include "sdlpp_vector.hpp"
#include "sdlpp_line.hpp"
#include <limits>
#include <vector>
namespace SDLPP {
class SDLPPSCOPE RectColider : public CollisionPolygon {
public:
RectColider( double x, double y, double w, double h );
RectColider( const Vec2D< double > &top_left, const Vec2D< double > &size );
RectColider( double x, double y, double w, double h, uint64_t id );
RectColider( const Vec2D< double > &top_left, const Vec2D< double > &size,
uint64_t id );
virtual ~RectColider() {}
virtual bool colidesWith( const CollisionPolygon &other ) const override;
virtual bool isCircle() const override;
@@ -17,20 +24,28 @@ public:
virtual int bottommost() const override;
virtual int leftmost() const override;
virtual int rightmost() const override;
virtual void updateCollision( int x, int y, int w, int h ) override;
virtual void
render( Renderer &renderer,
const std::tuple< int, int, int, int > &color ) override;
virtual void updateCollision( int x, int y, int w, int h,
uint64_t id ) override;
virtual void render( Renderer &renderer, const SDL_Color &color,
const SDL_Color &outline_color ) override;
virtual void render( Renderer &renderer, const SDL_Color &color ) override;
virtual void render( Renderer &renderer ) override;
virtual std::shared_ptr<CollisionPolygon> copySelf() override;
virtual std::shared_ptr< CollisionPolygon > copySelf() override;
virtual std::vector< Line< int > > getLines() const override;
void setMinWidth( int width );
void setMinHeight( int height );
private:
SDL_Rect getRect();
double w_;
double h_;
int pixel_w;
int pixel_h;
double width() const;
double height() const;
int pixel_width() const;
int pixel_height() const;
Vec2D< double > _size;
Vec2D< int > _size_pixel;
Vec2D< int > min_size = {0, 0};
};
} // end of namespace SDLPP
#endif
+84 -49
View File
@@ -4,33 +4,67 @@
namespace SDLPP {
RectangleRender::RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r )
: RenderObject( r ) {
og_x = x_ = x;
og_y = y_ = y;
og_w = w_ = w;
og_h = h_ = h;
updateSizeAndPosition();
}
: RectangleRender( { x, y }, { w, h }, r ) {}
RectangleRender::RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r,
const std::shared_ptr< Texture > &t,
int source_x, int source_y, int source_width,
int source_height )
: RectangleRender( x, y, w, h, r ) {
setTexture( t, source_x, source_y, source_width, source_height );
}
: RectangleRender( { x, y }, { w, h }, r, t, source_x, source_y,
source_width, source_height ) {}
RectangleRender::RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r,
const std::shared_ptr< Texture > &t,
const SDL_Rect &source_rect )
: RectangleRender( x, y, w, h, r ) {
setTexture( t, source_rect );
}
: RectangleRender( { x, y }, { w, h }, r, t, source_rect ) {}
RectangleRender::RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r,
const std::string &img_or_color,
bool is_polygon )
: RectangleRender( x, y, w, h, r ) {
: RectangleRender( { x, y }, { w, h }, r, img_or_color, is_polygon ) {}
RectangleRender::RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r,
const std::string &img, int source_x,
int source_y, int source_width,
int source_height )
: RectangleRender( { x, y }, { w, h }, r, img, source_x, source_y,
source_width, source_height ) {}
RectangleRender::RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r,
const std::string &img,
const SDL_Rect &source_rect )
: RectangleRender( { x, y }, { w, h }, r, img, source_rect ) {}
RectangleRender::RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r )
: RenderObject( r ) {
original = top_left;
original_size = size;
updateSizeAndPosition();
}
RectangleRender::RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::shared_ptr< Texture > &t,
int source_x, int source_y, int source_width,
int source_height )
: RectangleRender( top_left, size, r ) {
setTexture( t, source_x, source_y, source_width, source_height );
}
RectangleRender::RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::shared_ptr< Texture > &t,
const SDL_Rect &source_rect )
: RectangleRender( top_left, size, r ) {
setTexture( t, source_rect );
}
RectangleRender::RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::string &img_or_color,
bool is_polygon )
: RectangleRender( top_left, size, r ) {
if ( !is_polygon ) {
setTexture( img_or_color );
} else {
@@ -38,26 +72,29 @@ RectangleRender::RectangleRender( double x, double y, double w, double h,
color = img_or_color;
}
}
RectangleRender::RectangleRender( double x, double y, double w, double h,
RectangleRender::RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::string &img, int source_x,
int source_y, int source_width,
int source_height )
: RectangleRender( x, y, w, h, r ) {
: RectangleRender( top_left, size, r ) {
setTexture( img, source_x, source_y, source_width, source_height );
}
RectangleRender::RectangleRender( double x, double y, double w, double h,
RectangleRender::RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::string &img,
const SDL_Rect &source_rect )
: RectangleRender( x, y, w, h, r ) {
: RectangleRender( top_left, size, r ) {
setTexture( img, source_rect );
}
void RectangleRender::setColor( const std::string &color ) {
if ( !polygon ) {
polygon = std::make_shared< RectColider >( 0, 0, 1, 1 );
polygon->updateCollision( collisionPushX(), collisionPushY(),
collisionWidth(), collisionHeight() );
collisionWidth(), collisionHeight(),
getId() );
}
polygon->setColor( color );
}
@@ -65,13 +102,14 @@ void RectangleRender::setOutlineColor( const std::string &color ) {
if ( !polygon ) {
polygon = std::make_shared< RectColider >( 0, 0, 1, 1 );
polygon->updateCollision( collisionPushX(), collisionPushY(),
collisionWidth(), collisionHeight() );
collisionWidth(), collisionHeight(),
getId() );
}
polygon->setOutlineColor( color );
}
std::pair< std::pair< double, double >, std::pair< double, double > >
std::pair< Vec2D< double >, Vec2D< double > >
RectangleRender::getDoubleRect() const {
return { { og_x, og_y }, { og_w, og_h } };
return { original, original_size };
}
int RectangleRender::leftmost() {
return rect.x;
@@ -100,25 +138,30 @@ int RectangleRender::collisionHeight() {
void RectangleRender::updateSizeAndPosition() {
updateXY();
auto dimension = renderer->getSmallerSide();
rect.x = std::round( x_ * dimension );
rect.y = std::round( y_ * dimension );
rect.w = std::round( ( x_ + w_ ) * dimension ) - rect.x;
rect.h = std::round( ( y_ + h_ ) * dimension ) - rect.y;
rect.x = std::round( current.getX() * dimension );
rect.y = std::round( current.getY() * dimension );
rect.w =
std::round( ( current.getX() + original_size.getX() ) * dimension ) -
rect.x;
rect.h =
std::round( ( current.getY() + original_size.getY() ) * dimension ) -
rect.y;
if(static_cast<uint64_t>(rect.w) < min_size.getX())
rect.w = min_size.getX();
if(static_cast<uint64_t>(rect.h) < min_size.getY())
rect.h = min_size.getY();
if ( polygon )
polygon->updateCollision( collisionPushX(), collisionPushY(),
collisionWidth(), collisionHeight() );
collisionWidth(), collisionHeight(),
getId() );
for ( auto &x : collisions ) {
x->updateCollision( collisionPushX(), collisionPushY(),
collisionWidth(), collisionHeight() );
collisionWidth(), collisionHeight(), getId() );
}
}
SDL_Rect RectangleRender::getRect() {
return rect;
}
void RectangleRender::centerX() {
centerx = true;
updateSizeAndPosition();
}
std::shared_ptr< RenderObject > RectangleRender::copySelf() {
auto ret = std::make_shared< RectangleRender >( *this );
copyTo( ret );
@@ -130,22 +173,14 @@ void RectangleRender::copyTo( std::shared_ptr< RenderObject > other ) {
std::string RectangleRender::getColor() const {
return color;
}
void RectangleRender::updateXY() {
if ( !centerx ) {
x_ = og_x;
y_ = og_y;
return;
}
auto width = renderer->getWidth();
auto height = renderer->getHeight();
if ( width > height ) {
auto multiplier =
static_cast< double >( width ) / static_cast< double >( height );
x_ = og_x + static_cast< double >( multiplier - 1 ) / 2;
} else {
x_ = og_x;
}
y_ = og_y;
void RectangleRender::setMinWidth( uint64_t width ) {
min_size = {width, min_size.getY()};
}
void RectangleRender::setMinHeight( uint64_t height ) {
min_size = {min_size.getX(), height};
}
void RectangleRender::setSize( Vec2D< double > size ) {
original_size = size;
updateSizeAndPosition();
}
} // namespace SDLPP
+37 -9
View File
@@ -31,12 +31,40 @@ public:
RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r,
const std::string &img, const SDL_Rect &source_rect );
RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r );
RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::shared_ptr< Texture > &t, int source_x,
int source_y, int source_width, int source_height );
RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::shared_ptr< Texture > &t,
const SDL_Rect &source_rect = { -1, -1, -1, -1 } );
RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::string &img_or_color, bool is_polygon = false );
RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::string &img, int source_x, int source_y,
int source_width, int source_height );
RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::string &img, const SDL_Rect &source_rect );
virtual void setColor( const std::string &color ) override;
virtual void setOutlineColor( const std::string &color ) override;
virtual void specialAction( int /*UNUSED*/ ) override {}
virtual void custom_move( int /*UNUSED*/ ) override {}
virtual std::pair< std::pair< double, double >,
std::pair< double, double > >
virtual void custom_move( int ticks ) override {
RenderObject::custom_move(ticks);
}
virtual std::pair< Vec2D< double >, Vec2D< double > >
getDoubleRect() const override;
virtual int leftmost() override;
virtual int topmost() override;
@@ -48,18 +76,18 @@ public:
virtual int collisionHeight() override;
virtual void updateSizeAndPosition() override;
virtual SDL_Rect getRect() override;
virtual void centerX() override;
virtual std::shared_ptr< RenderObject > copySelf() override;
std::string getColor() const;
void setMinWidth( uint64_t width );
void setMinHeight( uint64_t height );
void setSize( Vec2D< double > size );
protected:
virtual void copyTo( std::shared_ptr< RenderObject > other ) override;
void updateXY();
double og_w;
double og_h;
double w_;
double h_;
Vec2D< double > original_size;
Vec2D< double > size;
std::string color = "";
Vec2D< uint64_t > min_size = {0, 0};
};
} // end of namespace SDLPP
#endif
+20 -7
View File
@@ -17,26 +17,39 @@ Renderer::~Renderer() {
SDL_Renderer *Renderer::getRendererPtr() {
return renderer;
}
std::pair< int, int > Renderer::getDimensions() const {
Vec2D< int > Renderer::getDimensions() const {
int width = 0, height = 0;
SDL_GetRendererOutputSize( renderer, &width, &height );
return { width, height };
}
Vec2D< double > Renderer::getDoubleDimensions() const {
auto dimensions = getDimensions();
if ( dimensions == dimensions_cache )
return double_dimensions_cache;
dimensions_cache = dimensions;
double smaller = dimensions.getX() < dimensions.getY() ? dimensions.getX()
: dimensions.getY();
double_dimensions_cache = {
static_cast< double >( dimensions.getX() ) / smaller,
static_cast< double >( dimensions.getY() ) / smaller
};
return double_dimensions_cache;
}
int Renderer::getWidth() const {
return getDimensions().first;
return getDimensions().getX();
}
int Renderer::getHeight() const {
return getDimensions().second;
return getDimensions().getY();
}
int Renderer::getSmallerSide() const {
auto dimensions = getDimensions();
return dimensions.first < dimensions.second ? dimensions.first
: dimensions.second;
return dimensions.getX() < dimensions.getY() ? dimensions.getX()
: dimensions.getY();
}
int Renderer::getLargerSide() const {
auto dimensions = getDimensions();
return dimensions.first > dimensions.second ? dimensions.first
: dimensions.second;
return dimensions.getX() > dimensions.getY() ? dimensions.getX()
: dimensions.getY();
}
void Renderer::setBlendMode( SDL_BlendMode blendMode ) {
SDL_SetRenderDrawBlendMode( renderer, blendMode );
+5 -1
View File
@@ -3,6 +3,7 @@
#include "sdlpp_common.hpp"
#include "sdlpp_window.hpp"
#include "sdlpp_vector.hpp"
#include <iostream>
@@ -13,7 +14,7 @@ public:
Renderer( Window &window );
virtual ~Renderer();
SDL_Renderer *getRendererPtr();
std::pair< int, int > getDimensions() const;
Vec2D< int > getDimensions() const;
int getWidth() const;
int getHeight() const;
int getSmallerSide() const;
@@ -23,10 +24,13 @@ public:
bool getRenderColiders();
void clearRenderer();
void presentRenderer();
Vec2D< double > getDoubleDimensions() const;
private:
SDL_Renderer *renderer = NULL;
bool render_coliders = false;
mutable Vec2D< int > dimensions_cache = { 0, 0 };
mutable Vec2D< double > double_dimensions_cache = { 0.0, 0.0 };
};
} // end of namespace SDLPP
#endif
+137 -33
View File
@@ -2,6 +2,7 @@
#include <cmath>
namespace SDLPP {
/* wheter to use entire texture rather than just a part of it */
bool RenderObject::entireTexture() {
return src_rect.x == -1 || src_rect.y == -1 || src_rect.w == -1 ||
src_rect.h == -1;
@@ -12,14 +13,19 @@ void RenderObject::render() {
polygon->render( *renderer );
if ( texture != NULL ) {
SDL_Rect *src = NULL;
if ( animation.empty() ) {
if ( animation.empty() || !animating ) {
if ( !entireTexture() )
src = &src_rect;
} else {
src = &animation[animation_index];
}
SDL_RenderCopy( renderer->getRendererPtr(),
texture->getTexturePtr(), src, &rect );
SDL_Point *rotation_point = NULL;
if ( rotation_center.getX() != -1 ) {
rotation_point = &rotation_center_point;
}
SDL_RenderCopyEx( renderer->getRendererPtr(),
texture->getTexturePtr(), src, &rect,
rotation_angle, rotation_point, flip );
}
if ( hasCollisions() && renderer->getRenderColiders() ) {
for ( const auto &col : getCollisions() )
@@ -28,28 +34,40 @@ void RenderObject::render() {
}
}
void RenderObject::setPos( double x, double y ) {
og_x = x;
og_y = y;
updateSizeAndPosition();
setPos( Vec2D< double >( x, y ) );
}
void RenderObject::setPos( const std::pair< double, double > &pos ) {
setPos( pos.first, pos.second );
setPos( Vec2D< double >( pos.first, pos.second ) );
}
std::pair< double, double > RenderObject::getPos() const {
return { og_x, og_y };
void RenderObject::setPos( const Vec2D< double > &vec ) {
original = vec;
// updateSizeAndPosition();
}
bool RenderObject::colidesWith( const RenderObject &other ) const {
Vec2D< double > RenderObject::getPos() const {
return original;
}
Vec2D< double > RenderObject::getAbsolutePos() const {
return current;
}
std::vector< uint64_t >
RenderObject::colidesWith( const RenderObject &other ) const {
if ( !hasCollisions() || !other.hasCollisions() || getHidden() ||
other.getHidden() ) {
return false;
return {};
}
std::vector< uint64_t > ret = {};
for ( const auto &x : collisions ) {
for ( const auto &y : other.getCollisions() ) {
if ( x->colidesWith( *y ) )
return true;
if ( x->colidesWith( *y ) ) {
ret.push_back( x->getId() );
break;
}
}
}
return false;
return ret;
}
void RenderObject::removeCollisions() {
collisions.clear();
}
bool RenderObject::hasCollisions() const {
return !collisions.empty();
@@ -63,6 +81,9 @@ void RenderObject::setTexture( const std::shared_ptr< Texture > &t,
texture = t;
src_rect = source_rect;
}
void RenderObject::setTextureKeepSRC( const std::shared_ptr< Texture > &t ) {
setTexture(t, src_rect);
}
void RenderObject::setTexture( const std::shared_ptr< Texture > &t,
int source_x, int source_y, int source_width,
int source_height ) {
@@ -96,15 +117,20 @@ void RenderObject::unsetColor() {
void RenderObject::setMovementSpeed( double speed ) {
movementSpeed = speed;
}
void RenderObject::addMovement( int x, int y ) {
movementDirection.first += x;
movementDirection.second += y;
void RenderObject::addMovement( double x, double y ) {
movementDirection += { x, y };
}
void RenderObject::setMovement( double x, double y ) {
movementDirection = { x, y };
}
Vec2D< double > RenderObject::getMovement() const {
return movementDirection;
}
void RenderObject::resetMovementX() {
movementDirection.first = 0;
movementDirection = { 0, movementDirection.getY() };
}
void RenderObject::resetMovementY() {
movementDirection.second = 0;
movementDirection = { movementDirection.getX(), 0 };
}
void RenderObject::clearColided() {
colidedWith.clear();
@@ -118,7 +144,7 @@ std::vector< std::shared_ptr< RenderObject > > &RenderObject::getColidedWith() {
void RenderObject::setId( uint64_t input_id ) {
id = input_id;
}
uint64_t RenderObject::getId() {
uint64_t RenderObject::getId() const {
return id;
}
void RenderObject::setHidden( bool hid ) {
@@ -128,14 +154,14 @@ bool RenderObject::getHidden() const {
return hidden;
}
void RenderObject::destroy() {
setHidden( true );
// setHidden( true );
kill = true;
}
bool RenderObject::getKilled() {
return kill;
}
void RenderObject::setColiderColor( const std::string &color ) {
colider_color = getColorsHEX( color );
colider_color = getSDLColorHEX( color );
}
void RenderObject::animate( int ticks ) {
@@ -144,7 +170,7 @@ void RenderObject::animate( int ticks ) {
if ( animation_next_frame <= 0 ) {
animation_index = ( animation_index + 1 ) % animation.size();
animation_next_frame =
( 1000 / animation_fps ) + animation_next_frame;
animation_next_frame_base + animation_next_frame;
}
}
}
@@ -152,17 +178,12 @@ void RenderObject::animate( int ticks ) {
void RenderObject::move( int ticks ) {
if ( permanent )
return;
auto addx =
static_cast< double >( movementSpeed * movementDirection.first ) *
( static_cast< double >( ticks ) / 1000 );
auto addy =
static_cast< double >( movementSpeed * movementDirection.second ) *
( static_cast< double >( ticks ) / 1000 );
auto addx = movementSpeed * movementDirection.getX() * ticks / 1000.0;
auto addy = movementSpeed * movementDirection.getY() * ticks / 1000.0;
if ( std::isnan( addx ) || std::isnan( addy ) )
return;
og_x += addx;
og_y += addy;
original += { addx, addy };
custom_move( ticks );
@@ -211,6 +232,9 @@ void RenderObject::setTextureSourceRect( const SDL_Rect &source_rect ) {
void RenderObject::setTextureSourceRect( int x, int y, int w, int h ) {
setTextureSourceRect( { x, y, w, h } );
}
SDL_Rect RenderObject::getTextureSourceRect() const {
return src_rect;
}
void RenderObject::setAnimationFrames( const std::vector< SDL_Rect > &frames ) {
animation = frames;
}
@@ -230,8 +254,88 @@ void RenderObject::resumeAnimation() {
void RenderObject::removeAnimation() {
animation.clear();
}
void RenderObject::setAnimationSpeed( const int fps ) {
void RenderObject::setAnimationSpeed( const double fps ) {
animation_fps = fps;
animation_next_frame = 1000 / fps;
animation_next_frame = animation_next_frame_base = 1000 / fps;
}
void RenderObject::visit( Visitor &visitor ) {
visitor.visit( *this );
}
void RenderObject::setAlignment( ObjectAlignment horizontal,
ObjectAlignment vertical ) {
_horizontal = horizontal;
_vertical = vertical;
}
void RenderObject::flipHorizontally() {
if ( flip & SDL_FLIP_HORIZONTAL ) {
flip = static_cast< SDL_RendererFlip >( flip & ~SDL_FLIP_HORIZONTAL );
} else {
flip = static_cast< SDL_RendererFlip >( flip | SDL_FLIP_HORIZONTAL );
}
}
void RenderObject::flipVertically() {
if ( flip & SDL_FLIP_VERTICAL ) {
flip = static_cast< SDL_RendererFlip >( flip & ~SDL_FLIP_VERTICAL );
} else {
flip = static_cast< SDL_RendererFlip >( flip | SDL_FLIP_VERTICAL );
}
}
void RenderObject::setRotationCenter( const Vec2D< double > &center ) {
rotation_center = center;
rotation_center_point = { static_cast< int >( center.getX() * rect.w ),
static_cast< int >( center.getY() * rect.h ) };
}
void RenderObject::rotateClockwise( int angle ) {
rotation_angle = ( rotation_angle + angle ) % 360;
}
void RenderObject::rotateCounterClockwise( int angle ) {
rotateClockwise( 360 - ( angle % 360 ) );
}
void RenderObject::setRotationSpeed(int speed) {
rotation_speed = speed;
}
void RenderObject::startRotation() {
rotating = true;
}
void RenderObject::stopRotation() {
rotating = false;
}
Vec2D< double > RenderObject::computeAlignmentAdditions() {
double x_addition = 0;
double y_addition = 0;
auto dimensions = renderer->getDoubleDimensions();
auto width_diff = dimensions.getX() - 1;
auto height_diff = dimensions.getY() - 1;
switch ( _horizontal ) {
case OBJ_CENTER:
x_addition = width_diff / 2;
break;
case OBJ_END:
x_addition = width_diff;
default:
break;
}
switch ( _vertical ) {
case OBJ_CENTER:
y_addition = height_diff / 2;
break;
case OBJ_END:
y_addition = height_diff;
default:
break;
}
return { x_addition, y_addition };
}
void RenderObject::updateXY() {
auto additions = computeAlignmentAdditions();
current = { original.getX() + additions.getX(),
original.getY() + additions.getY() };
}
void RenderObject::custom_move(int ticks) {
if(isRotating()) {
auto angle = ticks * rotation_speed / 1000; // tick = millisecond
rotateCounterClockwise(angle);
}
}
} // namespace SDLPP

Some files were not shown because too many files have changed in this diff Show More