Sign in to follow this  

2D Text Based Side-Scrolling Game (Linux) - Works and would like comments on coding

Recommended Posts

bedtime    159
This is a basic game that uses Linux ncurses to display characters. It can easily be ported to SDL. I am new to C++ and would like someone to comment on my code style and structure and perhaps give some suggestions. I don't expect anyone to read all this code - there are over 1500 lines of it. Just a glance and a comment would be great. I've provided ample notes with the code and made it as easy as possible to understand.

Please read the notes in 'main.cpp' for more information if you are interested.

// main

// game.cpp

// drawscreen.cpp

// game.h

// drawscreen.h

// Compile on Linux with:
[CODE]g++ -Wall main.cpp game.cpp drawscreen.cpp -lncurses -std=c++11[/CODE]

Below I've only posted two files as the size is too big to post all.

// main
// main.cpp
#include <iostream>
#include <ncurses.h>
#include <vector>
#include <algorithm>
#include <functional>
#include "game.h"
#include "drawscreen.h"
* This program 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.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <>.
* These dependancies must be installed to compile this program in ubuntu:
* sudo apt-get install build-essential ncurses-dev
* Compile & run on linux:
* g++ -Wall main.cpp game.cpp drawscreen.cpp -lncurses -std=c++11
* Run:
* ./a.out

* This game starts off with the main character in a blank rectangle bordered
* area with no other objects. With the instuctions below you can build your
* own level in realtime; add enemies, players, objects, create automatic
* movements... Later on there will be the ability to save the map to disk.
* Gameplay:
* a = left
* d = right
* s = down / stop jumping
* w = jump / up, when in edit mode
* unrestricted movement:
* up arrow
* down arrow
* left arrow
* right arrow
* steers character but is unrestrained and allows to go through objects.
* used mostly in edit mode
* e = edit mode
* edit mode allows one to move around the board without gravity effects
* on particular character
* r = record moves
* when 'r' is pressed the game starts recording your moves. press
* 'r' again to go back into play mode and playback the moves. note
* that while playing moves you cannot control the character. to
* regain control simply press 'r' twice. this will record 0 moves
* and allow movement freedom. also, moves will not play in edit mode
* 1-9 = switch to player number < keypressed >
* you can automatically switch to any other player by
* pressing their player number button
* 0 = control object
* pressing '0' whilst hovering over an object allows you to become that object
* '-' and '=', cycle through and change character types
* n = new object
* pressing 'n' make a new object appear right behind the current object.
* you must be in edit mode to add objects or game will go into infinit
* recursion due to pusher function in the collision method; bug
* c = clear object
* hover over a character and press 'c' to clear them
* q / esc = quit game
* Benefits of game:
* - NOTES!!! - Almost every line of code has notes, not on 'what' is
* happening, but 'why' it has to happen :)
* - 0 number of errors or warnings in compile (g++ -wall mode)
* - debugging stats on screen during gameplay
* - sectioned areas for speed and large maps
* - infinit player ability
* - multiple collision cooridinates per object (as many as needed)
* - most data is not hardcoded
* - using c++11 features (must compile for c++11)
* - easily upgradable to graphics (have done before with SDL)
* - collision detection can detect collision at any speed/skip rate
* - four direction distance detection on dashboard (can add other directions)
* - easy to add split / dual screens / dual/triple... games
* - all objects / characters treated the same. whatever a player
* can do, all objects can do, eg.. enemies, and even a brick, can jump.
* as well, enemies, player, and a brick can fly...
* - can morpth or take over control of any other player or object
* - encapsulated data; no #defines, static, and other global variables
* bugs (what game is without bugs??):
* #1 there is a bug that causes the characters to sink into
* the platform when entering and leaving other sections. temp fix
* can be implimented by uncommenting line 141/142 in drawscreen.cpp.
* temp fix applied by default
* #2 the method 'moveSection' in game.cpp causes system to lose players
* focus and alternates to other players can be temp fixed by commenting
* out this method
* #3 game.cpp, 'collision' method has a built in system that will be used
* to allow objects to move players, and players to move other players. this
* is not fully implimented and will cause infinit recursion if trying to
* add a new object whilst not in edit mode. temp fix applied by default
* in game.cpp, method 'keyboardCommand', case 110.
* Please note that I am a beginner programmer and this is my second
* small C++ game. I have not made a map or implimented any other
* features as I feel it would be better focus on the basics.
* Comments regarding programming style are programming tips are
* welcomed and encouraged. Please refrain from giving ideas
* regarding gameplay and gameplay options, such as, "You should make
* the character be able to shoot and duck." I am not looking for such
* input.
int main()

