├── .gitignore ├── CMakeLists.txt ├── README.md ├── cmake-modules ├── FindBox2D.cmake └── FindSFML.cmake ├── resources ├── icons │ └── box2d.png └── screenshot │ └── box2dsfml.png └── src ├── CMakeLists.txt ├── DebugDraw.cpp ├── DebugDraw.h ├── GameKernel.cpp ├── GameKernel.h ├── Globals.h ├── Material.cpp ├── Material.h ├── QueryCallback.cpp ├── QueryCallback.h └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | #-------------------------------C++ 2 | # Compiled Object files 3 | *.slo 4 | *.lo 5 | *.o 6 | 7 | # Compiled Dynamic libraries 8 | *.so 9 | 10 | # Compiled Static libraries 11 | *.lai 12 | *.la 13 | *.a 14 | #--------------------------------CMake 15 | CMakeCache.txt 16 | CMakeFiles 17 | Makefile 18 | cmake_install.cmake 19 | install_manifest.txt 20 | #--------------------------------Linux global 21 | .* 22 | !.gitignore 23 | *~ 24 | 25 | # KDE 26 | .directory 27 | #---------------------------------Windows globals 28 | # Windows image file caches 29 | Thumbs.db 30 | 31 | # Folder config file 32 | Desktop.ini 33 | #---------------------------------Mac globals 34 | .DS_Store 35 | Icon? 36 | 37 | # Thumbnails 38 | ._* 39 | 40 | # Files that might appear on external disk 41 | .Spotlight-V100 42 | .Trashes 43 | #----------------------------------Codeblocks 44 | bin/** 45 | obj/** 46 | *.cbp 47 | *.depend 48 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Box2D and SFML demo cmake build script 3 | # (C) 2011 - Xabier (sLoK) Larrakoetxea 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, see . 17 | # 18 | 19 | cmake_minimum_required(VERSION 2.8) 20 | 21 | # project name 22 | project(Box2DSFML) 23 | 24 | # define the path of our additional CMake modules 25 | set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake-modules") 26 | 27 | # define the build type 28 | set(CMAKE_BUILD_TYPE Release) 29 | 30 | # add the header path 31 | #include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src) 32 | 33 | install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/src/box2dsfml DESTINATION ${PROJECT_SOURCE_DIR}) 34 | 35 | # add the subdirectories 36 | add_subdirectory(src) 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Box2d and SFML demo 2 | =================== 3 | 4 | About 5 | ----- 6 | This little project is a demo of the merge of two great libs, SFML and Box2D 7 | 8 | Dependencies 9 | ------------ 10 | * [SFML](http://www.sfml-dev.org/) >= 1.6 11 | * [Box2D](http://www.box2d.org/) >= 2.1.2 12 | 13 | Screenshot 14 | ------------- 15 | 16 | ![Box2D-and-SML-demo screenshot](https://github.com/slok/Box2D-and-SFML-demo/raw/master/resources/screenshot/box2dsfml.png) 17 | 18 | Build & execute 19 | --------------- 20 | ### GNU/Linux 21 | 22 | mkdir ./build 23 | cd ./build 24 | cmake .. 25 | make 26 | make install 27 | cd ../ 28 | ./box2dsfml 29 | ### Windows 30 | You need a compiler like [Mingw](http://www.mingw.org/) and [CMake](http://www.cmake.org/) 31 | In windows you have to set the env variables. To do this, add to the PATH the location of this 4 paths 32 | 33 | * The lib directory of SFML (Where the SFML libs are: "*.a, *.dll ...") 34 | * The headers directory of SFML (Where "SFML" folder is) 35 | * The lib directory of where Box2D lib file is (For example: libBox2D.a) 36 | * The headers directory of Box2D (Where "Box2D" folder is) 37 | 38 | The PATH variable you should add (note: add ';' at the front) at the end of the PATH is something like this (Note that my Box2D lib is in the same folder of the Box2D header dir so I only add one path for the box2D) 39 | 40 | C:\sources\SFML-1.6\include;C:\sources\SFML-1.6\lib;C:\sources\Box2D_v2.1.2_bin 41 | Then use the same way to compile as in GNU/Linux (for example with mingw32-make) 42 | 43 | mkdir ./build 44 | [run cmake-gui] 45 | [select project and build dir] 46 | [push generate] 47 | [enter with cmd in build dir] 48 | mingw32-make 49 | mingw32-make install 50 | [if install fails, copy the executable in '/build/src/box2dsfml' to the root of the project (where resources folder is)] 51 | 52 | Features 53 | -------- 54 | * Materials 55 | * Dinamyc and static bodies (Box and circles) 56 | * Debug information (body count, contacts...) 57 | * Box2D debugDraw implementation for SFML 58 | * Mouse and key events to interact with the world 59 | * Mouse joint implemented to grab bodies 60 | * CMake build script 61 | 62 | Author 63 | ------ 64 | Xabier (sLoK) Larrakoetxea [slok69 [at] gmail.com] 65 | 66 | License 67 | ------- 68 | [GPL V3](http://www.gnu.org/licenses/gpl-3.0.html) 69 | -------------------------------------------------------------------------------- /cmake-modules/FindBox2D.cmake: -------------------------------------------------------------------------------- 1 | # source: http://breathe.git.sourceforge.net 2 | # 3 | # Locate Box2D library 4 | # This module defines 5 | # BOX2D_LIBRARY, the name of the library to link against 6 | # BOX2D_FOUND, if false, do not try to link to Box2D 7 | # BOX2D_INCLUDE_DIR, where to find Box2D headers 8 | # 9 | # Created by Sven-Hendrik Haase. Based on the FindZLIB.cmake module. 10 | 11 | IF(BOX2D_INCLUDE_DIR) 12 | # Already in cache, be silent 13 | SET(BOX2D_FIND_QUIETLY TRUE) 14 | ENDIF(BOX2D_INCLUDE_DIR) 15 | 16 | FIND_PATH(BOX2D_INCLUDE_DIR Box2D/Box2D.h) 17 | 18 | SET(BOX2D_NAMES box2d Box2d BOX2D Box2D) 19 | FIND_LIBRARY(BOX2D_LIBRARY NAMES ${BOX2D_NAMES}) 20 | MARK_AS_ADVANCED(BOX2D_LIBRARY BOX2D_INCLUDE_DIR) 21 | 22 | # Per-recommendation 23 | SET(BOX2D_INCLUDE_DIRS "${BOX2D_INCLUDE_DIR}") 24 | SET(BOX2D_LIBRARIES "${BOX2D_LIBRARY}") 25 | 26 | # handle the QUIETLY and REQUIRED arguments and set BOX2D_FOUND to TRUE if 27 | # all listed variables are TRUE 28 | 29 | INCLUDE(FindPackageHandleStandardArgs) 30 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Box2D DEFAULT_MSG BOX2D_LIBRARY BOX2D_INCLUDE_DIR) 31 | -------------------------------------------------------------------------------- /cmake-modules/FindSFML.cmake: -------------------------------------------------------------------------------- 1 | # Locate the SFML library 2 | # 3 | # This module defines the following variables: 4 | # - For each module XXX (SYSTEM, WINDOW, GRAPHICS, NETWORK, AUDIO, MAIN): 5 | # - 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) 6 | # - 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) 7 | # - SFML_XXX_LIBRARY, the name of the library to link to for the xxx module (includes both debug and optimized names if necessary) 8 | # - SFML_XXX_FOUND, true if either the debug or release library of the xxx module is found 9 | # - SFML_LIBRARIES, the list of all libraries corresponding to the required modules 10 | # - SFML_FOUND, true if all the required modules are found 11 | # - SFML_INCLUDE_DIR, the path where SFML headers are located (the directory containing the SFML/Config.hpp file) 12 | # 13 | # By default, the dynamic libraries of SFML will be found. To find the static ones instead, 14 | # you must set the SFML_STATIC_LIBRARIES variable to TRUE before calling find_package(SFML ...). 15 | # 16 | # If SFML is not installed in a standard path, you can use the SFMLDIR CMake variable or environment variable 17 | # to tell CMake where SFML is. 18 | 19 | # deduce the libraries suffix from the options 20 | set(FIND_SFML_LIB_SUFFIX "") 21 | if(SFML_STATIC_LIBRARIES) 22 | set(FIND_SFML_LIB_SUFFIX "${FIND_SFML_LIB_SUFFIX}-s") 23 | endif() 24 | 25 | # find the SFML include directory 26 | find_path(SFML_INCLUDE_DIR SFML/Config.hpp 27 | PATH_SUFFIXES include 28 | PATHS 29 | ~/Library/Frameworks 30 | /Library/Frameworks 31 | /usr/local/ 32 | /usr/ 33 | /sw # Fink 34 | /opt/local/ # DarwinPorts 35 | /opt/csw/ # Blastwave 36 | /opt/ 37 | ${SFMLDIR} 38 | $ENV{SFMLDIR}) 39 | 40 | # check the version number 41 | set(SFML_VERSION_OK TRUE) 42 | if(SFML_FIND_VERSION AND SFML_INCLUDE_DIR) 43 | # extract the major and minor version numbers from SFML/Config.hpp 44 | FILE(READ "${SFML_INCLUDE_DIR}/SFML/Config.hpp" SFML_CONFIG_HPP_CONTENTS) 45 | STRING(REGEX MATCH ".*#define SFML_VERSION_MAJOR ([0-9]+).*#define SFML_VERSION_MINOR ([0-9]+).*" SFML_CONFIG_HPP_CONTENTS "${SFML_CONFIG_HPP_CONTENTS}") 46 | STRING(REGEX REPLACE ".*#define SFML_VERSION_MAJOR ([0-9]+).*" "\\1" SFML_VERSION_MAJOR "${SFML_CONFIG_HPP_CONTENTS}") 47 | STRING(REGEX REPLACE ".*#define SFML_VERSION_MINOR ([0-9]+).*" "\\1" SFML_VERSION_MINOR "${SFML_CONFIG_HPP_CONTENTS}") 48 | math(EXPR SFML_REQUESTED_VERSION "${SFML_FIND_VERSION_MAJOR} * 10 + ${SFML_FIND_VERSION_MINOR}") 49 | 50 | # if we could extract them, compare with the requested version number 51 | if (SFML_VERSION_MAJOR) 52 | # transform version numbers to an integer 53 | math(EXPR SFML_VERSION "${SFML_VERSION_MAJOR} * 10 + ${SFML_VERSION_MINOR}") 54 | 55 | # compare them 56 | if(SFML_VERSION LESS SFML_REQUESTED_VERSION) 57 | set(SFML_VERSION_OK FALSE) 58 | endif() 59 | else() 60 | # SFML version is < 2.0 61 | if (SFML_REQUESTED_VERSION GREATER 19) 62 | set(SFML_VERSION_OK FALSE) 63 | set(SFML_VERSION_MAJOR 1) 64 | set(SFML_VERSION_MINOR x) 65 | endif() 66 | endif() 67 | endif() 68 | 69 | # find the requested modules 70 | set(SFML_FOUND TRUE) # will be set to false if one of the required modules is not found 71 | set(FIND_SFML_LIB_PATHS ~/Library/Frameworks 72 | /Library/Frameworks 73 | /usr/local 74 | /usr 75 | /sw 76 | /opt/local 77 | /opt/csw 78 | /opt 79 | ${SFMLDIR} 80 | $ENV{SFMLDIR}) 81 | foreach(FIND_SFML_COMPONENT ${SFML_FIND_COMPONENTS}) 82 | string(TOLOWER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_LOWER) 83 | string(TOUPPER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_UPPER) 84 | set(FIND_SFML_COMPONENT_NAME sfml-${FIND_SFML_COMPONENT_LOWER}${FIND_SFML_LIB_SUFFIX}) 85 | 86 | # no suffix for sfml-main, it is always a static library 87 | if(FIND_SFML_COMPONENT_LOWER STREQUAL "main") 88 | set(FIND_SFML_COMPONENT_NAME sfml-${FIND_SFML_COMPONENT_LOWER}) 89 | endif() 90 | 91 | # debug library 92 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG 93 | NAMES ${FIND_SFML_COMPONENT_NAME}-d 94 | PATH_SUFFIXES lib64 lib 95 | PATHS ${FIND_SFML_LIB_PATHS}) 96 | 97 | # release library 98 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE 99 | NAMES ${FIND_SFML_COMPONENT_NAME} 100 | PATH_SUFFIXES lib64 lib 101 | PATHS ${FIND_SFML_LIB_PATHS}) 102 | 103 | if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG OR SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE) 104 | # library found 105 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND TRUE) 106 | 107 | # if both are found, set SFML_XXX_LIBRARY to contain both 108 | if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE) 109 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY debug ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG} 110 | optimized ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE}) 111 | endif() 112 | 113 | # if only one debug/release variant is found, set the other to be equal to the found one 114 | if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE) 115 | # debug and not release 116 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG}) 117 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG}) 118 | endif() 119 | if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG) 120 | # release and not debug 121 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE}) 122 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE}) 123 | endif() 124 | else() 125 | # library not found 126 | set(SFML_FOUND FALSE) 127 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND FALSE) 128 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY "") 129 | set(FIND_SFML_MISSING "${FIND_SFML_MISSING} SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY") 130 | endif() 131 | 132 | # mark as advanced 133 | MARK_AS_ADVANCED(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY 134 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE 135 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG) 136 | 137 | # add to the global list of libraries 138 | set(SFML_LIBRARIES ${SFML_LIBRARIES} "${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY}") 139 | endforeach() 140 | 141 | # handle errors 142 | if(NOT SFML_VERSION_OK) 143 | # SFML version not ok 144 | set(FIND_SFML_ERROR "SFML found but version too low (requested: ${SFML_FIND_VERSION}, found: ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR})") 145 | set(SFML_FOUND FALSE) 146 | elseif(NOT SFML_FOUND) 147 | # include directory or library not found 148 | set(FIND_SFML_ERROR "Could NOT find SFML (missing: ${FIND_SFML_MISSING})") 149 | endif() 150 | if (NOT SFML_FOUND) 151 | if(SFML_FIND_REQUIRED) 152 | # fatal error 153 | message(FATAL_ERROR ${FIND_SFML_ERROR}) 154 | elseif(NOT SFML_FIND_QUIETLY) 155 | # error but continue 156 | message("${FIND_SFML_ERROR}") 157 | endif() 158 | endif() 159 | 160 | # handle success 161 | if(SFML_FOUND) 162 | message("Found SFML: ${SFML_INCLUDE_DIR}") 163 | endif() 164 | -------------------------------------------------------------------------------- /resources/icons/box2d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slok/Box2D-and-SFML-demo/91de93d0cc9c59fd8f2ce09c7c1a28ef81367ea2/resources/icons/box2d.png -------------------------------------------------------------------------------- /resources/screenshot/box2dsfml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slok/Box2D-and-SFML-demo/91de93d0cc9c59fd8f2ce09c7c1a28ef81367ea2/resources/screenshot/box2dsfml.png -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Box2D and SFML demo cmake build script 3 | # (C) 2011 - Xabier (sLoK) Larrakoetxea 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, see . 17 | # 18 | 19 | set(SRCROOT ${PROJECT_SOURCE_DIR}/src) 20 | 21 | # all source files 22 | set(SRC 23 | ${SRCROOT}/DebugDraw.cpp 24 | ${SRCROOT}/GameKernel.cpp 25 | ${SRCROOT}/Material.cpp 26 | ${SRCROOT}/QueryCallback.cpp 27 | ${SRCROOT}/main.cpp 28 | ) 29 | 30 | find_package(SFML REQUIRED COMPONENTS System Window Graphics) 31 | find_package(Box2D REQUIRED) 32 | 33 | #set headers stuff 34 | set(INCLUDE_DIRS 35 | ${PROJECT_SOURCE_DIR}/src 36 | ${SFML_INCLUDE_DIR} 37 | ${BOX2D_INCLUDE_DIR} 38 | ) 39 | 40 | #set lib stuff 41 | set(DEPEND_LIBS 42 | ${SFML_LIBRARIES} 43 | ${BOX2D_LIBRARY} 44 | ) 45 | 46 | include_directories(${INCLUDE_DIRS}) 47 | add_executable(box2dsfml ${SRC}) 48 | target_link_libraries(box2dsfml ${DEPEND_LIBS}) 49 | 50 | -------------------------------------------------------------------------------- /src/DebugDraw.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2010 Allen Jordan () 3 | Copyright (C) 2011 Xabier Larrakoetxea (slok) 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "DebugDraw.h" 20 | 21 | DebugDraw::DebugDraw(sf::RenderWindow &window) 22 | { 23 | this->window = &window; 24 | } 25 | 26 | DebugDraw::~DebugDraw() 27 | { 28 | 29 | } 30 | 31 | //convert a Box2D (float 0.0f - 1.0f range) color to a SFML color (uint8 0 - 255 range) 32 | sf::Color DebugDraw::B2SFColor(const b2Color &color, int alpha = 255) 33 | { 34 | sf::Color result((sf::Uint8)(color.r*255), (sf::Uint8)(color.g*255), (sf::Uint8)(color.b*255), (sf::Uint8) alpha); 35 | return result; 36 | } 37 | 38 | void DebugDraw::DrawAABB(b2AABB* aabb, const b2Color& color) 39 | { 40 | sf::Shape polygon; 41 | polygon.AddPoint(aabb->lowerBound.x*RATIO, aabb->lowerBound.y*RATIO, this->B2SFColor(color, 50), this->B2SFColor(color)); 42 | polygon.AddPoint(aabb->upperBound.x*RATIO, aabb->lowerBound.y*RATIO, this->B2SFColor(color, 50), this->B2SFColor(color)); 43 | polygon.AddPoint(aabb->upperBound.x*RATIO, aabb->upperBound.y*RATIO, this->B2SFColor(color, 50), this->B2SFColor(color)); 44 | polygon.AddPoint(aabb->lowerBound.x*RATIO, aabb->upperBound.y*RATIO, this->B2SFColor(color, 50), this->B2SFColor(color)); 45 | 46 | polygon.SetOutlineWidth(1.0f); 47 | this->window->Draw(polygon); 48 | std::cout << "DrawAABB\n"; 49 | } 50 | 51 | 52 | void DebugDraw::DrawString(int x, int y, const char* string) 53 | { 54 | sf::String fpsText; 55 | fpsText.SetFont(sf::Font::GetDefaultFont()); 56 | fpsText.SetSize(15); 57 | fpsText.SetPosition(x,y); 58 | fpsText.SetText(string); 59 | this->window->Draw(fpsText); 60 | } 61 | 62 | void DebugDraw::DrawPoint(const b2Vec2& p, float32 size, const b2Color& color) 63 | { 64 | std::cout << "DrawPoint\n"; 65 | } 66 | 67 | void DebugDraw::DrawTransform(const b2Transform& xf) 68 | { 69 | float x,y, lineSize, lineProportion; 70 | x = xf.position.x * RATIO; 71 | y = xf.position.y * RATIO; 72 | lineProportion = 0.15; // 0.15 ~ 10 pixels 73 | b2Vec2 p1 = xf.position, p2; 74 | 75 | //red (X axis) 76 | p2 = p1 + (lineProportion * xf.R.col1); 77 | sf::Shape redLine = sf::Shape::Line(p1.x*RATIO, p1.y*RATIO, p2.x*RATIO, p2.y*RATIO, 1, sf::Color::Red); 78 | 79 | //green (Y axis) 80 | p2 = p1 - (lineProportion * xf.R.col2); 81 | sf::Shape greenLine = sf::Shape::Line(p1.x*RATIO, p1.y*RATIO, p2.x*RATIO, p2.y*RATIO, 1, sf::Color::Green); 82 | 83 | this->window->Draw(redLine); 84 | this->window->Draw(greenLine); 85 | } 86 | 87 | void DebugDraw::DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) 88 | { 89 | 90 | sf::Shape line = sf::Shape::Line(p1.x*RATIO, p1.y*RATIO, p2.x*RATIO, p2.y*RATIO, 1, this->B2SFColor(color)); 91 | line.EnableFill(true); 92 | this->window->Draw(line); 93 | } 94 | 95 | void DebugDraw::DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) 96 | { 97 | //no converion in cordinates of center and upper left corner, Circle in sfml is managed by default with the center 98 | sf::Shape circle = sf::Shape::Circle(center.x*RATIO, center.y*RATIO, (radius*RATIO), this->B2SFColor(color, 50), 1.0f,this->B2SFColor(color)); 99 | 100 | // line of the circle wich shows the angle 101 | b2Vec2 p = center + (radius * axis); 102 | sf::Shape line = sf::Shape::Line(center.x*RATIO, center.y*RATIO, p.x*RATIO, p.y*RATIO, 1, this->B2SFColor(color)); 103 | 104 | this->window->Draw(circle); 105 | this->window->Draw(line); 106 | } 107 | 108 | void DebugDraw::DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) 109 | { 110 | sf::Shape circle = sf::Shape::Circle(center.x*RATIO, center.y*RATIO, radius*RATIO, this->B2SFColor(color, 50), 1.0f,this->B2SFColor(color)); 111 | circle.EnableFill(false); 112 | this->window->Draw(circle); 113 | } 114 | 115 | void DebugDraw::DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) 116 | { 117 | 118 | sf::Shape polygon; 119 | for (int32 i=0; iB2SFColor(color, 50), this->B2SFColor(color)); 123 | } 124 | polygon.SetOutlineWidth(1.0f); 125 | this->window->Draw(polygon); 126 | } 127 | 128 | void DebugDraw::DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) 129 | { 130 | sf::Shape polygon; 131 | for (int32 i=0; iB2SFColor(color, 50), this->B2SFColor(color, 255)); 135 | } 136 | polygon.SetOutlineWidth(1.0f); 137 | polygon.EnableFill(false); 138 | this->window->Draw(polygon); 139 | } 140 | 141 | 142 | void DebugDraw::DrawMouseJoint(b2Vec2& p1, b2Vec2& p2, const b2Color &boxColor, const b2Color &lineColor) 143 | { 144 | sf::Shape polygon; 145 | sf::Shape polygon2; 146 | float p1x = p1.x * RATIO; 147 | float p1y = p1.y * RATIO; 148 | float p2x = p2.x * RATIO; 149 | float p2y = p2.y * RATIO; 150 | float size = 4.0f; 151 | 152 | sf::Color boxClr = this->B2SFColor(boxColor); 153 | sf::Color lineClr = this->B2SFColor(lineColor); 154 | 155 | //first green box for the joint 156 | polygon.AddPoint(p1x-size/2, p1y-size/2, boxClr); 157 | polygon.AddPoint(p1x+size/2, p1y-size/2, boxClr); 158 | polygon.AddPoint(p1x+size/2, p1y+size/2, boxClr); 159 | polygon.AddPoint(p1x-size/2, p1y+size/2, boxClr); 160 | 161 | //second green box for the joint 162 | polygon2.AddPoint(p2x-size/2, p2y-size/2, boxClr); 163 | polygon2.AddPoint(p2x+size/2, p2y-size/2, boxClr); 164 | polygon2.AddPoint(p2x+size/2, p2y+size/2, boxClr); 165 | polygon2.AddPoint(p2x-size/2, p2y+size/2, boxClr); 166 | 167 | sf::Shape line = sf::Shape::Line(p1x, p1y, p2x, p2y, 1, lineClr); 168 | line.EnableFill(true); 169 | 170 | this->window->Draw(polygon); 171 | this->window->Draw(polygon2); 172 | this->window->Draw(line); 173 | } 174 | 175 | -------------------------------------------------------------------------------- /src/DebugDraw.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Allen Jordan () 3 | Copyright (C) 2011 Xabier Larrakoetxea (slok) 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef DEBUGDRAW_H 20 | #define DEBUGDRAW_H 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "Globals.h" 27 | 28 | class DebugDraw : public b2DebugDraw 29 | { 30 | public: 31 | DebugDraw(sf::RenderWindow &window); 32 | virtual ~DebugDraw(); 33 | 34 | void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color); 35 | void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color); 36 | void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color); 37 | void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color); 38 | void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color); 39 | void DrawTransform(const b2Transform& xf); 40 | void DrawPoint(const b2Vec2& p, float32 size, const b2Color& color); 41 | void DrawString(int x, int y, const char* string); 42 | void DrawAABB(b2AABB* aabb, const b2Color& color); 43 | sf::Color B2SFColor(const b2Color &color, int alpha); 44 | void DrawMouseJoint(b2Vec2& p1, b2Vec2& p2, const b2Color &boxColor, const b2Color &lineColor); 45 | 46 | private: 47 | sf::RenderWindow *window; 48 | }; 49 | 50 | #endif // DEBUGDRAW_H 51 | -------------------------------------------------------------------------------- /src/GameKernel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Xabier Larrakoetxea (slok) 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | 18 | #include "GameKernel.h" 19 | 20 | //re-declare statics 21 | sf::RenderWindow *GameKernel::app; 22 | b2World *GameKernel::physicsWorld; 23 | std::list GameKernel::physicsObjectList; 24 | DebugDraw *GameKernel::debugDraw; 25 | 26 | GameKernel::GameKernel(int widgth, int heigth) 27 | { 28 | //create and set the render window 29 | sf::RenderWindow *tempApp = new sf::RenderWindow(sf::VideoMode(widgth, heigth), "Box2DDebug"); 30 | tempApp->SetFramerateLimit(60); 31 | tempApp->UseVerticalSync(true); 32 | GameKernel::app = tempApp; 33 | 34 | //create and set physics world. 35 | b2World* world = new b2World(b2Vec2(0.0f,10.0f), true); //gravity and sleep bodies 36 | GameKernel::physicsWorld = world; 37 | //set variables 38 | this->resHeigth = heigth; 39 | this->resWidgth = widgth; 40 | 41 | if (this->physicsObjectList.empty()) 42 | { 43 | std::list physicsObjectList(); 44 | } 45 | std::cout << "[System][new] Memory allocation physicsWorld (Box2D world)\n"; 46 | std::cout << "[System][new] Memory allocation app (SFML render window)\n"; 47 | std::cout << "[System] Creating Game Kernel object \n"; 48 | } 49 | 50 | GameKernel::GameKernel() 51 | { 52 | 53 | } 54 | 55 | GameKernel::~GameKernel() 56 | { 57 | delete GameKernel::app; 58 | delete GameKernel::physicsWorld; 59 | delete GameKernel::debugDraw; 60 | std::cout << "[System][delete] Deleting app (SFML render window) \n"; 61 | std::cout << "[System][delete] Deleting physicsWorld (Box2D world) \n"; 62 | std::cout << "[System][delete] Deleting debugDraw \n"; 63 | } 64 | 65 | 66 | void GameKernel::ActivateDebugDraw() 67 | { 68 | //activate debug 69 | uint32 flags = b2DebugDraw::e_shapeBit; 70 | //flags += b2DebugDraw::e_jointBit; 71 | //flags += b2DebugDraw::e_aabbBit; 72 | //flags += b2DebugDraw::e_pairBit; 73 | //flags += b2DebugDraw::e_centerOfMassBit; 74 | 75 | GameKernel::debugDraw = new DebugDraw(*GameKernel::app); 76 | GameKernel::debugDraw->SetFlags(flags); 77 | GameKernel::physicsWorld->SetDebugDraw(GameKernel::debugDraw); 78 | 79 | std::cout << "[System][new] Memory allocation debugdraw\n"; 80 | } 81 | 82 | b2World* GameKernel::getPhysicsWorld() 83 | { 84 | return GameKernel::physicsWorld; 85 | } 86 | 87 | sf::RenderWindow* GameKernel::getApp() 88 | { 89 | return GameKernel::app; 90 | } 91 | 92 | std::list GameKernel::getphysicsObjectList() 93 | { 94 | return this->physicsObjectList; 95 | } 96 | 97 | 98 | DebugDraw* GameKernel::getdebugDraw() 99 | { 100 | return GameKernel::debugDraw; 101 | } 102 | 103 | void GameKernel::addDynamicBox(int x, int y, Material material) 104 | { 105 | b2BodyDef bodyDef; 106 | bodyDef.type = b2_dynamicBody; 107 | bodyDef.position.Set(x*UNRATIO, y*UNRATIO); 108 | bodyDef.angle = randomNumber(0,360)*RADTODEG; 109 | b2Body* bodyBox = GameKernel::physicsWorld->CreateBody(&bodyDef); 110 | b2PolygonShape dynamicBox; 111 | dynamicBox.SetAsBox(randomNumber(10,50)*UNRATIO, randomNumber(10,50)*UNRATIO); 112 | b2FixtureDef fixtureDef; 113 | fixtureDef.shape = &dynamicBox; 114 | 115 | /////add material class in the futurec. 116 | fixtureDef.density = material.getDensity(); 117 | fixtureDef.friction = material.getFriction(); 118 | fixtureDef.restitution = material.getRestitution(); 119 | ////// 120 | 121 | bodyBox->CreateFixture(&fixtureDef); 122 | 123 | //add the body to the list 124 | GameKernel::physicsObjectList.push_front(bodyBox); 125 | 126 | std::cout << "[Box2D] Adding dynamic rectangle \n"; 127 | } 128 | 129 | void GameKernel::addDynamicBox(int x, int y, float heigth, float widgth, Material material) 130 | { 131 | b2BodyDef bodyDef; 132 | bodyDef.type = b2_dynamicBody; 133 | bodyDef.position.Set(x*UNRATIO, y*UNRATIO); 134 | b2Body* bodyBox = GameKernel::physicsWorld->CreateBody(&bodyDef); 135 | b2PolygonShape dynamicBox; 136 | dynamicBox.SetAsBox(heigth*UNRATIO, widgth*UNRATIO); 137 | b2FixtureDef fixtureDef; 138 | fixtureDef.shape = &dynamicBox; 139 | 140 | /////add material class in the futurec. 141 | fixtureDef.density = material.getDensity(); 142 | fixtureDef.friction = material.getFriction(); 143 | fixtureDef.restitution = material.getRestitution(); 144 | ////// 145 | 146 | bodyBox->CreateFixture(&fixtureDef); 147 | 148 | //add the body to the list 149 | GameKernel::physicsObjectList.push_front(bodyBox); 150 | 151 | std::cout << "[Box2D] Adding dynamic rectangle \n"; 152 | } 153 | 154 | void GameKernel::addStaticBox(int x, int y) 155 | { 156 | b2BodyDef bodyDef; 157 | bodyDef.position.Set(x*UNRATIO, y*UNRATIO); 158 | bodyDef.angle = randomNumber(0,360)*RADTODEG; 159 | b2Body* bodyBox = GameKernel::physicsWorld->CreateBody(&bodyDef); 160 | b2PolygonShape staticBox; 161 | staticBox.SetAsBox(randomNumber(10,50)*UNRATIO, randomNumber(10,50)*UNRATIO); 162 | b2FixtureDef fixtureDef; 163 | fixtureDef.shape = &staticBox; 164 | bodyBox->CreateFixture(&fixtureDef); 165 | 166 | //add the body to the list 167 | GameKernel::physicsObjectList.push_front(bodyBox); 168 | 169 | std::cout << "[Box2D] Adding static rectangle \n"; 170 | } 171 | 172 | void GameKernel::addStaticBox(int x, int y, float heigth, float widgth) 173 | { 174 | b2BodyDef bodyDef; 175 | bodyDef.position.Set(x*UNRATIO, y*UNRATIO); 176 | b2Body* bodyBox = GameKernel::physicsWorld->CreateBody(&bodyDef); 177 | b2PolygonShape staticBox; 178 | staticBox.SetAsBox(heigth*UNRATIO, widgth*UNRATIO); 179 | b2FixtureDef fixtureDef; 180 | fixtureDef.shape = &staticBox; 181 | bodyBox->CreateFixture(&fixtureDef); 182 | 183 | //add the body to the list 184 | GameKernel::physicsObjectList.push_front(bodyBox); 185 | 186 | std::cout << "[Box2D] Adding static rectangle \n"; 187 | } 188 | 189 | void GameKernel::addDynamicCircle(int x, int y, Material material) 190 | { 191 | b2BodyDef bodyDef; 192 | bodyDef.type = b2_dynamicBody; 193 | bodyDef.position.Set(x*UNRATIO, y*UNRATIO); 194 | b2Body *bdCircle = GameKernel::physicsWorld->CreateBody(&bodyDef); 195 | b2CircleShape dynamicCircle; 196 | dynamicCircle.m_radius = (randomNumber(10,50)*UNRATIO); 197 | b2FixtureDef fixtureDef; 198 | fixtureDef.shape = &dynamicCircle; 199 | 200 | fixtureDef.density = material.getDensity(); 201 | fixtureDef.friction = material.getFriction(); 202 | fixtureDef.restitution = material.getRestitution(); 203 | 204 | bdCircle->CreateFixture(&fixtureDef); 205 | 206 | //add the body to the list 207 | GameKernel::physicsObjectList.push_front(bdCircle); 208 | 209 | std::cout << "[Box2D] Adding dynamic circle \n"; 210 | } 211 | 212 | void GameKernel::addDynamicCircle(int x, int y, float radius, Material material) 213 | { 214 | b2BodyDef bodyDef; 215 | bodyDef.type = b2_dynamicBody; 216 | bodyDef.position.Set(x*UNRATIO, y*UNRATIO); 217 | b2Body *bdCircle = GameKernel::physicsWorld->CreateBody(&bodyDef); 218 | b2CircleShape dynamicCircle; 219 | dynamicCircle.m_radius = (radius*UNRATIO); 220 | b2FixtureDef fixtureDef; 221 | fixtureDef.shape = &dynamicCircle; 222 | 223 | fixtureDef.density = material.getDensity(); 224 | fixtureDef.friction = material.getFriction(); 225 | fixtureDef.restitution = material.getRestitution(); 226 | 227 | bdCircle->CreateFixture(&fixtureDef); 228 | 229 | //add the body to the list 230 | GameKernel::physicsObjectList.push_front(bdCircle); 231 | 232 | std::cout << "[Box2D] Adding dynamic circle \n"; 233 | } 234 | 235 | void GameKernel::addStaticCircle(int x, int y) 236 | { 237 | b2BodyDef bodyDef; 238 | bodyDef.position.Set(x*UNRATIO, y*UNRATIO); 239 | b2Body *bdCircle = GameKernel::physicsWorld->CreateBody(&bodyDef); 240 | b2CircleShape staticCircle; 241 | staticCircle.m_radius = (randomNumber(10,50)*UNRATIO); 242 | b2FixtureDef fixtureDef; 243 | fixtureDef.shape = &staticCircle; 244 | 245 | bdCircle->CreateFixture(&fixtureDef); 246 | 247 | //add the body to the list 248 | GameKernel::physicsObjectList.push_front(bdCircle); 249 | 250 | std::cout << "[Box2D] Adding static circle \n"; 251 | } 252 | 253 | void GameKernel::addStaticCircle(int x, int y, float radius) 254 | { 255 | b2BodyDef bodyDef; 256 | bodyDef.position.Set(x*UNRATIO, y*UNRATIO); 257 | b2Body *bdCircle = GameKernel::physicsWorld->CreateBody(&bodyDef); 258 | b2CircleShape staticCircle; 259 | staticCircle.m_radius = (radius*UNRATIO); 260 | b2FixtureDef fixtureDef; 261 | fixtureDef.shape = &staticCircle; 262 | 263 | bdCircle->CreateFixture(&fixtureDef); 264 | 265 | //add the body to the list 266 | GameKernel::physicsObjectList.push_front(bdCircle); 267 | 268 | std::cout << "[Box2D] Adding static circle \n"; 269 | } 270 | 271 | int GameKernel::randomNumber(int min, int max) 272 | { 273 | /* 274 | srand(time(0)); 275 | int result = min+rand()%(max-min); 276 | //std::cout << "result: " << result << "\n"; 277 | 278 | */ 279 | sf::Randomizer::SetSeed(time(0)); 280 | return sf::Randomizer::Random(min, max); 281 | } 282 | 283 | void GameKernel::setWindowIcon(std::string imagePath) 284 | { 285 | sf::Image windowIcon; 286 | sf::Image background; 287 | sf::Sprite backgroundSprite; 288 | windowIcon.LoadFromFile(imagePath); 289 | GameKernel::app->SetIcon(windowIcon.GetWidth(),windowIcon.GetHeight(), windowIcon.GetPixelsPtr()); 290 | 291 | } 292 | 293 | void GameKernel::setBackground(std::string imagePath, sf::Image *background, sf::Sprite *bkSprite) 294 | { 295 | int alpha = 255; 296 | if (!imagePath.empty()) 297 | { 298 | background->LoadFromFile(imagePath); 299 | bkSprite->SetImage(*background); 300 | bkSprite->SetPosition(0,0); 301 | bkSprite->Resize(this->resWidgth,this->resHeigth); 302 | alpha = 150; 303 | } 304 | bkSprite->SetColor(sf::Color(255,255,255,alpha)); //alpha 305 | 306 | } 307 | 308 | void GameKernel::printDebugInfo() 309 | { 310 | std::string fpsString; 311 | std::ostringstream os; 312 | 313 | //calculate FPS 314 | float framerate = (1.0f / GameKernel::app->GetFrameTime()); 315 | 316 | //start adding data to the string 317 | os << framerate; 318 | fpsString = "Box2D & SFML Debug Draw V0.01a\nFPS: "; 319 | fpsString.append(os.str()); 320 | fpsString.append("\nbodies/contacts/joints/proxies = "); 321 | os.str(std::string()); 322 | os << GameKernel::physicsWorld->GetBodyCount() << "/" << 323 | GameKernel::physicsWorld->GetContactCount() << "/" << 324 | GameKernel::physicsWorld->GetJointCount() << "/" << 325 | GameKernel::physicsWorld->GetProxyCount(); 326 | 327 | fpsString.append(os.str()); 328 | GameKernel::debugDraw->DrawString(0,0,fpsString.c_str()); 329 | } 330 | 331 | void GameKernel::removePhysicBodies(int leftLimit, int rightLimit, int upLimit, int downLimit) 332 | { 333 | int count = 0; 334 | 335 | for(std::list::iterator i = GameKernel::physicsObjectList.begin();i != GameKernel::physicsObjectList.end();) 336 | { 337 | 338 | if( ((*i)->GetPosition().x*RATIO < leftLimit) || ((*i)->GetPosition().x*RATIO > rightLimit) || 339 | ((*i)->GetPosition().y*RATIO < upLimit) || ((*i)->GetPosition().y*RATIO > downLimit)) 340 | { 341 | GameKernel::physicsWorld->DestroyBody(*i); 342 | i = GameKernel::physicsObjectList.erase(i); //update iterator 343 | count++; 344 | } 345 | else 346 | i++; //nex body 347 | } 348 | 349 | std::cout << "[Box2D] bodies deleted: " << count << "\n"; 350 | } 351 | 352 | 353 | -------------------------------------------------------------------------------- /src/GameKernel.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Xabier Larrakoetxea (slok) 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | 18 | #ifndef GAMEKERNEL_H 19 | #define GAMEKERNEL_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "Material.h" 30 | #include "DebugDraw.h" 31 | #include "Globals.h" 32 | 33 | class GameKernel 34 | { 35 | public: 36 | //Constructor/Destructors 37 | GameKernel(); 38 | GameKernel(int widgth, int heigth); 39 | virtual ~GameKernel(); 40 | 41 | //methods 42 | void ActivateDebugDraw(); 43 | b2World *getPhysicsWorld(); 44 | sf::RenderWindow *getApp(); 45 | std::list getphysicsObjectList(); 46 | DebugDraw *getdebugDraw(); 47 | void addDynamicBox(int x, int y, Material material); 48 | void addDynamicBox(int x, int y, float heigth, float widgth, Material material); 49 | void addStaticBox(int x, int y); 50 | void addStaticBox(int x, int y, float heigth, float widgth); 51 | void addDynamicCircle(int x, int y, Material material); 52 | void addDynamicCircle(int x, int y, float radius, Material material); 53 | void addStaticCircle(int x, int y); 54 | void addStaticCircle(int x, int y, float radius); 55 | void setWindowIcon(std::string imagePath); 56 | void setBackground(std::string imagePath, sf::Image *background, sf::Sprite *bkSprite); 57 | static int randomNumber(int min, int max); 58 | void printDebugInfo(); 59 | void removePhysicBodies(int leftLimit, int rightLimit, int upLimit, int downLimit); 60 | 61 | 62 | private: 63 | //atributes 64 | static b2World *physicsWorld; 65 | static sf::RenderWindow *app; 66 | static std::list physicsObjectList; //list of pointers to the physics bodies 67 | static DebugDraw *debugDraw; 68 | int resWidgth; 69 | int resHeigth; 70 | 71 | //methods 72 | }; 73 | 74 | #endif // GAMEKERNEL_H 75 | -------------------------------------------------------------------------------- /src/Globals.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Xabier Larrakoetxea (slok) 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | 18 | #ifndef GLOBALS_H_INCLUDED 19 | #define GLOBALS_H_INCLUDED 20 | 21 | 22 | // 1 meter (box2d) is more or less 64 pixels (sfml) 23 | #define RATIO 30.0f 24 | #define PIXELS_PER_METER RATIO 25 | 26 | // 64 pixels (sfml) are more or less 1 meter (box2d) 27 | #define UNRATIO (1.0F/RATIO) 28 | #define METERS_PER_PIXEL UNRATIO 29 | 30 | //formula to convert radians to degrees = (radians * (pi/180)) 31 | #define RADTODEG (b2_pi / 180.0) 32 | 33 | #endif // GLOBALS_H_INCLUDED 34 | -------------------------------------------------------------------------------- /src/Material.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Xabier Larrakoetxea (slok) 3 | Copyright (C) 2009 (Edge) 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "Material.h" 20 | 21 | //Static member data 22 | const Material Material::DEFAULT(1.00f, 0.30f, 0.1f); 23 | const Material Material::METAL(7.85f, 0.20f, 0.2f); 24 | const Material Material::STONE(2.40f, 0.50f, 0.1f); 25 | const Material Material::WOOD(0.53f, 0.40f, 0.15f); 26 | const Material Material::GLASS(2.50f, 0.10f, 0.2f); 27 | const Material Material::RUBBER(1.50f, 0.80f, 0.4f); 28 | const Material Material::ICE(0.92f, 0.01f, 0.1f); 29 | const Material Material::PUMICE(0.25f, 0.60f, 0.0f); 30 | const Material Material::POLYSTYRENE(0.10f, 0.60f, 0.05f); 31 | const Material Material::FABRIC(0.03f, 0.60f, 0.1f); 32 | const Material Material::SPONGE(0.018f, 0.90f, 0.05f); 33 | const Material Material::AIR(0.001f, 0.90f, 0.0f); 34 | const Material Material::HELIUM(0.0001f, 0.9f, 0.0f); 35 | 36 | Material::Material(float density, float friction, float restitution) 37 | { 38 | this->density = density; 39 | this->friction = friction; 40 | this->restitution = restitution; 41 | } 42 | 43 | Material::Material() 44 | { 45 | //ctor 46 | } 47 | 48 | Material::~Material() 49 | { 50 | //dtor 51 | } 52 | 53 | void Material::setRestitution(float r) 54 | { 55 | this->restitution = r; 56 | } 57 | 58 | float Material::getRestitution() 59 | { 60 | return this->restitution; 61 | } 62 | 63 | void Material::setFriction(float f) 64 | { 65 | this->restitution = f; 66 | } 67 | 68 | float Material::getFriction() 69 | { 70 | return this->friction; 71 | } 72 | 73 | void Material::setDensity(float d) 74 | { 75 | this->density = d; 76 | } 77 | 78 | float Material::getDensity() 79 | { 80 | return this->density; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /src/Material.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Xabier Larrakoetxea (slok) 3 | Copyright (C) 2009 (Edge) 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef MATERIAL_H 20 | #define MATERIAL_H 21 | 22 | 23 | class Material 24 | { 25 | public: 26 | Material(); 27 | Material(float density, float friction, float restitution); 28 | virtual ~Material(); 29 | float getDensity(); 30 | void setDensity(float d); 31 | float getFriction(); 32 | void setFriction(float f); 33 | float getRestitution(); 34 | void setRestitution(float r); 35 | 36 | //static member data 37 | static const Material DEFAULT; 38 | static const Material METAL; 39 | static const Material STONE; 40 | static const Material WOOD; 41 | static const Material GLASS; 42 | static const Material RUBBER; 43 | static const Material ICE; 44 | static const Material PUMICE; 45 | static const Material POLYSTYRENE; 46 | static const Material FABRIC; 47 | static const Material SPONGE; 48 | static const Material AIR; 49 | static const Material HELIUM; 50 | 51 | private: 52 | float density; 53 | float friction; 54 | float restitution; 55 | }; 56 | 57 | #endif // MATERIAL_H 58 | -------------------------------------------------------------------------------- /src/QueryCallback.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Xabier Larrakoetxea (slok) 3 | Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include "QueryCallback.h" 20 | 21 | QueryCallback::QueryCallback(const b2Vec2& point) 22 | { 23 | m_point = point; 24 | m_fixture = NULL; 25 | } 26 | 27 | bool QueryCallback::ReportFixture(b2Fixture* fixture) 28 | { 29 | b2Body* body = fixture->GetBody(); 30 | if (body->GetType() == b2_dynamicBody) 31 | { 32 | bool inside = fixture->TestPoint(m_point); 33 | if (inside) 34 | { 35 | m_fixture = fixture; 36 | 37 | // We are done, terminate the query. 38 | return false; 39 | } 40 | } 41 | 42 | // Continue the query. 43 | return true; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /src/QueryCallback.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Xabier Larrakoetxea (slok) 3 | Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #ifndef QUERYCALLBACK_H 20 | #define QUERYCALLBACK_H 21 | 22 | #include 23 | 24 | class QueryCallback : public b2QueryCallback 25 | { 26 | public: 27 | QueryCallback(const b2Vec2& point); 28 | //virtual ~QueryCallback(); 29 | bool ReportFixture(b2Fixture* fixture); 30 | b2Vec2 m_point; 31 | b2Fixture* m_fixture; 32 | }; 33 | 34 | #endif // QUERYCALLBACK_H 35 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Xabier Larrakoetxea (slok) 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "GameKernel.h" 26 | #include "DebugDraw.h" 27 | #include "Globals.h" 28 | #include "QueryCallback.h" 29 | using namespace std; 30 | 31 | int main(int argc, char **argv) 32 | { 33 | GameKernel gameController(800,600); 34 | 35 | b2World *pWorld = gameController.getPhysicsWorld(); 36 | gameController.ActivateDebugDraw(); 37 | sf::RenderWindow *rWindow = gameController.getApp(); 38 | 39 | //add icon to the render window 40 | gameController.setWindowIcon("resources/icons/box2d.png"); 41 | 42 | //box2D step info 43 | float32 timeStep = 1.0f / 60.0f; 44 | int32 velocityIterations = 10; 45 | int32 positionIterations = 10; 46 | 47 | sf::Event Event; 48 | bool pause = false; 49 | bool staticMode= false; 50 | bool grabMode= false; 51 | bool debugString= true; 52 | bool helpMode= false; 53 | int p1x,p1y,p2x,p2y; //for the creation of boxes with the mouse; 54 | bool mouseIsPressed = false; //needed to know if we have to draw 55 | bool isForBox = true; // needed to know if we have to draw a box or a circle 56 | const sf::Input& input = rWindow->GetInput(); //for getting x and y coordiantes of the mouse 57 | sf::Shape drawingMouseBox; //for displaying white rectangle 58 | sf::Clock clock; //for the timing of the deletion of bodies out of the screen 59 | 60 | sf::Sprite bkSprite; 61 | sf::Image bkImage; 62 | 63 | gameController.setBackground("", &bkImage, &bkSprite); //without background path 64 | 65 | //help string 66 | std::string helpString = " *H: Enable/disable this help\n\ 67 | *S: switch between static and dynamic bodies\n\ 68 | *P: Pause/unpause the game\n\ 69 | *Space: Aleatory box\n\ 70 | *Enter: Aleatory circle\n\ 71 | *G: Enable/disable grab mode (mouse joint)\n\ 72 | *Right click: if not grab mode, add circle (move and release )\n\ 73 | *Left click: if not grab mode, add box (move and release)\n\ 74 | *0-9 num keys to change material"; 75 | 76 | //for the joints 77 | b2BodyDef bodyDef; 78 | b2Body* groundBody = pWorld->CreateBody(&bodyDef); 79 | b2MouseJoint* mouseJoint = NULL; 80 | 81 | //material of the bodies 82 | Material material = Material::DEFAULT; 83 | std::string materialStr = "Default"; 84 | 85 | while(rWindow->IsOpened()) 86 | { 87 | // Process events 88 | while(rWindow->GetEvent(Event)) 89 | { 90 | // Close window : exit 91 | if(Event.Type == sf::Event::Closed) 92 | rWindow->Close(); 93 | 94 | if(Event.Type == sf::Event::KeyPressed)//key press events 95 | { 96 | 97 | switch (Event.Key.Code) 98 | { 99 | //close events 100 | case sf::Key::Escape: rWindow->Close(); break; 101 | 102 | //game logic events 103 | case sf::Key::Space: //add box 104 | { 105 | if(staticMode) 106 | gameController.addStaticBox(GameKernel::randomNumber(0,800),GameKernel::randomNumber(0,600)); 107 | else 108 | gameController.addDynamicBox(GameKernel::randomNumber(0,800),GameKernel::randomNumber(0,600), material); 109 | 110 | break; 111 | } 112 | case sf::Key::Return: //add circle 113 | { 114 | if(staticMode) 115 | gameController.addStaticCircle(GameKernel::randomNumber(0,800),GameKernel::randomNumber(0,600)); 116 | else 117 | gameController.addDynamicCircle(GameKernel::randomNumber(0,800),GameKernel::randomNumber(0,600), material); 118 | 119 | break; 120 | } 121 | case sf::Key::I: //activate/desactivate debug upper-left information string 122 | { 123 | if(debugString) 124 | debugString = false; 125 | else 126 | debugString = true; 127 | 128 | break; 129 | } 130 | case sf::Key::S: //activate/desactivate static objects creation 131 | { 132 | if(staticMode) 133 | staticMode = false; 134 | else 135 | staticMode = true; 136 | 137 | break; 138 | } 139 | case sf::Key::P: //activate/desactivate static objects creation 140 | { 141 | if(pause) 142 | pause = false; 143 | else 144 | pause = true; 145 | 146 | break; 147 | } 148 | case sf::Key::G: //activate/desactivate grab mode 149 | { 150 | if(grabMode) 151 | grabMode = false; 152 | else 153 | grabMode = true; 154 | break; 155 | } 156 | case sf::Key::H: //activate/desactivate grab mode 157 | { 158 | if(!helpMode) 159 | { 160 | helpMode = true; 161 | pause = true; 162 | } 163 | else 164 | { 165 | helpMode = false; 166 | pause = false; 167 | } 168 | break; 169 | } 170 | //materials 171 | case sf::Key::Num1: material = Material::DEFAULT; materialStr = "Default"; break; 172 | case sf::Key::Num2: material = Material::METAL; materialStr = "Metal"; break; 173 | case sf::Key::Num3: material = Material::STONE; materialStr = "Stone"; break; 174 | case sf::Key::Num4: material = Material::WOOD; materialStr = "Wood"; break; 175 | case sf::Key::Num5: material = Material::GLASS; materialStr = "Glass"; break; 176 | case sf::Key::Num6: material = Material::RUBBER; materialStr = "Rubber"; break; 177 | case sf::Key::Num7: material = Material::ICE; materialStr = "Ice"; break; 178 | case sf::Key::Num8: material = Material::PUMICE; materialStr = "Pumice"; break; 179 | case sf::Key::Num9: material = Material::POLYSTYRENE; materialStr = "Polystyrene"; break; 180 | case sf::Key::Num0: material = Material::SPONGE; materialStr = "Sponge"; break; 181 | } 182 | } 183 | if(Event.Type == sf::Event::MouseButtonPressed) 184 | { 185 | mouseIsPressed = true; 186 | 187 | p1x = input.GetMouseX(); 188 | p1y = input.GetMouseY(); 189 | 190 | if(!grabMode) 191 | { 192 | switch (Event.MouseButton.Button) 193 | { 194 | case sf::Mouse::Left: isForBox = true; break; 195 | case sf::Mouse::Right: isForBox = false; break; 196 | } 197 | } 198 | else 199 | { 200 | // Make a small box. 201 | b2Vec2 p; 202 | 203 | p.x = p1x*UNRATIO; 204 | p.y = p1y*UNRATIO; 205 | 206 | b2AABB aabb; 207 | b2Vec2 d; 208 | d.Set(0.001f, 0.001f); 209 | aabb.lowerBound = p + d; 210 | aabb.upperBound = p - d; 211 | 212 | QueryCallback callback(p); 213 | pWorld->QueryAABB(&callback, aabb); 214 | 215 | if (callback.m_fixture) 216 | { 217 | b2Body* body = callback.m_fixture->GetBody(); 218 | b2MouseJointDef md; 219 | md.bodyA = groundBody; 220 | md.bodyB = body; 221 | md.target = p; 222 | md.maxForce = 1000.0f * body->GetMass(); 223 | mouseJoint = (b2MouseJoint*)pWorld->CreateJoint(&md); 224 | body->SetAwake(true); 225 | std::cout << "[Box2D][new] joint created\n"; 226 | } 227 | 228 | } 229 | } 230 | if(Event.Type == sf::Event::MouseMoved && mouseIsPressed) 231 | { 232 | p2x = input.GetMouseX(); 233 | p2y = input.GetMouseY(); 234 | if (!grabMode) 235 | { 236 | if (isForBox) 237 | { 238 | drawingMouseBox = sf::Shape::Rectangle(p1x, p1y, p2x, p2y, sf::Color::White,1, sf::Color::White); 239 | drawingMouseBox.EnableFill(false); 240 | drawingMouseBox.EnableOutline(true); 241 | 242 | } 243 | else 244 | { 245 | drawingMouseBox = sf::Shape::Circle(p1x, p1y, p2x-p1x, sf::Color::White, 1, sf::Color::White); 246 | drawingMouseBox.EnableFill(false); 247 | drawingMouseBox.EnableOutline(true); 248 | } 249 | 250 | } 251 | else 252 | { 253 | //move the joint (and the object) 254 | if (mouseJoint != NULL) 255 | { 256 | b2Vec2 p; 257 | p.x = p2x*UNRATIO; 258 | p.y = p2y*UNRATIO; 259 | mouseJoint->SetTarget(p); 260 | } 261 | } 262 | } 263 | 264 | if(Event.Type == sf::Event::MouseButtonReleased) 265 | { 266 | mouseIsPressed = false; 267 | 268 | if(!grabMode) 269 | { 270 | drawingMouseBox.EnableOutline(false); //because there is a second that shows in other position, sow we do "transparent" 271 | if (isForBox) 272 | { 273 | //calculate good coordinates (from upper-left, not center) for box2D (box2D is with center, sfml no) 274 | int tempP1x, tempP1y, wX, hY; 275 | 276 | wX = p2x-p1x; 277 | hY = p2y-p1y; 278 | tempP1x = p1x+wX/2; 279 | tempP1y = p1y+hY/2; 280 | 281 | if(staticMode) 282 | gameController.addStaticBox(tempP1x,tempP1y,wX/2,hY/2); 283 | else 284 | gameController.addDynamicBox(tempP1x,tempP1y,wX/2,hY/2, material); 285 | 286 | } 287 | else 288 | { 289 | if(staticMode) 290 | gameController.addStaticCircle(p1x,p1y,(p2x-p1x)); 291 | else 292 | gameController.addDynamicCircle(p1x,p1y,(p2x-p1x), material); 293 | } 294 | } 295 | else 296 | { 297 | //delete joint 298 | if (mouseJoint != NULL) 299 | { 300 | pWorld->DestroyJoint(mouseJoint); 301 | mouseJoint = NULL; 302 | std::cout << "[Box2D][delete] joint deleted\n"; 303 | } 304 | } 305 | } 306 | } 307 | 308 | rWindow->Clear(); 309 | 310 | //draw debug 311 | pWorld->DrawDebugData(); 312 | rWindow->Draw(bkSprite); 313 | 314 | //if there is a mouse joint, draw the joints and the line 315 | if(mouseJoint != NULL) 316 | { 317 | b2Vec2 p1 = mouseJoint->GetAnchorB(); 318 | b2Vec2 p2 = mouseJoint->GetTarget(); 319 | gameController.getdebugDraw()->DrawMouseJoint(p1, p2, b2Color(0.0f, 1.0f, 0.0f), b2Color(0.8f, 0.8f, 0.8f)); 320 | } 321 | 322 | //draw help string 323 | if(helpMode) 324 | { 325 | gameController.getdebugDraw()->DrawString(100,100,helpString.c_str()); 326 | } 327 | 328 | //print actual material 329 | gameController.getdebugDraw()->DrawString(0,50,materialStr.c_str()); 330 | 331 | // Instruct the world to perform a single step of simulation. 332 | // It is generally best to keep the time step and iterations fixed. 333 | if(!pause) 334 | pWorld->Step(timeStep, velocityIterations, positionIterations); 335 | else 336 | gameController.getdebugDraw()->DrawString(0,70,"*PAUSE*"); 337 | 338 | // Clear applied body forces. We didn't apply any forces, but you 339 | // should know about this function. 340 | pWorld->ClearForces(); 341 | 342 | //print or not to print, that's the question :D 343 | if (debugString) 344 | gameController.printDebugInfo(); 345 | 346 | if (mouseIsPressed) 347 | rWindow->Draw(drawingMouseBox); 348 | 349 | 350 | rWindow->Display(); 351 | if (clock.GetElapsedTime()> 30.0f) //every 30 seconds deletes the bodies out of bounds 352 | { 353 | clock.Reset(); 354 | gameController.removePhysicBodies(-50,850,-50, 650); 355 | } 356 | 357 | 358 | } 359 | 360 | // When the world destructor is called, all bodies and joints are freed. This can 361 | // create orphaned pointers, so be careful about your world management. 362 | return 0; 363 | } 364 | --------------------------------------------------------------------------------