Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
216 KB
Referenced Files
None
Subscribers
None
This document is not UTF8. It was detected as JIS and converted to UTF8 for display.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..70e45d6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+*.cbp
+*.depend
+*.layout
+*.exe
+*.dll
+*.o
+*.db
\ No newline at end of file
diff --git a/cmake_modules/FindSFML.cmake b/cmake_modules/FindSFML.cmake
new file mode 100644
index 0000000..31c1c70
--- /dev/null
+++ b/cmake_modules/FindSFML.cmake
@@ -0,0 +1,317 @@
+# This script locates the SFML library
+# ------------------------------------
+#
+# Usage
+# -----
+#
+# When you try to locate the SFML libraries, you must specify which modules you want to use (system, window, graphics, network, audio, main).
+# If none is given, the SFML_LIBRARIES variable will be empty and you'll end up linking to nothing.
+# example:
+# find_package(SFML COMPONENTS graphics window system) // find the graphics, window and system modules
+#
+# You can enforce a specific version, either MAJOR.MINOR or only MAJOR.
+# If nothing is specified, the version won't be checked (ie. any version will be accepted).
+# example:
+# find_package(SFML COMPONENTS ...) // no specific version required
+# find_package(SFML 2 COMPONENTS ...) // any 2.x version
+# find_package(SFML 2.4 COMPONENTS ...) // version 2.4 or greater
+#
+# By default, the dynamic libraries of SFML will be found. To find the static ones instead,
+# you must set the SFML_STATIC_LIBRARIES variable to TRUE before calling find_package(SFML ...).
+# Since you have to link yourself all the SFML dependencies when you link it statically, the following
+# additional variables are defined: SFML_XXX_DEPENDENCIES and SFML_DEPENDENCIES (see their detailed
+# description below).
+# In case of static linking, the SFML_STATIC macro will also be defined by this script.
+# example:
+# set(SFML_STATIC_LIBRARIES TRUE)
+# find_package(SFML 2 COMPONENTS network system)
+#
+# On Mac OS X if SFML_STATIC_LIBRARIES is not set to TRUE then by default CMake will search for frameworks unless
+# CMAKE_FIND_FRAMEWORK is set to "NEVER" for example. Please refer to CMake documentation for more details.
+# Moreover, keep in mind that SFML frameworks are only available as release libraries unlike dylibs which
+# are available for both release and debug modes.
+#
+# If SFML is not installed in a standard path, you can use the SFML_ROOT CMake (or environment) variable
+# to tell CMake where SFML is.
+#
+# Output
+# ------
+#
+# This script defines the following variables:
+# - For each specified module XXX (system, window, graphics, network, audio, main):
+# - SFML_XXX_LIBRARY_DEBUG: the name of the debug library of the xxx module (set to SFML_XXX_LIBRARY_RELEASE is no debug version is found)
+# - SFML_XXX_LIBRARY_RELEASE: the name of the release library of the xxx module (set to SFML_XXX_LIBRARY_DEBUG is no release version is found)
+# - SFML_XXX_LIBRARY: the name of the library to link to for the xxx module (includes both debug and optimized names if necessary)
+# - SFML_XXX_FOUND: true if either the debug or release library of the xxx module is found
+# - SFML_XXX_DEPENDENCIES: the list of libraries the module depends on, in case of static linking
+# - SFML_LIBRARIES: the list of all libraries corresponding to the required modules
+# - SFML_FOUND: true if all the required modules are found
+# - SFML_INCLUDE_DIR: the path where SFML headers are located (the directory containing the SFML/Config.hpp file)
+# - SFML_DEPENDENCIES: the list of libraries SFML depends on, in case of static linking
+#
+# example:
+# find_package(SFML 2 COMPONENTS system window graphics audio REQUIRED)
+# include_directories(${SFML_INCLUDE_DIR})
+# add_executable(myapp ...)
+# target_link_libraries(myapp ${SFML_LIBRARIES})
+
+# define the SFML_STATIC macro if static build was chosen
+if(SFML_STATIC_LIBRARIES)
+ add_definitions(-DSFML_STATIC)
+endif()
+
+# deduce the libraries suffix from the options
+set(FIND_SFML_LIB_SUFFIX "")
+if(SFML_STATIC_LIBRARIES)
+ set(FIND_SFML_LIB_SUFFIX "${FIND_SFML_LIB_SUFFIX}-s")
+endif()
+
+# define the list of search paths for headers and libraries
+set(FIND_SFML_PATHS
+ ${SFML_ROOT}
+ $ENV{SFML_ROOT}
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /usr/local
+ /usr
+ /sw
+ /opt/local
+ /opt/csw
+ /opt)
+
+# find the SFML include directory
+find_path(SFML_INCLUDE_DIR SFML/Config.hpp
+ PATH_SUFFIXES include
+ PATHS ${FIND_SFML_PATHS})
+
+# check the version number
+set(SFML_VERSION_OK TRUE)
+if(SFML_FIND_VERSION AND SFML_INCLUDE_DIR)
+ # extract the major and minor version numbers from SFML/Config.hpp
+ # we have to handle framework a little bit differently :
+ if("${SFML_INCLUDE_DIR}" MATCHES "SFML.framework")
+ set(SFML_CONFIG_HPP_INPUT "${SFML_INCLUDE_DIR}/Headers/Config.hpp")
+ else()
+ set(SFML_CONFIG_HPP_INPUT "${SFML_INCLUDE_DIR}/SFML/Config.hpp")
+ endif()
+ FILE(READ "${SFML_CONFIG_HPP_INPUT}" SFML_CONFIG_HPP_CONTENTS)
+ STRING(REGEX MATCH ".*#define SFML_VERSION_MAJOR ([0-9]+).*#define SFML_VERSION_MINOR ([0-9]+).*" SFML_CONFIG_HPP_CONTENTS "${SFML_CONFIG_HPP_CONTENTS}")
+ STRING(REGEX REPLACE ".*#define SFML_VERSION_MAJOR ([0-9]+).*" "\\1" SFML_VERSION_MAJOR "${SFML_CONFIG_HPP_CONTENTS}")
+ STRING(REGEX REPLACE ".*#define SFML_VERSION_MINOR ([0-9]+).*" "\\1" SFML_VERSION_MINOR "${SFML_CONFIG_HPP_CONTENTS}")
+ math(EXPR SFML_REQUESTED_VERSION "${SFML_FIND_VERSION_MAJOR} * 10 + ${SFML_FIND_VERSION_MINOR}")
+
+ # if we could extract them, compare with the requested version number
+ if (SFML_VERSION_MAJOR)
+ # transform version numbers to an integer
+ math(EXPR SFML_VERSION "${SFML_VERSION_MAJOR} * 10 + ${SFML_VERSION_MINOR}")
+
+ # compare them
+ if(SFML_VERSION LESS SFML_REQUESTED_VERSION)
+ set(SFML_VERSION_OK FALSE)
+ endif()
+ else()
+ # SFML version is < 2.0
+ if (SFML_REQUESTED_VERSION GREATER 19)
+ set(SFML_VERSION_OK FALSE)
+ set(SFML_VERSION_MAJOR 1)
+ set(SFML_VERSION_MINOR x)
+ endif()
+ endif()
+endif()
+
+# find the requested modules
+set(SFML_FOUND TRUE) # will be set to false if one of the required modules is not found
+foreach(FIND_SFML_COMPONENT ${SFML_FIND_COMPONENTS})
+ string(TOLOWER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_LOWER)
+ string(TOUPPER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_UPPER)
+ set(FIND_SFML_COMPONENT_NAME sfml-${FIND_SFML_COMPONENT_LOWER}${FIND_SFML_LIB_SUFFIX})
+
+ # no suffix for sfml-main, it is always a static library
+ if(FIND_SFML_COMPONENT_LOWER STREQUAL "main")
+ set(FIND_SFML_COMPONENT_NAME sfml-${FIND_SFML_COMPONENT_LOWER})
+ endif()
+
+ # debug library
+ find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG
+ NAMES ${FIND_SFML_COMPONENT_NAME}-d
+ PATH_SUFFIXES lib64 lib
+ PATHS ${FIND_SFML_PATHS})
+
+ # release library
+ find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE
+ NAMES ${FIND_SFML_COMPONENT_NAME}
+ PATH_SUFFIXES lib64 lib
+ PATHS ${FIND_SFML_PATHS})
+
+ if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG OR SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE)
+ # library found
+ set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND TRUE)
+
+ # if both are found, set SFML_XXX_LIBRARY to contain both
+ if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE)
+ set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY debug ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG}
+ optimized ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE})
+ endif()
+
+ # if only one debug/release variant is found, set the other to be equal to the found one
+ if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE)
+ # debug and not release
+ set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG})
+ set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG})
+ endif()
+ if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG)
+ # release and not debug
+ set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE})
+ set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE})
+ endif()
+ else()
+ # library not found
+ set(SFML_FOUND FALSE)
+ set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND FALSE)
+ set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY "")
+ set(FIND_SFML_MISSING "${FIND_SFML_MISSING} SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY")
+ endif()
+
+ # mark as advanced
+ MARK_AS_ADVANCED(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY
+ SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE
+ SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG)
+
+ # add to the global list of libraries
+ set(SFML_LIBRARIES ${SFML_LIBRARIES} "${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY}")
+endforeach()
+
+# in case of static linking, we must also define the list of all the dependencies of SFML libraries
+if(SFML_STATIC_LIBRARIES)
+
+ # detect the OS
+ if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+ set(FIND_SFML_OS_WINDOWS 1)
+ elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ set(FIND_SFML_OS_LINUX 1)
+ elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
+ set(FIND_SFML_OS_FREEBSD 1)
+ elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+ set(FIND_SFML_OS_MACOSX 1)
+ endif()
+
+ # start with an empty list
+ set(SFML_DEPENDENCIES)
+ set(FIND_SFML_DEPENDENCIES_NOTFOUND)
+
+ # macro that searches for a 3rd-party library
+ macro(find_sfml_dependency output friendlyname)
+ find_library(${output} NAMES ${ARGN} PATHS ${FIND_SFML_PATHS} PATH_SUFFIXES lib)
+ if(${${output}} STREQUAL "${output}-NOTFOUND")
+ unset(output)
+ set(FIND_SFML_DEPENDENCIES_NOTFOUND "${FIND_SFML_DEPENDENCIES_NOTFOUND} ${friendlyname}")
+ endif()
+ endmacro()
+
+ # sfml-system
+ list(FIND SFML_FIND_COMPONENTS "system" FIND_SFML_SYSTEM_COMPONENT)
+ if(NOT ${FIND_SFML_SYSTEM_COMPONENT} EQUAL -1)
+
+ # update the list -- these are only system libraries, no need to find them
+ if(FIND_SFML_OS_LINUX OR FIND_SFML_OS_FREEBSD OR FIND_SFML_OS_MACOSX)
+ set(SFML_SYSTEM_DEPENDENCIES "pthread")
+ endif()
+ if(FIND_SFML_OS_LINUX)
+ set(SFML_SYSTEM_DEPENDENCIES "rt")
+ endif()
+ if(FIND_SFML_OS_WINDOWS)
+ set(SFML_SYSTEM_DEPENDENCIES "winmm")
+ endif()
+ set(SFML_DEPENDENCIES ${SFML_DEPENDENCIES} ${SFML_SYSTEM_DEPENDENCIES})
+ endif()
+
+ # sfml-network
+ list(FIND SFML_FIND_COMPONENTS "network" FIND_SFML_NETWORK_COMPONENT)
+ if(NOT ${FIND_SFML_NETWORK_COMPONENT} EQUAL -1)
+
+ # update the list -- these are only system libraries, no need to find them
+ if(FIND_SFML_OS_WINDOWS)
+ set(SFML_NETWORK_DEPENDENCIES "ws2_32")
+ endif()
+ set(SFML_DEPENDENCIES ${SFML_DEPENDENCIES} ${SFML_NETWORK_DEPENDENCIES})
+ endif()
+
+ # sfml-window
+ list(FIND SFML_FIND_COMPONENTS "window" FIND_SFML_WINDOW_COMPONENT)
+ if(NOT ${FIND_SFML_WINDOW_COMPONENT} EQUAL -1)
+
+ # find libraries
+ if(FIND_SFML_OS_LINUX)
+ find_sfml_dependency(X11_LIBRARY "X11" X11)
+ find_sfml_dependency(XRANDR_LIBRARY "Xrandr" Xrandr)
+ endif()
+
+ # update the list
+ if(FIND_SFML_OS_WINDOWS)
+ set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "opengl32" "winmm" "gdi32")
+ elseif(FIND_SFML_OS_LINUX OR FIND_SFML_OS_FREEBSD)
+ set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "GL" ${X11_LIBRARY} ${XRANDR_LIBRARY})
+ if(FIND_SFML_OS_FREEBSD)
+ set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "usbhid")
+ endif()
+ elseif(FIND_SFML_OS_MACOSX)
+ set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "GL" "-framework Foundation -framework AppKit -framework IOKit -framework Carbon")
+ endif()
+ set(SFML_DEPENDENCIES ${SFML_DEPENDENCIES} ${SFML_WINDOW_DEPENDENCIES})
+ endif()
+
+ # sfml-graphics
+ list(FIND SFML_FIND_COMPONENTS "graphics" FIND_SFML_GRAPHICS_COMPONENT)
+ if(NOT ${FIND_SFML_GRAPHICS_COMPONENT} EQUAL -1)
+
+ # find libraries
+ find_sfml_dependency(FREETYPE_LIBRARY "FreeType" freetype)
+ find_sfml_dependency(GLEW_LIBRARY "GLEW" glew GLEW glew32 glew32s glew64 glew64s)
+ find_sfml_dependency(JPEG_LIBRARY "libjpeg" jpeg)
+
+ # update the list
+ set(SFML_GRAPHICS_DEPENDENCIES ${FREETYPE_LIBRARY} ${GLEW_LIBRARY} ${JPEG_LIBRARY})
+ set(SFML_DEPENDENCIES ${SFML_DEPENDENCIES} ${SFML_GRAPHICS_DEPENDENCIES})
+ endif()
+
+ # sfml-audio
+ list(FIND SFML_FIND_COMPONENTS "audio" FIND_SFML_AUDIO_COMPONENT)
+ if(NOT ${FIND_SFML_AUDIO_COMPONENT} EQUAL -1)
+
+ # find libraries
+ find_sfml_dependency(OPENAL_LIBRARY "OpenAL" openal openal32)
+ find_sfml_dependency(SNDFILE_LIBRARY "libsndfile" sndfile)
+
+ # update the list
+ set(SFML_AUDIO_DEPENDENCIES ${OPENAL_LIBRARY} ${SNDFILE_LIBRARY})
+ set(SFML_DEPENDENCIES ${SFML_DEPENDENCIES} ${SFML_AUDIO_DEPENDENCIES})
+ endif()
+
+endif()
+
+# handle errors
+if(NOT SFML_VERSION_OK)
+ # SFML version not ok
+ set(FIND_SFML_ERROR "SFML found but version too low (requested: ${SFML_FIND_VERSION}, found: ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR})")
+ set(SFML_FOUND FALSE)
+elseif(SFML_STATIC_LIBRARIES AND FIND_SFML_DEPENDENCIES_NOTFOUND)
+ set(FIND_SFML_ERROR "SFML found but some of its dependencies are missing (${FIND_SFML_DEPENDENCIES_NOTFOUND})")
+ set(SFML_FOUND FALSE)
+elseif(NOT SFML_FOUND)
+ # include directory or library not found
+ set(FIND_SFML_ERROR "Could NOT find SFML (missing: ${FIND_SFML_MISSING})")
+endif()
+if (NOT SFML_FOUND)
+ if(SFML_FIND_REQUIRED)
+ # fatal error
+ message(FATAL_ERROR ${FIND_SFML_ERROR})
+ elseif(NOT SFML_FIND_QUIETLY)
+ # error but continue
+ message("${FIND_SFML_ERROR}")
+ endif()
+endif()
+
+# handle success
+if(SFML_FOUND)
+ message(STATUS "Found SFML ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR} in ${SFML_INCLUDE_DIR}")
+endif()
\ No newline at end of file
diff --git a/cmakelists.txt b/cmakelists.txt
new file mode 100644
index 0000000..2a2a9d7
--- /dev/null
+++ b/cmakelists.txt
@@ -0,0 +1,24 @@
+cmake_minimum_required(VERSION 2.6)
+
+# Projet name
+project("Witch_Blast")
+
+file(
+ GLOB_RECURSE
+ source_files
+ src/*
+)
+
+add_executable(
+ "Witch_Blast"
+ ${source_files}
+)
+
+# Detect and add SFML
+set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
+find_package(SFML 2.1 REQUIRED system window graphics audio)
+target_link_libraries(Witch_Blast ${SFML_LIBRARIES})
+
+include_directories(${SFML_INCLUDE_DIR})
+
+Message(${SFML_LIBRARIES})
\ No newline at end of file
diff --git a/media/DejaVuSans-Bold.ttf b/media/DejaVuSans-Bold.ttf
new file mode 100644
index 0000000..08695f2
Binary files /dev/null and b/media/DejaVuSans-Bold.ttf differ
diff --git a/media/bat.png b/media/bat.png
new file mode 100644
index 0000000..7c7f9e8
Binary files /dev/null and b/media/bat.png differ
diff --git a/media/blood.png b/media/blood.png
new file mode 100644
index 0000000..083482f
Binary files /dev/null and b/media/blood.png differ
diff --git a/media/bolt.png b/media/bolt.png
new file mode 100644
index 0000000..231fe43
Binary files /dev/null and b/media/bolt.png differ
diff --git a/media/chest.png b/media/chest.png
new file mode 100644
index 0000000..5dcd1c7
Binary files /dev/null and b/media/chest.png differ
diff --git a/media/corpses.png b/media/corpses.png
new file mode 100644
index 0000000..2ccb4c0
Binary files /dev/null and b/media/corpses.png differ
diff --git a/media/corpses_big.png b/media/corpses_big.png
new file mode 100644
index 0000000..f0ffa83
Binary files /dev/null and b/media/corpses_big.png differ
diff --git a/media/doors.png b/media/doors.png
new file mode 100644
index 0000000..bacbc5c
Binary files /dev/null and b/media/doors.png differ
diff --git a/media/evil_flower.png b/media/evil_flower.png
new file mode 100644
index 0000000..14b6ae6
Binary files /dev/null and b/media/evil_flower.png differ
diff --git a/media/fairy.png b/media/fairy.png
new file mode 100644
index 0000000..8e2d71f
Binary files /dev/null and b/media/fairy.png differ
diff --git a/media/interface.png b/media/interface.png
new file mode 100644
index 0000000..de1a0cd
Binary files /dev/null and b/media/interface.png differ
diff --git a/media/items.png b/media/items.png
new file mode 100644
index 0000000..6988c9a
Binary files /dev/null and b/media/items.png differ
diff --git a/media/items_equip.png b/media/items_equip.png
new file mode 100644
index 0000000..5d8e4b6
Binary files /dev/null and b/media/items_equip.png differ
diff --git a/media/king_rat.png b/media/king_rat.png
new file mode 100644
index 0000000..0cba8ad
Binary files /dev/null and b/media/king_rat.png differ
diff --git a/media/minimap.png b/media/minimap.png
new file mode 100644
index 0000000..bea3919
Binary files /dev/null and b/media/minimap.png differ
diff --git a/media/pnj.png b/media/pnj.png
new file mode 100644
index 0000000..7f93942
Binary files /dev/null and b/media/pnj.png differ
diff --git a/media/rat.png b/media/rat.png
new file mode 100644
index 0000000..03eca9b
Binary files /dev/null and b/media/rat.png differ
diff --git a/media/sound/big_wall_impact.ogg b/media/sound/big_wall_impact.ogg
new file mode 100644
index 0000000..62baf44
Binary files /dev/null and b/media/sound/big_wall_impact.ogg differ
diff --git a/media/sound/blast00.ogg b/media/sound/blast00.ogg
new file mode 100644
index 0000000..9aa9b43
Binary files /dev/null and b/media/sound/blast00.ogg differ
diff --git a/media/sound/blast01.ogg b/media/sound/blast01.ogg
new file mode 100644
index 0000000..73c01b5
Binary files /dev/null and b/media/sound/blast01.ogg differ
diff --git a/media/sound/bonus.ogg b/media/sound/bonus.ogg
new file mode 100644
index 0000000..43f6a83
Binary files /dev/null and b/media/sound/bonus.ogg differ
diff --git a/media/sound/chest_opening.ogg b/media/sound/chest_opening.ogg
new file mode 100644
index 0000000..72f29e3
Binary files /dev/null and b/media/sound/chest_opening.ogg differ
diff --git a/media/sound/coin.ogg b/media/sound/coin.ogg
new file mode 100644
index 0000000..536c7bc
Binary files /dev/null and b/media/sound/coin.ogg differ
diff --git a/media/sound/door_closing.ogg b/media/sound/door_closing.ogg
new file mode 100644
index 0000000..60d710a
Binary files /dev/null and b/media/sound/door_closing.ogg differ
diff --git a/media/sound/door_opening.ogg b/media/sound/door_opening.ogg
new file mode 100644
index 0000000..5eae554
Binary files /dev/null and b/media/sound/door_opening.ogg differ
diff --git a/media/sound/drink.ogg b/media/sound/drink.ogg
new file mode 100644
index 0000000..4cb8ae0
Binary files /dev/null and b/media/sound/drink.ogg differ
diff --git a/media/sound/ennemy_dying.ogg b/media/sound/ennemy_dying.ogg
new file mode 100644
index 0000000..ee15c8b
Binary files /dev/null and b/media/sound/ennemy_dying.ogg differ
diff --git a/media/sound/impact.ogg b/media/sound/impact.ogg
new file mode 100644
index 0000000..542bc5b
Binary files /dev/null and b/media/sound/impact.ogg differ
diff --git a/media/sound/king_rat_cry_1.ogg b/media/sound/king_rat_cry_1.ogg
new file mode 100644
index 0000000..80c5dc8
Binary files /dev/null and b/media/sound/king_rat_cry_1.ogg differ
diff --git a/media/sound/king_rat_cry_2.ogg b/media/sound/king_rat_cry_2.ogg
new file mode 100644
index 0000000..bceb717
Binary files /dev/null and b/media/sound/king_rat_cry_2.ogg differ
diff --git a/media/sound/king_rat_die.ogg b/media/sound/king_rat_die.ogg
new file mode 100644
index 0000000..370a697
Binary files /dev/null and b/media/sound/king_rat_die.ogg differ
diff --git a/media/sound/pay.ogg b/media/sound/pay.ogg
new file mode 100644
index 0000000..da7ce37
Binary files /dev/null and b/media/sound/pay.ogg differ
diff --git a/media/sound/player_die.ogg b/media/sound/player_die.ogg
new file mode 100644
index 0000000..928ff2d
Binary files /dev/null and b/media/sound/player_die.ogg differ
diff --git a/media/sound/player_hit.ogg b/media/sound/player_hit.ogg
new file mode 100644
index 0000000..90f37f1
Binary files /dev/null and b/media/sound/player_hit.ogg differ
diff --git a/media/sound/step.ogg b/media/sound/step.ogg
new file mode 100644
index 0000000..bc33137
Binary files /dev/null and b/media/sound/step.ogg differ
diff --git a/media/sound/track00.ogg b/media/sound/track00.ogg
new file mode 100644
index 0000000..118b9e2
Binary files /dev/null and b/media/sound/track00.ogg differ
diff --git a/media/sound/wall_impact.ogg b/media/sound/wall_impact.ogg
new file mode 100644
index 0000000..4040f70
Binary files /dev/null and b/media/sound/wall_impact.ogg differ
diff --git a/media/sprite.png b/media/sprite.png
new file mode 100644
index 0000000..f2073b9
Binary files /dev/null and b/media/sprite.png differ
diff --git a/media/star.png b/media/star.png
new file mode 100644
index 0000000..9039d6d
Binary files /dev/null and b/media/star.png differ
diff --git a/media/star2.png b/media/star2.png
new file mode 100644
index 0000000..57ae3a7
Binary files /dev/null and b/media/star2.png differ
diff --git a/media/tiles.png b/media/tiles.png
new file mode 100644
index 0000000..d3277e6
Binary files /dev/null and b/media/tiles.png differ
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..b8f2d25
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,38 @@
+ WITCH BLAST
+============================
+Author: Seby (code, art and music)
+Email: sebygames@gmail.com
+2014
+============================
+
+Introduction
+------------
+
+Witch Blast is a free roguelite dungeon crawl shooter heavily inspired from Binding Of Isaac. The player plays as a novice magician in a dungeon and trying to get as far as he can, using various items he can find to defeat the inhabitants of the dungeon.
+
+Web: https://github.com/Cirrus-Minor/witchblast
+
+
+Install
+-------
+
+If there is no binary for your version, you have to compile the application. You will need the library SFML, minimal version 2.1.
+A CMake file is available.
+
+
+Commands
+--------
+
+WASD (US, DE) or QSDZ (FR) to move in 8 directions
+Arrows to shoot in 4 directions.
+
+
+Features
+--------
+
+- randomly generated dungeons,
+- powerful items,
+- monsters,
+- chest and keys,
+- merchant,
+- candy eye effects.
\ No newline at end of file
diff --git a/src/ArtefactDescriptionEntity.cpp b/src/ArtefactDescriptionEntity.cpp
new file mode 100644
index 0000000..b7e0b49
--- /dev/null
+++ b/src/ArtefactDescriptionEntity.cpp
@@ -0,0 +1,111 @@
+#include "ArtefactDescriptionEntity.h"
+#include "Constants.h"
+#include "sfml_game/ImageManager.h"
+#include "WitchBlastGame.h"
+#include "StaticTextEntity.h"
+
+ArtefactDescriptionEntity::ArtefactDescriptionEntity(ItemEntity::enumItemType itemType, WitchBlastGame* parent/*, sf::Font* my_font*/)
+ : SpriteEntity (ImageManager::getImageManager()->getImage(IMAGE_ITEMS_EQUIP), 0, 0, ITEM_WIDTH, ITEM_HEIGHT)
+{
+ //font = my_font;
+
+ this->setLifetime(6.0f);
+
+ this->setFrame(itemType - ItemEntity::itemMagicianHat);
+ this->setType(9);
+
+ float x0 = OFFSET_X + MAP_WIDTH * TILE_WIDTH * 0.5f - ARTEFACT_RECT_WIDTH * 0.5f;
+
+ rectangle.setSize(sf::Vector2f(ARTEFACT_RECT_WIDTH, ARTEFACT_RECT_HEIGHT));
+ rectangle.setPosition(sf::Vector2f(x0, ARTEFACT_POS_Y));
+ rectangle.setFillColor(sf::Color(20, 20, 70, 180));
+
+ rectangleBorder.setSize(sf::Vector2f(ARTEFACT_RECT_WIDTH + ARTEFACT_BORDER * 2.0f,
+ ARTEFACT_RECT_HEIGHT + ARTEFACT_BORDER * 2.0f));
+ rectangleBorder.setPosition(sf::Vector2f(x0 - ARTEFACT_BORDER, ARTEFACT_POS_Y - ARTEFACT_BORDER));
+ rectangleBorder.setFillColor(sf::Color(255, 255, 255, 180));
+
+ this->parent = parent;
+
+ this->x = x0 + 50.0f;
+ this->y = 500.0f;
+ sprite.setScale(3.5f, 3.5f);
+
+ z = 5000.0f;
+
+ switch (itemType)
+ {
+ case (ItemEntity::itemMagicianHat):
+ artefactName = "Enchanter Hat"; artefactDescription = "Increases fire rate"; break;
+ case (ItemEntity::itemLeatherBoots):
+ artefactName = "Leather Boots"; artefactDescription = "Increases speed"; break;
+ case (ItemEntity::itemBookDualShots):
+ artefactName = "Spell : Dual Bolts"; artefactDescription = "Shoots two bolts"; break;
+ case (ItemEntity::itemConcentrationAmulet):
+ artefactName = "Concentration Amulet"; artefactDescription = "Increases fire range"; break;
+ case (ItemEntity::itemBossKey):
+ artefactName = "Boss Key"; artefactDescription = "Open the boss gate"; break;
+ case (ItemEntity::itemVibrationGloves):
+ artefactName = "Vibration Gloves"; artefactDescription = "Vibrations + slighty increases fire rate"; break;
+ case (ItemEntity::itemMahoganyStaff):
+ artefactName = "Mahogany Staff"; artefactDescription = "Increases bolt's speed and damages"; break;
+ case (ItemEntity::itemFairy):
+ artefactName = "Fairy"; artefactDescription = "Help you in the dungeon"; break;
+ default: break;
+ }
+}
+
+ArtefactDescriptionEntity::~ArtefactDescriptionEntity()
+{
+}
+
+void ArtefactDescriptionEntity::animate(float delay)
+{
+
+ if (age < ARTEFACT_ZOOM_TIME)
+ {
+ float perc = 1.0f - age / ARTEFACT_ZOOM_TIME;
+ sprite.setScale(3.5f + perc * 50.0f, 3.5f + perc * 50.0f);
+ }
+ else
+ {
+ sprite.setScale(3.5f, 3.5f);
+ }
+ SpriteEntity::animate(delay);
+}
+
+void ArtefactDescriptionEntity::render(sf::RenderWindow* app)
+{
+ int nx = frame;
+ int ny = 0;
+
+ if (imagesProLine > 0)
+ {
+ nx = frame % imagesProLine;
+ ny = frame / imagesProLine;
+ }
+
+ sprite.setTextureRect(sf::IntRect(nx * width, ny * height, /*(nx + 1) **/ width, /*(ny + 1) */ height));
+
+ sprite.setPosition(x, y);
+ sprite.setRotation(angle);
+
+ if (isFading)
+ {
+ sprite.setColor(sf::Color(255, 255, 255, (sf::Uint8)(getFade() * 255)));
+ }
+
+ if (isShrinking)
+ {
+ sprite.setScale(getFade(), getFade());
+ }
+
+
+ app->draw(rectangleBorder);
+ app->draw(rectangle);
+
+ app->draw(sprite);
+
+ StaticTextEntity::Write(app, artefactName, 22, 315.0f, ARTEFACT_POS_Y + 15.0f, ALIGN_LEFT);
+ StaticTextEntity::Write(app, artefactDescription, 20, 315.0f, ARTEFACT_POS_Y + 55.0f, ALIGN_LEFT);
+}
diff --git a/src/ArtefactDescriptionEntity.h b/src/ArtefactDescriptionEntity.h
new file mode 100644
index 0000000..947e75a
--- /dev/null
+++ b/src/ArtefactDescriptionEntity.h
@@ -0,0 +1,25 @@
+#ifndef ARTEFACTDESCRIPTIONENTITY_H
+#define ARTEFACTDESCRIPTIONENTITY_H
+
+#include "sfml_game/SpriteEntity.h"
+#include "ItemEntity.h"
+
+class WitchBlastGame;
+
+class ArtefactDescriptionEntity : public SpriteEntity
+{
+ public:
+ ArtefactDescriptionEntity(ItemEntity::enumItemType, WitchBlastGame* parent);
+ ~ArtefactDescriptionEntity();
+
+ virtual void animate(float delay);
+ virtual void render(sf::RenderWindow* app);
+ private:
+ sf::RectangleShape rectangle;
+ sf::RectangleShape rectangleBorder;
+ WitchBlastGame* parent;
+
+ std::string artefactName;
+ std::string artefactDescription;
+};
+#endif // ARTEFACTDESCRIPTIONENTITY_H
diff --git a/src/BaseCreatureEntity.cpp b/src/BaseCreatureEntity.cpp
new file mode 100644
index 0000000..ccf37a8
--- /dev/null
+++ b/src/BaseCreatureEntity.cpp
@@ -0,0 +1,88 @@
+#include "BaseCreatureEntity.h"
+#include "sfml_game/ImageManager.h"
+#include "Constants.h"
+
+#include "WitchBlastGame.h"
+
+BaseCreatureEntity::BaseCreatureEntity(sf::Texture* image, float x = 0.0f, float y = 0.0f, int spriteWidth = -1, int spriteHeight = -1)
+ : CollidingSpriteEntity (image, x, y, spriteWidth, spriteHeight)
+{
+ hurting = false;
+ shadowFrame = -1;
+}
+
+void BaseCreatureEntity::setParent(WitchBlastGame* parent)
+{
+ parentGame = parent;
+}
+
+int BaseCreatureEntity::getHp()
+{
+ return hp;
+}
+
+int BaseCreatureEntity::getHpMax()
+{
+ return hpMax;
+}
+
+int BaseCreatureEntity::getHpDisplay()
+{
+ return hpDisplay;
+}
+
+void BaseCreatureEntity::animate(float delay)
+{
+ if (hpDisplay > hp) hpDisplay--;
+ else if (hpDisplay < hp) hpDisplay++;
+
+ z = y + height/2;
+ if (hurting)
+ {
+ hurtingDelay -= delay;
+ if (hurtingDelay > 0.0f)
+ {
+ int fadeColor = (sf::Uint8)((HURTING_DELAY - hurtingDelay) * 255);
+ sprite.setColor(sf::Color(255, fadeColor, fadeColor, 255 ));
+ }
+ else
+ {
+ hurting = false;
+ sprite.setColor(sf::Color(255, 255, 255, 255 ));
+ }
+ }
+ CollidingSpriteEntity::animate(delay);
+}
+
+void BaseCreatureEntity::render(sf::RenderWindow* app)
+{
+ if (!isDying && shadowFrame > -1)
+ {
+ // shadow
+ sprite.setTextureRect(sf::IntRect(shadowFrame * width, 0, width, height));
+ app->draw(sprite);
+ }
+ CollidingSpriteEntity::render(app);
+}
+
+void BaseCreatureEntity::calculateBB()
+{
+}
+
+void BaseCreatureEntity::hurt(int damages)
+{
+ hurting = true;
+ hurtingDelay = HURTING_DELAY;
+
+ hp -= damages;
+ if (hp <= 0)
+ {
+ hp = 0;
+ dying();
+ }
+}
+
+void BaseCreatureEntity::dying()
+{
+ isDying = true;
+}
diff --git a/src/BaseCreatureEntity.h b/src/BaseCreatureEntity.h
new file mode 100644
index 0000000..4c575c3
--- /dev/null
+++ b/src/BaseCreatureEntity.h
@@ -0,0 +1,36 @@
+#ifndef BASECREATUREENTITY_H
+#define BASECREATUREENTITY_H
+
+#include "sfml_game/CollidingSpriteEntity.h"
+
+class WitchBlastGame;
+
+class BaseCreatureEntity : public CollidingSpriteEntity
+{
+ public:
+ BaseCreatureEntity(sf::Texture* image, float x, float y, int spriteWidth, int spriteHeight);
+ int getHp();
+ int getHpMax();
+ int getHpDisplay();
+ virtual void animate(float delay);
+ virtual void render(sf::RenderWindow* app);
+ virtual void calculateBB();
+ virtual void hurt(int damages);
+ virtual void dying();
+ void setParent(WitchBlastGame* parent);
+ enum enumBloodColor { bloodRed, bloodGreen};
+ protected:
+ int hp;
+ int hpMax;
+ int hpDisplay;
+ float creatureSpeed;
+ int shadowFrame;
+
+ bool hurting;
+ float hurtingDelay;
+ WitchBlastGame* parentGame;
+ enumBloodColor bloodColor;
+ private:
+};
+
+#endif // BASECREATUREENTITY_H
diff --git a/src/BatEntity.cpp b/src/BatEntity.cpp
new file mode 100644
index 0000000..b17c5cc
--- /dev/null
+++ b/src/BatEntity.cpp
@@ -0,0 +1,124 @@
+#include "BatEntity.h"
+#include "PlayerEntity.h"
+#include "sfml_game/SpriteEntity.h"
+#include "sfml_game/ImageManager.h"
+#include "sfml_game/SoundManager.h"
+#include "Constants.h"
+#include "WitchBlastGame.h"
+
+BatEntity::BatEntity(float x, float y, GameMap* map)
+ : EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_BAT), x, y, map)
+{
+ creatureSpeed = BAT_SPEED;
+ velocity = Vector2D(creatureSpeed);
+ hp = BAT_HP;
+ meleeDamages = BAT_DAMAGES;
+
+ type = 22;
+ bloodColor = bloodRed;
+ changingDelay = -0.5f;
+ shadowFrame = 3;
+}
+
+void BatEntity::animate(float delay)
+{
+ changingDelay -= delay;
+ if (changingDelay < 0.0f)
+ {
+ velocity = Vector2D(creatureSpeed);
+ changingDelay = 0.5f + (float)(rand() % 2500) / 1000.0f;
+ }
+ if (age < 0.0f)
+ frame = 1;
+ else
+ frame = ((int)(age * 5.0f)) % 2;
+
+ testSpriteCollisions();
+ EnnemyEntity::animate(delay);
+}
+
+void BatEntity::calculateBB()
+{
+ boundingBox.left = (int)x - width / 2 + BAT_BB_LEFT;
+ boundingBox.width = width - BAT_BB_WIDTH_DIFF;
+ boundingBox.top = (int)y - height / 2 + BAT_BB_TOP;
+ boundingBox.height = height - BAT_BB_HEIGHT_DIFF;
+}
+
+void BatEntity::collideMapRight()
+{
+ // if (x > OFFSET_X + MAP_WIDTH * TILE_WIDTH)
+ velocity.x = -velocity.x;
+}
+
+void BatEntity::collideMapLeft()
+{
+ // if (x < OFFSET_X + MAP_WIDTH )
+ velocity.x = -velocity.x;
+}
+
+void BatEntity::collideMapTop()
+{
+// if (y > OFFSET_Y + MAP_HEIGHT * TILE_HEIGHT)
+ velocity.y = -velocity.y;
+}
+
+void BatEntity::collideMapBottom()
+{
+ // if (y < OFFSET_Y + MAP_HEIGHT )
+ velocity.y = -velocity.y;
+}
+
+bool BatEntity::collideWithMap(int direction)
+{
+ calculateBB();
+
+ int xTile0 = (boundingBox.left - offsetX) / tileWidth;
+ int xTilef = (boundingBox.left + boundingBox.width - offsetX) / tileWidth;
+ int yTile0 = (boundingBox.top - offsetY) / tileHeight;
+ int yTilef = (boundingBox.top + boundingBox.height - offsetY) / tileHeight;
+
+ if (boundingBox.top < 0) yTile0 = -1;
+
+ for (int xTile = xTile0; xTile <= xTilef; xTile++)
+ for (int yTile = yTile0; yTile <= yTilef; yTile++)
+ {
+ if (xTile == 0 || xTile == MAP_WIDTH - 1 || yTile == 0 || yTile == MAP_HEIGHT - 1)
+ {
+ switch (direction)
+ {
+ case DIRECTION_LEFT:
+ if (map->isLeftBlocking(xTile, yTile)) return true;
+ break;
+
+ case DIRECTION_RIGHT:
+ if (map->isRightBlocking(xTile, yTile)) return true;
+ break;
+
+ case DIRECTION_TOP:
+ if (map->isUpBlocking(xTile, yTile)) return true;
+ break;
+
+ case DIRECTION_BOTTOM:
+ if (map->isDownBlocking(xTile, yTile)) return true;
+ break;
+ }
+ }
+ }
+
+ return false;
+}
+
+void BatEntity::dying()
+{
+ isDying = true;
+ SpriteEntity* deadBat = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES), x, y, 64, 64);
+ deadBat->setZ(OFFSET_Y);
+ deadBat->setFrame(FRAME_CORPSE_BAT);
+ deadBat->setType(TYPE_CORPSE);
+
+ for (int i = 0; i < 4; i++) parentGame->generateBlood(x, y, bloodColor);
+
+ drop();
+ SoundManager::getSoundManager()->playSound(SOUND_ENNEMY_DYING);
+}
diff --git a/src/BatEntity.h b/src/BatEntity.h
new file mode 100644
index 0000000..c671d33
--- /dev/null
+++ b/src/BatEntity.h
@@ -0,0 +1,25 @@
+#ifndef BATSPRITE_H
+#define BATSPRITE_H
+
+#include "EnnemyEntity.h"
+
+class BatEntity : public EnnemyEntity
+{
+ public:
+ BatEntity(float x, float y, GameMap* map);
+ virtual void animate(float delay);
+ virtual void calculateBB();
+ protected:
+ virtual bool collideWithMap(int direction);
+ virtual void collideMapRight();
+ virtual void collideMapLeft();
+ virtual void collideMapTop();
+ virtual void collideMapBottom();
+
+ virtual void dying();
+ private:
+ float changingDelay;
+
+};
+
+#endif // BATSPRITE_H
diff --git a/src/BoltEntity.cpp b/src/BoltEntity.cpp
new file mode 100644
index 0000000..01d7fb1
--- /dev/null
+++ b/src/BoltEntity.cpp
@@ -0,0 +1,126 @@
+#include "BoltEntity.h"
+#include "Constants.h"
+#include "sfml_game/ImageManager.h"
+#include "sfml_game/SoundManager.h"
+
+BoltEntity::BoltEntity(sf::Texture* image, float x, float y, float boltLifeTime) : CollidingSpriteEntity (image, x, y, BOLT_WIDTH, BOLT_HEIGHT)
+{
+ lifetime = boltLifeTime;
+ damages = INITIAL_BOLT_DAMAGES;
+ type = 15;
+ viscosity = 0.97f;
+ frame = 0;
+}
+
+int BoltEntity::getDamages()
+{
+ return damages;
+}
+
+void BoltEntity::setDamages(int damages)
+{
+ this->damages = damages;
+}
+
+void BoltEntity::animate(float delay)
+{
+ SpriteEntity* trace = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_BOLT), x, y, BOLT_WIDTH, BOLT_HEIGHT);
+ trace->setFading(true);
+ trace->setZ(y);
+ trace->setLifetime(0.2f);
+ trace->setShrinking(true);
+ trace->setType(16);
+
+ z = y + height;
+ //if (viscosity < 1.0f && ((velocity.x)*(velocity.x) + (velocity.y)*(velocity.y)) < 900.0f) viscosity = 1.0f;
+
+ CollidingSpriteEntity::animate(delay);
+
+ if ( (lifetime - age) < 0.2f)
+ {
+ if (age >= lifetime)
+ sprite.setColor(sf::Color(255, 255, 255, 0));
+ else
+ sprite.setColor(sf::Color(255, 255, 255, (sf::Uint8)((lifetime - age) / 0.2f * 255)));
+ }
+
+ if (((velocity.x)*(velocity.x) + (velocity.y)*(velocity.y)) < 1500.0f) isDying = true;
+}
+
+void BoltEntity::collide()
+{
+ isDying = true;
+ for (int i=0; i<5; i++)
+ {
+ Vector2D vel(40.0f + rand() % 50);
+ generateParticule(vel);
+ }
+}
+
+void BoltEntity::generateParticule(Vector2D vel)
+{
+ SpriteEntity* trace = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_BOLT), x, y, BOLT_WIDTH, BOLT_HEIGHT);
+ trace->setFading(true);
+ trace->setZ(y);
+ trace->setLifetime(0.5f);
+ trace->setScale(0.3f, 0.3f);
+ trace->setVelocity(vel);
+ trace->setViscosity(0.97f);
+ trace->setType(16);
+}
+
+void BoltEntity::collideMapRight()
+{
+ velocity.x = 0.0f;
+ isDying = true;
+
+ SoundManager::getSoundManager()->playSound(SOUND_WALL_IMPACT);
+ for (int i=0; i<5; i++)
+ {
+ Vector2D vel(100.0f + rand() % 150);
+ if (vel.x > 0.0f) vel.x = - vel.x;
+ generateParticule(vel);
+ }
+}
+
+void BoltEntity::collideMapLeft()
+{
+ velocity.x = 0.0f;
+ isDying = true;
+
+ SoundManager::getSoundManager()->playSound(SOUND_WALL_IMPACT);
+ for (int i=0; i<5; i++)
+ {
+ Vector2D vel(100.0f + rand() % 150);
+ if (vel.x < 0.0f) vel.x = - vel.x;
+ generateParticule(vel);
+ }
+}
+
+void BoltEntity::collideMapTop()
+{
+ velocity.y = 0.0f;
+ isDying = true;
+
+ SoundManager::getSoundManager()->playSound(SOUND_WALL_IMPACT);
+ for (int i=0; i<5; i++)
+ {
+ Vector2D vel(100.0f + rand() % 150);
+ if (vel.y < 0.0f) vel.y = - vel.y;
+ generateParticule(vel);
+ }
+}
+
+void BoltEntity::collideMapBottom()
+{
+ velocity.y = 0.0f;
+ isDying = true;
+
+ SoundManager::getSoundManager()->playSound(SOUND_WALL_IMPACT);
+ for (int i=0; i<5; i++)
+ {
+ Vector2D vel(100.0f + rand() % 150);
+ if (vel.y > 0.0f) vel.y = - vel.y;
+ generateParticule(vel);
+ }
+}
diff --git a/src/BoltEntity.h b/src/BoltEntity.h
new file mode 100644
index 0000000..3d5c704
--- /dev/null
+++ b/src/BoltEntity.h
@@ -0,0 +1,27 @@
+#ifndef BOLTENTITY_H
+#define BOLTENTITY_H
+
+#include "sfml_game/CollidingSpriteEntity.h"
+
+class BoltEntity : public CollidingSpriteEntity
+{
+ public:
+ BoltEntity(sf::Texture* image, float x, float y, float boltLifeTime);
+ virtual void animate(float delay);
+ void collide();
+ void generateParticule(Vector2D vel);
+
+ int getDamages();
+ void setDamages(int damages);
+
+ protected:
+ virtual void collideMapRight();
+ virtual void collideMapLeft();
+ virtual void collideMapTop();
+ virtual void collideMapBottom();
+
+ int damages;
+ private:
+};
+
+#endif // BOLTENTITY_H
diff --git a/src/ChestEntity.cpp b/src/ChestEntity.cpp
new file mode 100644
index 0000000..85e3f6a
--- /dev/null
+++ b/src/ChestEntity.cpp
@@ -0,0 +1,81 @@
+#include "ChestEntity.h"
+#include "PlayerEntity.h"
+#include "sfml_game/ImageManager.h"
+#include "sfml_game/SoundManager.h"
+#include "sfml_game/SpriteEntity.h"
+#include "Constants.h"
+
+ChestEntity::ChestEntity(float x, float y, int chestType, bool isOpen)
+ : CollidingSpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CHEST), x, y, 48, 48)
+{
+ type = 19;
+ imagesProLine = 2;
+ this->isOpen = isOpen;
+ this->chestType = chestType;
+ frame = chestType * 2 + (isOpen ? 1 : 0);
+}
+
+bool ChestEntity::getOpened()
+{
+ return isOpen;
+}
+
+int ChestEntity::getChestType()
+{
+ return chestType;
+}
+
+void ChestEntity::animate(float delay)
+{
+ CollidingSpriteEntity::animate(delay);
+ if (!isOpen) testSpriteCollisions();
+ z = y + height/2;
+}
+
+void ChestEntity::calculateBB()
+{
+ boundingBox.left = (int)x - width / 2;
+ boundingBox.width = width;
+ boundingBox.top = (int)y - height / 2;
+ boundingBox.height = height;
+}
+
+
+void ChestEntity::readCollidingEntity(CollidingSpriteEntity* entity)
+{
+ PlayerEntity* playerEntity = dynamic_cast<PlayerEntity*>(entity);
+
+ if (collideWithEntity(entity))
+ {
+ if (!isOpen && playerEntity != NULL && !playerEntity->isDead())
+ {
+ open();
+ frame += 1;
+ }
+ }
+}
+
+void ChestEntity::open()
+{
+ isOpen = true;
+ SoundManager::getSoundManager()->playSound(SOUND_CHEST_OPENING);
+
+ if (chestType == CHEST_BASIC)
+ {
+ for (int i = 0; i < 5; i++)
+ {
+ ItemEntity* newItem = new ItemEntity(ItemEntity::itemCopperCoin, x, y);
+ newItem->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ newItem->setVelocity(Vector2D(50.0f + rand()% 150));
+ newItem->setViscosity(0.96f);
+ }
+ }
+ else if (chestType == CHEST_FAIRY)
+ {
+ ItemEntity* newItem = new ItemEntity(ItemEntity::itemFairy, x, y);
+ newItem->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ newItem->setVelocity(Vector2D(50.0f + rand()% 150));
+ newItem->setViscosity(0.96f);
+ }
+}
+
diff --git a/src/ChestEntity.h b/src/ChestEntity.h
new file mode 100644
index 0000000..6940d69
--- /dev/null
+++ b/src/ChestEntity.h
@@ -0,0 +1,26 @@
+#ifndef CHESTENTITY_H
+#define CHESTENTITY_H
+
+#include "sfml_game/CollidingSpriteEntity.h"
+
+class ChestEntity : public CollidingSpriteEntity
+{
+ public:
+ ChestEntity(float x, float y, int chestType, bool isOpen);
+ virtual void animate(float delay);
+ virtual void calculateBB();
+
+ void open();
+ bool getOpened();
+ int getChestType();
+
+ protected:
+
+ virtual void readCollidingEntity(CollidingSpriteEntity* entity);
+
+ private:
+ bool isOpen;
+ int chestType;
+};
+
+#endif // CHESTENTITY_H
diff --git a/src/Constants.h b/src/Constants.h
new file mode 100644
index 0000000..b30e785
--- /dev/null
+++ b/src/Constants.h
@@ -0,0 +1,232 @@
+/** This file is part of Ostrich Riders.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CONSTANTS_H_INCLUDED
+#define CONSTANTS_H_INCLUDED
+
+#include <string>
+
+//#define _68X68
+
+const std::string APP_NAME = "Witch Blast";
+const std::string APP_VERSION = "0.0.4";
+
+const int SCREEN_WIDTH = 970; //1024;
+const int SCREEN_HEIGHT = 720; //768;
+
+const int TILE_WIDTH = 64;
+const int TILE_HEIGHT = 64;
+
+const int OFFSET_X = 5;
+const int OFFSET_Y = 5;
+
+const int MAP_WIDTH = 15;
+const int MAP_HEIGHT = 9;
+
+const int FLOOR_WIDTH = 13;
+const int FLOOR_HEIGHT = 7;
+
+const int ITEM_WIDTH = 32;
+const int ITEM_HEIGHT = 32;
+
+const int BOLT_WIDTH = 24;
+const int BOLT_HEIGHT = 24;
+
+const int BB_LEFT = 22;
+const int BB_RIGHT = 22;
+const int BB_TOP = 4;
+const int BB_BOTTOM = 31;
+
+enum item_images {
+ IMAGE_PLAYER,
+ IMAGE_BOLT,
+ IMAGE_TILES,
+ IMAGE_RAT,
+ IMAGE_MINIMAP,
+ IMAGE_DOOR,
+ IMAGE_ITEMS,
+ IMAGE_ITEMS_EQUIP,
+ IMAGE_CHEST,
+ IMAGE_BAT,
+ IMAGE_FLOWER,
+
+ IMAGE_KING_RAT,
+
+ IMAGE_BLOOD,
+ IMAGE_CORPSES,
+ IMAGE_CORPSES_BIG,
+ IMAGE_STAR,
+ IMAGE_STAR_2,
+ IMAGE_INTERFACE,
+
+ IMAGE_PNJ,
+ IMAGE_FAIRY
+};
+
+enum sound_resources {
+ SOUND_STEP,
+ SOUND_BLAST_STANDARD,
+ SOUND_BLAST_FLOWER,
+ SOUND_DOOR_CLOSING,
+ SOUND_DOOR_OPENING,
+ SOUND_CHEST_OPENING,
+ SOUND_IMPACT,
+ SOUND_BONUS,
+ SOUND_DRINK,
+ SOUND_PLAYER_HIT,
+ SOUND_PLAYER_DIE,
+ SOUND_ENNEMY_DYING,
+ SOUND_COIN_PICK_UP,
+ SOUND_PAY,
+ SOUND_WALL_IMPACT,
+ SOUND_BIG_WALL_IMPACT,
+ SOUND_KING_RAT_1,
+ SOUND_KING_RAT_2,
+ SOUND_KING_RAT_DIE
+};
+
+const int TYPE_BLOOD = 11;
+const int TYPE_CORPSE = 12;
+
+const int TYPE_ITEM = 19;
+
+enum corpses_ressources{
+ FRAME_CORPSE_RAT,
+ FRAME_CORPSE_BAT,
+ FRAME_CORPSE_FLOWER,
+ FRAME_CORPSE_GREEN_RAT,
+
+ FRAME_CORPSE_KING_RAT
+};
+
+// Player game play
+const float INITIAL_PLAYER_SPEED = 180.0f;
+const int INITIAL_PLAYER_HP = 20;
+const float INITIAL_PLAYER_FIRE_DELAY = 0.7f;
+const float ACQUIRE_DELAY = 2.8f;
+const float UNLOCK_DELAY = 1.0f;
+
+const float INITIAL_BOLT_LIFE = 0.4f;
+const int INITIAL_BOLT_DAMAGES = 5;
+const float INITIAL_BOLT_VELOCITY = 700.0f;
+
+const float FAIRY_SPEED = 180.0f; //400.0f;
+const float FAIRY_FIRE_DELAY = 0.8f;
+const float FAIRY_BOLT_LIFE = 0.4f;
+const int FAIRY_BOLT_DAMAGES = 5;
+const float FAIRY_BOLT_VELOCITY = 700.0f;
+
+// Items
+const int NUMBER_EQUIP_ITEMS = 8;
+enum item_equip {
+ EQUIP_ENCHANTER_HAT,
+ EQUIP_LEATHER_BOOTS,
+ EQUIP_BOOK_DUAL,
+ EQUIP_CONCENTRATION_AMULET,
+ EQUIP_BOSS_KEY,
+ EQUIP_VIBRATION_GLOVES,
+ EQUIP_MAHONAGY_STAFF,
+
+ EQUIP_FAIRY
+ };
+//const int ITEM_ENCHANTER_HAT = 0,
+ // itemLeatherBoots,
+ // itemBookDualShots
+enum chest_type_enum {
+ CHEST_BASIC,
+ CHEST_FAIRY
+};
+// Artefact Info
+const float ARTEFACT_RECT_WIDTH = 600.0f;
+const float ARTEFACT_RECT_HEIGHT = 100.0f;
+const float ARTEFACT_POS_Y = 450.0f;
+const float ARTEFACT_BORDER = 8.0f;
+const float ARTEFACT_ZOOM_TIME = 0.5f;
+
+// monster type
+enum monster_type_enum
+{
+ MONSTER_RAT,
+ MONSTER_BAT,
+ MONSTER_EVIL_FLOWER,
+
+ MONSTER_KING_RAT
+};
+
+const float DOOR_OPEN_TIME = 1.0f;
+const float DOOR_CLOSE_TIME = 1.0f;
+
+// Rat
+const float RAT_SPEED = 160.0f;
+const int RAT_HP = 15;
+const int RAT_DAMAGES = 5;
+const int RAT_BB_LEFT = 14;
+const int RAT_BB_WIDTH_DIFF = 28;
+const int RAT_BB_TOP = 22;
+const int RAT_BB_HEIGHT_DIFF = 22;
+
+// Green Rat
+const float GREEN_RAT_SPEED = 170.0f;
+const int GREEN_RAT_HP = 10;
+const int GREEN_RAT_DAMAGES = 5;
+const float GREEN_RAT_FADE = 1.0f;
+/*const int RAT_BB_LEFT = 14;
+const int RAT_BB_WIDTH_DIFF = 28;
+const int RAT_BB_TOP = 22;
+const int RAT_BB_HEIGHT_DIFF = 22;*/
+
+// Bat
+const float BAT_SPEED = 250.0f;
+const int BAT_HP = 5;
+const int BAT_DAMAGES = 5;
+const int BAT_BB_LEFT = 5;
+const int BAT_BB_WIDTH_DIFF = 10;
+const int BAT_BB_TOP = 2;
+const int BAT_BB_HEIGHT_DIFF = 32;
+
+// Evl Flower
+const int EVIL_FLOWER_HP = 10;
+const int EVIL_FLOWER_MELEE_DAMAGES = 8;
+const int EVIL_FLOWER_MISSILE_DAMAGES = 5;
+const int EVIL_FLOWER_BB_LEFT = 14;
+const int EVIL_FLOWER_BB_WIDTH_DIFF = 28;
+const int EVIL_FLOWER_BB_TOP = 22;
+const int EVIL_FLOWER_BB_HEIGHT_DIFF = 22;
+const float EVIL_FLOWER_FIRE_DELAY = 2.7f;
+const float EVIL_FLOWER_FIRE_VELOCITY = 220.0f;
+
+
+// Rat
+const float KING_RAT_SPEED = 200.0f;
+const float KING_RAT_RUNNING_SPEED = 600.0f;
+const float KING_RAT_BERSERK_SPEED = 250.0f;
+const int KING_RAT_HP = 400;
+const int KING_RAT_DAMAGES = 8;
+
+// TILES
+const int TILE_FIRE_IN = 1;
+
+// MEDIAMANAGERS
+//IMAGES
+const int IMAGE_PLAYER1 = 0;
+
+//SOUND
+const int SOUND_COLLISION_WITH_JOUSTER = 0;
+
+// EFFECTS
+const float HURTING_DELAY = 0.4f;
+
+#endif // CONSTANTS_H_INCLUDED
diff --git a/src/DoorEntity.cpp b/src/DoorEntity.cpp
new file mode 100644
index 0000000..0df4480
--- /dev/null
+++ b/src/DoorEntity.cpp
@@ -0,0 +1,286 @@
+#include "DoorEntity.h"
+#include "Constants.h"
+#include "sfml_game/ImageManager.h"
+
+DoorEntity::DoorEntity(int direction) : SpriteEntity (ImageManager::getImageManager()->getImage(IMAGE_DOOR))
+{
+ this->direction = direction;
+ isOpen = true;
+ removeCenter();
+ width = TILE_WIDTH;
+ height = TILE_HEIGHT;
+ z = OFFSET_Y;
+ type = 3;
+ doorType = 0;
+
+ //isOpen = false;
+ //timer = DOOR_CLOSE_TIME;
+}
+
+
+void DoorEntity::animate(float delay)
+{
+ age += delay;
+
+ if (timer > 0.0f) timer -= delay;
+ //SpriteEntity::animate(delay);
+}
+
+void DoorEntity::setOpen(bool open)
+{
+ isOpen = open;
+ timer = 0.0f;
+}
+
+void DoorEntity::setDoorType(int doorType)
+{
+ this->doorType = doorType;
+}
+
+void DoorEntity::closeDoor()
+{
+ isOpen = false;
+ timer = DOOR_CLOSE_TIME;
+}
+
+void DoorEntity::openDoor()
+{
+ isOpen = true;
+ timer = DOOR_OPEN_TIME;
+}
+
+void DoorEntity::render(sf::RenderWindow* app)
+{
+ if (!isVisible) return;
+ float xl, yl, xr, yr;
+
+ if (direction == 8)
+ {
+ yl = OFFSET_Y;
+ yr = OFFSET_Y;
+ if (isOpen)
+ {
+ if (timer > 0.0f)
+ {
+ xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH / 2
+ - 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_WIDTH / 2);
+ xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH / 2
+ + 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_WIDTH / 2);
+ }
+ else
+ {
+ xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH * 1.2f;
+ xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH * 1.2f;
+ }
+ }
+ else
+ {
+ if (timer > 0.0f)
+ {
+ xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH / 2
+ - 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_WIDTH / 2);
+ xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH / 2
+ + 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_WIDTH / 2);
+ }
+ else
+ {
+ xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH /2;;
+ xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH /2;
+ }
+ }
+
+ // back
+ sprite.setTextureRect(sf::IntRect(3 * width, doorType * height, width * 3, height));
+ sprite.setPosition(OFFSET_X + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, OFFSET_Y);
+ app->draw(sprite);
+
+ // door
+ sprite.setTextureRect(sf::IntRect(0.5f * width, doorType * height, width, height));
+ sprite.setPosition(xl, yl);
+ app->draw(sprite);
+
+ sprite.setTextureRect(sf::IntRect(1.5f * width, doorType * height, width, height));
+ sprite.setPosition(xr, yr);
+ app->draw(sprite);
+
+ // front
+ sprite.setTextureRect(sf::IntRect(6 * width, doorType * height, width * 3, height));
+ sprite.setPosition(OFFSET_X + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, OFFSET_Y);
+ app->draw(sprite);
+ }
+
+ if (direction == 4)
+ {
+ xl = OFFSET_X;
+ xr = OFFSET_X;
+ if (isOpen)
+ {
+ if (timer > 0.0f)
+ {
+ yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT / 2
+ - 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_HEIGHT / 2);
+ yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT / 2
+ + 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_HEIGHT / 2);
+ }
+ else
+ {
+ yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT * 1.2f;
+ yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT * 1.2f;
+ }
+ }
+ else
+ {
+
+ if (timer > 0.0f)
+ {
+ yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT / 2
+ - 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_HEIGHT / 2);
+ yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT / 2
+ + 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_HEIGHT / 2);
+ }
+ else
+ {
+ yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT /2;
+ yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT /2;
+ }
+ }
+
+ // back
+ sprite.setTextureRect(sf::IntRect(width + (3 * width * doorType), 2 * height, width , height* 3));
+ sprite.setPosition(OFFSET_X + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, OFFSET_Y);
+ sprite.setPosition(OFFSET_X, + (MAP_HEIGHT / 2 - 1) * TILE_HEIGHT + OFFSET_Y);
+ app->draw(sprite);
+
+
+ // door
+ sprite.setTextureRect(sf::IntRect( 3 * width * doorType, 2.5 * height, width, height));
+ sprite.setPosition(xl, yl);
+ app->draw(sprite);
+
+ sprite.setTextureRect(sf::IntRect( 3 * width * doorType, 3.5 * height, width, height));
+ sprite.setPosition(xr, yr);
+ app->draw(sprite);
+
+ // front
+ sprite.setTextureRect(sf::IntRect(2 * width + (3 * width * doorType), 2 * height, width , height* 3));
+ sprite.setPosition(OFFSET_X + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, OFFSET_Y);
+ sprite.setPosition(OFFSET_X, + (MAP_HEIGHT / 2 - 1) * TILE_HEIGHT + OFFSET_Y);
+ app->draw(sprite);
+ }
+
+ if (direction == 2)
+ {
+ sprite.setRotation(0.0f);
+
+ yl = OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 1);
+ yr = OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 1);
+ if (isOpen)
+ {
+ if (timer > 0.0f)
+ {
+ xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH / 2
+ - 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_WIDTH / 2);
+ xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH / 2
+ + 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_WIDTH / 2);
+ }
+ else
+ {
+ xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH * 1.2f;
+ xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH * 1.2f;
+ }
+ }
+ else
+ {
+ if (timer > 0.0f)
+ {
+ xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH / 2
+ - 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_WIDTH / 2);
+ xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH / 2
+ + 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_WIDTH / 2);
+ }
+ else
+ {
+ xl = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH - TILE_WIDTH /2;;
+ xr = OFFSET_X + (MAP_WIDTH / 2 ) * TILE_WIDTH + TILE_WIDTH /2;
+ }
+ }
+
+ // back
+ sprite.setTextureRect(sf::IntRect(3 * width, (1 + doorType) * height, width * 3, -height));
+ sprite.setPosition(OFFSET_X + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, yl);
+ app->draw(sprite);
+
+ // door
+ sprite.setTextureRect(sf::IntRect(0.5f * width, (1 + doorType) * height, width, -height));
+ sprite.setPosition(xl, yl);
+ app->draw(sprite);
+
+ sprite.setTextureRect(sf::IntRect(1.5f * width, (1 + doorType) * height, width, -height));
+ sprite.setPosition(xr, yr);
+ app->draw(sprite);
+
+ // front
+ sprite.setTextureRect(sf::IntRect(6 * width, (1 + doorType) * height, width * 3, -height));
+ sprite.setPosition(OFFSET_X + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, yl);
+ //sprite.setRotation(angle);
+ app->draw(sprite);
+ }
+
+ if (direction == 6)
+ {
+ xl = OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 1);
+ xr = OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 1);
+ if (isOpen)
+ {
+ if (timer > 0.0f)
+ {
+ yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT / 2
+ - 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_HEIGHT / 2);
+ yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT / 2
+ + 1.2f * ((1.0f - (timer / DOOR_OPEN_TIME)) * TILE_HEIGHT / 2);
+ }
+ else
+ {
+ yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT * 1.2f;
+ yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT * 1.2f;
+ }
+ }
+ else
+ {
+ if (timer > 0.0f)
+ {
+ yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT / 2
+ - 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_HEIGHT / 2);
+ yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT / 2
+ + 1.2f * ((timer / DOOR_OPEN_TIME) * TILE_HEIGHT / 2);
+ }
+ else
+ {
+ yl = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT - TILE_HEIGHT /2;
+ yr = OFFSET_Y + (MAP_HEIGHT / 2 ) * TILE_HEIGHT + TILE_HEIGHT /2;
+ }
+ }
+
+ // back
+ sprite.setTextureRect(sf::IntRect(width * 2 + (3 * width * doorType), 2 * height, -width , height* 3));
+ sprite.setPosition(xl + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, OFFSET_Y);
+ sprite.setPosition(xl, + (MAP_HEIGHT / 2 - 1) * TILE_HEIGHT + OFFSET_Y);
+ app->draw(sprite);
+
+
+ // door
+ sprite.setTextureRect(sf::IntRect(1 * width + (3 * width * doorType), 2.5 * height, -width, height));
+ sprite.setPosition(xl, yl);
+ app->draw(sprite);
+
+ sprite.setTextureRect(sf::IntRect(1* width + (3 * width * doorType), 3.5 * height, -width, height));
+ sprite.setPosition(xr, yr);
+ app->draw(sprite);
+
+ // front
+ sprite.setTextureRect(sf::IntRect(3 * width + (3 * width * doorType), 2 * height, -width , height* 3));
+ sprite.setPosition(xl + (MAP_WIDTH / 2 - 1) * TILE_WIDTH, OFFSET_Y);
+ sprite.setPosition(xl, + (MAP_HEIGHT / 2 - 1) * TILE_HEIGHT + OFFSET_Y);
+ app->draw(sprite);
+ }
+}
diff --git a/src/DoorEntity.h b/src/DoorEntity.h
new file mode 100644
index 0000000..0ac6bee
--- /dev/null
+++ b/src/DoorEntity.h
@@ -0,0 +1,24 @@
+#ifndef DOORENTITY_H
+#define DOORENTITY_H
+
+#include "sfml_game/SpriteEntity.h"
+
+class DoorEntity : public SpriteEntity
+{
+ public:
+ DoorEntity(int direction);
+ virtual void animate(float delay);
+ void render(sf::RenderWindow* app);
+
+ void setOpen(bool open);
+ void setDoorType(int doorType);
+ void closeDoor();
+ void openDoor();
+
+ private:
+ int direction;
+ bool isOpen;
+ float timer;
+ int doorType;
+};
+#endif // DOORENTITY_H
diff --git a/src/DungeonMap.cpp b/src/DungeonMap.cpp
new file mode 100644
index 0000000..8371ad5
--- /dev/null
+++ b/src/DungeonMap.cpp
@@ -0,0 +1,464 @@
+#include "DungeonMap.h"
+#include "GameFloor.h"
+#include "ItemEntity.h"
+#include "ChestEntity.h"
+#include "sfml_game/ImageManager.h"
+#include <cstdlib>
+#include <stdio.h>
+#include <iostream>
+
+DungeonMap::DungeonMap(int width, int height) : GameMap(width, height)
+{
+
+}
+
+DungeonMap::DungeonMap(GameFloor* gameFloor, int x, int y) : GameMap(MAP_WIDTH, MAP_HEIGHT)
+{
+ this->gameFloor = gameFloor;
+ this->x = x;
+ this->y = y;
+ cleared = false;
+ visited = false;
+ known = false;
+}
+
+DungeonMap::~DungeonMap()
+{
+ //dtor
+}
+
+bool DungeonMap::isVisited()
+{
+ return visited;
+}
+
+void DungeonMap::setVisited(bool b)
+{
+ visited = b;
+}
+
+bool DungeonMap::isKnown()
+{
+ return known;
+}
+
+void DungeonMap::setKnown(bool b)
+{
+ known = b;
+}
+
+bool DungeonMap::isCleared()
+{
+ return cleared;
+}
+
+void DungeonMap::setCleared(bool b)
+{
+ cleared = b;
+}
+
+roomTypeEnum DungeonMap::getRoomType()
+{
+ return roomType;
+}
+
+void DungeonMap::setRoomType(roomTypeEnum roomType)
+{
+ this->roomType = roomType;
+}
+
+void DungeonMap::displayToConsole()
+{
+ for (int j=0; j < MAP_HEIGHT; j++)
+ {
+ for (int i=0; i < MAP_WIDTH; i++)
+ {
+ printf("%d", map[i][j]);
+ }
+ printf("\n");
+ }
+ printf("\n");
+}
+
+bool DungeonMap::isDownBlocking(int x, int y)
+{
+ if (!inMap(x, y)) return false;
+ if (map[x][y] >= MAP_WALL) return true;
+ return false;
+}
+
+bool DungeonMap::isUpBlocking(int x, int y)
+{
+ if (!inMap(x, y)) return false;
+ if (map[x][y] >= MAP_WALL) return true;
+ return false;
+}
+
+bool DungeonMap::isLeftBlocking(int x, int y)
+{
+ if (!inMap(x, y)) return false;
+ if (map[x][y] >= MAP_WALL) return true;
+ return false;
+}
+
+bool DungeonMap::isRightBlocking(int x, int y)
+{
+ if (!inMap(x, y)) return false;
+ if (map[x][y] >= MAP_WALL) return true;
+ return false;
+}
+
+bool DungeonMap::isWalkable(int x, int y)
+{
+ return (map[x][y] < MAP_WALL);
+}
+
+void DungeonMap::randomize(int n)
+{
+ int i, j;
+ int x0 = MAP_WIDTH / 2;
+ int y0 = MAP_HEIGHT / 2;
+
+ initRoom();
+
+ // bonus
+ if (n == 5)
+ {
+ roomType = roomTypeBonus;
+ }
+ // others
+ else if (n > 0)
+ {
+ int r = rand() % 4;
+
+ if (r == 0) // corner blocks
+ {
+ map[1][1] = 4;
+ map[1][MAP_HEIGHT -2] = 4;
+ map[MAP_WIDTH - 2][1] = 4;
+ map[MAP_WIDTH - 2][MAP_HEIGHT -2] = 4;
+ }
+
+ else if (r == 1) // bloc in the middle
+ {
+ for (i = x0-1; i <= x0+1; i++)
+ for (j = y0-1; j <= y0+1; j++)
+ map[i][j] = 4;
+ }
+
+ else if (r == 2) // checker
+ {
+ for (i = 2; i < MAP_WIDTH - 2; i = i + 2)
+ for (j = 2; j < MAP_HEIGHT - 2; j = j + 2)
+ map[i][j] = 4;
+ }
+
+ cleared = false;
+ roomType = (roomTypeEnum)(rand() % 3);
+ }
+ else
+ {
+ cleared = true;
+ }
+}
+
+int DungeonMap::hasNeighbourLeft()
+{
+ if (x > 0 && gameFloor->getRoom(x-1, y) > 0)
+ {
+ if (gameFloor->getRoom(x-1, y) == roomTypeBoss) return 2;
+ else return 1;
+ }
+ return 0;
+}
+int DungeonMap::hasNeighbourRight()
+{
+ if (x < MAP_WIDTH -1 && gameFloor->getRoom(x+1, y) > 0)
+ {
+ if (gameFloor->getRoom(x+1, y) == roomTypeBoss) return 2;
+ else return 1;
+ }
+ return 0;
+}
+int DungeonMap::hasNeighbourUp()
+{
+ if (y > 0 && gameFloor->getRoom(x, y-1) > 0)
+ {
+ if (gameFloor->getRoom(x, y-1) == roomTypeBoss) return 2;
+ else return 1;
+ }
+ return 0;
+}
+int DungeonMap::hasNeighbourDown()
+{
+ if (y < MAP_HEIGHT -1 && gameFloor->getRoom(x, y+1) > 0)
+ {
+ if (gameFloor->getRoom(x, y+1) == roomTypeBoss) return 2;
+ else return 1;
+ }
+ return 0;
+}
+
+void DungeonMap::initRoom()
+{
+ int x0 = MAP_WIDTH / 2;
+ int y0 = MAP_HEIGHT / 2;
+ int i, j;
+
+ map[0][0] = MAP_WALL_7;
+ for ( i = 1 ; i < width -1 ; i++)
+ {
+ map[i][0] = MAP_WALL_8;
+ map[i][height - 1] = MAP_WALL_2;
+ }
+ map[width - 1][0] = MAP_WALL_9;
+ for ( int i = 1 ; i < height -1 ; i++)
+ {
+ map[0][i] = MAP_WALL_4;
+ map[width - 1][i] = MAP_WALL_6;
+ }
+ map[0][height - 1] = MAP_WALL_1;
+ map[width - 1][height - 1] = MAP_WALL_3;
+
+
+
+ for ( i = 1 ; i < width - 1 ; i++)
+ for ( j = 1 ; j < height - 1 ; j++)
+ {
+ map[i][j] = 0;
+ if (rand()%8 == 0) map[i][j] = rand()%(MAP_NORMAL_FLOOR + 1);
+ }
+
+ if (gameFloor != NULL)
+ {
+
+ if (x > 0 && gameFloor->getRoom(x-1, y) > 0)
+ {
+ //map[0][y0-1] = 0;
+ map[0][y0] = 0;
+ //map[0][y0+1] = 0;
+ }
+ if (x < MAP_WIDTH -1 && gameFloor->getRoom(x+1, y) > 0)
+ {
+ //map[MAP_WIDTH -1][y0-1] = 0;
+ map[MAP_WIDTH -1][y0] = 0;
+ //map[MAP_WIDTH -1][y0+1] = 0;
+ }
+ if (y > 0 && gameFloor->getRoom(x, y-1) > 0)
+ {
+ //map[x0-1][0] = 0;
+ map[x0][0] = 0;
+ //map[x0+1][0] = 0;
+ }
+ if (y < MAP_HEIGHT -1 && gameFloor->getRoom(x, y+1) > 0)
+ {
+ //map[x0-1][MAP_HEIGHT -1] = 0;
+ map[x0][MAP_HEIGHT -1] = 0;
+ //map[x0+1][MAP_HEIGHT -1] = 0;
+ }
+ }
+}
+
+Vector2D DungeonMap::generateBonusRoom()
+{
+ initRoom();
+ int x0 = MAP_WIDTH / 2;
+ int y0 = MAP_HEIGHT / 2;
+
+ map[x0 - 1][y0 - 1] = MAP_WALL;
+ map[x0 - 1][y0 + 1] = MAP_WALL;
+ map[x0 + 1][y0 - 1] = MAP_WALL;
+ map[x0 + 1][y0 + 1] = MAP_WALL;
+
+ return (Vector2D(OFFSET_X + x0 * TILE_WIDTH + TILE_WIDTH / 2, OFFSET_Y + y0 * TILE_HEIGHT + TILE_HEIGHT / 2));
+}
+
+void DungeonMap::generateCarpet(int x0, int y0, int w, int h, int n)
+{
+ int xf = x0 + w - 1;
+ int yf = y0 + h - 1;
+
+ map[x0][y0] = n;
+ map[x0][yf] = n + 6;
+ map[xf][y0] = n + 2;
+ map[xf][yf] = n + 8;
+
+ int i, j;
+ for (i = x0 + 1; i <= xf - 1; i++)
+ {
+ map[i][y0] = n + 1;
+ map[i][yf] = n + 7;
+ for (j = y0 + 1; j <= yf - 1; j++)
+ map[i][j] = n + 4;
+ }
+
+ for (j = y0 + 1; j <= yf - 1; j++)
+ {
+ map[x0][j] = n + 3;
+ map[xf][j] = n + 5;
+ }
+}
+
+Vector2D DungeonMap::generateMerchantRoom()
+{
+ initRoom();
+ int x0 = 3;
+ int y0 = 3;
+
+ generateCarpet(3, 3, 9, 3, 20);
+
+
+ return (Vector2D(OFFSET_X + x0 * TILE_WIDTH + TILE_WIDTH / 2, OFFSET_Y + y0 * TILE_HEIGHT + TILE_HEIGHT / 2));
+}
+
+Vector2D DungeonMap::generateKeyRoom()
+{
+ initRoom();
+ int x0 = MAP_WIDTH / 2;
+ int y0 = MAP_HEIGHT / 2;
+
+ for (int i = x0 - 1; i <= x0 + 1; i++)
+ for (int j = y0 - 1; j <= y0 + 1; j++)
+ map[i][j] = MAP_WALL;
+
+ map[x0][y0] = 0;
+ map[x0][y0+1] = MAP_DOOR;
+
+ return (Vector2D(OFFSET_X + x0 * TILE_WIDTH + TILE_WIDTH / 2, OFFSET_Y + y0 * TILE_HEIGHT + TILE_HEIGHT / 2));
+}
+
+void DungeonMap::generateRoom(int type)
+{
+ initRoom();
+ int x0 = MAP_WIDTH / 2;
+ int y0 = MAP_HEIGHT / 2;
+ int i, j, r;
+
+ if (type == 0)
+ {
+ if (roomType == roomTypeStarting)
+ generateCarpet(5, 3, 5, 3, 30);
+ }
+ if (type == 1)
+ {
+ // corner block
+ map[1][1] = MAP_WALL;
+ map[1][MAP_HEIGHT -2] = MAP_WALL;
+ map[MAP_WIDTH - 2][1] = MAP_WALL;
+ map[MAP_WIDTH - 2][MAP_HEIGHT -2] = MAP_WALL;
+ }
+ if (type == 2)
+ {
+ r = 1 + rand() % 3;
+ for (i = x0 - r; i <= x0 + r; i++)
+ for (j = y0 - 1; j <= y0 + 1; j++)
+ map[i][j] = MAP_WALL;
+ }
+}
+
+void DungeonMap::addItem(int itemType, float x, float y, bool merch)
+{
+ itemListElement ilm;
+ ilm.type = itemType;
+ ilm.x = x;
+ ilm.y = y;
+ ilm.merch = merch;
+ itemList.push_back(ilm);
+}
+
+void DungeonMap::addSprite(int spriteType, int frame, float x, float y, float scale)
+{
+ spriteListElement slm;
+ slm.type = spriteType;
+ slm.frame = frame;
+ slm.x = x;
+ slm.y = y;
+ slm.scale = scale;
+ spriteList.push_back(slm);
+}
+
+void DungeonMap::addChest(int chestType, bool state, float x, float y)
+{
+ chestListElement clm;
+ clm.type = chestType;
+ clm.state = state;
+ clm.x = x;
+ clm.y = y;
+ chestList.push_back(clm);
+}
+
+void DungeonMap::restoreItems()
+{
+ ItemList::iterator it;
+ for (it = itemList.begin (); it != itemList.end ();)
+ {
+ itemListElement ilm = *it;
+ it++;
+
+ ItemEntity* itemEntity = new ItemEntity((ItemEntity::enumItemType)(ilm.type), ilm.x, ilm.y);
+ itemEntity->setMap(this, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ itemEntity->setMerchandise(ilm.merch);
+ }
+ itemList.clear();
+}
+
+void DungeonMap::restoreSprites()
+{
+ SpriteList::iterator it;
+
+ for (it = spriteList.begin (); it != spriteList.end ();)
+ {
+ spriteListElement ilm = *it;
+ it++;
+
+ if (ilm.type == TYPE_BLOOD)
+ {
+ SpriteEntity* blood = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_BLOOD), ilm.x, ilm.y, 16, 16, 6);
+ blood->setZ(OFFSET_Y - 1);
+ blood->setFrame(ilm.frame);
+ blood->setType(TYPE_BLOOD);
+ blood->setScale(ilm.scale, ilm.scale);
+ }
+ else if (ilm.type == TYPE_CORPSE)
+ {
+ SpriteEntity* corpse;
+
+ if (ilm.frame >= FRAME_CORPSE_KING_RAT)
+ {
+ corpse = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES_BIG), ilm.x, ilm.y, 128, 128);
+ corpse->setFrame(ilm.frame - FRAME_CORPSE_KING_RAT);
+ }
+ else
+ {
+ corpse = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES), ilm.x, ilm.y, 64, 64);
+ corpse->setFrame(ilm.frame);
+ }
+
+ corpse->setZ(OFFSET_Y);
+ corpse->setType(TYPE_CORPSE);
+ }
+ }
+ spriteList.clear();
+}
+
+void DungeonMap::restoreChests()
+{
+ ChestList::iterator it;
+
+ for (it = chestList.begin (); it != chestList.end ();)
+ {
+ chestListElement clm = *it;
+ it++;
+
+ ChestEntity* chestEntity = new ChestEntity(clm.x, clm.y, clm.type, clm.state);
+ chestEntity->setMap(this, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ }
+ chestList.clear();
+}
+
+void DungeonMap::restoreMapObjects()
+{
+ restoreItems();
+ restoreSprites();
+ restoreChests();
+}
diff --git a/src/DungeonMap.h b/src/DungeonMap.h
new file mode 100644
index 0000000..95779ee
--- /dev/null
+++ b/src/DungeonMap.h
@@ -0,0 +1,102 @@
+#ifndef MAGICMAP_H
+#define MAGICMAP_H
+
+#include "sfml_game/GameMap.h"
+#include "sfml_game/MyTools.h"
+#include <list>
+
+const int MAP_NORMAL_FLOOR = 3;
+const int MAP_WALL = 50;
+const int MAP_DOOR = 51;
+const int MAP_WALL_7 = 52;
+const int MAP_WALL_8 = 53;
+const int MAP_WALL_9 = 54;
+const int MAP_WALL_4 = 55;
+const int MAP_WALL_6 = 56;
+const int MAP_WALL_1 = 57;
+const int MAP_WALL_2 = 58;
+const int MAP_WALL_3 = 59;
+
+
+class GameFloor;
+
+enum roomTypeEnum
+{
+ roomTypeStarting,
+ roomTypeStandard,
+ roomTypeBoss,
+ roomTypeMerchant,
+ roomTypeKey,
+ roomTypeBonus,
+ roomTypeExit
+};
+
+class DungeonMap : public GameMap
+{
+ public:
+ DungeonMap(int width, int height);
+ DungeonMap(GameFloor* gameFloor, int x, int y);
+ virtual ~DungeonMap();
+ void displayToConsole();
+ bool isVisited();
+ void setVisited(bool b);
+ bool isKnown();
+ void setKnown(bool b);
+ bool isCleared();
+ void setCleared(bool b);
+ bool isWalkable(int x, int y);
+
+ // 0 == no, 1 == yes, 2 == boss
+ int hasNeighbourLeft();
+ int hasNeighbourRight();
+ int hasNeighbourUp();
+ int hasNeighbourDown();
+
+ virtual bool isDownBlocking(int x, int y);
+ virtual bool isUpBlocking(int x, int y);
+ virtual bool isLeftBlocking(int x, int y);
+ virtual bool isRightBlocking(int x, int y);
+
+ virtual void randomize(int n);
+ void initRoom();
+ void generateCarpet(int x0, int y0, int w, int h, int n);
+ void generateRoom(int type);
+ Vector2D generateBonusRoom();
+ Vector2D generateMerchantRoom();
+ Vector2D generateKeyRoom();
+
+ void addItem(int itemType, float x, float y, bool merch);
+ void addSprite(int spriteType, int frame, float x, float y, float scale);
+ void addChest(int chestType, bool state, float x, float y);
+ void restoreItems();
+ void restoreSprites();
+ void restoreChests();
+ void restoreMapObjects();
+
+ roomTypeEnum getRoomType();
+ void setRoomType(roomTypeEnum roomType);
+
+ struct itemListElement { int type; float x; float y; bool merch; };
+ typedef std::list<itemListElement> ItemList;
+
+ struct spriteListElement { int type; int frame; float x; float y; float scale;};
+ typedef std::list<spriteListElement> SpriteList;
+
+ struct chestListElement { int type; bool state; float x; float y;};
+ typedef std::list<chestListElement> ChestList;
+
+ protected:
+ private:
+ GameFloor* gameFloor;
+ int x, y;
+ bool visited;
+ bool known;
+ bool cleared;
+
+ roomTypeEnum roomType;
+ ItemList itemList;
+ SpriteList spriteList;
+ ChestList chestList;
+};
+
+#endif // MAGICMAP_H
diff --git a/src/EnnemyBoltEntity.cpp b/src/EnnemyBoltEntity.cpp
new file mode 100644
index 0000000..4615847
--- /dev/null
+++ b/src/EnnemyBoltEntity.cpp
@@ -0,0 +1,114 @@
+#include "EnnemyBoltEntity.h"
+#include "Constants.h"
+#include "sfml_game/ImageManager.h"
+
+EnnemyBoltEntity::EnnemyBoltEntity(sf::Texture* image, float x = 0.0f, float y = 0.0f) : CollidingSpriteEntity (image, x, y, BOLT_WIDTH, BOLT_HEIGHT)
+{
+ //lifetime = INITIAL_BOLT_LIFE;
+ damages = INITIAL_BOLT_DAMAGES;
+ type = 19;
+ //viscosity = 0.97f;
+ frame = 1;
+}
+
+int EnnemyBoltEntity::getDamages()
+{
+ return damages;
+}
+
+void EnnemyBoltEntity::setDamages(int damages)
+{
+ this->damages = damages;
+}
+
+void EnnemyBoltEntity::animate(float delay)
+{
+ SpriteEntity* trace = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_BOLT), x, y, BOLT_WIDTH, BOLT_HEIGHT);
+ trace->setFading(true);
+ trace->setZ(y);
+ trace->setLifetime(0.2f);
+ trace->setShrinking(true);
+ trace->setFrame(frame);
+ trace->setType(16);
+
+ z = y + height;
+ CollidingSpriteEntity::animate(delay);
+
+ if ( (lifetime - age) < 0.2f)
+ {
+ if (age >= lifetime)
+ sprite.setColor(sf::Color(255, 255, 255, 0));
+ else
+ sprite.setColor(sf::Color(255, 255, 255, (sf::Uint8)((lifetime - age) / 0.2f * 255)));
+ }
+}
+
+void EnnemyBoltEntity::collide()
+{
+ isDying = true;
+}
+
+void EnnemyBoltEntity::generateParticule(Vector2D vel)
+{
+ SpriteEntity* trace = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_BOLT), x, y, BOLT_WIDTH, BOLT_HEIGHT);
+ trace->setFading(true);
+ trace->setZ(y);
+ trace->setLifetime(0.5f);
+ trace->setScale(0.3f, 0.3f);
+ trace->setVelocity(vel);
+ trace->setViscosity(0.97f);
+ trace->setFrame(frame);
+ trace->setType(16);
+}
+
+void EnnemyBoltEntity::collideMapRight()
+{
+ velocity.x = 0.0f;
+ isDying = true;
+
+ for (int i=0; i<5; i++)
+ {
+ Vector2D vel(100.0f + rand() % 150);
+ if (vel.x > 0.0f) vel.x = - vel.x;
+ generateParticule(vel);
+ }
+}
+
+void EnnemyBoltEntity::collideMapLeft()
+{
+ velocity.x = 0.0f;
+ isDying = true;
+
+ for (int i=0; i<5; i++)
+ {
+ Vector2D vel(100.0f + rand() % 150);
+ if (vel.x < 0.0f) vel.x = - vel.x;
+ generateParticule(vel);
+ }
+}
+
+void EnnemyBoltEntity::collideMapTop()
+{
+ velocity.y = 0.0f;
+ isDying = true;
+
+ for (int i=0; i<5; i++)
+ {
+ Vector2D vel(100.0f + rand() % 150);
+ if (vel.y < 0.0f) vel.y = - vel.y;
+ generateParticule(vel);
+ }
+}
+
+void EnnemyBoltEntity::collideMapBottom()
+{
+ velocity.y = 0.0f;
+ isDying = true;
+
+ for (int i=0; i<5; i++)
+ {
+ Vector2D vel(100.0f + rand() % 150);
+ if (vel.y > 0.0f) vel.y = - vel.y;
+ generateParticule(vel);
+ }
+}
diff --git a/src/EnnemyBoltEntity.h b/src/EnnemyBoltEntity.h
new file mode 100644
index 0000000..85aa57f
--- /dev/null
+++ b/src/EnnemyBoltEntity.h
@@ -0,0 +1,27 @@
+#ifndef ENNEMYBOLTENTITY_H
+#define ENNEMYBOLTENTITY_H
+
+#include "sfml_game/CollidingSpriteEntity.h"
+
+class EnnemyBoltEntity : public CollidingSpriteEntity
+{
+ public:
+ EnnemyBoltEntity(sf::Texture* image, float x, float y);
+ virtual void animate(float delay);
+ void collide();
+ void generateParticule(Vector2D vel);
+
+ int getDamages();
+ void setDamages(int damages);
+
+ protected:
+ virtual void collideMapRight();
+ virtual void collideMapLeft();
+ virtual void collideMapTop();
+ virtual void collideMapBottom();
+
+ int damages;
+ private:
+};
+
+#endif // ENNEMYBOLTENTITY_H
diff --git a/src/EnnemyEntity.cpp b/src/EnnemyEntity.cpp
new file mode 100644
index 0000000..58879b1
--- /dev/null
+++ b/src/EnnemyEntity.cpp
@@ -0,0 +1,108 @@
+#include "EnnemyEntity.h"
+#include "BoltEntity.h"
+#include "PlayerEntity.h"
+#include "sfml_game/SpriteEntity.h"
+#include "sfml_game/ImageManager.h"
+#include "sfml_game/SoundManager.h"
+#include "Constants.h"
+#include <iostream>
+#include "WitchBlastGame.h"
+
+EnnemyEntity::EnnemyEntity(sf::Texture* image, float x, float y, GameMap* map)
+ : BaseCreatureEntity (image, x, y, 64, 64)
+{
+ type = 21;
+ bloodColor = bloodRed;
+ setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+
+ z = y;
+ age = -0.001f * (rand()%800) - 0.4f;
+}
+
+void EnnemyEntity::animate(float delay)
+{
+ testSpriteCollisions();
+ if (age > 0.0f)
+ BaseCreatureEntity::animate(delay);
+ else
+ age += delay;
+}
+
+void EnnemyEntity::calculateBB()
+{
+ boundingBox.left = (int)x - width / 2;
+ boundingBox.width = width;
+ boundingBox.top = (int)y - height / 2;
+ boundingBox.height = height;
+}
+
+void EnnemyEntity::collideMapRight()
+{
+ velocity.x = 0.0f;
+}
+
+void EnnemyEntity::collideMapLeft()
+{
+ velocity.x = 0.0f;
+}
+
+void EnnemyEntity::collideMapTop()
+{
+ velocity.y = 0.0f;
+}
+
+void EnnemyEntity::collideMapBottom()
+{
+ velocity.y = 0.0f;
+}
+
+void EnnemyEntity::readCollidingEntity(CollidingSpriteEntity* entity)
+{
+
+ PlayerEntity* playerEntity = dynamic_cast<PlayerEntity*>(entity);
+ BoltEntity* boltEntity = dynamic_cast<BoltEntity*>(entity);
+ //if (playerEntity == NULL && boltEntity) return;
+
+ if (collideWithEntity(entity))
+ {
+ if (playerEntity != NULL && !playerEntity->isDead())
+ playerEntity->hurt(meleeDamages);
+ else if (boltEntity != NULL && !boltEntity->getDying() && boltEntity->getAge() > 0.05f)
+ {
+ boltEntity->collide();
+ hurt(boltEntity->getDamages());
+ parentGame->generateBlood(x, y, bloodColor);
+ SoundManager::getSoundManager()->playSound(SOUND_IMPACT);
+
+ float xs = (x + boltEntity->getX()) / 2;
+ float ys = (y + boltEntity->getY()) / 2;
+ SpriteEntity* star = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_STAR_2), xs, ys);
+ star->setFading(true);
+ star->setZ(y+ 100);
+ star->setLifetime(0.7f);
+ star->setType(16);
+ star->setSpin(400.0f);
+ }
+ }
+}
+
+void EnnemyEntity::dying()
+{
+ isDying = true;
+ SpriteEntity* deadRat = new SpriteEntity(ImageManager::getImageManager()->getImage(3), x, y, 64, 64);
+ //deadRat->setZ(y + height);
+ deadRat->setZ(OFFSET_Y);
+ deadRat->setFrame(2);
+ deadRat->setType(13);
+}
+
+void EnnemyEntity::drop()
+{
+ if (rand() % 5 == 0)
+ {
+ ItemEntity* newItem = new ItemEntity(ItemEntity::itemCopperCoin, x, y);
+ newItem->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ newItem->setVelocity(Vector2D(100.0f + rand()% 250));
+ newItem->setViscosity(0.96f);
+ }
+}
diff --git a/src/EnnemyEntity.h b/src/EnnemyEntity.h
new file mode 100644
index 0000000..873c91e
--- /dev/null
+++ b/src/EnnemyEntity.h
@@ -0,0 +1,27 @@
+#ifndef ENNEMYPRITE_H
+#define ENNEMYPRITE_H
+
+#include "BaseCreatureEntity.h"
+
+class EnnemyEntity : public BaseCreatureEntity
+{
+ public:
+ EnnemyEntity(sf::Texture* image, float x, float y, GameMap* map);
+ virtual void animate(float delay);
+ virtual void calculateBB();
+ protected:
+ virtual void collideMapRight();
+ virtual void collideMapLeft();
+ virtual void collideMapTop();
+ virtual void collideMapBottom();
+
+ virtual void readCollidingEntity(CollidingSpriteEntity* entity);
+ virtual void dying();
+ virtual void drop();
+
+ int meleeDamages;
+ private:
+
+};
+
+#endif // ENNEMYPRITE_H
diff --git a/src/EvilFlowerEntity.cpp b/src/EvilFlowerEntity.cpp
new file mode 100644
index 0000000..c81e0c5
--- /dev/null
+++ b/src/EvilFlowerEntity.cpp
@@ -0,0 +1,107 @@
+#include "EvilFlowerEntity.h"
+#include "BoltEntity.h"
+#include "EnnemyBoltEntity.h"
+#include "PlayerEntity.h"
+#include "sfml_game/SpriteEntity.h"
+#include "sfml_game/ImageManager.h"
+#include "sfml_game/SoundManager.h"
+#include "Constants.h"
+#include "WitchBlastGame.h"
+#include <math.h>
+
+EvilFlowerEntity::EvilFlowerEntity(float x, float y, GameMap* map, PlayerEntity* player)
+ : EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_FLOWER), x, y, map)
+{
+ hp = EVIL_FLOWER_HP;
+ meleeDamages = EVIL_FLOWER_MELEE_DAMAGES;
+
+ setSpin(50.0f);
+ frame = 0;
+
+ type = 23;
+ bloodColor = bloodGreen;
+ //shadowFrame = 2;
+
+ fireDelay = EVIL_FLOWER_FIRE_DELAY;
+ this->player = player;
+ age = -1.0f + (rand() % 2500) * 0.001f;
+}
+
+void EvilFlowerEntity::animate(float delay)
+{
+ if (fireDelay < 0.7f) setSpin(500.0f);
+ else if (fireDelay < 1.4f) setSpin(120.0f);
+ else setSpin(50.0f);
+
+ testSpriteCollisions();
+ EnnemyEntity::animate(delay);
+ angle += spin * delay;
+
+ if (age > 0.0f)
+ {
+ fireDelay -= delay;
+ if (fireDelay <= 0.0f)
+ {
+ fireDelay = EVIL_FLOWER_FIRE_DELAY;
+ fire();
+ }
+ }
+}
+
+void EvilFlowerEntity::calculateBB()
+{
+ boundingBox.left = (int)x - width / 2 + EVIL_FLOWER_BB_LEFT;
+ boundingBox.width = width - EVIL_FLOWER_BB_WIDTH_DIFF;
+ boundingBox.top = (int)y - height / 2 + EVIL_FLOWER_BB_TOP;
+ boundingBox.height = height - EVIL_FLOWER_BB_HEIGHT_DIFF;
+}
+
+void EvilFlowerEntity::dying()
+{
+ isDying = true;
+ SpriteEntity* deadFlower = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES), x, y, 64, 64);
+ deadFlower->setZ(OFFSET_Y);
+ deadFlower->setFrame(FRAME_CORPSE_FLOWER);
+ deadFlower->setType(TYPE_CORPSE);
+
+ for (int i = 0; i < 4; i++) parentGame->generateBlood(x, y, bloodColor);
+ drop();
+ SoundManager::getSoundManager()->playSound(SOUND_ENNEMY_DYING);
+}
+
+void EvilFlowerEntity::fire()
+{
+ SoundManager::getSoundManager()->playSound(SOUND_BLAST_FLOWER);
+ EnnemyBoltEntity* bolt = new EnnemyBoltEntity
+ (ImageManager::getImageManager()->getImage(IMAGE_BOLT), x, y + 10);
+ bolt->setFrame(1);
+ bolt->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+
+ bolt->setVelocity(Vector2D(200.0f, 0.0f));
+
+ float tan = (player->getX() - x) / (player->getY() - y);
+ float angle = atan(tan);
+
+ if (player->getY() > y)
+ bolt->setVelocity(Vector2D(sin(angle) * EVIL_FLOWER_FIRE_VELOCITY,
+ cos(angle) * EVIL_FLOWER_FIRE_VELOCITY));
+ else
+ bolt->setVelocity(Vector2D(-sin(angle) * EVIL_FLOWER_FIRE_VELOCITY,
+ -cos(angle) * EVIL_FLOWER_FIRE_VELOCITY));
+}
+
+void EvilFlowerEntity::render(sf::RenderWindow* app)
+{
+ sprite.setPosition(x, y);
+ float savedAngle = sprite.getRotation();
+ sprite.setRotation(0.0f);
+
+ // shadow
+ sprite.setTextureRect(sf::IntRect(width * 2, 0, width, height));
+ app->draw(sprite);
+ sprite.setTextureRect(sf::IntRect(width, 0, width, height));
+ app->draw(sprite);
+
+ sprite.setRotation(savedAngle);
+ EnnemyEntity::render(app);
+}
diff --git a/src/EvilFlowerEntity.h b/src/EvilFlowerEntity.h
new file mode 100644
index 0000000..d70e37c
--- /dev/null
+++ b/src/EvilFlowerEntity.h
@@ -0,0 +1,22 @@
+#ifndef EVILFLOWER_H
+#define EVILFLOWER_H
+
+#include "EnnemyEntity.h"
+#include "PlayerEntity.h"
+
+class EvilFlowerEntity : public EnnemyEntity
+{
+ public:
+ EvilFlowerEntity(float x, float y, GameMap* map, PlayerEntity* player);
+ virtual void animate(float delay);
+ virtual void calculateBB();
+ virtual void render(sf::RenderWindow* app);
+ void fire();
+ protected:
+ virtual void dying();
+ private:
+ float fireDelay;
+ PlayerEntity* player;
+};
+
+#endif // EVILFLOWER_H
diff --git a/src/FairyEntity.cpp b/src/FairyEntity.cpp
new file mode 100644
index 0000000..5c8bf33
--- /dev/null
+++ b/src/FairyEntity.cpp
@@ -0,0 +1,79 @@
+#include "FairyEntity.h"
+#include "BoltEntity.h"
+#include "Constants.h"
+#include "sfml_game/ImageManager.h"
+#include "sfml_game/SoundManager.h"
+#include <iostream>
+
+FairyEntity::FairyEntity(float x, float y, PlayerEntity* parentEntity) : SpriteEntity (ImageManager::getImageManager()->getImage(IMAGE_FAIRY), x, y, 48, 72)
+{
+ this->x = x;
+ this->y = y;
+
+ this->setFrame(0);
+ this->parentEntity = parentEntity;
+
+ type = 2;
+ //viscosity = 0.99f;
+
+ fireDelay = -1.0f;
+}
+
+
+void FairyEntity::animate(float delay)
+{
+ z = y + height;
+
+ if (fireDelay > 0) fireDelay -= delay;
+
+ frame = ((int)(age * 10.0f)) % 2;
+
+ float dist2 = (x - parentEntity->getX()) * (x - parentEntity->getX()) + (y - parentEntity->getY()) * (y - parentEntity->getY());
+
+ if (dist2 > 15000.0f)
+ {
+ float tan = (parentEntity->getX() - x) / (parentEntity->getY() - y);
+ float angle = atan(tan);
+
+ if (parentEntity->getY() > y)
+ setVelocity(Vector2D(sin(angle) * FAIRY_SPEED, cos(angle) * FAIRY_SPEED));
+ else
+ setVelocity(Vector2D(-sin(angle) * FAIRY_SPEED, -cos(angle) * FAIRY_SPEED));
+
+ viscosity = 1.0f;
+
+ /*velocity.x = 2 * (parentEntity->getX() - x);
+ velocity.y = 2 * (parentEntity->getY() - y);*/
+ }
+ else if (dist2 < 50000.0f)
+ {
+ viscosity = 0.96f;
+ }
+
+ // x = parentEntity->getX() + 50;
+ // y = parentEntity->getY() - 20;
+
+ SpriteEntity::animate(delay);
+}
+
+void FairyEntity::fire(int dir, GameMap* map)
+{
+ if (fireDelay <= 0.0f)
+ {
+ SoundManager::getSoundManager()->playSound(SOUND_BLAST_STANDARD);
+ fireDelay = FAIRY_FIRE_DELAY;
+
+ float velx = 0.0f;
+ float vely = 0.0f;
+
+ if (dir == 4) velx = - FAIRY_BOLT_VELOCITY;
+ if (dir == 6) velx = + FAIRY_BOLT_VELOCITY;
+ if (dir == 2) vely = + FAIRY_BOLT_VELOCITY;
+ if (dir == 8) vely = - FAIRY_BOLT_VELOCITY;
+
+ BoltEntity* bolt = new BoltEntity(ImageManager::getImageManager()->getImage(IMAGE_BOLT), x, y, FAIRY_BOLT_LIFE);
+ bolt->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ bolt->setDamages(FAIRY_BOLT_DAMAGES);
+ bolt->setVelocity(Vector2D(velx, vely));
+ }
+}
diff --git a/src/FairyEntity.h b/src/FairyEntity.h
new file mode 100644
index 0000000..d51eae7
--- /dev/null
+++ b/src/FairyEntity.h
@@ -0,0 +1,22 @@
+#ifndef FAIRYENTITY_H
+#define FAIRYENTITY_H
+
+#include "sfml_game/SpriteEntity.h"
+#include "PlayerEntity.h"
+#include "sfml_game/GameMap.h"
+
+class FairyEntity : public SpriteEntity
+{
+ public:
+ FairyEntity(float x, float y, PlayerEntity* parentEntity);
+ virtual void animate(float delay);
+
+ void fire(int dir, GameMap* map);
+
+ protected:
+
+ private:
+ PlayerEntity* parentEntity;
+ float fireDelay;
+};
+#endif // MAGNETENTITY_H
diff --git a/src/GameFloor.cpp b/src/GameFloor.cpp
new file mode 100644
index 0000000..2edcd50
--- /dev/null
+++ b/src/GameFloor.cpp
@@ -0,0 +1,261 @@
+#include "GameFloor.h"
+#include <time.h>
+#include <cstdlib>
+#include <stdio.h>
+#include <iostream>
+
+GameFloor::GameFloor(int level)
+{
+ this->level = level;
+ srand(time(NULL));
+ createFloor();
+}
+
+GameFloor::~GameFloor()
+{
+ //dtor
+}
+
+int GameFloor::getRoom(int x, int y)
+{
+ if (x < 0 || y < 0 || x >= FLOOR_WIDTH || y >= FLOOR_HEIGHT) return 0;
+ return floor[x][y];
+}
+
+DungeonMap* GameFloor::getMap(int x, int y)
+{
+ if (x < 0 || y < 0 || x >= FLOOR_WIDTH || y >= FLOOR_HEIGHT) return NULL;
+ return maps[x][y];
+}
+
+DungeonMap* GameFloor::getAndVisitMap(int x, int y)
+{
+ maps[x][y]->setVisited(true);
+
+ if (x > 0 && floor[x-1][y] > 0) maps[x-1][y]->setKnown(true);
+ if (x < FLOOR_WIDTH - 1 && floor[x+1][y] > 0) maps[x+1][y]->setKnown(true);;
+ if (y > 0 && floor[x][y-1] > 0) maps[x][y-1]->setKnown(true);;
+ if (y < FLOOR_HEIGHT - 1 && floor[x][y+1] > 0) maps[x][y+1]->setKnown(true);;
+
+ return maps[x][y];
+}
+
+void GameFloor::displayToConsole()
+{
+ for (int j=0; j < FLOOR_HEIGHT; j++)
+ {
+ for (int i=0; i < FLOOR_WIDTH; i++)
+ {
+ switch (floor[i][j])
+ {
+ case 0: printf("."); break;
+ case 1: printf("#"); break;
+ case 2: printf("&"); break;
+ case 3: printf("$"); break;
+ case 4: printf("!"); break;
+ case 5: printf("*"); break;
+ case 6: printf("X"); break;
+ }
+ }
+ printf("\n");
+ }
+}
+
+int GameFloor::neighboorCount(int x, int y)
+{
+ int count = 0;
+ if (x > 0 && floor[x-1][y] > 0) count++;
+ if (x < FLOOR_WIDTH - 1 && floor[x+1][y] > 0) count++;
+ if (y > 0 && floor[x][y-1] > 0) count++;
+ if (y < FLOOR_HEIGHT - 1 && floor[x][y+1] > 0) count++;
+ return count;
+}
+
+bool GameFloor::isSuperIsolated(int x, int y)
+{
+ if (neighboorCount(x, y) != 1) return false;
+ else
+ {
+ if (x > 0 && floor[x-1][y]==1 && neighboorCount(x-1, y) == 2)
+ {
+ floor[x-1][y] = roomTypeBoss;
+ floor[x][y] = roomTypeExit;
+ return true;
+ }
+ else if (x < FLOOR_WIDTH - 1 && floor[x+1][y]==1 && neighboorCount(x+1, y) == 2)
+ {
+ floor[x+1][y] = roomTypeBoss;
+ floor[x][y] = roomTypeExit;
+ return true;
+ }
+ else if (y > 0 && floor[x][y-1]==1 && neighboorCount(x, y-1) == 2)
+ {
+ floor[x][y-1] = roomTypeBoss;
+ floor[x][y] = roomTypeExit;
+ return true;
+ }
+ else if (y < FLOOR_HEIGHT - 1 && floor[x][y+1]==1 && neighboorCount(x, y+1) == 2)
+ {
+ floor[x][y+1] = roomTypeBoss;
+ floor[x][y] = roomTypeExit;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool GameFloor::finalize()
+{
+ bool bKey = false;
+ bool bBonus = false;
+ bool bMerchant = false;
+ bool bExit = false;
+
+ for (int i=0; i < FLOOR_WIDTH; i++)
+ for (int j=0; j < FLOOR_HEIGHT; j++)
+ {
+ if (floor[i][j] == 1 && neighboorCount(i, j) == roomTypeStandard)
+ {
+ if (!bExit && isSuperIsolated(i, j))
+ {
+ bExit = true;
+ }
+ else
+ {
+ if (!bKey)
+ {
+ floor[i][j]= roomTypeKey;
+ bKey = true;
+ }
+ else if (!bBonus)
+ {
+ floor[i][j]= roomTypeBonus;
+ bBonus = true;
+ }
+ else if (!bMerchant)
+ {
+ floor[i][j]= roomTypeMerchant;
+ bMerchant = true;
+ }
+ }
+ }
+ }
+
+ return bExit && bKey && bBonus;
+}
+
+void GameFloor::createFloor()
+{
+ bool ok=false;
+ while (!ok)
+ {
+ generate();
+ ok = finalize();
+
+ int x0 = FLOOR_WIDTH / 2;
+ int y0 = FLOOR_HEIGHT / 2;
+
+ // Maps
+ for (int i=0; i < FLOOR_WIDTH; i++)
+ for (int j=0; j < FLOOR_HEIGHT; j++)
+ if (floor[i][j] > 0)
+ {
+ maps[i][j] = new DungeonMap(this, i, j);
+ if (i == x0 && j == y0)
+ //maps[i][j]->randomize(0);
+ maps[i][j]->setRoomType(roomTypeStarting);
+ else
+ //maps[i][j]->randomize(floor[i][j]);
+ maps[i][j]->setRoomType((roomTypeEnum)(floor[i][j]));
+ }
+
+ displayToConsole();
+ }
+}
+
+void GameFloor::generate()
+{
+ int i, j;
+ int nbRooms;
+ int requiredRoms = 15;
+ // Init
+ for (i=0; i < FLOOR_WIDTH; i++)
+ for (j=0; j < FLOOR_HEIGHT; j++)
+ {
+ floor[i][j] = 0;
+ //if (maps[i][j] != NULL) delete maps[i][j];
+ }
+
+
+ // First room
+ int x0 = FLOOR_WIDTH / 2;
+ int y0 = FLOOR_HEIGHT / 2;
+ floor[x0][y0] = 1;
+ nbRooms = 1;
+
+ // neighboor
+ while (nbRooms == 1)
+ {
+ if (rand() % 3 == 0)
+ {
+ floor[x0-1][y0] = 1;
+ nbRooms++;
+ }
+ if (rand() % 3 == 0)
+ {
+ floor[x0+1][y0] = 1;
+ nbRooms++;
+ }
+ if (rand() % 3 == 0)
+ {
+ floor[x0][y0-1] = 1;
+ nbRooms++;
+ }
+ if (rand() % 3 == 0)
+ {
+ floor[x0][y0+1] = 1;
+ nbRooms++;
+ }
+ }
+
+ // others
+ while (nbRooms < requiredRoms)
+ for (int k = 0; k < 8; k++)
+ {
+ i = rand() % FLOOR_WIDTH;
+ j = rand() % FLOOR_HEIGHT;
+ if (floor[i][j] == 0)
+ {
+ int n = neighboorCount(i, j);
+ switch (n)
+ {
+ case 1:
+ {
+ floor[i][j] = 1;
+ nbRooms++;
+ break;
+ }
+ case 2:
+ {
+ if (rand()% 5 == 0)
+ {
+ floor[i][j] = 1;
+ nbRooms++;
+ }
+ break;
+ }
+ case 3:
+ {
+ if (rand()% 20 == 0)
+ {
+ floor[i][j] = 1;
+ nbRooms++;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+
+}
diff --git a/src/GameFloor.h b/src/GameFloor.h
new file mode 100644
index 0000000..a26e99d
--- /dev/null
+++ b/src/GameFloor.h
@@ -0,0 +1,30 @@
+#ifndef GAMEFLOOR_H
+#define GAMEFLOOR_H
+
+#include "constants.h"
+#include "DungeonMap.h"
+
+class GameFloor
+{
+ public:
+ GameFloor(int level);
+ virtual ~GameFloor();
+ void createFloor();
+ void displayToConsole();
+ int getRoom(int x, int y);
+ DungeonMap* getMap(int x, int y);
+ DungeonMap* getAndVisitMap(int x, int y);
+ protected:
+ private:
+ int level;
+ int floor[FLOOR_WIDTH][FLOOR_HEIGHT];
+
+ int neighboorCount(int x, int y);
+ bool isSuperIsolated(int x, int y);
+ void generate();
+ bool finalize();
+
+ DungeonMap* maps[FLOOR_WIDTH][FLOOR_HEIGHT];
+};
+
+#endif // GAMEFLOOR_H
diff --git a/src/GreenRatEntity.cpp b/src/GreenRatEntity.cpp
new file mode 100644
index 0000000..024c4d4
--- /dev/null
+++ b/src/GreenRatEntity.cpp
@@ -0,0 +1,103 @@
+#include "GreenRatEntity.h"
+#include "BoltEntity.h"
+#include "PlayerEntity.h"
+#include "sfml_game/SpriteEntity.h"
+#include "sfml_game/ImageManager.h"
+#include "sfml_game/SoundManager.h"
+#include "Constants.h"
+#include "WitchBlastGame.h"
+
+GreenRatEntity::GreenRatEntity(float x, float y, GameMap* map, PlayerEntity* player)
+ : EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_RAT), x, y, map)
+{
+ imagesProLine = 4;
+ creatureSpeed = GREEN_RAT_SPEED;
+ velocity = Vector2D(creatureSpeed);
+ hp = GREEN_RAT_HP;
+ meleeDamages = GREEN_RAT_DAMAGES;
+
+ type = 21;
+ bloodColor = bloodRed;
+ shadowFrame = 3;
+
+ timer = (rand() % 50) / 10.0f;
+ age = -GREEN_RAT_FADE;
+ frame = 4;
+ this->player = player;
+}
+
+void GreenRatEntity::animate(float delay)
+{
+ z = y + boundingBox.top + boundingBox.height;
+
+ if (age > 0.0f)
+ {
+ sprite.setColor(sf::Color(255,255,255,255));
+ frame = 4 + ((int)(age * 5.0f)) % 2;
+ timer = timer - delay;
+ if (timer <= 0.0f)
+ {
+ timer = (rand() % 50) / 10.0f;
+ float tan = (player->getX() - x) / (player->getY() - y);
+ float angle = atan(tan);
+
+ if (player->getY() > y)
+ setVelocity(Vector2D(sin(angle) * RAT_SPEED,
+ cos(angle) * RAT_SPEED));
+ else
+ setVelocity(Vector2D(-sin(angle) * RAT_SPEED,
+ -cos(angle) * RAT_SPEED));
+ }
+ }
+ else
+ {
+ sprite.setColor(sf::Color(255,255,255,255 * (1.0 + age)));
+ }
+
+
+
+ testSpriteCollisions();
+ EnnemyEntity::animate(delay);
+}
+
+void GreenRatEntity::calculateBB()
+{
+ boundingBox.left = (int)x - width / 2 + RAT_BB_LEFT;
+ boundingBox.width = width - RAT_BB_WIDTH_DIFF;
+ boundingBox.top = (int)y - height / 2 + RAT_BB_TOP;
+ boundingBox.height = height - RAT_BB_HEIGHT_DIFF;
+}
+
+void GreenRatEntity::collideMapRight()
+{
+ velocity.x = -velocity.x;
+}
+
+void GreenRatEntity::collideMapLeft()
+{
+ velocity.x = -velocity.x;
+}
+
+void GreenRatEntity::collideMapTop()
+{
+ velocity.y = -velocity.y;
+}
+
+void GreenRatEntity::collideMapBottom()
+{
+ velocity.y = -velocity.y;
+}
+
+
+void GreenRatEntity::dying()
+{
+ isDying = true;
+ SpriteEntity* deadRat = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES), x, y, 64, 64);
+ deadRat->setZ(OFFSET_Y);
+ deadRat->setFrame(FRAME_CORPSE_GREEN_RAT);
+ deadRat->setType(TYPE_CORPSE);
+
+ for (int i = 0; i < 4; i++) parentGame->generateBlood(x, y, bloodColor);
+ //drop();
+ SoundManager::getSoundManager()->playSound(SOUND_ENNEMY_DYING);
+}
diff --git a/src/GreenRatEntity.h b/src/GreenRatEntity.h
new file mode 100644
index 0000000..572fd8f
--- /dev/null
+++ b/src/GreenRatEntity.h
@@ -0,0 +1,26 @@
+#ifndef GREENRATSPRITE_H
+#define GREENRATSPRITE_H
+
+#include "EnnemyEntity.h"
+#include "PlayerEntity.h"
+
+class GreenRatEntity : public EnnemyEntity
+{
+ public:
+ GreenRatEntity(float x, float y, GameMap* map, PlayerEntity* player);
+ virtual void animate(float delay);
+ virtual void calculateBB();
+ protected:
+ virtual void collideMapRight();
+ virtual void collideMapLeft();
+ virtual void collideMapTop();
+ virtual void collideMapBottom();
+
+ //virtual void readCollidingEntity(CollidingSpriteEntity* entity);
+ virtual void dying();
+ private:
+ float timer;
+ PlayerEntity* player;
+};
+
+#endif // GREENRATSPRITE_H
diff --git a/src/ItemEntity.cpp b/src/ItemEntity.cpp
new file mode 100644
index 0000000..b0e059b
--- /dev/null
+++ b/src/ItemEntity.cpp
@@ -0,0 +1,157 @@
+#include "ItemEntity.h"
+#include "sfml_game/ImageManager.h"
+#include "sfml_game/SpriteEntity.h"
+#include "Constants.h"
+#include "MagnetEntity.h"
+#include "WitchBlastGame.h"
+#include "StaticTextEntity.h"
+#include <iostream>
+#include <sstream>
+
+const int itemCost[12] =
+{
+ 1, // copper coin
+ 5, // silver
+ 20, // gold
+ 8, // health
+
+ 20, // hat
+ 20, // boots
+ 20, // dual
+ 20, // amulet
+ 100, // boss key
+ 20, // gloves
+ 20, // staff
+
+ 30, // fairy
+};
+
+ItemEntity::ItemEntity(enumItemType itemType, float x, float y)
+ : CollidingSpriteEntity(ImageManager::getImageManager()->getImage(itemType >= itemMagicianHat ? IMAGE_ITEMS_EQUIP : IMAGE_ITEMS), x, y, ITEM_WIDTH, ITEM_HEIGHT)
+{
+ type = TYPE_ITEM;
+ this->itemType = itemType;
+ frame = itemType;
+ if (itemType >= itemMagicianHat) frame = itemType - itemMagicianHat;
+ isMerchandise = false;
+}
+
+void ItemEntity::setMerchandise(bool isMerchandise)
+{
+ this->isMerchandise = isMerchandise;
+}
+bool ItemEntity::getMerchandise()
+{
+ return isMerchandise;
+}
+
+int ItemEntity::getPrice()
+{
+ return (itemCost[(int)(itemType)]);
+}
+
+void ItemEntity::setParent(WitchBlastGame* parent)
+{
+ parentGame = parent;
+}
+
+
+void ItemEntity::animate(float delay)
+{
+ z = y + height;
+ CollidingSpriteEntity::animate(delay);
+ if (age > 0.7f) testSpriteCollisions();
+}
+
+void ItemEntity::render(sf::RenderWindow* app)
+{
+ // shadow
+ sprite.setTextureRect(sf::IntRect(9 * width, height, width, height));
+ app->draw(sprite);
+
+ // price
+ if (isMerchandise)
+ {
+ std::ostringstream oss;
+ oss << getPrice() << " $";
+ StaticTextEntity::Write(app, oss.str(), 16, x, y + 18.0f, ALIGN_CENTER);
+ }
+
+ CollidingSpriteEntity::render(app);
+}
+
+void ItemEntity::calculateBB()
+{
+ boundingBox.left = (int)x - width / 2;
+ boundingBox.width = width;
+ boundingBox.top = (int)y - height / 2;
+ boundingBox.height = height;
+}
+
+void ItemEntity::dying()
+{
+ isDying = true;
+}
+
+void ItemEntity::readCollidingEntity(CollidingSpriteEntity* entity)
+{
+ PlayerEntity* playerEntity = dynamic_cast<PlayerEntity*>(entity);
+
+ if (collideWithEntity(entity))
+ {
+ if (playerEntity != NULL && !playerEntity->isDead())
+ {
+ if (isMerchandise == false || playerEntity->getGold() >= getPrice())
+ {
+ playerEntity->acquireItem(itemType);
+
+ if (isMerchandise) playerEntity->pay(getPrice());
+
+ //isDying = true;
+ dying();
+
+ if (itemType >= itemMagicianHat)
+ {
+
+ parentGame->showArtefactDescription(itemType);
+ SpriteEntity* spriteItem = new SpriteEntity(
+ image,
+ playerEntity->getX(), playerEntity->getY() - 60.0f, ITEM_WIDTH, ITEM_HEIGHT);
+ spriteItem->setFrame(frame);
+ spriteItem->setZ(z);
+ spriteItem->setLifetime(ACQUIRE_DELAY);
+
+ SpriteEntity* spriteStar = new SpriteEntity(
+ ImageManager::getImageManager()->getImage(IMAGE_STAR),
+ playerEntity->getX(), playerEntity->getY() - 60.0f);
+ spriteStar->setScale(4.0f, 4.0f);
+ spriteStar->setZ(z-1.0f);
+ spriteStar->setLifetime(ACQUIRE_DELAY);
+ spriteStar->setSpin(50.0f);
+ }
+ else
+ new MagnetEntity(x, y, playerEntity, itemType);
+ }
+ }
+ }
+}
+
+void ItemEntity::collideMapRight()
+{
+ velocity.x = -velocity.x * 0.66f;
+}
+
+void ItemEntity::collideMapLeft()
+{
+ velocity.x = -velocity.x * 0.66f;
+}
+
+void ItemEntity::collideMapTop()
+{
+ velocity.y = -velocity.y * 0.66f;
+}
+
+void ItemEntity::collideMapBottom()
+{
+ velocity.y = -velocity.y * 0.66f;
+}
diff --git a/src/ItemEntity.h b/src/ItemEntity.h
new file mode 100644
index 0000000..6f01832
--- /dev/null
+++ b/src/ItemEntity.h
@@ -0,0 +1,58 @@
+#ifndef ITEMENTITY_H
+#define ITEMENTITY_H
+
+#include "sfml_game/CollidingSpriteEntity.h"
+
+class WitchBlastGame;
+
+class ItemEntity : public CollidingSpriteEntity
+{
+ public:
+ enum enumItemType
+ {
+ itemCopperCoin,
+ itemSilverCoin,
+ itemGoldCoin,
+ itemHealth,
+
+ itemMagicianHat,
+ itemLeatherBoots,
+ itemBookDualShots,
+ itemConcentrationAmulet,
+ itemBossKey,
+ itemVibrationGloves,
+ itemMahoganyStaff,
+ itemFairy
+ };
+
+
+
+ void setMerchandise(bool isMerchandise);
+ bool getMerchandise();
+ int getPrice();
+ /*ItemEntity(sf::Texture* image, float x, float y, int itemType, int spriteWidth, int spriteHeight);*/
+ ItemEntity(enumItemType itemType, float x, float y);
+ virtual void animate(float delay);
+ virtual void render(sf::RenderWindow* app);
+ virtual void calculateBB();
+ virtual void dying();
+ void setParent(WitchBlastGame* parent);
+ enumItemType getItemType() { return itemType; };
+
+ protected:
+ WitchBlastGame* parentGame;
+ enumItemType itemType;
+
+ bool isMerchandise;
+
+ virtual void collideMapRight();
+ virtual void collideMapLeft();
+ virtual void collideMapTop();
+ virtual void collideMapBottom();
+
+ virtual void readCollidingEntity(CollidingSpriteEntity* entity);
+
+ private:
+};
+
+#endif // ITEMENTITY_H
diff --git a/src/KingRatEntity.cpp b/src/KingRatEntity.cpp
new file mode 100644
index 0000000..3611c21
--- /dev/null
+++ b/src/KingRatEntity.cpp
@@ -0,0 +1,345 @@
+#include "KingRatEntity.h"
+#include "GreenRatEntity.h"
+#include "BoltEntity.h"
+#include "PlayerEntity.h"
+#include "sfml_game/SpriteEntity.h"
+#include "sfml_game/ImageManager.h"
+#include "sfml_game/SoundManager.h"
+#include "Constants.h"
+#include "WitchBlastGame.h"
+#include "StaticTextEntity.h"
+
+#include <iostream>
+
+KingRatEntity::KingRatEntity(float x, float y, GameMap* map, PlayerEntity* player)
+ : EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_KING_RAT), x, y, map)
+{
+ width = 128;
+ height = 128;
+ creatureSpeed = KING_RAT_SPEED;
+ velocity = Vector2D(creatureSpeed);
+ hp = KING_RAT_HP;
+ hpDisplay = hp;
+ hpMax = KING_RAT_HP;
+ meleeDamages = KING_RAT_DAMAGES;
+
+ type = 21;
+ bloodColor = bloodRed;
+ shadowFrame = 4;
+ frame = 0;
+ sprite.setOrigin(64.0f, 64.0f);
+ this->player = player;
+
+ state = 0;
+ timer = 2.0f + (rand() % 40) / 10.0f;
+ age = 0.0f;
+
+ berserkDelay = 1.0f + rand()%5 * 0.1f;
+
+ hasBeenBerserk = false;
+}
+
+void KingRatEntity::animate(float delay)
+{
+ float timerMult = 1.0f;
+ if (hp <= hpMax / 4)
+ {
+ creatureSpeed = KING_RAT_SPEED * 1.4f;
+ timerMult = 0.7f;
+ }
+ else if (hp <= hpMax / 2)
+ {
+ creatureSpeed = KING_RAT_SPEED * 1.2f;
+ timerMult = 0.85f;
+ }
+ else
+ {
+ creatureSpeed = KING_RAT_SPEED;
+ }
+
+ if (state == 5)
+ {
+ velocity.x *= 0.965f;
+ velocity.y *= 0.965f;
+ }
+
+ else
+ {
+ if (velocity.x > 0.1f) sprite.setScale(-1.0f, 1.0f);
+ else if (velocity.x < -0.1f) sprite.setScale(1.0f, 1.0f);
+ }
+
+
+ timer -= delay;
+
+ if (timer <= 0.0f)
+ {
+ if (state == 0)
+ {
+ state = 1;
+ // generate rats
+ generateGreenRats();
+ SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_1);
+ timer = 2.0f;
+
+ velocity.x = 0.0f;
+ velocity.y = 0.0f;
+ }
+
+ else if (state == 1) // generate rats
+ {
+ // to normal or berserk
+ if (hp < hpMax / 4 && !hasBeenBerserk)
+ {
+ hasBeenBerserk = true;
+ timer = 12.0f;
+ state = 6;
+ velocity = Vector2D(KING_RAT_BERSERK_SPEED);
+ SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_2);
+ }
+ else
+ {
+ timer = 7.0f * timerMult;
+ velocity = Vector2D(creatureSpeed);
+ state = 2;
+ }
+ }
+
+ else if (state == 2) // normal -> rush
+ {
+ state = 3;
+ // angry
+ timer = 2.0f;
+
+ velocity.x = 0.0f;
+ velocity.y = 0.0f;
+ SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_2);
+ }
+
+ else if (state == 3) // normal -> rush
+ {
+ state = 4;
+ // rush
+ timer = 12.0f;
+
+ float tan = (player->getX() - x) / (player->getY() - y);
+ float angle = atan(tan);
+
+ if (player->getY() > y)
+ setVelocity(Vector2D(sin(angle) * KING_RAT_RUNNING_SPEED,
+ cos(angle) * KING_RAT_RUNNING_SPEED));
+ else
+ setVelocity(Vector2D(-sin(angle) * KING_RAT_RUNNING_SPEED,
+ -cos(angle) * KING_RAT_RUNNING_SPEED));
+ }
+ else if (state == 5) // wall impact
+ {
+ // to normal or berserk
+ if (hp < hpMax / 4 && !hasBeenBerserk)
+ {
+ hasBeenBerserk = true;
+ timer = 12.0f;
+ state = 6;
+ velocity = Vector2D(KING_RAT_BERSERK_SPEED);
+ SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_2);
+ }
+ else
+ {
+ timer = 7.0f * timerMult;
+ velocity = Vector2D(creatureSpeed);
+ state = 0;
+ }
+ }
+
+ else if (state == 6)
+ {
+ timer = 7.0f * timerMult;
+ velocity = Vector2D(creatureSpeed);
+ state = 0;
+ }
+ }
+
+ if (state == 6)
+ {
+ berserkDelay -= delay;
+
+ if (berserkDelay <= 0.0f)
+ {
+ berserkDelay = 0.8f + (rand()%10) / 10.0f;
+ SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_2);
+
+ float tan = (player->getX() - x) / (player->getY() - y);
+ float angle = atan(tan);
+
+ if (player->getY() > y)
+ setVelocity(Vector2D(sin(angle) * KING_RAT_BERSERK_SPEED,
+ cos(angle) * KING_RAT_BERSERK_SPEED));
+ else
+ setVelocity(Vector2D(-sin(angle) * KING_RAT_BERSERK_SPEED,
+ -cos(angle) * KING_RAT_BERSERK_SPEED));
+ }
+ }
+
+ frame = 0;
+
+ if (state == 1)
+ frame = 3;
+ else if (state == 3 || state == 6)
+ {
+ frame = 3; //0;
+ int r = ((int)(age * 10.0f)) % 2;
+ if (r == 0)
+ sprite.setScale(-1.0f, 1.0f);
+ else
+ sprite.setScale(1.0f, 1.0f);
+ }
+ else if (state == 4)
+ {
+ int r = ((int)(age * 7.5f)) % 4;
+ if (r == 1) frame = 1;
+ else if (r == 3) frame = 2;
+ }
+ else if (state == 5)
+ {
+ frame = 0;
+ }
+ else
+ {
+ int r = ((int)(age * 5.0f)) % 4;
+ if (r == 1) frame = 1;
+ else if (r == 3) frame = 2;
+ }
+
+ testSpriteCollisions();
+ EnnemyEntity::animate(delay);
+}
+
+void KingRatEntity::hurt(int damages)
+{
+ hurting = true;
+ hurtingDelay = HURTING_DELAY;
+
+ if (state == 6)
+ hp -= damages / 4;
+ else
+ hp -= damages;
+
+ if (hp <= 0)
+ {
+ hp = 0;
+ dying();
+ }
+}
+
+void KingRatEntity::calculateBB()
+{
+ boundingBox.left = (int)x - width / 2 + 25;
+ boundingBox.width = width - 50;
+ boundingBox.top = (int)y - height / 2 + 25;
+ boundingBox.height = height - 35;
+}
+
+
+void KingRatEntity::afterWallCollide()
+{
+ if (state == 4)
+ {
+ state = 5;
+ timer = 1.4f;
+ velocity.x *= 0.75f;
+ velocity.y *= 0.75f;
+ //velocity = Vector2D(creatureSpeed);
+ SoundManager::getSoundManager()->playSound(SOUND_BIG_WALL_IMPACT);
+ }
+}
+void KingRatEntity::collideMapRight()
+{
+ velocity.x = -velocity.x;
+
+ afterWallCollide();
+}
+
+void KingRatEntity::collideMapLeft()
+{
+ velocity.x = -velocity.x;
+
+ afterWallCollide();
+}
+
+void KingRatEntity::collideMapTop()
+{
+ velocity.y = -velocity.y;
+
+ afterWallCollide();
+}
+
+void KingRatEntity::collideMapBottom()
+{
+ velocity.y = -velocity.y;
+
+ afterWallCollide();
+}
+
+
+void KingRatEntity::dying()
+{
+ isDying = true;
+ SpriteEntity* deadRat = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES_BIG), x, y, 128, 128);
+ deadRat->setZ(OFFSET_Y);
+ deadRat->setFrame(FRAME_CORPSE_KING_RAT - FRAME_CORPSE_KING_RAT);
+ deadRat->setType(TYPE_CORPSE);
+
+ for (int i = 0; i < 10; i++) parentGame->generateBlood(x, y, bloodColor);
+
+ SoundManager::getSoundManager()->playSound(SOUND_KING_RAT_DIE);
+}
+
+void KingRatEntity::generateGreenRats()
+{
+ for (int i = 0; i < 5; i++)
+ {
+ float xr = x + -100 + rand() % 200;
+ float yr = y + -100 + rand() % 200;
+
+ if (xr > OFFSET_X + TILE_WIDTH * 1.5f && xr < OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 2)
+ && yr > OFFSET_Y + TILE_HEIGHT * 1.5f && yr < OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 2))
+ {
+ new GreenRatEntity(xr, yr, map, player);
+ }
+ else
+ i--;
+ }
+}
+
+void KingRatEntity::render(sf::RenderWindow* app)
+{
+ EnnemyEntity::render(app);
+
+ if (state == 6)
+ {
+ int r = ((int)(age *12.0f)) % 2;
+ if (r == 0)
+ sprite.setTextureRect(sf::IntRect(1 * width, 1 * height, width, height));
+ else
+ sprite.setTextureRect(sf::IntRect(2 * width, 1 * height, -width, height));
+
+ sprite.setPosition(x, y);
+ sprite.setColor(sf::Color(255, 255, 255, 190));
+ app->draw(sprite);
+ sprite.setColor(sf::Color(255, 255, 255, 255));
+ }
+
+ float l = hpDisplay * ((MAP_WIDTH - 1) * TILE_WIDTH) / KING_RAT_HP;
+
+ sf::RectangleShape rectangle(sf::Vector2f((MAP_WIDTH - 1) * TILE_WIDTH, 25));
+ rectangle.setFillColor(sf::Color(0, 0, 0,128));
+ rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT));
+ app->draw(rectangle);
+
+ rectangle.setSize(sf::Vector2f(l, 25));
+ rectangle.setFillColor(sf::Color(190, 20, 20));
+ rectangle.setPosition(sf::Vector2f(OFFSET_X + TILE_WIDTH / 2, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT));
+ app->draw(rectangle);
+
+ StaticTextEntity::Write(app, "Rat King",18, OFFSET_X + TILE_WIDTH / 2 + 10.0f, OFFSET_Y + 25 + (MAP_HEIGHT - 1) * TILE_HEIGHT + 1.0f, ALIGN_LEFT);
+}
diff --git a/src/KingRatEntity.h b/src/KingRatEntity.h
new file mode 100644
index 0000000..d52cf97
--- /dev/null
+++ b/src/KingRatEntity.h
@@ -0,0 +1,34 @@
+#ifndef KINGRATSPRITE_H
+#define KINGRATSPRITE_H
+
+#include "EnnemyEntity.h"
+#include "PlayerEntity.h"
+
+class KingRatEntity : public EnnemyEntity
+{
+ public:
+ KingRatEntity(float x, float y, GameMap* map, PlayerEntity* player);
+ virtual void animate(float delay);
+ virtual void render(sf::RenderWindow* app);
+ virtual void calculateBB();
+ protected:
+ virtual void collideMapRight();
+ virtual void collideMapLeft();
+ virtual void collideMapTop();
+ virtual void collideMapBottom();
+ void afterWallCollide();
+ virtual void hurt(int damages);
+
+ void generateGreenRats();
+
+ //virtual void readCollidingEntity(CollidingSpriteEntity* entity);
+ virtual void dying();
+ private:
+ float timer;
+ float berserkDelay;
+ int state;
+ bool hasBeenBerserk;
+ PlayerEntity* player;
+};
+
+#endif // KINGRATSPRITE_H
diff --git a/src/MagnetEntity.cpp b/src/MagnetEntity.cpp
new file mode 100644
index 0000000..1acf365
--- /dev/null
+++ b/src/MagnetEntity.cpp
@@ -0,0 +1,30 @@
+#include "MagnetEntity.h"
+#include "Constants.h"
+#include "sfml_game/ImageManager.h"
+
+MagnetEntity::MagnetEntity(float x, float y, PlayerEntity* parentEntity, ItemEntity::enumItemType itemType) : SpriteEntity (ImageManager::getImageManager()->getImage(IMAGE_ITEMS), x, y, ITEM_WIDTH, ITEM_HEIGHT)
+{
+ this->x = x;
+ this->y = y;
+ this->setLifetime(0.7f);
+ //itemFadingEntity->setFading(true);
+ this->setShrinking(true);
+ this->setVelocity(Vector2D(150.0f - rand()%300, -260.0f));
+ this->setWeight(800.0f);
+ this->setFrame(itemType);
+ this->parentEntity = parentEntity;
+}
+
+
+void MagnetEntity::animate(float delay)
+{
+ z = y + height;
+
+ if (age > lifetime * 0.3f)
+ {
+ velocity.x += (parentEntity->getX() - x) * delay * 30.0f;
+ velocity.y += (parentEntity->getY() - y) * delay * 30.0f;
+ }
+
+ SpriteEntity::animate(delay);
+}
diff --git a/src/MagnetEntity.h b/src/MagnetEntity.h
new file mode 100644
index 0000000..859cffd
--- /dev/null
+++ b/src/MagnetEntity.h
@@ -0,0 +1,18 @@
+#ifndef MAGNETENTITY_H
+#define MAGNETENTITY_H
+
+#include "sfml_game/SpriteEntity.h"
+#include "PlayerEntity.h"
+
+class MagnetEntity : public SpriteEntity
+{
+ public:
+ MagnetEntity(float x, float y, PlayerEntity* parentEntity, ItemEntity::enumItemType );
+ virtual void animate(float delay);
+
+ protected:
+
+ private:
+ PlayerEntity* parentEntity;
+};
+#endif // MAGNETENTITY_H
diff --git a/src/PlayerEntity.cpp b/src/PlayerEntity.cpp
new file mode 100644
index 0000000..8223871
--- /dev/null
+++ b/src/PlayerEntity.cpp
@@ -0,0 +1,538 @@
+#include "PlayerEntity.h"
+#include "BoltEntity.h"
+#include "EnnemyBoltEntity.h"
+#include "ItemEntity.h"
+#include "FairyEntity.h"
+#include "sfml_game/ImageManager.h"
+#include "sfml_game/SoundManager.h"
+#include "Constants.h"
+#include "WitchBlastGame.h"
+
+#include <iostream>
+
+PlayerEntity::PlayerEntity(sf::Texture* image, float x = 0.0f, float y = 0.0f) : BaseCreatureEntity (image, x, y, 64, 96)
+{
+ fireDelay = INITIAL_PLAYER_FIRE_DELAY;
+ fireVelocity = INITIAL_BOLT_VELOCITY;
+ currentFireDelay = -1.0f;
+ canFirePlayer = true;
+ type = 1;
+
+ creatureSpeed = INITIAL_PLAYER_SPEED;
+ imagesProLine = 8;
+ playerStatus = playerStatusPlaying;
+ hp = INITIAL_PLAYER_HP;
+ hpDisplay = hp;
+ hpMax = INITIAL_PLAYER_HP;
+ gold = 0;
+
+ boltLifeTime = INITIAL_BOLT_LIFE;
+
+ bloodColor = bloodRed;
+
+ for (int i = 0; i < NUMBER_EQUIP_ITEMS; i++) equip[i] = false;
+ colliding = 0;
+
+ // TEST
+ //equip[EQUIP_BOSS_KEY] = true;
+}
+
+void PlayerEntity::moveTo(float newX, float newY)
+{
+ float dx = newX - x;
+ float dy = newY - y;
+
+ x = newX;
+ y = newY;
+
+ if (equip[EQUIP_FAIRY])
+ {
+ fairy->setX(fairy->getX() + dx);
+ fairy->setY(fairy->getY() + dy);
+ }
+}
+
+float PlayerEntity::getPercentFireDelay()
+{
+ if (canFirePlayer) return 1.0f;
+
+ else return (1.0f - currentFireDelay / fireDelay);
+}
+
+int PlayerEntity::getColliding()
+{
+ return colliding;
+}
+
+bool PlayerEntity::isDead()
+{
+ return playerStatus==playerStatusDead;
+}
+
+void PlayerEntity::setEntering()
+{
+ playerStatus = playerStatusEntering;
+}
+
+void PlayerEntity::pay(int price)
+{
+ gold -= price;
+ if (gold < 0) gold = 0;
+ SoundManager::getSoundManager()->playSound(SOUND_BLAST_STANDARD);
+}
+
+void PlayerEntity::animate(float delay)
+{
+ // rate of fire
+ if (!canFirePlayer)
+ {
+ currentFireDelay -= delay;
+ canFirePlayer = (currentFireDelay <= 0.0f);
+ }
+ // acquisition animation
+ if (playerStatus == playerStatusAcquire)
+ {
+ acquireDelay -= delay;
+ if (acquireDelay <= 0.0f)
+ {
+ equip[acquiredItem] = true;
+ computePlayer();
+ playerStatus = playerStatusPlaying;
+
+ if (acquiredItem == (int)EQUIP_FAIRY)
+ {
+ fairy = new FairyEntity(x, y - 50.0f, this);
+ }
+ }
+ }
+ else if (playerStatus == playerStatusUnlocking)
+ {
+ acquireDelay -= delay;
+ if (acquireDelay <= 0.0f)
+ {
+ playerStatus = playerStatusPlaying;
+ }
+ }
+ //z = y;
+ if (playerStatus != playerStatusDead) testSpriteCollisions();
+ colliding = 0;
+ BaseCreatureEntity::animate(delay);
+
+ if (isMoving())
+ {
+ frame = ((int)(age * 5.0f)) % 4;
+ if (frame == 2) frame = 0;
+ if (frame == 3) frame = 2;
+ SoundManager::getSoundManager()->playSound(SOUND_STEP);
+ }
+ else if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking)
+ frame = 3;
+ else if (playerStatus == playerStatusDead)
+ frame = 0;
+ else
+ frame = 0;
+
+ if (x < OFFSET_X)
+ parentGame->moveToOtherMap(4);
+ else if (x > OFFSET_X + MAP_WIDTH * TILE_WIDTH)
+ parentGame->moveToOtherMap(6);
+ else if (y < OFFSET_Y)
+ parentGame->moveToOtherMap(8);
+ else if (y > OFFSET_Y + MAP_HEIGHT * TILE_HEIGHT - 5)
+ parentGame->moveToOtherMap(2);
+
+ if (playerStatus == playerStatusEntering)
+ {
+ if (boundingBox.left > OFFSET_X + TILE_WIDTH
+ && (boundingBox.left + boundingBox.width) < OFFSET_X + TILE_WIDTH * (MAP_WIDTH - 1)
+ && boundingBox.top > OFFSET_Y + TILE_HEIGHT
+ && (boundingBox.top + boundingBox.height) < OFFSET_Y + TILE_HEIGHT * (MAP_HEIGHT - 1))
+ {
+ playerStatus = playerStatusPlaying;
+ parentGame->closeDoors();
+ }
+ }
+
+ if (playerStatus == playerStatusDead)
+ {
+ z = OFFSET_Y - 2;
+ }
+}
+
+
+void PlayerEntity::render(sf::RenderWindow* app)
+{
+
+ sprite.setPosition(x, y);
+
+ if (playerStatus == playerStatusDead)
+ {
+ // blood
+ sprite.setTextureRect(sf::IntRect(6 * width, 0, width, height));
+ app->draw(sprite);
+
+ // body
+ sprite.setTextureRect(sf::IntRect(3 * width, height, width, height));
+ app->draw(sprite);
+
+ // feet
+ sprite.setTextureRect(sf::IntRect(3 * width, 2 * height, width, height));
+ app->draw(sprite);
+
+ // hand
+ sprite.setTextureRect(sf::IntRect(3 * width, 3 * height, width, height));
+ app->draw(sprite);
+ }
+ else
+ {
+ // shadow
+ sprite.setTextureRect(sf::IntRect(7 * width, 0, width, height));
+ app->draw(sprite);
+
+ // body
+ sprite.setTextureRect(sf::IntRect(frame * width, height, width, height));
+ app->draw(sprite);
+
+ // head
+ if (playerStatus != playerStatusAcquire && playerStatus != playerStatusUnlocking)
+ {
+ sprite.setTextureRect(sf::IntRect(0, 0, width, height));
+ app->draw(sprite);
+
+ // hat
+ if (equip[EQUIP_ENCHANTER_HAT])
+ {
+ sprite.setTextureRect(sf::IntRect(3 * width, 0, width, height));
+ app->draw(sprite);
+ }
+ }
+ // feet
+ if( equip[EQUIP_LEATHER_BOOTS])
+ sprite.setTextureRect(sf::IntRect((frame + 4) * width, 2 * height, width, height));
+ else
+ sprite.setTextureRect(sf::IntRect(frame * width, 2 * height, width, height));
+ app->draw(sprite);
+
+ // staff
+ if ( equip[EQUIP_MAHONAGY_STAFF])
+ sprite.setTextureRect(sf::IntRect(frame * width + 4, 4 * height, width, height));
+ else
+ sprite.setTextureRect(sf::IntRect(frame * width + 4, 4 * height, width, height));
+ app->draw(sprite);
+
+ // hands
+ if( equip[EQUIP_VIBRATION_GLOVES])
+ sprite.setTextureRect(sf::IntRect((frame + 4) * width, 3 * height, width, height));
+ else
+ sprite.setTextureRect(sf::IntRect(frame * width, 3 * height, width, height));
+ app->draw(sprite);
+
+ // head
+ if (playerStatus == playerStatusAcquire || playerStatus == playerStatusUnlocking)
+ {
+ sprite.setTextureRect(sf::IntRect(width, 0, width, height));
+ app->draw(sprite);
+
+ // hat
+ if (equip[EQUIP_ENCHANTER_HAT])
+ {
+ sprite.setTextureRect(sf::IntRect(3 * width, 0, width, height));
+ app->draw(sprite);
+ }
+
+ // staff
+ sprite.setTextureRect(sf::IntRect(width * 1, 4 * height, width, height));
+ app->draw(sprite);
+ }
+
+ // necklace
+ if (equip[EQUIP_CONCENTRATION_AMULET])
+ {
+ sprite.setTextureRect(sf::IntRect(frame * width, 5 * height, width, height));
+ app->draw(sprite);
+
+ sprite.setColor(sf::Color(255,255,255, (1.0f + sin(age * 5.0f)) * 100));
+ sprite.setTextureRect(sf::IntRect(5 * width, 0, width, height));
+ app->draw(sprite);
+ sprite.setColor(sf::Color(255,255,255,255));
+ }
+ }
+}
+
+
+void PlayerEntity::calculateBB()
+{
+ boundingBox.left = (int)x - width / 2;
+ boundingBox.width = width;
+ boundingBox.top = (int)y - height / 2;
+ boundingBox.height = height;
+
+ float fPrez = 10.0f;
+ boundingBox.left += fPrez;
+ boundingBox.width -= (fPrez + fPrez);
+ boundingBox.top += 52.0f;
+ boundingBox.height = boundingBox.width - 10.0f;
+}
+
+void PlayerEntity::readCollidingEntity(CollidingSpriteEntity* entity)
+{
+
+ EnnemyBoltEntity* boltEntity = dynamic_cast<EnnemyBoltEntity*>(entity);
+
+ if (collideWithEntity(entity))
+ {
+ if (boltEntity != NULL && !boltEntity->getDying())
+ {
+ boltEntity->collide();
+ hurt(boltEntity->getDamages());
+ parentGame->generateBlood(x, y, bloodColor);
+ }
+ }
+}
+
+void PlayerEntity::move(int direction)
+{
+ if (playerStatus == playerStatusPlaying)
+ {
+ float speedx = 0.0f, speedy = 0.0f;
+ if (direction == 1 || direction == 4 || direction == 7)
+ speedx = - creatureSpeed;
+ else if (direction == 3 || direction == 6 || direction == 9)
+ speedx = creatureSpeed;
+ if (direction == 1 || direction == 2 || direction == 3)
+ speedy = creatureSpeed;
+ else if (direction == 7 || direction == 8 || direction == 9)
+ speedy = - creatureSpeed;
+ setVelocity(Vector2D(speedx, speedy));
+ }
+}
+
+bool PlayerEntity::isMoving()
+{
+ if (velocity.x < -1.0f || velocity.x > 1.0f) return true;
+ if (velocity.y < -1.0f || velocity.y > 1.0f) return true;
+ return false;
+}
+
+bool PlayerEntity::isEquiped(int eq)
+{
+ return equip[eq];
+}
+
+void PlayerEntity::generateBolt(float velx, float vely)
+{
+ BoltEntity* bolt = new BoltEntity(ImageManager::getImageManager()->getImage(1), x, y + 20, boltLifeTime);
+ bolt->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ bolt->setDamages(fireDamages);
+ bolt->setVelocity(Vector2D(velx, vely));
+}
+
+void PlayerEntity::fire(int direction)
+{
+ if (equip[EQUIP_FAIRY] && playerStatus != playerStatusDead)
+ fairy->fire(direction, map);
+
+ if (canFirePlayer && playerStatus != playerStatusDead)
+ {
+ SoundManager::getSoundManager()->playSound(SOUND_BLAST_STANDARD);
+
+ if (equip[EQUIP_BOOK_DUAL])
+ {
+ float shoot_angle = 0.2f;
+
+ if ((direction == 4 && velocity.x < -1.0f) || (direction == 6 && velocity.x > 1.0f)
+ || (direction == 8 && velocity.y < -1.0f) || (direction == 2 && velocity.y > 1.0f))
+ shoot_angle = 0.1f;
+ else if ((direction == 6 && velocity.x < -1.0f) || (direction == 4 && velocity.x > 1.0f)
+ || (direction == 2 && velocity.y < -1.0f) || (direction == 8 && velocity.y > 1.0f))
+ shoot_angle = 0.35f;
+
+ if (equip[EQUIP_VIBRATION_GLOVES]) shoot_angle += (1000 - rand() % 2000) * 0.0001f;
+
+ switch(direction)
+ {
+ case 4: generateBolt(-fireVelocity * cos(shoot_angle), fireVelocity * sin(shoot_angle));
+ generateBolt(-fireVelocity * cos(shoot_angle), - fireVelocity * sin(shoot_angle));break;
+ case 6: generateBolt(fireVelocity * cos(shoot_angle), fireVelocity * sin(shoot_angle));
+ generateBolt(fireVelocity * cos(shoot_angle), - fireVelocity * sin(shoot_angle));break;
+ case 8: generateBolt(fireVelocity * sin(shoot_angle), -fireVelocity * cos(shoot_angle));
+ generateBolt(-fireVelocity * sin(shoot_angle), - fireVelocity * cos(shoot_angle));break;
+ case 2: generateBolt(fireVelocity * sin(shoot_angle), fireVelocity * cos(shoot_angle));
+ generateBolt(-fireVelocity * sin(shoot_angle), fireVelocity * cos(shoot_angle));break;
+ }
+ }
+ else
+ {
+ if (equip[EQUIP_VIBRATION_GLOVES])
+ {
+ float shoot_angle = (1000 - rand() % 2000) * 0.0001f;
+ switch(direction)
+ {
+ case 4: generateBolt(-fireVelocity * cos(shoot_angle), fireVelocity * sin(shoot_angle)); break;
+ case 6: generateBolt(fireVelocity * cos(shoot_angle), fireVelocity * sin(shoot_angle)); break;
+ case 8: generateBolt(fireVelocity * sin(shoot_angle), -fireVelocity * cos(shoot_angle)); break;
+ case 2: generateBolt(fireVelocity * sin(shoot_angle), fireVelocity * cos(shoot_angle)); break;
+ }
+ }
+ else
+ {
+ switch(direction)
+ {
+ case 4: generateBolt(-fireVelocity, 0.0f); break;
+ case 6: generateBolt(fireVelocity, 0.0f); break;
+ case 8: generateBolt(0.0f, -fireVelocity); break;
+ case 2: generateBolt(0.0f, fireVelocity); break;
+ }
+ }
+ }
+
+ canFirePlayer = false;
+ currentFireDelay = fireDelay;
+ }
+}
+
+bool PlayerEntity::canFire()
+{
+ return canFirePlayer;
+}
+
+bool PlayerEntity::canMove()
+{
+ return (playerStatus == playerStatusPlaying);
+}
+
+void PlayerEntity::hurt(int damages)
+{
+ if (!hurting)
+ {
+ SoundManager::getSoundManager()->playSound(SOUND_PLAYER_HIT);
+ BaseCreatureEntity::hurt(damages);
+ parentGame->generateBlood(x, y, bloodColor);
+ parentGame->generateBlood(x, y, bloodColor);
+ }
+}
+
+void PlayerEntity::loseItem(ItemEntity::enumItemType itemType, bool isEquip)
+{
+ CollidingSpriteEntity* itemSprite
+ = new CollidingSpriteEntity(ImageManager::getImageManager()->getImage(isEquip ? IMAGE_ITEMS_EQUIP : IMAGE_ITEMS), x, y, 32, 32);
+ itemSprite->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ itemSprite->setZ(OFFSET_Y - 1);
+ itemSprite->setFrame(itemType);
+ itemSprite->setType(TYPE_BLOOD);
+ itemSprite->setVelocity(Vector2D(rand()%450));
+ itemSprite->setViscosity(0.95f);
+ itemSprite->setSpin( (rand() % 700) - 350.0f);
+}
+
+void PlayerEntity::dying()
+{
+ playerStatus = playerStatusDead;
+ hp = 0;
+ SoundManager::getSoundManager()->playSound(SOUND_PLAYER_DIE);
+ setVelocity(Vector2D(0.0f, 0.0f));
+
+ int i;
+ for (i = 0; i < gold; i++) loseItem(ItemEntity::itemCopperCoin, false);
+
+ for (i = 0; i < NUMBER_EQUIP_ITEMS; i++)
+ if (equip[i]) loseItem(ItemEntity::enumItemType(i), true);
+
+ for (i = 0; i < 8; i++) parentGame->generateBlood(x, y, bloodColor);
+
+ CollidingSpriteEntity* itemSprite
+ = new CollidingSpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_PLAYER), x, y, 64, 64);
+ itemSprite->setMap(map, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ itemSprite->setZ(OFFSET_Y - 1);
+ itemSprite->setImagesProLine(10);
+ itemSprite->setFrame(/*11*/1);
+ itemSprite->setType(TYPE_BLOOD);
+ itemSprite->setVelocity(Vector2D(rand()%450));
+ itemSprite->setViscosity(0.95f);
+ itemSprite->setSpin( (rand() % 700) - 350.0f);
+}
+
+void PlayerEntity::acquireItem(ItemEntity::enumItemType type)
+{
+ if (type >= ItemEntity::itemMagicianHat) acquireStance(type);
+ else switch (type)
+ {
+ case ItemEntity::itemCopperCoin: gold++;
+ SoundManager::getSoundManager()->playSound(SOUND_COIN_PICK_UP);
+ break;
+ case ItemEntity::itemSilverCoin: gold = gold + 5; break;
+ case ItemEntity::itemGoldCoin: gold = gold + 10; break;
+ case ItemEntity::itemHealth: hp += 15;
+ SoundManager::getSoundManager()->playSound(SOUND_DRINK);
+ if (hp > hpMax) hp = hpMax; break;
+ default: break;
+ }
+}
+
+void PlayerEntity::computePlayer()
+{
+ fireDelay = INITIAL_PLAYER_FIRE_DELAY;
+ creatureSpeed = INITIAL_PLAYER_SPEED;
+ fireVelocity = INITIAL_BOLT_VELOCITY;
+ fireDamages = INITIAL_BOLT_DAMAGES;
+
+ if (equip[EQUIP_VIBRATION_GLOVES]) fireDelay *= 0.90f;
+ if (equip[EQUIP_ENCHANTER_HAT]) fireDelay *= 0.75f;
+ if (equip[EQUIP_LEATHER_BOOTS]) creatureSpeed += 50.0f;
+ if (equip[EQUIP_BOOK_DUAL]) fireDelay *= 1.6f;
+ if (equip[EQUIP_CONCENTRATION_AMULET]) boltLifeTime *= 1.5f;
+ if (equip[EQUIP_MAHONAGY_STAFF])
+ {
+ fireVelocity *= 1.15f;
+ fireDamages *= 1.5f;
+ }
+}
+
+void PlayerEntity::acquireStance(ItemEntity::enumItemType type)
+{
+ velocity.x = 0.0f;
+ velocity.y = 0.0f;
+ playerStatus = playerStatusAcquire;
+ acquireDelay = ACQUIRE_DELAY;
+ acquiredItem = (ItemEntity::enumItemType)(type - ItemEntity::itemMagicianHat);
+ SoundManager::getSoundManager()->playSound(SOUND_BONUS);
+}
+
+void PlayerEntity::collideMapRight()
+{
+ colliding = 6;
+}
+
+void PlayerEntity::collideMapLeft()
+{
+ colliding = 4;
+}
+
+void PlayerEntity::collideMapTop()
+{
+ colliding = 8;
+}
+
+void PlayerEntity::collideMapBottom()
+{
+ colliding = 2;
+}
+
+void PlayerEntity::useBossKey()
+{
+ velocity.x = 0.0f;
+ velocity.y = 0.0f;
+ playerStatus = playerStatusUnlocking;
+ acquireDelay = UNLOCK_DELAY;
+ acquiredItem = (ItemEntity::enumItemType)(type - ItemEntity::itemMagicianHat);
+ SoundManager::getSoundManager()->playSound(SOUND_BONUS);
+ equip[EQUIP_BOSS_KEY] = false;
+
+
+ SpriteEntity* spriteItem = new SpriteEntity(
+ ImageManager::getImageManager()->getImage(IMAGE_ITEMS_EQUIP),
+ x, y - 60.0f, ITEM_WIDTH, ITEM_HEIGHT);
+ spriteItem->setFrame(EQUIP_BOSS_KEY);
+ spriteItem->setZ(z);
+ spriteItem->setLifetime(UNLOCK_DELAY);
+}
diff --git a/src/PlayerEntity.h b/src/PlayerEntity.h
new file mode 100644
index 0000000..ccbdd5b
--- /dev/null
+++ b/src/PlayerEntity.h
@@ -0,0 +1,84 @@
+#ifndef PLAYERSPRITE_H
+#define PLAYERSPRITE_H
+
+#include "BaseCreatureEntity.h"
+#include "ItemEntity.h"
+#include "Constants.h"
+
+class FairyEntity;
+
+class PlayerEntity : public BaseCreatureEntity
+{
+ public:
+ PlayerEntity(sf::Texture* image, float x, float y);
+ virtual void animate(float delay);
+ virtual void render(sf::RenderWindow* app);
+
+ void moveTo(float newX, float newY);
+
+ virtual void calculateBB();
+ void move(int direction);
+ void fire(int direction);
+ bool canFire();
+ bool isMoving();
+ bool isEquiped(int eq);
+ void setEntering();
+ bool canMove();
+ virtual void dying();
+ virtual void hurt(int damages);
+ bool isDead();
+ float getPercentFireDelay();
+ void acquireItem(ItemEntity::enumItemType type);
+ void loseItem(ItemEntity::enumItemType itemType, bool isEquip);
+ void acquireStance(ItemEntity::enumItemType type);
+ void useBossKey();
+
+ int getGold() {return gold; }
+ void pay(int price);
+ int getColliding();
+
+ enum playerStatusEnum
+ {
+ playerStatusPlaying,
+ playerStatusEntering,
+ playerStatusAcquire,
+ playerStatusUnlocking,
+ playerStatusDead
+ };
+ protected:
+ void computePlayer();
+ virtual void readCollidingEntity(CollidingSpriteEntity* entity);
+ void generateBolt(float velx, float vely);
+
+ virtual void collideMapRight();
+ virtual void collideMapLeft();
+ virtual void collideMapTop();
+ virtual void collideMapBottom();
+
+ private:
+ //int hp;
+ //int hpMax;
+ int fireDamages;
+ float fireVelocity;
+ float fireDelay;
+ float currentFireDelay;
+ float boltLifeTime;
+ int gold;
+
+ // float hurtingDelay;
+ // float currentHurtingDelay;
+
+ bool canFirePlayer;
+ //float playerSpeed;
+ playerStatusEnum playerStatus;
+ float acquireDelay;
+ ItemEntity::enumItemType acquiredItem;
+
+ bool equip[NUMBER_EQUIP_ITEMS];
+
+ int colliding;
+
+ FairyEntity* fairy;
+};
+
+#endif // PLAYERSPRITE_H
diff --git a/src/PnjEntity.cpp b/src/PnjEntity.cpp
new file mode 100644
index 0000000..ee60f1c
--- /dev/null
+++ b/src/PnjEntity.cpp
@@ -0,0 +1,101 @@
+#include "PnjEntity.h"
+#include "Constants.h"
+#include "StaticTextEntity.h"
+#include "sfml_game/ImageManager.h"
+
+PnjEntity::PnjEntity(float x, float y, int pnjType) : SpriteEntity (ImageManager::getImageManager()->getImage(IMAGE_PNJ), x, y, 64, 96)
+{
+ this->x = x;
+ this->y = y;
+
+ x0 = x;
+ y0 = y;
+
+ pnjVelocity = 140.0f;
+
+ xGoal = x0 + 180.0f;
+ direction = 6;
+ velocity.x = pnjVelocity;
+
+ isSpeaking = false;
+ speechTimer = 2.5f + 0.1f * (rand() % 50);
+ headFrame = 2;
+
+ type = 17;
+}
+
+
+void PnjEntity::animate(float delay)
+{
+ if (direction == 6 && x >= xGoal)
+ {
+ direction = 4;
+ velocity.x = -pnjVelocity;
+ xGoal = x0 - 180.0f;
+ }
+ else if (direction == 4 && x <= xGoal)
+ {
+ direction = 6;
+ velocity.x = pnjVelocity;
+ xGoal = x0 + 180.0f;
+ }
+
+ speechTimer -= delay;
+ if (speechTimer <= 0.0f)
+ {
+ if (isSpeaking)
+ {
+ isSpeaking = false;
+ speechTimer = 3.0f + 0.1f * (rand() % 65);
+ velocity.x = (direction == 6) ? pnjVelocity : -pnjVelocity;
+ }
+ else
+ {
+ isSpeaking = true;
+ speechTimer = 5.0f;
+ velocity.x = 0.0f;
+ int r = rand() % 3;
+ switch (r)
+ {
+ case 0: speech = "Best price in entire dungeon !"; break;
+ case 1: speech = "Welcome in deep deep stores !"; break;
+ case 2: speech = "Have look to our merchandise !"; break;
+ }
+ }
+ }
+
+ if (isSpeaking)
+ {
+ headFrame = 2 + (int)(4 * age) % 2;
+ }
+ else
+ {
+ frame = 0 + (int)(4 * age) % 2;
+ headFrame = 2;
+ }
+ z = y + height;
+
+ SpriteEntity::animate(delay);
+}
+
+void PnjEntity::render(sf::RenderWindow* app)
+{
+ sprite.setPosition(x, y);
+
+ // shadow
+ sprite.setTextureRect(sf::IntRect(4 * width, 0, width, height));
+ app->draw(sprite);
+
+ // body
+ sprite.setTextureRect(sf::IntRect(frame * width, 0, width, height));
+ app->draw(sprite);
+
+ // head
+ sprite.setTextureRect(sf::IntRect(headFrame * width, 0, width, height));
+ app->draw(sprite);
+
+ if (isSpeaking)
+ {
+ StaticTextEntity::Write(app, speech, 20, x0, y0 - 72.0f, ALIGN_CENTER);
+ }
+}
diff --git a/src/PnjEntity.h b/src/PnjEntity.h
new file mode 100644
index 0000000..36418eb
--- /dev/null
+++ b/src/PnjEntity.h
@@ -0,0 +1,26 @@
+#ifndef PNJENTITY_H
+#define PNJENTITY_H
+
+#include "sfml_game/SpriteEntity.h"
+
+class PnjEntity : public SpriteEntity
+{
+ public:
+ PnjEntity(float x, float y, int pnjType );
+ virtual void animate(float delay);
+ virtual void render(sf::RenderWindow* app);
+
+ protected:
+ float x0, y0;
+ float xGoal;
+ int direction;
+ float pnjVelocity;
+
+ float speechTimer;
+ bool isSpeaking;
+ std::string speech;
+ int headFrame;
+
+ private:
+};
+#endif // PNJENTITY_H
diff --git a/src/RatEntity.cpp b/src/RatEntity.cpp
new file mode 100644
index 0000000..648bb4f
--- /dev/null
+++ b/src/RatEntity.cpp
@@ -0,0 +1,72 @@
+#include "RatEntity.h"
+#include "BoltEntity.h"
+#include "PlayerEntity.h"
+#include "sfml_game/SpriteEntity.h"
+#include "sfml_game/ImageManager.h"
+#include "sfml_game/SoundManager.h"
+#include "Constants.h"
+#include "WitchBlastGame.h"
+
+RatEntity::RatEntity(float x, float y, GameMap* map)
+ : EnnemyEntity (ImageManager::getImageManager()->getImage(IMAGE_RAT), x, y, map)
+{
+ creatureSpeed = RAT_SPEED;
+ velocity = Vector2D(creatureSpeed);
+ hp = RAT_HP;
+ meleeDamages = RAT_DAMAGES;
+
+ type = 21;
+ bloodColor = bloodRed;
+ shadowFrame = 3;
+}
+
+void RatEntity::animate(float delay)
+{
+ if (age > 0.0f)
+ frame = ((int)(age * 5.0f)) % 2;
+
+ testSpriteCollisions();
+ EnnemyEntity::animate(delay);
+}
+
+void RatEntity::calculateBB()
+{
+ boundingBox.left = (int)x - width / 2 + RAT_BB_LEFT;
+ boundingBox.width = width - RAT_BB_WIDTH_DIFF;
+ boundingBox.top = (int)y - height / 2 + RAT_BB_TOP;
+ boundingBox.height = height - RAT_BB_HEIGHT_DIFF;
+}
+
+void RatEntity::collideMapRight()
+{
+ velocity.x = -velocity.x;
+}
+
+void RatEntity::collideMapLeft()
+{
+ velocity.x = -velocity.x;
+}
+
+void RatEntity::collideMapTop()
+{
+ velocity.y = -velocity.y;
+}
+
+void RatEntity::collideMapBottom()
+{
+ velocity.y = -velocity.y;
+}
+
+
+void RatEntity::dying()
+{
+ isDying = true;
+ SpriteEntity* deadRat = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_CORPSES), x, y, 64, 64);
+ deadRat->setZ(OFFSET_Y);
+ deadRat->setFrame(FRAME_CORPSE_RAT);
+ deadRat->setType(TYPE_CORPSE);
+
+ for (int i = 0; i < 4; i++) parentGame->generateBlood(x, y, bloodColor);
+ drop();
+ SoundManager::getSoundManager()->playSound(SOUND_ENNEMY_DYING);
+}
diff --git a/src/RatEntity.h b/src/RatEntity.h
new file mode 100644
index 0000000..592b4e5
--- /dev/null
+++ b/src/RatEntity.h
@@ -0,0 +1,24 @@
+#ifndef RATSPRITE_H
+#define RATSPRITE_H
+
+#include "EnnemyEntity.h"
+
+class RatEntity : public EnnemyEntity
+{
+ public:
+ RatEntity(float x, float y, GameMap* map);
+ virtual void animate(float delay);
+ virtual void calculateBB();
+ protected:
+ virtual void collideMapRight();
+ virtual void collideMapLeft();
+ virtual void collideMapTop();
+ virtual void collideMapBottom();
+
+ //virtual void readCollidingEntity(CollidingSpriteEntity* entity);
+ virtual void dying();
+ private:
+
+};
+
+#endif // RATSPRITE_H
diff --git a/src/StaticTextEntity.cpp b/src/StaticTextEntity.cpp
new file mode 100644
index 0000000..a4152be
--- /dev/null
+++ b/src/StaticTextEntity.cpp
@@ -0,0 +1,38 @@
+#include "StaticTextEntity.h"
+#include <iostream>
+
+StaticTextEntity::StaticTextEntity()
+{
+ //ctor
+}
+
+/*void StaticTextEntity::Write()
+{
+ static sf::font font;
+}*/
+
+void StaticTextEntity::Write(sf::RenderWindow* app, std::string str, int size, float x, float y, int align)
+{
+ static bool fontDefined = false;
+ static sf::Font statFont;
+ static sf::Text statText;
+
+ if (fontDefined == false)
+ {
+ fontDefined = true;
+
+ if (!statFont.loadFromFile("media/DejaVuSans-Bold.ttf"))
+ {
+ // erreur...
+ }
+ statText.setFont(statFont);
+ }
+
+ statText.setString(str);
+ statText.setCharacterSize(size);
+ if (align == ALIGN_CENTER)
+ statText.setPosition(x - statText.getLocalBounds().width / 2, y);
+ else
+ statText.setPosition(x, y);
+ app->draw(statText);
+}
diff --git a/src/StaticTextEntity.h b/src/StaticTextEntity.h
new file mode 100644
index 0000000..c6e4b1d
--- /dev/null
+++ b/src/StaticTextEntity.h
@@ -0,0 +1,21 @@
+#ifndef STATICTEXTENTITY_H
+#define STATICTEXTENTITY_H
+
+#include <SFML/Graphics.hpp>
+
+const int ALIGN_LEFT = 0;
+const int ALIGN_RIGHT = 1;
+const int ALIGN_CENTER = 2;
+
+class StaticTextEntity
+{
+ public:
+
+ static void Write(sf::RenderWindow* app, std::string str, int size, float x, float y, int align);
+
+ protected:
+ private:
+ StaticTextEntity();
+};
+
+#endif // STATICTEXTENTITY_H
diff --git a/src/WitchBlastGame.cpp b/src/WitchBlastGame.cpp
new file mode 100644
index 0000000..bff20ba
--- /dev/null
+++ b/src/WitchBlastGame.cpp
@@ -0,0 +1,823 @@
+#include "WitchBlastGame.h"
+#include "sfml_game/SpriteEntity.h"
+#include "sfml_game/TileMapEntity.h"
+#include "DungeonMap.h"
+#include "sfml_game/ImageManager.h"
+#include "sfml_game/SoundManager.h"
+#include "sfml_game/EntityManager.h"
+#include "Constants.h"
+#include "RatEntity.h"
+#include "GreenRatEntity.h"
+#include "KingRatEntity.h"
+#include "BatEntity.h"
+#include "ChestEntity.h"
+#include "EvilFlowerEntity.h"
+#include "ItemEntity.h"
+#include "ArtefactDescriptionEntity.h"
+#include "StaticTextEntity.h"
+#include "PnjEntity.h"
+
+#include <iostream>
+#include <sstream>
+
+WitchBlastGame::WitchBlastGame(): Game(SCREEN_WIDTH, SCREEN_HEIGHT)
+{
+ app->setTitle(APP_NAME + " V" + APP_VERSION);
+ ImageManager::getImageManager()->addImage((char*)"media/sprite.png");
+ ImageManager::getImageManager()->addImage((char*)"media/bolt.png");
+ ImageManager::getImageManager()->addImage((char*)"media/tiles.png");
+ ImageManager::getImageManager()->addImage((char*)"media/rat.png");
+ ImageManager::getImageManager()->addImage((char*)"media/minimap.png");
+ ImageManager::getImageManager()->addImage((char*)"media/doors.png");
+ ImageManager::getImageManager()->addImage((char*)"media/items.png");
+ ImageManager::getImageManager()->addImage((char*)"media/items_equip.png");
+ ImageManager::getImageManager()->addImage((char*)"media/chest.png");
+ ImageManager::getImageManager()->addImage((char*)"media/bat.png");
+ ImageManager::getImageManager()->addImage((char*)"media/evil_flower.png");
+ ImageManager::getImageManager()->addImage((char*)"media/king_rat.png");
+ ImageManager::getImageManager()->addImage((char*)"media/blood.png");
+ ImageManager::getImageManager()->addImage((char*)"media/corpses.png");
+ ImageManager::getImageManager()->addImage((char*)"media/corpses_big.png");
+ ImageManager::getImageManager()->addImage((char*)"media/star.png");
+ ImageManager::getImageManager()->addImage((char*)"media/star2.png");
+ ImageManager::getImageManager()->addImage((char*)"media/interface.png");
+ ImageManager::getImageManager()->addImage((char*)"media/pnj.png");
+ ImageManager::getImageManager()->addImage((char*)"media/fairy.png");
+
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/step.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/blast00.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/blast01.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/door_closing.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/door_opening.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/chest_opening.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/impact.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/bonus.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/drink.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/player_hit.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/player_die.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/ennemy_dying.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/coin.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/pay.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/wall_impact.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/big_wall_impact.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/king_rat_cry_1.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/king_rat_cry_2.ogg");
+ SoundManager::getSoundManager()->addSound((char*)"media/sound/king_rat_die.ogg");
+
+
+ music.openFromFile("media/sound/track00.ogg");
+ music.setVolume(75);
+ music.setLoop(true);
+
+ if (!font.loadFromFile("media/DejaVuSans-Bold.ttf"))
+ {
+ // erreur...
+ }
+ myText.setFont(font); // font est un sf::Font
+}
+
+WitchBlastGame::~WitchBlastGame()
+{
+ //dtor
+}
+
+void WitchBlastGame::startNewGame()
+{
+ // cleaning all entities
+ EntityManager::getEntityManager()->clean();
+
+ gameState = gameStateInit;
+
+ currentFloor = new GameFloor(1);
+ floorX = FLOOR_WIDTH / 2;
+ floorY = FLOOR_HEIGHT / 2;
+
+ miniMap = new GameMap(FLOOR_WIDTH, FLOOR_HEIGHT);
+ refreshMinimap();
+
+ // the interface
+ SpriteEntity* interface = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_INTERFACE));
+ interface->setZ(10000.0f);
+ interface->removeCenter();
+ interface->setType(0);
+
+ // key symbol on the interface
+ keySprite.setTexture(*ImageManager::getImageManager()->getImage(IMAGE_ITEMS_EQUIP));
+ keySprite.setTextureRect(sf::IntRect(ITEM_WIDTH * EQUIP_BOSS_KEY, 0, ITEM_WIDTH, ITEM_HEIGHT));
+ keySprite.setPosition(326, 616);
+
+ // minimap on the interface
+ TileMapEntity* miniMapEntity = new TileMapEntity(ImageManager::getImageManager()->getImage(4), miniMap, 16, 12, 10);
+ miniMapEntity->setX(400);
+ miniMapEntity->setY(607);
+ miniMapEntity->setZ(10001.0f);
+
+ // current map (tiles)
+ currentTileMap = new TileMapEntity(ImageManager::getImageManager()->getImage(IMAGE_TILES), currentMap, 64, 64, 10);
+ currentTileMap->setX(OFFSET_X);
+ currentTileMap->setY(OFFSET_Y);
+
+ // doors
+ doorEntity[0] = new DoorEntity(8);
+ doorEntity[1] = new DoorEntity(4);
+ doorEntity[2] = new DoorEntity(2);
+ doorEntity[3] = new DoorEntity(6);
+
+ // the player
+ player = new PlayerEntity(ImageManager::getImageManager()->getImage(0),
+ OFFSET_X + (TILE_WIDTH * MAP_WIDTH * 0.5f),
+ OFFSET_Y + (TILE_HEIGHT * MAP_HEIGHT * 0.5f));
+ player->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ player->setParent(this);
+
+ // generate the map
+ refreshMap();
+
+ // first map is open
+ roomClosed = false;
+
+ // and the boss room is closed
+ bossRoomOpened = false;
+
+ // game time counter an state
+ lastTime = getAbsolutTime();
+ gameState = gameStatePlaying;
+ music.play();
+}
+
+void WitchBlastGame::startGame()
+{
+ startNewGame();
+
+ // Start game loop
+ while (app->isOpen())
+ {
+ // Process events
+ sf::Event event;
+
+ while (app->pollEvent(event))
+ {
+ // Close window : exit
+ if (event.type == sf::Event::Closed)
+ app->close();
+ }
+
+ if (player->canMove()) player->setVelocity(Vector2D(0.0f, 0.0f));
+
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q) || sf::Keyboard::isKeyPressed(sf::Keyboard::A))
+ {
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::Z) || sf::Keyboard::isKeyPressed(sf::Keyboard::W))
+ player->move(7);
+ else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
+ player->move(1);
+ else
+ player->move(4);
+ }
+ else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
+ {
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::Z) || sf::Keyboard::isKeyPressed(sf::Keyboard::W))
+ player->move(9);
+ else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
+ player->move(3);
+ else
+ player->move(6);
+ }
+ else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Z) || sf::Keyboard::isKeyPressed(sf::Keyboard::W))
+ {
+ player->move(8);
+ }
+ else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
+ {
+ player->move(2);
+ }
+
+
+ if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
+ player->fire(4);
+ else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
+ player->fire(6);
+ else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
+ player->fire(8);
+ else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
+ player->fire(2);
+
+ if (player->isDead() && sf::Keyboard::isKeyPressed(sf::Keyboard::Return))
+ startNewGame();
+
+ onUpdate();
+ EntityManager::getEntityManager()->sortByZ();
+ onRender();
+
+ verifyDoorUnlocking();
+
+ if (roomClosed)
+ {
+ if (GetEnnemyCount() == 0)
+ {
+ currentMap->setCleared(true);
+ openDoors();
+ }
+ }
+ }
+ quitGame();
+}
+
+void WitchBlastGame::createFloor()
+{
+}
+
+void WitchBlastGame::closeDoors()
+{
+ if (!currentMap->isCleared())
+ {
+ int i;
+ for(i = 0; i < MAP_WIDTH; i++)
+ {
+ if (currentMap->getTile(i, 0) < 4) currentMap->setTile(i, 0, MAP_DOOR);
+ if (currentMap->getTile(i, MAP_HEIGHT - 1) < 4) currentMap->setTile(i, MAP_HEIGHT - 1, MAP_DOOR);
+ }
+ for(i = 0; i < MAP_HEIGHT; i++)
+ {
+ if (currentMap->getTile(0, i) < 4) currentMap->setTile(0, i, MAP_DOOR);
+ if (currentMap->getTile(MAP_WIDTH - 1, i) < 4) currentMap->setTile(MAP_WIDTH - 1, i, MAP_DOOR);
+ }
+ roomClosed = true;
+ /*SoundManager::getSoundManager()->playSound(SOUND_DOOR_CLOSING);
+ for (int i=0; i<4; i++)
+ doorEntity[i]->closeDoor();*/
+ }
+}
+
+void WitchBlastGame::openDoors()
+{
+ int i, j;
+ for(i = 0; i < MAP_WIDTH; i++)
+ for(j = 0; j < MAP_WIDTH; j++)
+ if (currentMap->getTile(i, j) == MAP_DOOR) currentMap->setTile(i, j, 0);
+ roomClosed = false;
+ SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
+
+ if (currentMap->hasNeighbourUp() == 2 && !bossRoomOpened)
+ currentMap->setTile(MAP_WIDTH/2, 0, MAP_DOOR);
+ else
+ doorEntity[0]->openDoor();
+
+ if (currentMap->hasNeighbourLeft() == 2 && !bossRoomOpened)
+ currentMap->setTile(0, MAP_HEIGHT / 2, MAP_DOOR);
+ else
+ doorEntity[1]->openDoor();
+
+ if (currentMap->hasNeighbourDown() == 2 && !bossRoomOpened)
+ currentMap->setTile(MAP_WIDTH / 2, MAP_HEIGHT - 1, MAP_DOOR);
+ else
+ doorEntity[2]->openDoor();
+
+ if (currentMap->hasNeighbourRight() == 2 && !bossRoomOpened)
+ currentMap->setTile(MAP_WIDTH - 1, MAP_HEIGHT / 2, MAP_DOOR);
+ else
+ doorEntity[3]->openDoor();
+}
+
+int WitchBlastGame::GetEnnemyCount()
+{
+ int n=0;
+
+ EntityManager::EntityList* entityList =EntityManager::getEntityManager()->getList();
+ EntityManager::EntityList::iterator it;
+
+ for (it = entityList->begin (); it != entityList->end ();)
+ {
+ GameEntity *e = *it;
+ it++;
+
+ if (e->getType() >= 20)
+ {
+ n++;
+ } // endif
+ } // end for
+
+ return n;
+}
+
+void WitchBlastGame::refreshMap()
+{
+ // clean the sprites from old map
+ EntityManager::getEntityManager()->partialClean(10);
+
+ // if new map, it has to be randomized
+ bool generateMap = !(currentFloor->getMap(floorX, floorY)->isVisited());
+ currentMap = currentFloor->getAndVisitMap(floorX, floorY);
+
+ // load the map
+ currentTileMap->setMap(currentMap);
+ player->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ refreshMinimap();
+
+ if(generateMap)
+ this->generateMap();
+ else
+ {
+ if (currentMap->getRoomType() == roomTypeMerchant)
+ new PnjEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
+ OFFSET_Y + (MAP_HEIGHT / 2 - 2) * TILE_HEIGHT,
+ 0);
+ }
+
+ // for testing purpose (new stuff)
+ if (player->getAge() <2.0f)
+ {
+ /*ItemEntity* book = new ItemEntity(ItemEntity::itemHealth, player->getX(), player->getY()- 180);
+ book->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ book->setMerchandise(true);*/
+
+ int bonusType = getRandomEquipItem(true);
+ ItemEntity* boots = new ItemEntity((ItemEntity::enumItemType)(ItemEntity::itemMagicianHat + bonusType), player->getX(), player->getY()+ 180);
+ boots->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+
+ //ChestEntity* chest = new ChestEntity(player->getX() + 100, player->getY()+ 150, CHEST_FAIRY, false);
+ //chest->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ }
+
+ // check doors
+ doorEntity[0]->setVisible(currentMap->hasNeighbourUp() > 0);
+ if (currentMap->hasNeighbourUp() == 1) doorEntity[0]->setDoorType(0);
+ if (currentMap->hasNeighbourUp() == 2 || currentMap->getRoomType()==roomTypeBoss) doorEntity[0]->setDoorType(1);
+ if (currentMap->hasNeighbourUp() == 2 && !bossRoomOpened)
+ {
+ doorEntity[0]->setOpen(false);
+ currentMap->setTile(MAP_WIDTH/2, 0, MAP_DOOR);
+ }
+ else
+ doorEntity[0]->setOpen(true);
+
+ doorEntity[3]->setVisible(currentMap->hasNeighbourRight() > 0);
+ if (currentMap->hasNeighbourRight() == 1) doorEntity[3]->setDoorType(0);
+ if (currentMap->hasNeighbourRight() == 2 || currentMap->getRoomType()==roomTypeBoss) doorEntity[3]->setDoorType(1);
+ if (currentMap->hasNeighbourRight() == 2 && !bossRoomOpened)
+ {
+ doorEntity[3]->setOpen(false);
+ currentMap->setTile(MAP_WIDTH - 1, MAP_HEIGHT / 2, MAP_DOOR);
+ }
+ else
+ doorEntity[3]->setOpen(true);
+
+ doorEntity[2]->setVisible(currentMap->hasNeighbourDown() > 0);
+ if (currentMap->hasNeighbourDown() == 1) doorEntity[2]->setDoorType(0);
+ if (currentMap->hasNeighbourDown() == 2 || currentMap->getRoomType()==roomTypeBoss) doorEntity[2]->setDoorType(1);
+ if (currentMap->hasNeighbourDown() == 2 && !bossRoomOpened)
+ {
+ doorEntity[2]->setOpen(false);
+ currentMap->setTile(MAP_WIDTH/2, MAP_HEIGHT - 1, MAP_DOOR);
+ }
+ else
+ doorEntity[2]->setOpen(true);
+
+ doorEntity[1]->setVisible(currentMap->hasNeighbourLeft() > 0);
+ if (currentMap->hasNeighbourLeft() == 1) doorEntity[1]->setDoorType(0);
+ if (currentMap->hasNeighbourLeft() == 2 || currentMap->getRoomType()==roomTypeBoss) doorEntity[1]->setDoorType(1);
+ if (currentMap->hasNeighbourLeft() == 2 && !bossRoomOpened)
+ {
+ doorEntity[1]->setOpen(false);
+ currentMap->setTile(0, MAP_HEIGHT / 2, MAP_DOOR);
+ }
+ else
+ doorEntity[1]->setOpen(true);
+}
+
+void WitchBlastGame::refreshMinimap()
+{
+ for (int j=0; j < FLOOR_HEIGHT; j++)
+ for (int i=0; i < FLOOR_WIDTH; i++)
+ {
+ int n = currentFloor->getRoom(i, j);
+ if (n > 0 && currentFloor->getMap(i, j)->isVisited())
+ miniMap->setTile(i, j, currentFloor->getRoom(i, j));
+ else if (n > 0 && currentFloor->getMap(i, j)->isKnown())
+ miniMap->setTile(i, j, 9);
+ else
+ miniMap->setTile(i, j, 0);
+ }
+ miniMap->setTile(floorX, floorY, 8);
+}
+
+void WitchBlastGame::checkEntering()
+{
+ if (!currentMap->isCleared())
+ {
+ player->setEntering();
+ SoundManager::getSoundManager()->playSound(SOUND_DOOR_CLOSING);
+ for (int i=0; i<4; i++)
+ doorEntity[i]->closeDoor();
+ }
+}
+
+void WitchBlastGame::saveMapItems()
+{
+ EntityManager::EntityList* entityList =EntityManager::getEntityManager()->getList();
+ EntityManager::EntityList::iterator it;
+
+ for (it = entityList->begin (); it != entityList->end ();)
+ {
+ GameEntity* e = *it;
+ it++;
+
+ ItemEntity* itemEntity = dynamic_cast<ItemEntity*>(e);
+ ChestEntity* chestEntity = dynamic_cast<ChestEntity*>(e);
+
+ if (itemEntity != NULL)
+ {
+ currentMap->addItem(itemEntity->getItemType(), itemEntity->getX(), itemEntity->getY(), itemEntity->getMerchandise());
+ } // endif
+ else if (chestEntity != NULL)
+ {
+ currentMap->addChest(chestEntity->getChestType(), chestEntity->getOpened(), chestEntity->getX(), chestEntity->getY());
+ } // endif
+ else
+ {
+ SpriteEntity* spriteEntity = dynamic_cast<SpriteEntity*>(e);
+ if (spriteEntity != NULL && (e->getType() == TYPE_BLOOD || e->getType() == TYPE_CORPSE ) )
+ {
+ int spriteFrame = spriteEntity->getFrame();
+ if (spriteEntity->getWidth() == 128) spriteFrame += FRAME_CORPSE_KING_RAT;
+ currentMap->addSprite(e->getType(), spriteFrame, e->getX(), e->getY(), spriteEntity->getScaleX());
+ }
+
+ }
+ } // end for
+}
+
+void WitchBlastGame::moveToOtherMap(int direction)
+{
+ saveMapItems();
+ switch (direction)
+ {
+ case (4): floorX--; player->moveTo((OFFSET_X + MAP_WIDTH * TILE_WIDTH), player->getY()); player->move(4); break;
+ case (6): floorX++; player->moveTo(OFFSET_X, player->getY()); player->move(6); break;
+ case (8): floorY--; player->moveTo(player->getX(), OFFSET_Y + MAP_HEIGHT * TILE_HEIGHT - 10); player->move(8); break;
+ case (2): floorY++; player->moveTo(player->getX(), OFFSET_Y); break;
+ }
+ refreshMap();
+ checkEntering();
+ currentMap->restoreMapObjects();
+}
+
+void WitchBlastGame::onRender()
+{
+ // clear the view
+ app->clear(sf::Color(32, 32, 32));
+
+ // render the game objects
+ EntityManager::getEntityManager()->render(app);
+
+ myText.setColor(sf::Color(255, 255, 255, 255));
+ myText.setCharacterSize(17);
+ myText.setString("WASD or ZQSD to move\nArrows to shoot");
+ myText.setPosition(650, 650);
+ app->draw(myText);
+
+ myText.setCharacterSize(18);
+ std::ostringstream oss;
+ oss << player->getGold();
+ myText.setString(oss.str());
+ myText.setPosition(690, 612);
+ app->draw(myText);
+
+ myText.setColor(sf::Color(0, 0, 0, 255));
+ myText.setCharacterSize(16);
+ myText.setString("Level 1");
+ myText.setPosition(410, 692);
+ app->draw(myText);
+
+ sf::RectangleShape rectangle(sf::Vector2f(200, 25));
+ // life
+
+ if (gameState == gameStatePlaying)
+ {
+ // life and mana
+ rectangle.setFillColor(sf::Color(190, 20, 20));
+ rectangle.setPosition(sf::Vector2f(90, 622));
+ rectangle.setSize(sf::Vector2f(200.0f * (float)(player->getHpDisplay()) / (float)(player->getHpMax()) , 25));
+ app->draw(rectangle);
+
+ rectangle.setFillColor(sf::Color(255, 190, 190));
+ rectangle.setPosition(sf::Vector2f(90, 625));
+ rectangle.setSize(sf::Vector2f(200.0f * (float)(player->getHpDisplay()) / (float)(player->getHpMax()) , 2));
+ app->draw(rectangle);
+
+ rectangle.setFillColor(sf::Color(20, 20, 190));
+ rectangle.setPosition(sf::Vector2f(90, 658));
+ rectangle.setSize(sf::Vector2f(200.0f * player->getPercentFireDelay() , 25));
+ app->draw(rectangle);
+
+ rectangle.setFillColor(sf::Color(190, 190, 255));
+ rectangle.setPosition(sf::Vector2f(90, 661));
+ rectangle.setSize(sf::Vector2f(200.0f * player->getPercentFireDelay() , 2));
+ app->draw(rectangle);
+
+ // drawing the key on the interface
+ if (player->isEquiped(EQUIP_BOSS_KEY)) app->draw(keySprite);
+
+ if (player->isDead())
+ {
+ float x0 = OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2;
+ int fade = 255 * (1.0f + cos(2.0f * getAbsolutTime())) * 0.5f;
+
+ myText.setColor(sf::Color(255, 255, 255, 255));
+ myText.setCharacterSize(25);
+ myText.setString("GAME OVER");
+ myText.setPosition(x0 - myText.getLocalBounds().width / 2, 400);
+ app->draw(myText);
+
+ myText.setColor(sf::Color(255, 255, 255, fade));
+ myText.setCharacterSize(20);
+ myText.setString("Press [ENTER] to play again !");
+ myText.setPosition(x0 - myText.getLocalBounds().width / 2, 440);
+ app->draw(myText);
+ }
+ else if (currentMap->getRoomType() == roomTypeExit)
+ {
+ float x0 = OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2;
+ myText.setColor(sf::Color(255, 255, 255, 255));
+ myText.setCharacterSize(25);
+ myText.setString("CONGRATULATIONS !\nYou've challenged this demo and\nmanaged to kill the boss !\nSee you soon for new adventures !");
+ myText.setPosition(x0 - myText.getLocalBounds().width / 2, 220);
+ app->draw(myText);
+ }
+ }
+
+ app->display();
+}
+
+void WitchBlastGame::generateBlood(float x, float y, BaseCreatureEntity::enumBloodColor bloodColor)
+{
+ SpriteEntity* blood = new SpriteEntity(ImageManager::getImageManager()->getImage(IMAGE_BLOOD), x, y, 16, 16, 6);
+ //deadRat->setZ(y + height);
+ blood->setZ(OFFSET_Y - 1);
+ int b0 = 0;
+ if (bloodColor == BaseCreatureEntity::bloodGreen) b0 += 6;
+ blood->setFrame(b0 + rand()%6);
+ blood->setType(TYPE_BLOOD);
+ blood->setVelocity(Vector2D(rand()%250));
+ blood->setViscosity(0.95f);
+
+ float bloodScale = 1.0f + (rand() % 10) * 0.1f;
+ blood->setScale(bloodScale, bloodScale);
+}
+
+void WitchBlastGame::showArtefactDescription(ItemEntity::enumItemType itemType)
+{
+ new ArtefactDescriptionEntity(itemType, this); //, &font);
+}
+
+void WitchBlastGame::generateMap()
+{
+ if (currentMap->getRoomType() == roomTypeStandard)
+ generateStandardMap();
+ else if (currentMap->getRoomType() == roomTypeBonus)
+ {
+ currentMap->setCleared(true);
+ Vector2D v = currentMap->generateBonusRoom();
+ int bonusType = getRandomEquipItem(false);
+ if (bonusType == EQUIP_FAIRY)
+ {
+ ChestEntity* chest = new ChestEntity(v.x, v.y, CHEST_FAIRY, false);
+ chest->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ }
+ else
+ {
+ ItemEntity* newItem
+ = new ItemEntity( (ItemEntity::enumItemType)(ItemEntity::itemMagicianHat + bonusType), v.x ,v.y);
+ newItem->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ }
+ }
+ else if (currentMap->getRoomType() == roomTypeKey)
+ {
+ Vector2D v = currentMap->generateKeyRoom();
+ ItemEntity* newItem
+ = new ItemEntity( (ItemEntity::enumItemType)(ItemEntity::itemBossKey), v.x ,v.y);
+ newItem->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ initMonsterArray();
+ int x0 = MAP_WIDTH / 2;
+ int y0 = MAP_HEIGHT / 2;
+ monsterArray[x0][y0] = true;
+ findPlaceMonsters(MONSTER_RAT, 5);
+ findPlaceMonsters(MONSTER_BAT, 5);
+ }
+ else if (currentMap->getRoomType() == roomTypeMerchant)
+ {
+ currentMap->generateMerchantRoom();
+
+ ItemEntity* item1 = new ItemEntity(
+ ItemEntity::itemHealth,
+ OFFSET_X + (MAP_WIDTH / 2 - 2) * TILE_WIDTH + TILE_WIDTH / 2,
+ OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT);
+ item1->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ item1->setMerchandise(true);
+
+ int bonusType = getRandomEquipItem(true);
+ ItemEntity* item2 = new ItemEntity(
+ (ItemEntity::enumItemType)(ItemEntity::itemMagicianHat + bonusType),
+ OFFSET_X + (MAP_WIDTH / 2 + 2) * TILE_WIDTH + TILE_WIDTH / 2,
+ OFFSET_Y + (MAP_HEIGHT / 2) * TILE_HEIGHT);
+ item2->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ item2->setMerchandise(true);
+
+ new PnjEntity(OFFSET_X + (MAP_WIDTH / 2) * TILE_WIDTH + TILE_WIDTH / 2,
+ OFFSET_Y + (MAP_HEIGHT / 2 - 2) * TILE_HEIGHT,
+ 0);
+
+ currentMap->setCleared(true);
+ }
+ else if (currentMap->getRoomType() == roomTypeBoss)
+ {
+ currentMap->generateRoom(0);
+
+ boss = new KingRatEntity(OFFSET_X + (MAP_WIDTH / 2 - 2) * TILE_WIDTH + TILE_WIDTH / 2,
+ OFFSET_Y + (MAP_HEIGHT / 2 - 2) * TILE_HEIGHT + TILE_HEIGHT / 2,
+ currentMap, player);
+ }
+ else if (currentMap->getRoomType() == roomTypeStarting)
+ {
+ currentMap->generateRoom(0);
+ currentMap->setCleared(true);
+ }
+ else if (currentMap->getRoomType() == roomTypeExit)
+ {
+ currentMap->generateRoom(0);
+ currentMap->setCleared(true);
+ }
+ else
+ currentMap->randomize(currentMap->getRoomType());
+}
+
+void WitchBlastGame::initMonsterArray()
+{
+ for (int i = 0; i < MAP_WIDTH; i++)
+ for (int j = 0; j < MAP_HEIGHT; j++)
+ monsterArray[i][j] = false;
+}
+
+void WitchBlastGame::addMonster(monster_type_enum monsterType, float xm, float ym)
+{
+ switch (monsterType)
+ {
+ case MONSTER_RAT: new RatEntity(xm, ym - 2, currentMap); break;
+ case MONSTER_BAT: new BatEntity(xm, ym, currentMap); break;
+ case MONSTER_EVIL_FLOWER: new EvilFlowerEntity(xm, ym, currentMap, player); break;
+
+ case MONSTER_KING_RAT: new KingRatEntity(xm, ym, currentMap, player); break;
+ }
+}
+
+void WitchBlastGame::findPlaceMonsters(monster_type_enum monsterType, int amount)
+{
+ // find a suitable place
+ bool isMonsterFlying = monsterType == MONSTER_BAT;
+
+ bool bOk;
+ int xm, ym;
+ float xMonster, yMonster;
+
+ for (int index = 0; index < amount; index++)
+ {
+ bOk = false;
+
+ while (!bOk)
+ {
+ bOk = true;
+ xm = 1 +rand() % (MAP_WIDTH - 3);
+ ym = 1 +rand() % (MAP_HEIGHT - 3);
+ if (monsterArray[xm][ym])
+ {
+ bOk = false;
+ }
+ if (bOk && !isMonsterFlying && !currentMap->isWalkable(xm, ym))
+ {
+ bOk = false;
+ }
+ if (bOk)
+ {
+ xMonster = OFFSET_X + xm * TILE_WIDTH + TILE_WIDTH * 0.5f;
+ yMonster = OFFSET_Y + ym * TILE_HEIGHT+ TILE_HEIGHT * 0.5f;
+
+ float dist2 = (xMonster - player->getX())*(xMonster - player->getX()) + (yMonster - player->getY())*(yMonster - player->getY());
+ if ( dist2 < 75000.0f)
+ {
+ bOk = false;
+ }
+ else
+ {
+ addMonster(monsterType, xMonster, yMonster);
+ monsterArray[xm][ym] = true;
+ }
+ }
+ }
+ }
+}
+
+void WitchBlastGame::generateStandardMap()
+{
+ initMonsterArray();
+
+ int random = rand() % 100;
+
+ if (random < 20)
+ {
+ currentMap->generateRoom(rand()%3);
+ findPlaceMonsters(MONSTER_RAT,4);
+ }
+ else if (random < 40)
+ {
+ currentMap->generateRoom(rand()%4);
+ findPlaceMonsters(MONSTER_BAT,4);
+ }
+ else if (random < 60)
+ {
+ currentMap->generateRoom(rand()%4);
+ findPlaceMonsters(MONSTER_EVIL_FLOWER,4);
+ }
+ else if (random < 80)
+ {
+ Vector2D v = currentMap->generateBonusRoom();
+ ChestEntity* chest = new ChestEntity(v.x, v.y, CHEST_BASIC, false);
+ chest->setMap(currentMap, TILE_WIDTH, TILE_HEIGHT, OFFSET_X, OFFSET_Y);
+ currentMap->setCleared(true);
+ }
+ else
+ {
+ currentMap->generateRoom(rand()%3);
+ findPlaceMonsters(MONSTER_RAT,3);
+ findPlaceMonsters(MONSTER_BAT,3);
+ }
+ //currentMap->setCleared(true);
+}
+
+int WitchBlastGame::getRandomEquipItem(bool toSale = false)
+{
+ std::vector<int> bonusSet;
+ int setSize = 0;
+ for (int i = 0; i < NUMBER_EQUIP_ITEMS; i++)
+ {
+ if (!player->isEquiped(i) && i != EQUIP_BOSS_KEY)
+ {
+ if (!toSale || i!= EQUIP_FAIRY)
+ {
+ bonusSet.push_back(i);
+ setSize++;
+ }
+ }
+ }
+ int bonusType = 0;
+ if (setSize > 0) bonusType = bonusSet[rand() % setSize];
+
+ return bonusType;
+}
+
+void WitchBlastGame::verifyDoorUnlocking()
+{
+ int colliding = (player->getColliding());
+
+ if (colliding > 0 && currentMap->isCleared() && !bossRoomOpened && player->isEquiped(EQUIP_BOSS_KEY))
+ {
+ int xt = (player->getX() - OFFSET_X) / TILE_WIDTH;
+ int yt = (player->getY() - OFFSET_Y) / TILE_HEIGHT;
+ //std::cout << "VERIFY: " << xt << ", " << yt << std::endl;
+
+ if (yt <= 1 && xt >= MAP_WIDTH / 2 - 1 && xt <= MAP_WIDTH / 2 + 1 && currentMap->hasNeighbourUp() == 2)
+ {
+ //std::cout << "touch? !";
+ doorEntity[0]->openDoor();
+ currentMap->setTile(MAP_WIDTH / 2, 0, 0);
+ SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
+ player->useBossKey();
+ bossRoomOpened = true;
+ }
+ if (yt >= MAP_HEIGHT - 2 && xt >= MAP_WIDTH / 2 - 1 &&xt <= MAP_WIDTH / 2 + 1 && currentMap->hasNeighbourDown() == 2)
+ {
+ //std::cout << "touch? !";
+ doorEntity[2]->openDoor();
+ currentMap->setTile(MAP_WIDTH / 2, MAP_HEIGHT - 1, 0);
+ SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
+ player->useBossKey();
+ bossRoomOpened = true;
+ }
+ if (xt <= 1 && yt >= MAP_HEIGHT / 2 - 1 && yt <= MAP_HEIGHT / 2 + 1 && currentMap->hasNeighbourLeft() == 2)
+ {
+ //std::cout << "touch? !";
+ doorEntity[1]->openDoor();
+ currentMap->setTile(0, MAP_HEIGHT / 2, 0);
+ SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
+ player->useBossKey();
+ bossRoomOpened = true;
+ }
+ if (xt >= MAP_WIDTH - 2 && yt >= MAP_HEIGHT / 2 - 1 && yt <= MAP_HEIGHT / 2 + 1 && currentMap->hasNeighbourRight() == 2)
+ {
+ //std::cout << "touch? !";
+ doorEntity[3]->openDoor();
+ currentMap->setTile(MAP_WIDTH - 1, MAP_HEIGHT / 2, 0);
+ SoundManager::getSoundManager()->playSound(SOUND_DOOR_OPENING);
+ player->useBossKey();
+ bossRoomOpened = true;
+ }
+ }
+}
diff --git a/src/WitchBlastGame.h b/src/WitchBlastGame.h
new file mode 100644
index 0000000..ea27c67
--- /dev/null
+++ b/src/WitchBlastGame.h
@@ -0,0 +1,77 @@
+#ifndef MAGICGAME_H
+#define MAGICGAME_H
+
+#include "sfml_game/Game.h"
+#include "sfml_game/TileMapEntity.h"
+#include "PlayerEntity.h"
+#include "EnnemyEntity.h"
+#include "DoorEntity.h"
+#include "GameFloor.h"
+
+
+class WitchBlastGame : public Game
+{
+ public:
+ WitchBlastGame();
+ virtual ~WitchBlastGame();
+
+ virtual void startGame();
+ void moveToOtherMap(int direction);
+ void closeDoors();
+ void openDoors();
+ int GetEnnemyCount();
+ void generateBlood(float x, float y, BaseCreatureEntity::enumBloodColor bloodColor);
+ void showArtefactDescription(ItemEntity::enumItemType itemType);
+
+ void write(std::string test_str, int size, float x, float y);
+
+ protected:
+ virtual void onRender();
+
+ private:
+ bool isFiring;
+
+ PlayerEntity* player;
+ EnnemyEntity* boss;
+ GameMap* miniMap;
+ DungeonMap* currentMap;
+ GameFloor* currentFloor;
+
+ sf::Font font;
+ sf::Text myText;
+ sf::Sprite keySprite;
+ sf::Music music;
+
+ TileMapEntity* currentTileMap;
+
+ int floorX, floorY;
+
+ void startNewGame();
+
+ void createFloor();
+ void refreshMap();
+ void refreshMinimap();
+ void generateMap();
+ void generateStandardMap();
+ void checkEntering();
+ void saveMapItems();
+ void initMonsterArray();
+ void addMonster(monster_type_enum monsterType, float xm, float ym);
+ void findPlaceMonsters(monster_type_enum monsterType, int amount);
+ int getRandomEquipItem(bool toSale);
+ void verifyDoorUnlocking();
+
+ bool roomClosed;
+ bool bossRoomOpened;
+ enum gameStateEnum { gameStateInit, gameStatePlaying};
+ gameStateEnum gameState;
+
+ // use to remember if a case has a monster in monster spawn
+ bool monsterArray[MAP_WIDTH][MAP_HEIGHT];
+
+ // the doors graphics
+ //SpriteEntity* doorSprite[4];
+ DoorEntity* doorEntity[4];
+};
+
+#endif // MAGICGAME_H
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..47067dc
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,73 @@
+#include <SFML/Graphics.hpp>
+
+#include "WitchBlastGame.h"
+
+
+int main()
+{
+ WitchBlastGame game; //1200, 800);
+
+ game.startGame();
+
+ return 0;
+}
+
+/*
+#include <SFML/Graphics.hpp>
+
+class ClassA
+{
+public:
+ ClassA(sf::Font* font)
+ {
+ text_A.setFont(*font);
+ text_A.setString("Hello world");
+ text_A.setCharacterSize(24);
+ }
+
+ void display(sf::RenderWindow &window)
+ {
+ window.draw(text_A);
+ }
+
+private:
+ sf::Font* font_A;
+ sf::Text text_A;
+};
+
+int main()
+{
+ sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
+ sf::CircleShape shape(100.f);
+ shape.setFillColor(sf::Color::Green);
+
+
+ sf::Font* font = new sf::Font();
+ if (!font->loadFromFile("media/DejaVuSans-Bold.ttf")) {}
+ sf::Text text;
+ text.setFont(*font); // font est un sf::Font
+ text.setString("Hello world");
+ text.setCharacterSize(24); // exprim?e en pixels, pas en points !
+ text.setColor(sf::Color::Red);
+ text.setStyle(sf::Text::Bold | sf::Text::Underlined);
+
+ ClassA* classA = new ClassA(font);
+
+ while (window.isOpen())
+ {
+ sf::Event event;
+ while (window.pollEvent(event))
+ {
+ if (event.type == sf::Event::Closed)
+ window.close();
+ }
+
+ window.clear();
+ window.draw(text);
+ classA->display(window);
+ window.display();
+ }
+
+ return 0;
+}
+*/
diff --git a/src/sfml_game/CollidingSpriteEntity.cpp b/src/sfml_game/CollidingSpriteEntity.cpp
new file mode 100644
index 0000000..c73b9d1
--- /dev/null
+++ b/src/sfml_game/CollidingSpriteEntity.cpp
@@ -0,0 +1,280 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "CollidingSpriteEntity.h"
+
+CollidingSpriteEntity::CollidingSpriteEntity(sf::Texture* image, float x, float y, int width, int height)
+ : SpriteEntity(image, x, y, width, height)
+{
+ maxY = 1000.0f;
+}
+
+CollidingSpriteEntity::~CollidingSpriteEntity()
+{
+}
+
+GameMap* CollidingSpriteEntity::getMap()
+{
+ return map;
+}
+
+void CollidingSpriteEntity::setMap(GameMap* map, int tileWidth, int tileHeight, int offsetX, int offsetY)
+{
+ this->map = map;
+ setTileDimensions(tileWidth, tileHeight);
+ this->offsetX = offsetX;
+ this->offsetY = offsetY;
+}
+
+void CollidingSpriteEntity::setTileDimensions(int width, int height)
+{
+ tileWidth = width;
+ tileHeight = height;
+}
+
+void CollidingSpriteEntity::render(sf::RenderWindow* app)
+{
+ SpriteEntity::render(app);
+}
+
+
+void CollidingSpriteEntity::animate(float delay)
+{
+ velocity.x *= viscosity;
+ velocity.y *= viscosity;
+
+ spin *= viscosity;
+ angle += spin * delay;
+
+ velocity.y += weight * delay;
+
+ if ((int)velocity.x > 0)
+ {
+ x += velocity.x * delay;
+
+ if (collideWithMap(DIRECTION_LEFT))
+ {
+ x = (float)((int)x);
+ while (collideWithMap(DIRECTION_LEFT))
+ x--;
+ collideMapRight();
+ }
+ else if (x > map->getWidth() * tileWidth + offsetX)
+ {
+ exitMap(DIRECTION_RIGHT);
+ }
+ }
+ else if ((int)velocity.x < 0)
+ {
+ x += velocity.x * delay;
+
+ if (collideWithMap(DIRECTION_RIGHT))
+ {
+ x = (float)((int)x);
+ while (collideWithMap(DIRECTION_RIGHT))
+ x++;
+ collideMapLeft();
+ }
+ else if (x < offsetX)
+ {
+ exitMap(DIRECTION_LEFT);
+ }
+ }
+
+ velocity.y += weight * delay;
+ if ( velocity.y > maxY) velocity.y = maxY;
+
+ if ((int)velocity.y > 0)
+ {
+ y += velocity.y * delay;
+
+ if (collideWithMap(DIRECTION_BOTTOM))
+ {
+ y = (float)((int)y);
+ while (collideWithMap(DIRECTION_BOTTOM))
+ y--;
+ collideMapBottom();
+ }
+ }
+ else if ((int)velocity.y < 0)
+ {
+ y += velocity.y * delay;
+ //calculateBB();
+
+ if (collideWithMap(DIRECTION_TOP))
+ {
+ y = (float)((int)y);
+ while (collideWithMap(DIRECTION_TOP))
+ y++;
+ collideMapTop();
+ }
+ }
+
+
+
+ // for platforming
+ /* if ((int)weight == 0)
+ {
+ if (!(isOnGround()))
+ {
+ makeFall();
+ }
+ }*/
+
+ if (lifetime > 0)
+ {
+ if (age >= lifetime) isDying = true;
+ }
+ age += delay;
+}
+
+void CollidingSpriteEntity::calculateBB()
+{
+ boundingBox.left = (int)x - width / 2;
+ boundingBox.width = width;
+ boundingBox.top = (int)y - height / 2;
+ boundingBox.height = height;
+}
+
+void CollidingSpriteEntity::makeFall()
+{
+ weight = normalWeight;
+}
+
+bool CollidingSpriteEntity::isOnGround()
+{
+ calculateBB();
+
+ int xTile0 = (boundingBox.left - offsetX) / tileWidth;
+ int xTilef = (boundingBox.left + boundingBox.width - offsetX) / tileWidth;
+ int yTile = (boundingBox.top + boundingBox.height + 1 - offsetY) / tileHeight;
+
+ for (int xTile = xTile0; xTile <= xTilef; xTile++)
+ {
+ if (map->isDownBlocking(xTile, yTile)) return true;
+ }
+ return false;
+}
+
+void CollidingSpriteEntity::exitMap(int direction)
+{
+ if (direction == 0) {}
+}
+
+void CollidingSpriteEntity::collideMapRight()
+{
+ velocity.x = 0.0f;
+}
+
+void CollidingSpriteEntity::collideMapLeft()
+{
+ velocity.x = 0.0f;
+}
+
+void CollidingSpriteEntity::collideMapTop()
+{
+ velocity.y = 0.0f;
+}
+
+void CollidingSpriteEntity::collideMapBottom()
+{
+ velocity.y = 0.0f;
+}
+
+
+bool CollidingSpriteEntity::collideWithMap(int direction)
+{
+ calculateBB();
+
+ int xTile0 = (boundingBox.left - offsetX) / tileWidth;
+ int xTilef = (boundingBox.left + boundingBox.width - offsetX) / tileWidth;
+ int yTile0 = (boundingBox.top - offsetY) / tileHeight;
+ int yTilef = (boundingBox.top + boundingBox.height - offsetY) / tileHeight;
+
+ if (boundingBox.top < 0) yTile0 = -1;
+
+ for (int xTile = xTile0; xTile <= xTilef; xTile++)
+ for (int yTile = yTile0; yTile <= yTilef; yTile++)
+ {
+ switch (direction)
+ {
+ case DIRECTION_LEFT:
+ if (map->isLeftBlocking(xTile, yTile)) return true;
+ break;
+
+ case DIRECTION_RIGHT:
+ if (map->isRightBlocking(xTile, yTile)) return true;
+ break;
+
+ case DIRECTION_TOP:
+ if (map->isUpBlocking(xTile, yTile)) return true;
+ break;
+
+ case DIRECTION_BOTTOM:
+ if (map->isDownBlocking(xTile, yTile)) return true;
+ break;
+ }
+ }
+
+ return false;
+}
+
+bool CollidingSpriteEntity::collideWithEntity(CollidingSpriteEntity* entity)
+{
+ calculateBB();
+ entity->calculateBB();
+
+ return boundingBox.intersects(entity->boundingBox);
+
+ /*if (boundingBox.left > entity->boundingBox.left + entity->boundingBox.width) return false;
+ if (boundingBox.Right < entity->boundingBox.Left) return false;
+ if (boundingBox.Top > entity->boundingBox.Bottom) return false;
+ if (boundingBox.Bottom < entity->boundingBox.Top) return false;*/
+
+ return true;
+}
+
+void CollidingSpriteEntity::testSpriteCollisions()
+{
+ EntityManager::EntityList* entityList = EntityManager::getEntityManager()->getList();
+
+ EntityManager::EntityList::iterator it;
+ EntityManager::EntityList::iterator oldit = entityList->begin ();
+
+ for (it = entityList->begin (); it != entityList->end ();)
+ {
+ GameEntity* entity = *it;
+
+ CollidingSpriteEntity* collidingEntity = dynamic_cast<CollidingSpriteEntity*>(entity);
+ if (collidingEntity != NULL)
+ {
+ readCollidingEntity(collidingEntity);
+ }
+ oldit = it;
+ it++;
+
+ } // end for*/
+}
+
+void CollidingSpriteEntity::readCollidingEntity(CollidingSpriteEntity* entity)
+{
+ if (entity == NULL) return;
+}
+
+void CollidingSpriteEntity::collideEntity(CollidingSpriteEntity* entity)
+{
+ if (entity == NULL) return;
+}
diff --git a/src/sfml_game/CollidingSpriteEntity.h b/src/sfml_game/CollidingSpriteEntity.h
new file mode 100644
index 0000000..e06f294
--- /dev/null
+++ b/src/sfml_game/CollidingSpriteEntity.h
@@ -0,0 +1,76 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef COLLIDINGSPRITEENTITY_H_INCLUDED
+#define COLLIDINGSPRITEENTITY_H_INCLUDED
+
+#include "SpriteEntity.h"
+#include "GameMap.h"
+
+// Basis class for Jouster
+class CollidingSpriteEntity : public SpriteEntity
+{
+public:
+ CollidingSpriteEntity(sf::Texture* image, float x = 0.0f, float y = 0.0f, int width = -1, int height = -1);
+ ~CollidingSpriteEntity();
+
+ GameMap* getMap();
+ void setMap(GameMap* map, int tileWidth, int tileHeight, int offsetX, int offsetY);
+ void setTileDimensions(int width, int height);
+
+ virtual void render(sf::RenderWindow* app);
+ virtual void animate(float delay);
+
+ virtual void calculateBB();
+ virtual void makeFall();
+ virtual bool collideWithMap(int direction);
+ virtual bool collideWithEntity(CollidingSpriteEntity* entity);
+
+ enum directionEnum
+ {
+ DIRECTION_RIGHT,
+ DIRECTION_LEFT,
+ DIRECTION_TOP,
+ DIRECTION_BOTTOM
+ };
+
+ bool isOnGround();
+
+protected:
+ GameMap* map; // map to test collisions with
+ sf::IntRect boundingBox; // BoundingBox
+ int tileWidth;
+ int tileHeight;
+ int offsetX;
+ int offsetY;
+
+ float normalWeight;
+ float maxY;
+
+ virtual void exitMap(int direction);
+
+ virtual void collideMapRight();
+ virtual void collideMapLeft();
+ virtual void collideMapTop();
+ virtual void collideMapBottom();
+
+ virtual void collideEntity(CollidingSpriteEntity* entity);
+
+ virtual void testSpriteCollisions();
+ virtual void readCollidingEntity(CollidingSpriteEntity* entity);
+};
+
+#endif // COLLIDINGSPRITEENTITY_H_INCLUDED
diff --git a/src/sfml_game/EntityManager.cpp b/src/sfml_game/EntityManager.cpp
new file mode 100644
index 0000000..9f69fdc
--- /dev/null
+++ b/src/sfml_game/EntityManager.cpp
@@ -0,0 +1,197 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "EntityManager.h"
+#include <stdlib.h>
+#include <iostream>
+
+#include "GuiEntity.h"
+
+EntityManager::EntityManager()
+{
+ initIterator();
+ mItems = 0;
+}
+
+ EntityManager* EntityManager::getEntityManager()
+ {
+ static EntityManager singleton;
+ return &singleton;
+ }
+
+
+void EntityManager::add(GameEntity* g)
+{
+ entityList.push_back(g);
+ mItems++;
+}
+
+
+void EntityManager::initIterator()
+{
+ mIterator = entityList.begin ();
+}
+
+GameEntity* EntityManager::nextItem()
+{
+ if (mIterator == entityList.end ()) return NULL;
+
+ GameEntity *e = *mIterator;
+ mIterator++;
+ return e;
+}
+
+void EntityManager::animate (float delay)
+{
+ if (!isEmpty())
+ {
+ EntityList::iterator it;
+ EntityList::iterator oldit = entityList.begin ();
+ //bool isBegin = false;
+ for (it = entityList.begin (); it != entityList.end () && !isEmpty();)
+ {
+ GameEntity *e = *it;
+ oldit = it;
+ it++;
+
+ if (e->getDying())
+ {
+ entityList.erase(oldit);
+ e->onDying();
+ delete e;
+ //e == NULL;
+ mItems--;
+ } // endif
+ else
+ e->animate(delay);
+ } // end for
+ }
+}
+
+void EntityManager::render(sf::RenderWindow* app)
+{
+ if (!isEmpty())
+ {
+ EntityList::iterator it;
+ EntityList::iterator oldit = entityList.begin ();
+ //bool isBegin = false;
+ for (it = entityList.begin (); it != entityList.end () && !isEmpty();)
+ {
+ GameEntity* e = *it;
+ oldit = it;
+ e->render(app);
+ it++;
+ } // end for
+ }
+}
+
+void EntityManager::onEvent(sf::Event event)
+{
+ if (!isEmpty())
+ {
+ EntityList::iterator it;
+ EntityList::iterator oldit = entityList.begin ();
+ for (it = entityList.begin (); it != entityList.end () && !isEmpty();)
+ {
+ GuiEntity* guiEntity = dynamic_cast<GuiEntity*>(*it);
+ if (guiEntity != NULL)
+ {
+ guiEntity->onEvent(event);
+ }
+ oldit = it;
+ it++;
+ } // end for
+ }
+}
+
+void EntityManager::clean ()
+{
+ if (!isEmpty())
+ {
+ EntityList::iterator it;
+ EntityList::iterator oldit = entityList.begin ();
+ //bool isBegin = false;
+ //EL.clear();
+ for (it = entityList.begin (); it != entityList.end ();)
+ {
+ GameEntity *e = *it;
+ oldit = it;
+ it++;
+
+ entityList.erase(oldit);
+
+ //e->onDying();
+ delete e;
+ //e == NULL;
+ } // end for*/
+ mItems = 0;
+ }
+}
+
+void EntityManager::displayToConsole()
+{
+ std::cout << "{ ";
+ if (!isEmpty())
+ {
+ EntityList::iterator it;
+ //bool isBegin = false;
+ //EL.clear();
+ for (it = entityList.begin (); it != entityList.end ();)
+ {
+ GameEntity *e = *it;
+ it++;
+
+ std::cout << e->getType() << ", ";
+ //e == NULL;
+ } // end for*/
+ }
+ std::cout << " }" << std::endl;
+}
+
+void EntityManager::partialClean (int n)
+{
+ if (!isEmpty())
+ {
+ EntityList::iterator it;
+ //bool isBegin = false;
+ for (it = entityList.begin (); it != entityList.end () && !isEmpty();)
+ {
+ GameEntity *e = *it;
+ it++;
+
+ if (e->getType() >= n)
+ {
+ e->setDying(true);
+ } // endif
+ } // end for
+ }
+}
+
+EntityManager::EntityList* EntityManager::getList()
+{
+ return &entityList;
+}
+
+
+bool compareZ(GameEntity* g1, GameEntity* g2)
+{
+ return g1->getZ() < g2->getZ();
+}
+
+void EntityManager::sortByZ()
+{
+ entityList.sort(compareZ);
+}
diff --git a/src/sfml_game/EntityManager.h b/src/sfml_game/EntityManager.h
new file mode 100644
index 0000000..656977d
--- /dev/null
+++ b/src/sfml_game/EntityManager.h
@@ -0,0 +1,66 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ENTITYMANAGER
+#define __ENTITYMANAGER
+
+#include <list>
+class GameEntity;
+#include "GameEntity.h"
+
+class EntityManager
+{
+
+public:
+ static EntityManager* getEntityManager();
+
+ void initIterator();
+ void add(GameEntity* g);
+ void animate (float delay);
+ void render (sf::RenderWindow* app);
+ void onEvent(sf::Event event);
+ void displayToConsole();
+
+ typedef std::list<GameEntity*> EntityList;
+
+ EntityList* getList();
+ void clean();
+ void partialClean(int n);
+ void sortByZ();
+
+protected:
+ EntityManager();
+ ~EntityManager() { clean(); }; // TODO !
+
+ GameEntity* nextItem();
+
+
+ bool isEmpty() { return mItems == 0; };
+ int count() { return mItems; }
+
+ void saveIterator() { mSavedIterator = mIterator; }
+ void restoreIterator() { mIterator = mSavedIterator; }
+
+
+private:
+
+ EntityList entityList;
+ EntityList::iterator mIterator, mSavedIterator;
+ int mItems;
+
+};
+
+#endif
diff --git a/src/sfml_game/Game.cpp b/src/sfml_game/Game.cpp
new file mode 100644
index 0000000..262428f
--- /dev/null
+++ b/src/sfml_game/Game.cpp
@@ -0,0 +1,101 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Game.h"
+
+#include "GameEntity.h"
+#include "EntityManager.h"
+
+#include <iostream>
+
+Game::Game(int screenWidth, int screenHeight, std::string windowsTitle, bool fullScreen)
+{
+ this->screenWidth = screenWidth;
+ this->screenHeight = screenHeight;
+
+ if (fullScreen)
+ app = new sf::RenderWindow(sf::VideoMode(this->screenWidth, this->screenHeight), windowsTitle, sf::Style::Fullscreen);
+ else
+ app = new sf::RenderWindow(sf::VideoMode(this->screenWidth, this->screenHeight), windowsTitle); // , sf::Style::Close);
+ app->setFramerateLimit(60);
+}
+
+Game::~Game()
+{
+ printf("Deleting the game...\n");
+ //delete(app);
+}
+
+float Game::getAbsolutTime()
+{
+ static sf::Clock clock;
+ //return clock.getElapsedTime();
+ return clock.getElapsedTime().asSeconds();
+}
+
+void Game::startGame()
+{
+ lastTime = getAbsolutTime();
+
+ // Start game loop
+ while (app->isOpen())
+ {
+
+
+
+ // Process events
+ sf::Event event;
+
+ while (app->pollEvent(event))
+ {
+
+ // Close window : exit
+ if (event.type == sf::Event::Closed)
+ app->close();
+
+ }
+
+ onUpdate();
+ onRender();
+
+ }
+
+ quitGame();
+}
+
+void Game::quitGame()
+{
+}
+
+void Game::onRender()
+{
+ // clear the view
+ app->clear(sf::Color(32, 32, 32));
+
+ // render the game objects
+ EntityManager::getEntityManager()->render(app);
+
+ app->display();
+}
+
+void Game::onUpdate()
+{
+ float delta = getAbsolutTime() - lastTime;
+ lastTime = getAbsolutTime();
+ EntityManager::getEntityManager()->animate(delta);
+ //if (delta > 0.02f) std::cout << delta << std::endl;
+}
+
diff --git a/src/sfml_game/Game.h b/src/sfml_game/Game.h
new file mode 100644
index 0000000..a64ed92
--- /dev/null
+++ b/src/sfml_game/Game.h
@@ -0,0 +1,51 @@
+/** This file is part of sfmlGame.
+ *
+ * sfmlGame is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * sfmlGame is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with sfmlGame. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GAME_H_INCLUDED
+#define GAME_H_INCLUDED
+
+#include <stdio.h>
+
+#include <SFML/Graphics.hpp>
+#include <SFML/Window.hpp>
+#include <SFML/Audio.hpp>
+
+//#include "Entity/EntityManager.h"
+
+class Game
+{
+ public:
+ Game(int screenWidth, int screenHeight, std::string windowsTitle = "Generic sfmlGame", bool fullScreen = false);
+ virtual ~Game();
+
+ virtual void startGame();
+ virtual void quitGame();
+
+ static float getAbsolutTime();
+
+ protected:
+ virtual void onRender(); // screen and game items rendering
+ virtual void onUpdate();
+
+ int screenWidth;
+ int screenHeight;
+
+ float lastTime;
+
+ sf::RenderWindow* app;
+};
+
+#endif // GAME_H_INCLUDED
diff --git a/src/sfml_game/GameEntity.cpp b/src/sfml_game/GameEntity.cpp
new file mode 100644
index 0000000..f8db7d7
--- /dev/null
+++ b/src/sfml_game/GameEntity.cpp
@@ -0,0 +1,123 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "GameEntity.h"
+#include <stdlib.h>
+
+GameEntity::GameEntity()
+{
+ GameEntity(0.0f, 0.0f);
+ type = 0;
+}
+
+bool GameEntity::operator < (const GameEntity& rhs)
+{
+ return z > rhs.z;
+}
+
+GameEntity::GameEntity(float m_x, float m_y)
+{
+ x = m_x;
+ y = m_y;
+ bbox.x = 0.0f; bbox.y = 0.0f;
+ bbox.width = 0.0f; bbox.height = 0.0f;
+ age = 0;
+ lifetime = -1;
+ visible = true;
+ isDying = false;
+ viscosity = 1.0f;
+
+ weight = 0.0f;
+ velocity.x = 0.0f;
+ velocity.y = 0.0f;
+
+ angle = 0.0f;
+ spin = 0.0f;
+
+ EntityManager::getEntityManager()->add(this);
+}
+
+GameEntity::~GameEntity()
+{
+}
+
+bool GameEntity::getDying() { return isDying; }
+float GameEntity::getX() { return x; }
+float GameEntity::getY() { return y; }
+float GameEntity::getZ() { return z; }
+float GameEntity::getAge() { return age; }
+int GameEntity::getType() { return type; }
+Vector2D GameEntity::getVelocity() { return Vector2D(velocity.x, velocity.y); }
+
+void GameEntity::setX(float x) { this->x = x; }
+void GameEntity::setY(float y) { this->y = y; }
+void GameEntity::setZ(float z) { this->z = z; }
+void GameEntity::setAngle(float angle) { this->angle = angle; }
+void GameEntity::setWeight(float weight) { this->weight = weight; }
+void GameEntity::setSpin(float spin) { this->spin = spin; }
+void GameEntity::setAge(float age) { this->age = age; }
+void GameEntity::setLifetime(float lifetime) { this->lifetime = lifetime; }
+void GameEntity::setVelocity(Vector2D velocity)
+{
+ this->velocity.x = velocity.x;
+ this->velocity.y = velocity.y;
+}
+void GameEntity::setDying(bool dying) { isDying = dying; }
+void GameEntity::setType(int type) { this->type = type; }
+void GameEntity::setViscosity(float viscosity) { this->viscosity = viscosity; }
+
+void GameEntity::animate(float delay)
+{
+ velocity.x *= viscosity;
+ velocity.y *= viscosity;
+
+ spin *= viscosity;
+ angle += spin * delay;
+
+ velocity.y += weight * delay;
+
+ x += velocity.x * delay;
+ y += velocity.y * delay;
+
+
+ age += delay;
+ if (lifetime > 0)
+ {
+ if (age >= lifetime) isDying = true;
+ }
+}
+
+void GameEntity::render(sf::RenderWindow* app)
+{
+ if (app == NULL) return;
+}
+
+void GameEntity::onDying()
+{
+}
+
+float GameEntity::getFade()
+{
+ if (lifetime > 0)
+ {
+ float f= 1.0f - (float)age/lifetime;
+ if (f < 0.0f) f=0.0f;
+ if (f > 1.0f) f=1.0f;
+ return f;
+ }
+ else return 1.0f;
+}
+
diff --git a/src/sfml_game/GameEntity.h b/src/sfml_game/GameEntity.h
new file mode 100644
index 0000000..0abfdbe
--- /dev/null
+++ b/src/sfml_game/GameEntity.h
@@ -0,0 +1,102 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GAMEENTITY
+#define __GAMEENTITY
+
+#include <SFML/Graphics.hpp>
+
+#include "MyTools.h"
+#include "EntityManager.h"
+#include "Game.h"
+
+class EntityManager;
+
+/** Objects to be displayed during the game.
+ * A basic physics has been implemented.
+ * The EntityManager will destroy the GameEntity when dying. */
+class GameEntity
+{
+public:
+ struct bboxStruct
+ {
+ float x, y, width, height;
+ } bbox;
+
+ GameEntity();
+ GameEntity(float m_x, float m_y);
+ //GameEntity(float m_x = 0.0f, float m_y = 0.0f, m_type = TypePart02 );
+
+ virtual ~GameEntity();
+
+ bool operator < (const GameEntity& rhs);
+
+
+ // accesors
+ bool getDying();
+ float getX();
+ float getY();
+ float getZ();
+ Vector2D getVelocity();
+ float getAge();
+ int getType();
+
+ // mutators
+ void setX(float x);
+ void setY(float y);
+ void setZ(float z);
+ void setAngle(float angle);
+ void setWeight(float weight);
+ void setVelocity(Vector2D velocity);
+ void setSpin(float spin);
+ void setAge(float age);
+ void setLifetime(float lifetime);
+ void setDying(bool dying);
+ void setType(int type);
+ void setViscosity(float viscosity);
+
+
+ virtual void render(sf::RenderWindow* app);
+ virtual void animate(float delay);
+
+ virtual void onDying();
+
+ float getFade();
+
+
+
+protected:
+ // position and physics (geometry)
+ float x, y, z;
+ float angle;
+ float spin;
+
+ Vector2D velocity;
+ Vector2D acceleration;
+ float weight;
+ float viscosity;
+
+ // visibility
+ bool visible;
+
+ // life_time
+ float age, lifetime;
+ bool isDying;
+
+ int type;
+};
+
+#endif
diff --git a/src/sfml_game/GameMap.cpp b/src/sfml_game/GameMap.cpp
new file mode 100644
index 0000000..a601cd1
--- /dev/null
+++ b/src/sfml_game/GameMap.cpp
@@ -0,0 +1,125 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <cstdlib>
+#include <fstream>
+
+#include "GameMap.h"
+
+GameMap::GameMap(int width, int height)
+{
+ this->width = width;
+ this->height = height;
+
+ map = new int* [width];
+ int i = 0;
+ for ( i = 0 ; i < width ; i++)
+ map[i] = new int [height];
+
+ for ( i = 0 ; i < width ; i++)
+ for ( int j = 0 ; j < height ; j++)
+ map[i][j] = 0;
+}
+
+GameMap::~GameMap()
+{
+ for ( int i = 0 ; i < width ; i++)
+ delete map [i];
+ delete map;
+}
+
+int GameMap::getWidth() { return width; }
+int GameMap::getHeight() { return height; }
+
+int GameMap::getTile(int x, int y)
+{
+ if (!inMap(x, y)) return -1;
+ return map[x][y];
+}
+
+bool GameMap::inMap(int x, int y)
+{
+ if (x < 0) return false;
+ if (y < 0) return false;
+ if (x >= width) return false;
+ if (y >= height) return false;
+ return true;
+}
+
+bool GameMap::isDownBlocking(int x, int y)
+{
+ if (!inMap(x, y)) return false;
+ return (map[x][y] > 0);
+}
+
+bool GameMap::isUpBlocking(int x, int y)
+{
+ if (y < 0) return true;
+ if (!inMap(x, y)) return false;
+ return (map[x][y] > 0);
+}
+
+bool GameMap::isLeftBlocking(int x, int y)
+{
+ if (!inMap(x, y)) return false;
+ return (map[x][y] > 0);
+}
+
+bool GameMap::isRightBlocking(int x, int y)
+{
+ if (!inMap(x, y)) return false;
+ return (map[x][y] > 0);
+}
+
+void GameMap::setTile(int x, int y, int n)
+{
+ if (!inMap(x, y)) return;
+ map[x][y] = n;
+}
+
+void GameMap::randomize(int n)
+{
+ for ( int i = 0 ; i < width ; i++)
+ for ( int j = 0 ; j < height ; j++)
+ map[i][j] = (int) (((float) rand() / (float)RAND_MAX * ((float)n)));
+
+}
+
+void GameMap::loadFromFile(const char* fileName)
+{
+ ifstream f(fileName);
+ if (!f.is_open()) return;
+
+ int n;
+ int i;
+
+ // dimensions
+ f >> n;
+ if (n != width) return;
+ f >> n;
+ if (n != height) return;
+
+ for (int j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+ f >> n;
+ map[i][j] = n;
+ }
+ }
+
+ f.close();
+}
diff --git a/src/sfml_game/GameMap.h b/src/sfml_game/GameMap.h
new file mode 100644
index 0000000..30c2e0b
--- /dev/null
+++ b/src/sfml_game/GameMap.h
@@ -0,0 +1,50 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GAMEMAP_H_INCLUDED
+#define GAMEMAP_H_INCLUDED
+
+#include <string>
+
+using namespace std ;
+
+class GameMap
+{
+public:
+ GameMap(int width, int height);
+ virtual ~GameMap();
+ int getWidth();
+ int getHeight();
+ int getTile(int x, int y);
+
+ virtual bool isDownBlocking(int x, int y);
+ virtual bool isUpBlocking(int x, int y);
+ virtual bool isLeftBlocking(int x, int y);
+ virtual bool isRightBlocking(int x, int y);
+
+ bool inMap(int x, int y);
+ void setTile(int x, int y, int n);
+
+ virtual void randomize(int n);
+ virtual void loadFromFile(const char* fileName);
+
+protected:
+ int width;
+ int height;
+ int** map;
+};
+
+#endif // GAMEMAP_H_INCLUDED
diff --git a/src/sfml_game/GuiEntity.cpp b/src/sfml_game/GuiEntity.cpp
new file mode 100644
index 0000000..cc270bf
--- /dev/null
+++ b/src/sfml_game/GuiEntity.cpp
@@ -0,0 +1,41 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "GuiEntity.h"
+
+GuiEntity::GuiEntity(float x, float y) : GameEntity(x, y)
+{
+ isActive = true;
+}
+
+bool GuiEntity::getActive() { return isActive; }
+
+void GuiEntity::setActive(bool active) { isActive = active; }
+
+void GuiEntity::render(sf::RenderWindow* app)
+{
+ if (app == NULL) return;
+}
+
+void GuiEntity::animate(float delay)
+{
+ GameEntity::animate(delay);
+}
+
+void GuiEntity::onEvent(sf::Event event)
+{
+ if (event.type == sf::Event::Closed) return;
+}
diff --git a/src/sfml_game/GuiEntity.h b/src/sfml_game/GuiEntity.h
new file mode 100644
index 0000000..506e75b
--- /dev/null
+++ b/src/sfml_game/GuiEntity.h
@@ -0,0 +1,41 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GUIENTITY_H_INCLUDED
+#define GUIENTITY_H_INCLUDED
+
+#include "GameEntity.h"
+
+// Basis class for GUI
+class GuiEntity : public GameEntity
+{
+public:
+ GuiEntity(float x = 0.0f, float y = 0.0f);
+
+ bool getActive();
+
+ void setActive(bool active);
+
+ virtual void render(sf::RenderWindow* app);
+ virtual void animate(float delay);
+
+ virtual void onEvent(sf::Event event);
+
+protected:
+ bool isActive;
+};
+
+#endif // GUIENTITY_H_INCLUDED
diff --git a/src/sfml_game/ImageManager.cpp b/src/sfml_game/ImageManager.cpp
new file mode 100644
index 0000000..29117af
--- /dev/null
+++ b/src/sfml_game/ImageManager.cpp
@@ -0,0 +1,58 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ImageManager.h"
+#include <stdio.h>
+
+ImageManager::ImageManager()
+{
+}
+
+ImageManager::~ImageManager()
+{
+ printf("Releasing video memory...\n");
+ for (unsigned int i = 0; i < imageArray.size(); i++)
+ {
+ delete(imageArray[i]);
+ }
+ imageArray.clear();
+}
+
+ ImageManager* ImageManager::getImageManager()
+ {
+ static ImageManager singleton;
+ return &singleton;
+ }
+
+void ImageManager::addImage(char* fileName)
+{
+ sf::Texture* newImage = new sf::Texture;
+ newImage->loadFromFile(fileName);
+ imageArray.push_back(newImage);
+}
+
+bool ImageManager::reloadImage(int n, const char* fileName)
+{
+ sf::Texture* newImage = new sf::Texture;
+ bool result = newImage->loadFromFile(fileName);
+ imageArray[n] = newImage;
+ return result;
+}
+
+sf::Texture* ImageManager::getImage(int n)
+{
+ return imageArray[n];
+}
diff --git a/src/sfml_game/ImageManager.h b/src/sfml_game/ImageManager.h
new file mode 100644
index 0000000..8ed2dd2
--- /dev/null
+++ b/src/sfml_game/ImageManager.h
@@ -0,0 +1,37 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IMAGEMANAGER_H_INCLUDED
+#define IMAGEMANAGER_H_INCLUDED
+
+#include <SFML/Graphics.hpp>
+
+class ImageManager
+{
+public:
+ static ImageManager* getImageManager();
+ void addImage(char* fileName);
+ bool reloadImage(int n, const char* fileName);
+ sf::Texture* getImage(int n);
+
+private:
+ ImageManager();
+ ~ImageManager();
+
+ std::vector<sf::Texture*> imageArray;
+};
+
+#endif // IMAGEMANAGER_H_INCLUDED
diff --git a/src/sfml_game/MyTools.h b/src/sfml_game/MyTools.h
new file mode 100644
index 0000000..c3dce91
--- /dev/null
+++ b/src/sfml_game/MyTools.h
@@ -0,0 +1,65 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MYTOOLS
+#define __MYTOOLS
+
+#include <stdlib.h>
+#include <math.h>
+
+/** Vector utility, used in physics
+ ** Default constructor creates a random Vector */
+class Vector2D
+{
+public:
+ float x, y;
+ Vector2D(float amplitude = 1.0f)
+ {
+ float v = (float)rand() / (float)RAND_MAX;
+ v *= 6.283f;
+ x = cosf(v) * amplitude;
+ y = sinf(v) * amplitude;
+ }
+
+ Vector2D(float m_x, float m_y) { x = m_x; y = m_y; }
+
+ float distance2(Vector2D vector)
+ {
+ return ( (vector.x - x) * (vector.x - x) + (vector.y - y) * (vector.y - y) );
+ }
+
+ float distance2(Vector2D vector, float repeatZone)
+ {
+ float result = (vector.x - x) * (vector.x - x) + (vector.y - y) * (vector.y - y);
+
+ float d2 = (vector.x - ( x + repeatZone) ) * (vector.x - ( x + repeatZone)) + (vector.y - y) * (vector.y - y);
+ if (d2 < result) result = d2;
+
+ d2 = ( (vector.x + repeatZone) - x) * ((vector.x + repeatZone) - x) + (vector.y - y) * (vector.y - y);
+ if (d2 < result) result = d2;
+
+ return result;
+ }
+};
+
+class IntCoord
+{
+public:
+ int x, y;
+ IntCoord(int x, int y) { this->x = x; this->y = y; }
+};
+
+#endif
diff --git a/src/sfml_game/SoundManager.cpp b/src/sfml_game/SoundManager.cpp
new file mode 100644
index 0000000..f82eeee
--- /dev/null
+++ b/src/sfml_game/SoundManager.cpp
@@ -0,0 +1,67 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "SoundManager.h"
+#include <iostream>
+
+
+SoundManager::SoundManager()
+{
+}
+
+SoundManager::~SoundManager()
+{
+ std::cout << "Releasing audio memory...\n";
+ for (unsigned int i = 0; i < soundBufferArray.size(); i++)
+ {
+ soundArray[i]->stop();
+ delete(soundArray[i]);
+ delete(soundBufferArray[i]);
+ }
+ soundArray.clear();
+ soundBufferArray.clear();
+}
+
+ SoundManager* SoundManager::getSoundManager()
+ {
+ static SoundManager singleton;
+ return &singleton;
+ }
+
+void SoundManager::addSound(char* fileName)
+{
+ //std::cout << "Loading sound: " << fileName << "...\n";
+
+ sf::SoundBuffer* newSoundBuffer = new sf::SoundBuffer;
+ newSoundBuffer->loadFromFile(fileName);
+ soundBufferArray.push_back(newSoundBuffer);
+
+ sf::Sound* newSound = new sf::Sound;
+ newSound->setBuffer(*newSoundBuffer);
+ soundArray.push_back(newSound);
+}
+
+void SoundManager::playSound(int n)
+{
+ if (soundArray[n]->getStatus() != sf::Sound::Playing)
+ soundArray[n]->play();
+}
+
+void SoundManager::stopSound(int n)
+{
+ if (soundArray[n]->getStatus() == sf::Sound::Playing)
+ soundArray[n]->stop();
+}
diff --git a/src/sfml_game/SoundManager.h b/src/sfml_game/SoundManager.h
new file mode 100644
index 0000000..19ae4c6
--- /dev/null
+++ b/src/sfml_game/SoundManager.h
@@ -0,0 +1,38 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SOUNDMANAGER_H_INCLUDED
+#define SOUNDMANAGER_H_INCLUDED
+
+#include <SFML/Audio.hpp>
+
+class SoundManager
+{
+public:
+ static SoundManager* getSoundManager();
+ void addSound(char* fileName);
+ void playSound(int n);
+ void stopSound(int n);
+
+private:
+ SoundManager();
+ ~SoundManager();
+
+ std::vector<sf::SoundBuffer*> soundBufferArray;
+ std::vector<sf::Sound*> soundArray;
+};
+
+#endif // SOUNDMANAGER_H_INCLUDED
diff --git a/src/sfml_game/SpriteEntity.cpp b/src/sfml_game/SpriteEntity.cpp
new file mode 100644
index 0000000..afa5fb8
--- /dev/null
+++ b/src/sfml_game/SpriteEntity.cpp
@@ -0,0 +1,110 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "SpriteEntity.h"
+
+SpriteEntity::SpriteEntity(sf::Texture* image, float x, float y, int width, int height, int imagesProLine) : GameEntity(x, y)
+{
+ frame = 0;
+ isFading = false;
+ isShrinking = false;
+ isVisible = true;
+ this->image = image;
+ sprite.setTexture(*image);
+ this->width = width <= 0 ? image->getSize().x : width;
+ this->height = height <= 0 ? image->getSize().y : height;
+ //sprite.SetSubRect(sf::IntRect(0, 0, this->width, this->height));
+ sprite.setOrigin((float)(this->width / 2), (float)(this->height / 2));
+ this->imagesProLine = imagesProLine;
+}
+
+int SpriteEntity::getFrame() { return frame; }
+
+int SpriteEntity::getWidth() { return width; }
+
+float SpriteEntity::getScaleX()
+{
+ return sprite.getScale().x;
+}
+
+void SpriteEntity::setFading(bool isFading)
+{
+ this->isFading = isFading;
+}
+
+void SpriteEntity::setShrinking(bool isShrinking)
+{
+ this->isShrinking = isShrinking;
+}
+
+void SpriteEntity::setVisible(bool isVisible)
+{
+ this->isVisible = isVisible;
+}
+
+void SpriteEntity::setFrame(int frame) { this->frame = frame; }
+
+void SpriteEntity::setScale(float scx, float scy)
+{
+ sprite.setScale(scx, scy);
+}
+
+void SpriteEntity::setImagesProLine(int n)
+{
+ imagesProLine = n;
+}
+
+void SpriteEntity::removeCenter()
+{
+ sprite.setOrigin(0.0f, 0.0f);
+}
+
+void SpriteEntity::render(sf::RenderWindow* app)
+{
+ if (isVisible)
+ {
+ int nx = frame;
+ int ny = 0;
+
+ if (imagesProLine > 0)
+ {
+ nx = frame % imagesProLine;
+ ny = frame / imagesProLine;
+ }
+
+ sprite.setTextureRect(sf::IntRect(nx * width, ny * height, /*(nx + 1) **/ width, /*(ny + 1) */ height));
+
+ sprite.setPosition(x, y);
+ sprite.setRotation(angle);
+
+ if (isFading)
+ {
+ sprite.setColor(sf::Color(255, 255, 255, (sf::Uint8)(getFade() * 255)));
+ }
+
+ if (isShrinking)
+ {
+ sprite.setScale(getFade(), getFade());
+ }
+
+ app->draw(sprite);
+ }
+}
+
+void SpriteEntity::animate(float delay)
+{
+ GameEntity::animate(delay);
+}
diff --git a/src/sfml_game/SpriteEntity.h b/src/sfml_game/SpriteEntity.h
new file mode 100644
index 0000000..6ff6250
--- /dev/null
+++ b/src/sfml_game/SpriteEntity.h
@@ -0,0 +1,58 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SPRITEENTITY_H_INCLUDED
+#define SPRITEENTITY_H_INCLUDED
+
+#include "GameEntity.h"
+
+// Basis class for sprite
+class SpriteEntity : public GameEntity
+{
+public:
+ // create a sprite with the entire image
+ SpriteEntity(sf::Texture* image, float x = 0.0f, float y = 0.0f, int width = -1, int height = -1, int imagesProLine = 0);
+
+ int getFrame();
+ float getScaleX();
+ int getWidth();
+
+ void setFading(bool isFading);
+ void setShrinking(bool isShrinking);
+ void setVisible(bool isVisible);
+ void setFrame(int frame);
+ void setImagesProLine(int n);
+ void setScale(float scx, float scy);
+
+ void removeCenter();
+
+ virtual void render(sf::RenderWindow* app);
+ virtual void animate(float delay);
+
+protected:
+ sf::Sprite sprite;
+ sf::Texture* image;
+ int width;
+ int height;
+ int frame;
+ int imagesProLine;
+
+ bool isFading;
+ bool isShrinking;
+ bool isVisible;
+};
+
+#endif // SPRITEENTITY_H_INCLUDED
diff --git a/src/sfml_game/TileMapEntity.cpp b/src/sfml_game/TileMapEntity.cpp
new file mode 100644
index 0000000..ed93204
--- /dev/null
+++ b/src/sfml_game/TileMapEntity.cpp
@@ -0,0 +1,69 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "TileMapEntity.h"
+
+TileMapEntity::TileMapEntity(sf::Texture* image, GameMap* gameMap, int tileWidth, int tileHeight, int tilesProLine)
+ : GameEntity(0.0f, 0.0f)
+{
+ this->image = image;
+ this->tileWidth = tileWidth;
+ this->tileHeight = tileHeight;
+ this->tilesProLine = tilesProLine;
+ this->gameMap = gameMap;
+ this->z = -1.0f;
+
+ type = 0;
+}
+
+TileMapEntity::~TileMapEntity()
+{
+}
+
+void TileMapEntity::setMap(GameMap* gameMap)
+{
+ this->gameMap = gameMap;
+}
+
+int TileMapEntity::getTilesProLine()
+{
+ return tilesProLine;
+}
+
+void TileMapEntity::render(sf::RenderWindow* app)
+{
+ sf::Sprite tileSprite;
+ tileSprite.setTexture(*image);
+
+ for (int i = 0; i < gameMap->getWidth(); i++)
+ for (int j = 0; j < gameMap->getHeight(); j++)
+ {
+ tileSprite.setPosition(x + (float)(i * tileWidth), y + (float)(j * tileHeight));
+ int nx = gameMap->getTile(i, j) % tilesProLine;
+ int ny = gameMap->getTile(i, j) / tilesProLine;
+
+
+ tileSprite.setTextureRect(sf::IntRect( nx * tileWidth, ny * tileHeight,
+ /*(nx + 1) **/ tileWidth, /*(ny + 1) **/ tileHeight));
+
+ app->draw(tileSprite);
+ }
+}
+
+void TileMapEntity::animate(float delay)
+{
+ age += delay;
+}
diff --git a/src/sfml_game/TileMapEntity.h b/src/sfml_game/TileMapEntity.h
new file mode 100644
index 0000000..bc0dd96
--- /dev/null
+++ b/src/sfml_game/TileMapEntity.h
@@ -0,0 +1,48 @@
+/** This file is part of sfmlGame.
+ *
+ * FreeTumble is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FreeTumble is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FreeTumble. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TILEMAPENTITY_H_INCLUDED
+#define TILEMAPENTITY_H_INCLUDED
+
+#include "GameEntity.h"
+#include "GameMap.h"
+
+// Basis class for TileMap
+class TileMapEntity : public GameEntity
+{
+public:
+ // create a sprite with the entire image
+ TileMapEntity(sf::Texture* image, GameMap* gameMap, int tileWidth, int tileHeight, int tilesProLine);
+ ~TileMapEntity();
+
+ int getTilesProLine();
+ void setMap(GameMap* gameMap);
+
+ virtual void render(sf::RenderWindow* app);
+ virtual void animate(float delay);
+
+protected:
+ int width;
+ int height;
+ int tileWidth;
+ int tileHeight;
+ int tilesProLine;
+
+ sf::Texture* image;
+ GameMap* gameMap;
+};
+
+#endif // TILEMAPENTITY_H_INCLUDED

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jun 11, 11:55 AM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68915
Default Alt Text
(216 KB)

Event Timeline