// create draw object
DrawScreen drawGame;

// create game object vector
std::vector<std::vector<Game>> obj;

// create game character objects
Game::initialiseGame(obj, drawGame);

// run game
while (drawGame.keepPlaying())
// get key presses and slow down game speed

// draw objects

// calculate the lowest and highest section within range
register unsigned int lowSection, highSection;
drawGame.sectionLowTohigh(obj, lowSection, highSection);
// move objects
for(unsigned int currentSection = lowSection;
currentSection <= highSection; ++currentSection)
for(unsigned int i = 0; i < obj[currentSection].size(); ++i)
obj[currentSection][i].moveCharacter(obj, drawGame, currentSection, i);

// draw all data to screen
// shut down ncurses and exit

return 0;

// game.h
// game.h
#ifndef GAME_H
#define GAME_H
#include <vector>
enum struct characterType
enum struct movementType
enum struct moverType
enum struct modeType
// not yet used
enum struct layerType
struct movementArray
movementType moveType; // type of move
unsigned int repNumber; // how many times to repeat this move?

class DrawScreen;
class Game

// game qualities
static void initialiseGame(std::vector<std::vector<Game>> & obj, DrawScreen &Draw);
// character qualities
inline void setCharacter(const characterType & i) { character = i; }
inline void setBornCharacter(const characterType & i) { setCharacter(bornCharacter = i); }
inline void setMovement(const movementType & i) { movement = i; }
inline void setMoverType(const moverType & i) { mover = i; }
inline void setLayer(const layerType & i) { layer = i; }
inline void setMode(const modeType & i) { mode = i; }
inline void setSequenceNumber(const unsigned int & i) { sequenceNumber = i; }
inline void setSequenceRep(const unsigned int & i) { sequenceRep = i; }
inline void setNoTurn(const bool & i) { hasNoTurn = i; }
inline void setPlayerNum(const int & i) { playerNum = i; }
inline characterType getCharacter() const { return character; }
inline characterType getBornCharacter() const { return bornCharacter; }
inline movementType getMovement() const { return movement; }
inline moverType getMoverType() const { return mover; }
inline layerType getLayer() const { return layer; }
inline modeType getMode() const { return mode; }
inline unsigned int getSequenceNumber() const { return sequenceNumber; }
inline unsigned int getSequenceRep() const { return sequenceRep; }
inline bool getNoTurn() const { return hasNoTurn; }
inline int getPlayerNum() const {return playerNum; }

// character morphing qualities
void changeCharacter(const int & key);
bool becomeCharacter(std::vector<std::vector<Game>> & obj, DrawScreen &drawGame, const int &currentSection, const int &objNum);
void createCharacter(std::vector<std::vector<Game>> & obj, DrawScreen &drawGame, const int &currentSection, const int &objNum);
void clearCharacter(std::vector<std::vector<Game>> & obj, DrawScreen &Draw, const int &currentSection, const int &objNum);
bool changePlayer(std::vector<std::vector<Game>> & obj, DrawScreen &Draw, const int &currentSection, const int &objNum);
// character position on board
inline void setPosY(const int &y) { posY = y; }
inline void setPosX(const int &x) { posX = x; }
inline void setMoveDistance(const int &i) { moveDistance = i; }
inline int getPosY() const { return posY; }
inline int getPosX() const { return posX; }
inline int getMoveDistance() const { return moveDistance; }

