Compare commits
219 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9617499ab8 | |||
| 5a0cb397b1 | |||
| 2e8132b458 | |||
| d41c77ab96 | |||
| b175e58714 | |||
| f0182cf4d4 | |||
| fd96a1c2cc | |||
| c453c2fe9a | |||
| 411f00e468 | |||
| 9402f2afa2 | |||
| 6ac2726a94 | |||
| c5283000c7 | |||
| 41ba43ed93 | |||
| 92a30b8c51 | |||
| 7bd652f4e9 | |||
| 3cde73d1ed | |||
| d89712ebab | |||
| 1462c2211b | |||
| 938958b709 | |||
| e5641f3bfd | |||
| e6df794618 | |||
| f137f6609f | |||
| 59e09f77fd | |||
| 4109cfe1af | |||
| 09cb13195c | |||
| 9e4cc97f79 | |||
| aa5043a811 | |||
| f9a32bdb72 | |||
| 45ab92c31f | |||
| 31f00ed5d0 | |||
| 3437aa6b47 | |||
| 6211e8c756 | |||
| a1afaf427a | |||
| 8b9ef16929 | |||
| 5201d10e20 | |||
| 65edc9e8a0 | |||
| 4477c39524 | |||
| 6cee97059c | |||
| 70f30b6767 | |||
| c505915fd2 | |||
| fffa56706d | |||
| ab6dcccbac | |||
| 98c5b5b0dc | |||
| fa60a0f163 | |||
| 2a2467ccc2 | |||
| 58fd1a37a8 | |||
| 6558329547 | |||
| 3a80fab3dd | |||
| 4414ee6ff7 | |||
| 4143af9962 | |||
| 92ffac0edf | |||
| c59851b490 | |||
| 38dfa533c4 | |||
| 194415500d | |||
| 94d24e37fa | |||
| 2402567330 | |||
| a3a1e900b5 | |||
| b98d283d09 | |||
| c8e749a145 | |||
| e87495db2e | |||
| edb8444d7d | |||
| 2dff727934 | |||
| 0d855ed218 | |||
| 303490a619 | |||
| f4a067fe23 | |||
| 8ca70fa11e | |||
| f3062464d2 | |||
| d60dc07e10 | |||
| f6cf68f71f | |||
| 7e06da5fc0 | |||
| ca39b7edc9 | |||
| 3bf086f48a | |||
| 28d7e208fc | |||
| edeeadb232 | |||
| e31c4bb2db | |||
| 94bf4fc39d | |||
| 45ac4dad64 | |||
| a01b6070f3 | |||
| c183e58f6e | |||
| c7309d56a3 | |||
| f3c4380bfb | |||
| 4f65dba2e0 | |||
| f7002f0f38 | |||
| a194bfb86e | |||
| e283b36229 | |||
| 0608202483 | |||
| f35aa095f3 | |||
| f04dc1e23b | |||
| 7b2adac922 | |||
| a7aa86c8e3 | |||
| 4742f3dd02 | |||
| 7cb3f95e44 | |||
| 6238022ed2 | |||
| 7b1ef25f37 | |||
| d4393ef179 | |||
| 4728056b76 | |||
| b87318f44d | |||
| 7d9763443a | |||
| d267402ec5 | |||
| 8e566ddb03 | |||
| 509e5e36c2 | |||
| fe157494ec | |||
| 040b3b63c2 | |||
| bfe658618e | |||
| 37f7bab63e | |||
| e67cf508a2 | |||
| 130a01feda | |||
| d638108223 | |||
| 3be728843a | |||
| 79d9f266b4 | |||
| 0e71dfa7d5 | |||
| 76f5c43197 | |||
| 2617156833 | |||
| b423ac7b8c | |||
| a54d079fd2 | |||
| 76f55fd98c | |||
| 301c4f3142 | |||
| 0475f4967b | |||
| 243c1d9d04 | |||
| af3954cb61 | |||
| 0b3689b0ae | |||
| 78c9b9feb0 | |||
| 57a573783d | |||
| 2b405c5d31 | |||
| 26cbdd0f8e | |||
| 808f392119 | |||
| 5d20757d43 | |||
| cd0a301e52 | |||
| af94cc0e03 | |||
| 3bef592cb1 | |||
| 58974f8a7e | |||
| 3cb36fe180 | |||
| 5b8c0f88bb | |||
| a55a9142af | |||
| be638591c8 | |||
| 9d9068091b | |||
| af3588501a | |||
| db338fd544 | |||
| 757a03568d | |||
| b8c56c06fd | |||
| 6e61eb03b9 | |||
| 734b0b58cb | |||
| d2bc497070 | |||
| 19c29b261c | |||
| 49bceafe0b | |||
| 55f88a547c | |||
| c2fb78b0a6 | |||
| 6fe283bb34 | |||
| 0c4f2482c7 | |||
| 79d5f348c4 | |||
| bd8a841e6f | |||
| 670d5b7c1b | |||
| cc6f3f838b | |||
| 91df7c3f63 | |||
| df61983f55 | |||
| f0df1cc3b2 | |||
| 7ed8b0f4e1 | |||
| 7390f684f5 | |||
| b75b44201a | |||
| bea479bf72 | |||
| 8672830db8 | |||
| 088fb4d15a | |||
| 930875ccf8 | |||
| d9a88f2de2 | |||
| 0358aa36c7 | |||
| d04cbea02d | |||
| d80ae9a4e2 | |||
| ede8bbbe8b | |||
| 83cda5f860 | |||
| b54ba5034c | |||
| 7b4c3c9697 | |||
| c849895c72 | |||
| 85807ca962 | |||
| 900382bfce | |||
| e084ed6f86 | |||
| f89d36c177 | |||
| c383654349 | |||
| 7b0f72e273 | |||
| ad7f737e16 | |||
| 8b8f3b7f06 | |||
| 96857a99af | |||
| 34324d3054 | |||
| e84284e613 | |||
| 61e45e89a5 | |||
| 183bd53b66 | |||
| d4991ea3a7 | |||
| 1927b71629 | |||
| 5562ca4d82 | |||
| 4e81ac6562 | |||
| 4f20274f11 | |||
| 90dc26251b | |||
| b52dee267b | |||
| ff741dd882 | |||
| b611e2479a | |||
| e8e9e12b58 | |||
| 7c38e122d0 | |||
| e5d0610f6d | |||
| fc1d06a2b8 | |||
| 0f1e44615c | |||
| 5d03da3131 | |||
| b0b84101a2 | |||
| dd6f37264c | |||
| 19e66bf34a | |||
| 7206dbf7c3 | |||
| 5b96de0d9d | |||
| 1f5e3a999c | |||
| 87970bfc4b | |||
| ee82430f82 | |||
| 6cfe2046d4 | |||
| 4cd351c7a3 | |||
| 8540573455 | |||
| 6ecdb6d90d | |||
| aaae85a932 | |||
| 8b3eee0673 | |||
| 406186d8bb | |||
| 594316dcea | |||
| 2f20661b5b | |||
| d2cf54556e | |||
| 258ce51cfe |
+4
-4
@@ -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
@@ -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 ]
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
sprites
|
||||
*txt
|
||||
mario
|
||||
editor
|
||||
.DS_Store
|
||||
*bin
|
||||
build
|
||||
.vscode
|
||||
@@ -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})
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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} };
|
||||
@@ -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.
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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 > ¢er, 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 > ¢er, 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,6 +10,9 @@ namespace SDLPP {
|
||||
class SDLPPSCOPE CircleColider : public CollisionPolygon {
|
||||
public:
|
||||
CircleColider( double x, double y, double rad );
|
||||
CircleColider( const Vec2D< double > ¢er, double rad );
|
||||
CircleColider( double x, double y, double rad, uint64_t id );
|
||||
CircleColider( const Vec2D< double > ¢er, 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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifndef SDLPP_HPP_GEOMETRY
|
||||
#define SDLPP_HPP_GEOMETRY
|
||||
|
||||
#include "sdlpp_geometry_vector.hpp"
|
||||
#include "sdlpp_geometry_line.hpp"
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
@@ -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 > ¢er ) {
|
||||
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
Reference in New Issue
Block a user