HeavylI Engine
HeavylI Engine
is a game engine (with graphics, ECS, and scripting support) based on the HeavylI
graphics library.
Usage:
This crate should be used with the heavyli
(currently version 0.0.6) crate to get the best results from the engine.
This engine includes ECS support (check heavyli_engine::ecs
), native script support (check heavyli_engine::ecs::native_script
), Lua scripting support (check heavyli_engine::lua_script
), and basic sprite handling using Renderer2D and Sprite2D (check heavyli::render
).
Code Example:
First, checkout the resources folder in the heavyli
repository in order to load the images needed for this example.
In this example we'll create a little mario game (no physics here though).
To start, add this Lua script example at res/test.lua
(see the resources folder in the repo):
function start()
math.randomseed(os.time())
mario_texture = add_texture("res/mario-stand.png")
block_texture = add_texture("res/basic-block.png")
renderer:add_sprite(0, 0.0, 0.0, 0.5, 0.5, mario_texture)
renderer:add_sprite(2, 1.0, 1.0, 0.5, 0.5, block_texture)
renderer:add_sprite(3, 0.5, 1.0, 0.5, 0.5, block_texture)
renderer:add_sprite(4, 1.0, 0.5, 0.5, 0.5, block_texture)
renderer:add_sprite(5, 0.5, 0.5, 0.5, 0.5, block_texture)
end
counter = 6
pos_x = 0
pos_y = 0
speed = 1
mario_texture = 0
block_texture = 0
function update()
speed = delta_time
if key_pressed("up") then
pos_y = pos_y + speed
elseif key_pressed("down") then
pos_y = pos_y - speed
end
if key_pressed("left") then
pos_x = pos_x + speed
elseif key_pressed("right") then
pos_x = pos_x - speed
end
renderer:set_sprite_position(0, pos_x, pos_y)
renderer:set_camera_position(0, pos_x, pos_y)
if key_pressed("a") then
renderer:add_sprite(counter, counter % 12 * 0.5, math.random() % 30, 0.5, 0.5, block_texture)
counter = counter + 1
print(counter)
end
end
Also, you should have these two shader files:
shader/basic_fragment.glsl
:
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
in vec2 texCoord;
uniform sampler2D texture1;
void main()
{
vec4 col = texture(texture1, texCoord) * vec4(ourColor, 1.0f);
if (0 == col.r && 0 == col.g && 0 == col.b)
{
discard;
}
FragColor = col;
}
shader/basic_vertex.glsl
:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 texCoord;
uniform mat4 translation;
void main()
{
gl_Position = translation * vec4(aPos, 1.0);
ourColor = aColor;
texCoord = aTexCoord;
}
With this script you'll have a little mario game running.
Now, for the rust code:
extern crate glfw;
extern crate heavyli;
extern crate heavyli_engine;
extern crate nalgebra_glm as glm;
use crate::heavyli::{opengl_modules::init_glfw, rendering::window::Window};
use crate::heavyli_engine::{
ecs::scene::{Scene, SceneCore, SceneState, Update},
render::{
camera::Camera,
utils::{configure_window, window_end_frame, window_start_frame},
},
};
const SCR_WIDTH: u32 = 800;
const SCR_HEIGHT: u32 = 600;
fn main() {
let mut glfw = init_glfw();
let mut window = Window::new(&glfw, "Sandbox", SCR_WIDTH, SCR_HEIGHT);
configure_window(&mut window);
let mut scene = Scene::new(&mut glfw, &mut window, Scene1::new());
scene.start();
while SceneState::End != scene.get_state() {
scene.update(120.0);
}
}
fn set_window_title(window: &mut Window, delta_time: f32) {
let mut title = "Sandbox | FPS: ".to_string();
title.push_str(
(1.0 / if 0.0 != delta_time && delta_time > 0.000001 {
delta_time
} else {
f32::MIN_POSITIVE
})
.to_string()
.as_str(),
);
window.set_title(&title);
}
pub struct Scene1 {
delta_count: f32,
}
impl Scene1 {
fn new() -> Self {
Self { delta_count: 0.0 }
}
}
impl Update for Scene1 {
fn start(&mut self, core: &mut SceneCore) {
core.registry.lock().unwrap().add_component(
0,
Camera::new(glm::vec3(0.0, 0.0, -5.0), glm::vec2(0.0, 90.0)),
);
let script_id = core.lua_script_manager.create_script_handler();
if let Err(err) = core
.lua_script_manager
.script_load(script_id, "res/test.lua")
{
println!("Error: {}", err);
}
}
fn update(&mut self, core: &mut SceneCore) {
window_start_frame(core.window);
let cam_view = core
.registry
.lock()
.unwrap()
.get_component::<Camera>(0)
.unwrap()
.borrow_mut()
.lock()
.unwrap()
.get_view();
core.renderer
.render(glm::vec2(SCR_WIDTH as f32, SCR_HEIGHT as f32), &cam_view);
self.delta_count += core.delta_time;
if self.delta_count >= 1.0 {
set_window_title(core.window, core.delta_time);
self.delta_count = 0.0;
}
if !core.window.is_open() {
core.state = SceneState::End;
}
if SceneState::End == core.state {
core.renderer.delete_all_sprites();
}
window_end_frame(core.window, core.glfw);
}
}
Features:
- ECS (Entity Component System) Support
- Native Scripts support (NativeScript trait)
- External Language Scripting - Lua Support (LuaScript struct)
- Scene Support