// movement methods
void moveUp(std::vector<std::vector<Game>> & obj, DrawScreen &drawGame, const int &currentSection, const int &objNum);
void moveDown(std::vector<std::vector<Game>> & obj, DrawScreen &drawGame, const int &currentSection, const int &objNum);
void moveLeft(std::vector<std::vector<Game>> & obj, DrawScreen &drawGame, const int &currentSection, const int &objNum);
void moveRight(std::vector<std::vector<Game>> & obj, DrawScreen &drawGame, const int &currentSection, const int &objNum);
void moveInitiateJump(std::vector<std::vector<Game>> & obj, DrawScreen &drawGame, const int &currentSection, const int &objNum);
bool moveJump(std::vector<std::vector<Game>> & obj, DrawScreen &drawGame, const int &currentSection, const int &objNum);
void moveGravity(std::vector<std::vector<Game>> & obj, DrawScreen &drawGame, const int &currentSection, const int &objNum);
bool moveObj(std::vector<std::vector<Game>> & obj, DrawScreen &Draw, const int &currentSection, const int &objNum, const int &direction);
// jumping information
inline void setJumpPos(const int &i) { jumpPos = i; } // set position within jump
inline void setMaxJump(const int &i) { maxJump = i; } // height of jump
inline int getJumpPos() const { return jumpPos; } //
inline int getMaxJump() const { return maxJump; } //
// object control methods
int collision(std::vector<std::vector<Game>> & obj, DrawScreen &drawGame, const int &currentSection, const int &objNum, const int &angleToCheck);
int moveCharacter(std::vector<std::vector<Game>> & obj, DrawScreen &drawGame, const int &currentSection, const int &objNum);
void keyboardCommand(std::vector<std::vector<Game>> & obj, DrawScreen &Draw, const int &currentSection, const int &objNum);
void objSize(std::vector<std::vector<Game>> & obj, const int &currentSection, const int &objNum1, std::vector<int> * ybottom, std::vector<int> * xleft, std::vector<int> * ytop, std::vector<int> * xright);
void moveNow(std::vector<std::vector<Game>> & obj, DrawScreen &Draw, const int &currentSection, const int &objNum, const int &direction, const int &distance);
void moveSection(std::vector<std::vector<Game>> & obj, DrawScreen &Draw, const int &currentSection, const int &objNum, const int &direction, const int &distance);
void recordMovement();
void toggleEdit(DrawScreen &Draw);
void playMode(std::vector<std::vector<Game>> & obj, DrawScreen &Draw, const int &currentSection, const int &objNum);
void playMovement(std::vector<std::vector<Game>> & obj, DrawScreen &Draw, const int &currentSection, const int &objNum);
// debug information
void printStats(std::vector<std::vector<Game>> & obj, DrawScreen &Draw, const int &currentSection, const int &objNum);

// personal character data
characterType bornCharacter =
characterType::humanplayer; // innate character
characterType character =
characterType::humanplayer; // current playing character
movementType movement =
movementType::wait; // current enemy movement
movementType lastMove; // current enemy movement
moverType mover; // can the object move other objects?
layerType layer; // bkgrounnd, foreground...
modeType mode = modeType::play; // eg. play, edit, record...
std::vector<movementArray> moveSeq; // movement sequence for objects & enemies
// character qualities
int posY = 5; // y location on board
int posX = 10; // x location on board
int playerNum = 0; // what player number
int jumpPos = 0; // jump
int maxJump = 10; // height of jump
unsigned int moveDistance = 1; // distance character moves each turn
unsigned int sequenceNumber = 0; // sequence move number
unsigned int sequenceRep = 0; // sequence repetition number
bool hasNoTurn = false; // needed for section changing...
#endif // Game_H

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this