See the file LICENSE for the license governing this code.
Level
is a cocos2d::Node
which contains the TMXTiledMap
, Physics
, backgrounds, foregrounds, LevelObjects
, scripts, exit points and more.
A Level
can be given an overall color value which is used by dynamic texturing and some objects to derive color.
Level
handles moving the camera by following the specified cameraFollowNode
. It uses a smoothing and clamping algorithm which causes the camera to smoothly move from one position to another and never shows anything beyond the extent of the Level
.
Moving the camera automatically causes backgrounds and foregrounds to be parallaxed.
A screen shake camera animation can be put into effect by using setScreenShakeTimer
and setScreenShakeStrength
.
The setMirrorY
method can be used to set the y-position at which the Level
should mirror all sprites.
This can create water-like reflections.
The default is 0
which disables all reflections.
Level
can put the game into slow motion by using setSlowMotionTimer
.
The Player
object uses this to go into slow-mo when melee attacking.
Because the Level
updates all LevelObjects
during its tick
by iterating its children, arrays are maintained so that objects can be added or removed after the update has finished.
Use addObject
to add an object when the Level
is already running.
Methods such as isClearTileArea
and getDistanceFromGround
are included to query the state of the TMX map’s tiles.
These methods convert regular point-based math to tile-based math in order to determine if a tile exists.
projection
(string) to specify the camera projection to use. Currently accepts 2d
or 3d
. Default: 3d
.music
(string filename) to specify the music filename to loop.hue
(integer 0-359) or color
(0-255, 0-255, 0-255) to specify the color of the level. Used by backgrounds, dynamic texturing and some objects.spritesheet
(string filename) to specify a spritesheet to be loaded.texturing
(string) to specify the algorithm used for dynamic texturing. Default: none
. See below for more info on dynamic texturing.mirror
(integer) to specify the Y value in points that a mirror reflection will occur. Default 0
means disabled.bgX
(where X
is an integer) to specify a background image to parallax. X
is the background index. A background starts with a z
of -100 and adds the background index. So bg1
specifies background index 1
and will have a z
of -99. Also, the background index is used as a map key, so each index must be unique or else it will be overwritten.fgX
(where X
is an integer) to specify a foreground image to parallax. The X
value works like a background index only it’s a foreground index. Foregrounds have a minimum z
of 0, so fg1
specifies a foreground with a z
of 1
.no-parallax
(boolean 1
or true
) to disable all background and foreground parallaxing. With no-parallax
enabled, backgrounds and foregrounds are anchored to the middle of the level.script-event
(string filename) to specify the filename of a script to be run when triggering event
. Replace event
with the event name. Currently, onEnter
(property key script-onEnter
) is the only event supported.sound-loop
(string filename) to specify a sound to keep looping during the level (though using music
may loop better).solid
(boolean 1
or true
) to specify that the layer is solid. All tiles will have solid physical structures built around them.z
(integer) to specify the z index for the layer. The first layer defaults to a z
of 0
, then 1
, then 2
, etc.globalz
(floating point or string) to give the layer a global z
index other than zero. Set to auto
to enable automatic global z
ordering, which uses values 1.0 through 2.0. A value of 0.0 is ignored. Takes precedence over local z
ordering. Use auto
knowing that it has to create a separate non-sprite-batched sprite for each tile, as children of a SpriteBatchNode
cannot have individual global z
values (the parent SpriteBatchNode
‘s global z
is used).parallax
(integer) to treat the layer as a parallaxed background. The amount of parallax, given in tiles, is specified using the value. For example parallax
= 8
will parallax the layer by 8
tiles.oneway
(string direction left
, right
, up
or down
) to specify that all tiles in the layer are one-way tiles with the given direction. Specifying oneway
= up
for example creates one-way tiles that can be jumped up to from below, but not jumped down from.Each time a Level
is created, the game’s random seed is used in conjuction with Assets/World.plist
to generate the current overall area.
Once the area has been generated, a level is generated (or loaded) within that area corresponding with the current area / level number.
An area can be completely structured with fixed tmx levels, completely random or a combination of both. Random level generation actually creates an xml tmx map as a string in memory and can be logged for debugging. Overall area maps can be logged to the console as well.
See LevelGenerator.cpp
for detail on area and level generation.
Assets/World.plist
is a dictionary of all areas in the game. The key specifies the area number.
Within each area dictionary, there are several key-value pairs which describe the area.
texturing
specifies the dynamic texturing algorithm that will be used by default for each level. A fixed tmx level file can override this by setting map property texturing
. Currently accepted values are mountain
, cave
and none
.size
specifies the number of levels contained in the area.title
specifies an optional title for the area.features
is a dictionary of arrays specifying the features that the level generator will place inside the level. Features also determine the shape and exit points the generator will create. Specifying a feature named tmx
will specify a fixed tmx map file to load for that area. If a fixed map is used, no level is dynamically generated.See World.plist
for examples.
Once the level has been generated (or loaded in the case of static tmx files) it is passed through the dynamic texture generator. If the level has specified to use dynamic texturing, an algorithm is used to scan solid tiles and draw individual pixels into a buffer of memory. When finished, the buffer is turned into a texture, added as a child and the tmx layers of the level are set to invisible.
See LevelTextures.cpp
for details on the process of procedural texture generation.
ExitPoint
represents a position in the Level
which corresponds with an exit to another level.
The ExitPoint
contains the linked area, level and direction which the exit should animate.
Whenever the Player
is found to be out of bounds of the level, the nearest ExitPoint
is found and used to sucessfully complete the level.
A new LevelScene
is created for the new Level
and a sliding transition is then used to smoothly animate between the scenes.
ExitPoint
objects are specified in the tmx by creating objects of type Exit
.
1-3
is a reference to area 1
, level 3
.direction
(string left
, right
, up
or down
) to specify the direction of exit. Used by the level transition animation and sometimes by the dynamic area generator.
#pragma once
#include "Headers.h"
class LevelScene;
struct ExitPoint
{
int area, level, direction;
Vec2 pos;
ExitPoint() : area(0), level(0), direction(0), pos(Vec2::ZERO) {}
ExitPoint(int _area, int _level, int _direction, const Vec2& _pos) : area(_area), level(_level), direction(_direction), pos(_pos) {}
};
class Level : public Node, public PhysicsDelegate
{
public:
Level(int areaNum, int levelNum, float ease);
~Level();
Get current area / level number.
GETTER(int, areaNumber, AreaNumber);
GETTER(int, levelNumber, LevelNumber);
The node that the camera will follow. Defaults to the Player
object.
GETTER_SETTER(Node*, cameraFollowNode, CameraFollowNode);
Get the level color.
const Color3B& getLevelColor() {return color;}
If the map has any automatic global Z layers.
GETTER(bool, hasAutoGlobalZ, HasAutoGlobalZ);
Current camera position.
GETTER(Vec2, cameraPosition, CameraPosition);
Offset of map.
GETTER(Vec2, mapOffset, MapOffset);
If level is complete and did succeed.
GETTER(bool, isComplete, IsComplete);
GETTER(bool, didSucceed, DidSucceed);
The player entry / exit direction.
GETTER(int, entryDirection, EntryDirection);
GETTER(int, exitDirection, ExitDirection);
The Y height at which a mirror reflection has its horizon (the default, zero, indicates no reflection).
GETTER(float, mirrorY, MirrorY);
Set a timer during which the game will play in slow motion.
GETTER_SETTER(double, slowMotionTimer, SlowMotionTimer);
Set a timer during which the screen will be shook.
GETTER_SETTER(double, screenShakeTimer, ScreenShakeTimer);
GETTER_SETTER(double, screenShakeStrength, ScreenShakeStrength);
How long the level has been running.
GETTER(double, upTime, UpTime);
Sets up the camera with the given screen middle.
void setupCamera(const Vec2& screenMiddle);
Moves the camera to the given position using the given time delta for smoothing.
void moveCamera(const Vec2& position, float delta);
Adds an object to the level with the given properties.
Used to add objects dynamically once the level is already running.
Automatically calls addChildAfterUpdate
to ensure the addition happens outside the update loop.
LevelObject* addObject(string className, ValueMap& properties);
Add a child outside of the update loop.
void addChildAfterUpdate(Node* n, int z = 0, int tag = 0);
Updates the level and all the objects using tick
and animate
methods.
void update(float dt);
Completes the level and either transitions to the next level or shows the player a continue screen.
Use area -1
, level -1
to flag the level completion as unsuccessful.
void completeLevel(int nextArea, int nextLevel);
Return the tile position for the given world position.
void getTilePos(const Point& posInPoints, int& x, int& y) const;
Clamp the tile position so it is guaranteed to be within bounds of the map size.
void clampTilePos(int& x, int& y) const;
Return the TMX layer if a tile exists at the given tile position.
TMXLayer* layerForTile(int x, int y, bool highlight = false) const;
Return true if a solid object at the given position with the given width and height can fit.
bool isClearTileArea(const Vec2& posInPoints, float width, float height) const;
bool isClearTileArea(TMXLayer* layer, int x, int y, int width, int height) const;
Get an object position which is guaranteed to be clear of tiles.
Vec2 getClearObjectPosition(const Vec2& desiredPosInPoints, int tileWidth, int tileHeight);
Vec2 getPlayerPosition(const Vec2& intialPosInPoints);
Return true if a solid tile is below the given object.
bool hasSolidTileBelow(const Vec2& posInPoints, float width, float height);
Vec2 getSolidTileBelow(const Vec2& posInPoints, float width, float height);
Return the object’s distance from the ground.
float getDistanceFromGround(LevelObject& obj);
If possible, hang on an edge near the position.
bool hangOnEdge(LevelObject& obj) const;
If possible, step up a tile.
bool stepUp(LevelObject& obj) const;
Highlight a tile.
void highlightTile(TMXLayer* layer, int x, int y, const Color3B& color) const;
Destroy a tile.
void destroyTileNear(const Point& pos);
void animateDestroyTileNear(const Point& pos);
Returns true if the level position is valid.
bool isValidPosition(const Point& posInPoints, float radius) const;
Return true if the object is out of bounds.
bool isOutOfBounds(const LevelObject& obj) const;
Create fixtures to represent a polygon.
void createPolygonFixtures(vector<Vec2>& polygon, long type, float friction, int category);
Returns the total level size in tiles.
Size getMapSize() const;
Returns the total level size in pixels / points.
const Size& getTotalSize() const;
Size getTotalSizeInPoints() const;
Returns the tile size in pixels / points.
Size getTileSize() const;
Size getTileSizeInPoints() const;
Return the color of the level.
Color3B getLevelColor() const;
Get the Player
object from the object layer’s children.
Player& getPlayer();
Gets the parent LevelScene
.
LevelScene& getLevelScene();
Gets a level object by tag.
LevelObject* getLevelObject(int tag);
Gets the closest exit point to the given position.
const ExitPoint& getClosestExit(const Vec2& pos);
Get the given exit point.
const ExitPoint& getExit(int area, int level);
Get an object by name.
LevelObject* getObjectByName(const string& name);
Returns the object at the given destination or null if none found.
LevelObject* objectAt(const Point& dest, LevelObject* forObject, bool isSolid, float fuzziness);
Animate a tile explosion.
void animateExplosion(const Vec2& pos, float scale, float duration, const Color3B& color);
Wake physics bodies up after a pause.
void wakePhysicsBodies();
Remove a script.
void removeScript(const string& filename);
Push / pop music to play.
void pushMusic(const string& filename, bool playImmediately);
string popMusic();
Implements PhysicsDelegate
to pass on collision contact data to level objects.
virtual bool beginContact(void* userDataA, int categoryA, void* userDataB, int categoryB);
If kDebugDrawBoxes
is set to 1
, this will draw debug boxes around all the tiles and objects.
virtual void draw(Renderer* renderer, const Mat4& transform, uint32_t flags) override;
Handlers.
virtual void onEnter();
virtual void onEnterTransitionDidFinish();
virtual void onExit();
private:
typedef Node super;
typedef Level self;
TMXTiledMap* map;
Physics physics;
Color3B color;
LayerColor* bgColor;
int layerCount,objectCount;
Size totalSize,cameraExtent;
Point cameraMin,cameraMax,cameraOffset,cameraDest;
double accumulator,lastTickTime,completeTime;
vector<Node*> objectsToAdd,objectsToRemove;
std::map<LevelObject*,bool> levelObjects;
int entryX1,entryX2,entryY1,entryY2;
LayerColor* shadowLayer;
float* shadowMap;
Sprite* fgTerrain,*bgTerrain;
LayerColor* radialLayer;
bool disableParallax;
std::map<int, Node*> backgrounds;
std::map<int, Node*> backgroundLayers;
std::map<int, Node*> foregrounds;
std::map<string,string> scripts;
vector<ExitPoint> exits;
double screenShakeAccumulator;
std::vector<string> music;
std::map<string, int> soundLoops;
string texturing;
Mat4 modelView;
CustomCommand customCommand;
void loadMap(const string& filename);
void createMap(int areaNum, int levelNum, float ease);
void parseMapProperties();
void createPhysicalWorld();
void createFixtures(TMXLayer* layer, int onewayDirection);
void createRectangularFixture(TMXLayer* layer, int x, int y, int onewayDirection);
void prepareLayers();
int prepareLayer(TMXLayer* layer);
void setAutoGlobalZ(TMXLayer* layer);
void setTileOpacity(TMXLayer* layer, int opacity);
void createTerrain(TMXLayer* layer);
void animateParallax();
void addObjects();
void tickObjects(float delta);
void animateObjects(float delta);
void addAndRemoveObjects();
bool destroyTile(int x, int y);
void animateEntry();
void onDraw();
void updateShadowsShader();
void updateRadialShader();
bool runScript(const string& key);
void animateDestroyTile(int x, int y);
};
Core
Object types