#game-engine #graphics #gamedev

simple_engine_2d

A very simple 2D engine

2 releases

0.1.1 Apr 15, 2024
0.1.0 Mar 31, 2024

#321 in Rendering

40 downloads per month

MIT/Apache

66KB
1.5K SLoC

About

This is a simple 2D game engine designed for small 2D games. There is no rich functionality or unique features here.

Getting started

It is enough to add an engine to dependencies of your new project and it is ready for use. Don't forget to add the image feature if you are going to load textures from files.

How it works

First, you need to initialize the global state of the Application. This is also necessary to work with the engine components.

Next, in order for something to be displayed, you need a Scene. The scene allows you to react to user actions, as well as define and control the SceneItems (objects being drawn in the scene). There may be several scenes. The upper-left corner of the scene has the coordinate (0.0; 0.0), and the bottom-right corner has the coordinate (1.0; 1.0).

SceneItems are located on the Scene itself. This is a combination of the Shape and the Texture displayed on it. The Shape defines a geometric shape on the scene, and pixels from the Texture fill the space inside.

When everything is set up, all that remains is to launch the application via Application::run().

A little example

Let's create a simple scene where a rectangle with a white texture will move around:

use simple_engine_2d::*;

struct MyScene {
    my_item: SceneItem<Rect>,
}

impl MyScene {
    fn new() -> MyScene {
        // create a Shape with origin at top-left corner and 1/5 of size of scene
        let rect = Rect::new(0.0, 0.0, 0.2, 0.2);
        // create a Texture from an array of white opaque pixels (10x10)
        let texture = Texture::new(TextureDescriptor {
            width: 10,
            height: 10,
            pixels: Box::new([Color::WHITE; 10 * 10]),
            pixel_access: false,
            filter: TextureFilterMode::Linear,
        });
        // create a SceneItem from them
        MyScene {
            my_item: SceneItem::new(texture, rect),
        }
    }
}

impl Scene for MyScene {
    fn draw(&'static self, context: &mut DrawContext) {
        self.my_item.draw(context);
    }

    fn key_pressed(&'static mut self, key: KeyCode) {
        let rect: &mut Rect = self.my_item.shape_mut();
        let is_moved = match key {
            KeyCode::ArrowLeft => {
                rect.origin.move_by(-0.1, 0.0);
                true
            }
            KeyCode::ArrowRight => {
                rect.origin.move_by(0.1, 0.0);
                true
            }
            KeyCode::ArrowUp => {
                rect.origin.move_by(0.0, -0.1);
                true
            }
            KeyCode::ArrowDown => {
                rect.origin.move_by(0.0, 0.1);
                true
            }
            _ => false,
        };
        if is_moved {
            self.my_item.commit_shape_changes();
        }
    }
}

fn main() {
    Application::initialize(AppInitParams::default());
    Application::add_scene(MyScene::new());
    Application::run();
}

Dependencies

~4–43MB
~649K SLoC