cthit / CodeIT

2d platform game base
0 stars 2 forks source link

CodeIT

A basic game/framework for a 2d-platformer built with python. The purpose of the project is to be easily modifiable both for people with and without prior coding experience.


Table of Contents


Installation (Overly explicit)

  1. if you want to use an IDE, we recommend PyCharm (We recomend this, especially for Windows users). Which should include a python installation

  2. Make sure that you have Git installed on your system if not:

    • On Windows or Download and install using the wizard or install a graphical git client i.e Gitkraken.
    • On a Linux based system (or Mac) install using your package manager of choice
  3. Clone the project into your prefered folder.

    • if using GitKraken follow the instructions after installing
    • if using a Terminal

      cd <Your preffered folder>

      git clone https://github.com/cthit/2d-platform-game-it.git

PyCharm Instructions

Done!

Unix Instructions (if not runing PyCharm)

Finally if you run into any problem feel free to contact digIT

General instructions

Introduction

The game is built around making it very simple to add new content to the game and is therefore split into a few different parts:

All of these are modifiable in different ways which are described below.


General Information

The GameMethods Class

GameMethods is an object that exposes certain methods of the main Game class:

Behaviours

Behaviours are used to define the different behaviours of an entity for example some built in behaviours are:

Information about creating new behaviours can be found here.


Simplest modifications

Level Creation

To create a new level for the game you simply have to do the following steps:

  1. Create a folder with a name of your choosing in the levels folder.
  2. Create an .bmp image named map.bmp which will be your level. The game will later spawn entities and tiles according to the pixel values of the image.
  3. Add a config.ini file in the folder containing at least a General tab with a Name and a Index property.
  4. (optional!) You can also add a color-map.ini file if you want to use custom entities or tiles in your level. This file needs to contain a [Colors] tag and then a property with the hex value of the color you want to assign to the tile/entity which maps to the tile/entity class name you want. ex:
[Colors]
FF0000 = Player  ; This makes all RED, #FF0000, (255,0,0) pixels on your map.bmp turn into Player entities

Config details

[General]
Name = Grass Level
Index = 2

The name property is simply a name for the level and can be whatever you want to name your level. The index property decides which order the levels come in and can be any number >= 1 (if there are more than one with the same index one of them will be selected by random).

There are also several other properties and tags which are optional and will be using the default settings if not present. These are:

Physics

[Physics]
Gravity = 5

Gravity is the downwards acceleration that is applied to falling entities in the level (default 9.82) can be negative! gravity = blockheight/s^2 Camera

There are several different camera modes to choose from, but only choose one per level.

Camera(Static)

Static is the simplest mode it defines a camera that is fixed in place and size.

[Camera]
; Static camera mode
Mode = Static
Blocksize = 10
X = 50
X-unit = percent
Y = 20
Y-unit = tiles

The blocksize attribute defines how big (in pixels) a single tile should be.

X, X-unit, Y and Y-unit are all properties to define how the camera should be positioned.

X-unit and Y-unit is either "percent" or "tiles" and defines how much the camera should be offset from its default position (centered in the upper left corner of the level.)

The "Percent" unit means percent of the level width (for x) and height (for y).

Camera(Follow)

The follow mode centers the camera on an entity in the level.

[Camera]
; Follow camera mode
Mode = Follow
Target = Player
Blocksize = 10

"Target" is the name of the entity on the map. Make sure that there are no more than one such entity on the map. (The camera can, for instance, not follow two player entities simultaneously)

Camera(Tile)

The Tile mode divides the level into smaller sections, and the camera focuses on the section containing its target. (Think Super Mario)

[Camera]
; Tile Camera mode
Mode = Tile
X = 0
X-span = 20
Y = 0
Y-span = 10
Target = Player

In the tile mode. Instead of "blocksize", you define how many tiles should be visible height- and width wise.

This is done using the attributes X-span and Y-span.

The X and Y values are used to offset the tiling grid.

Pre-Existing Levels

There are a number of levels already in the game so to avoid unintentional index-clashes, here's a list of the currently existing levels by index, note that indexes <= 0 are used for non game-level levels such as menu screens.

Creating new tiles

Creating new tiles is probably the easiest modification you can do to the game altough a custom level is probably required to use the new tiles.

To create a new tile you simply have to create a new folder with the name of the tile (in lowercase letters only) and then put an image with the name of the tile in that folder. example for tile named Stone:

├── tiles
    ├── stone
        └── Stone.png

Intermediate Modifications

Creating new entities

Creating new entities is similar to creating new tiles. You create a folder with the name of the entity (folder name needs to be lowercase only) and it in the /entities folder, then put an image with the name of the entity in that folder. After this you need to put a python file with the name of the entity in the folder. example for an entity called PowerUp:

├── entities
    ├── powerup
        ├── PowerUp.py
        └── PowerUp.png

The python file needs to contain a class with the name of the entity and it needs to inherit from the base Entity class or another class that does inherit from the Entity class, for example if you want to create an enemy it's probably a good idea to inherit from the character class. The class constructor also needs to take an x, y and a name which also will need to be passed onto the super constructor.

example for an enemy class:

from entities.character.Character import Character

class Enemy(Character):
    def __init__(self, x, y, name):
        super().__init__(x, y, name)
        ...

Entity also have some default methods that can be overriden to add new features to the game most nobable of these is the update method which is called once every frame and looks like this:

def update(self, delta_time, keys, config, game_methods):
    ...

The entity class has the following properties:

The entity class also has the following methods:

Entities and Behaviours

Some of these methods are used for adding and getting behaviours so for easy reference, to add a new Behaviour to the entity use the register_behaviour(self, behaviour) or register_behaviours(self, behaviours) methods (generally called from the constructor, _init_). For example, to add the fall behaviour to an entity:

from behaviours.Fall import Fall

...

def __init__(self, x, y, name):
   self.register_behaviour(Fall())

If you later want to change something to the behaviour you can access it you can use the get_behaviour(self, behaviour_name) method. For example to change weather an entity with the collide behaviour is a trigger (get's the collision events but otherwise acts like a ghost) you can do like this:

from behaviours.Collide import Collide

...
   self.get_behaviour(Collide).is_trigger = True

Creating new Behaviours

To create a new behaviour you simply need to create a python file in the behaviours folder and make inherit from the behaviour class either directly or through another class. The behaviour class constructor takes an optional owner parameter which can be used to set the owner of the behaviour at initialization. The Behaviour class also has the following methods:

You can read more about how to use behaviours with entities here.

Changing the UI

The UI is defined by "Views", and each level can optionally have one view associated with it. To bind a view to a level, you simply have to add View = ViewName under the [GUI] tag in your config.ini.

All views are located as python scripts in the "views" folder.

Here is an example of a very basic "main menu" view.

from src.gui.elements.button.Button import Button
from src.gui.elements.text.TextBlock import TextBlock

def load_view(gui, game):
    gui.add_gui_element(TextBlock("Welcome to my game!", 100, 100))
    gui.add_gui_element(Button("Start Game", 100, 150, lambda: game.load_level(1)))

The name of the view is defined by the name of the view file. So this would be MainMenu.py, and the main menu level would have View = MainMenu in its config.

If the view is a pure GUI screen (not a game level), make sure the Type property under the [General] tag in the levels config to "Pure GUI" i.e. for the main menu:


[General]
Name = Main Menu
Type = Pure GUI
Index = 0
[GUI]
View = MainMenu