Game Structure
Beginner-Friendly Guide to 3D Game Development with Infinit Engine and ModernGL Infinit Engine is designed to make game development easy for beginners. If you're just starting out, don't worry! This guide will walk you through everything you need to do step-by-step. We'll explain the game structure, how to organize your project, and how to access assets and use ModernGL to render 3D objects. 1. Setting Up the Project Folder Structure First, you need to organize your files and folders. This helps you keep your game project clean and easy to manage. Here's how you should structure your game folder: bash Copy Edit MyGameProject/ ├── assets/ # Folder for your game assets like images, models, and sounds │ ├── images/ # Store images (e.g., player sprites, textures) │ ├── models/ # Store 3D models (e.g., .obj, .fbx files) │ └── sounds/ # Store sound files (e.g., .wav, .mp3) ├── code/ # Folder for your Python scripts (game logic, rendering) │ ├── main.py # Main file to run your game │ ├── renderer.py # Script for rendering 3D models and textures │ └── game_logic.py # Script for the game's mechanics (e.g., player movement) ├── build/ # Folder to store compiled or packaged versions of your game └── README.md # This file! (Documentation about your game) 2. Installing Required Libraries To start using Infinit Engine and ModernGL, you'll need to install the required libraries. ModernGL helps us render 3D graphics, while Pygame handles creating windows and managing events. You can install these libraries by running this in your terminal or command prompt: bash Copy Edit pip install pygame pyopengl moderngl Once installed, you're ready to start coding! 3. Creating the Renderer with ModernGL Now, we're going to use ModernGL to render 3D objects in the game window. We'll use a simple example to help you understand the core concepts. renderer.py (Setting Up ModernGL) First, we create a script called renderer.py that will handle all of the rendering (drawing 3D objects) for the game. python Copy Edit import moderngl import numpy as np import pygame as Infinit2D from PIL import Image import os class Renderer: def __init__(self, width, height): self.width = width self.height = height # Create a ModernGL context (basically an OpenGL environment) self.context = moderngl.create_context() # Set up the Pygame window with OpenGL Infinit2D.display.set_mode((self.width, self.height), Infinit2D.OPENGL | Infinit2D.DOUBLEBUF) Infinit2D.display.set_caption("3D Game with ModernGL") # Create shader programs (this is how we tell the GPU how to render objects) self.program = self.create_shader() # Set up a simple projection matrix (this controls how objects appear on the screen) self.projection = np.array([ [2.0 / self.width, 0, 0, 0], [0, 2.0 / self.height, 0, 0], [0, 0, 1.0, 0], [0, 0, 0, 1] ], dtype=np.float32) self.model_matrix = np.identity(4, dtype=np.float32) def create_shader(self): """ Create the shaders to tell the GPU how to draw objects """ # Vertex shader (defines how to display objects in 3D space) vertex_shader = """ #version 330 uniform mat4 projection; uniform mat4 model; in vec2 in_vert; in vec2 in_text; out vec2 tex_coords; void main() { tex_coords = in_text; gl_Position = projection * model * vec4(in_vert, 0.0, 1.0); } """ # Fragment shader (defines the color of objects) fragment_shader = """ #version 330 uniform sampler2D texture1; in vec2 tex_coords; out vec4 fragColor; void main() { fragColor = texture(texture1, tex_coords); } """ # Compile and link the shaders to create a program return self.context.program(vertex_shader=vertex_shader, fragment_shader=fragment_shader) def load_texture(self, image_path): """ Load a texture (image) and turn it into a 3D texture """ image = Image.open(image_path).transpose(Image.FLIP_TOP_BOTTOM) image_data = np.array(image, dtype=np.uint8) # Create the texture texture = self.context.texture(image.size, 3, image_data) texture.use() return texture def load_model(self, model_path): """ Load a simple model (for now, a 2D square) """ vertices = np.array([ -0.5, -0.5, 0, 0, 1, 0.5, -0.5, 0, 1, 1, 0.5, 0.5, 0, 1, 0, -0.5, 0.5, 0, 0, 0 ], dtype=np.float32) # Create the vertex buffer object (VBO) to hold the model data vbo = self.context.buffer(vertices) # Create a vertex array object (VAO) to define how the data is laid out vao = self.context.simple_vertex_array(self.program, vbo, 'in_vert', 'in_text') return vao def render(self): """ Render the 3D objects in the game window """ # Clear the screen self.context.clear() # Apply the projection matrix to define how the world is viewed self.program['projection'].write(self.projection) self.program['model'].write(self.model_matrix) # Draw the model (this can be expanded with more models) vao = self.load_model("assets/models/cube.obj") # You will need to add a model (like a cube.obj) vao.render(moderngl.TRIANGLE_FAN) # Update the screen with the rendered image Infinit2D.display.flip() Explaining the Renderer Code ModernGL Context: This sets up a rendering environment where you can draw 3D objects. Shaders: Shaders are small programs that run on your graphics card to render 3D objects. The vertex shader controls how objects are placed in the 3D world, and the fragment shader controls how objects appear (color, texture). Textures: Textures are images (like pictures or sprites) that are applied to the 3D objects. Model Loading: We load 3D models (for example, .obj files) and prepare them for rendering. 4. Accessing and Using Models and Textures In the assets/models/ folder, you'll need to store 3D models (like .obj files). You can then load them using the load_model() function. Importing Models and Textures To import a texture (image file like .png, .jpg), use the load_texture() method: python Copy Edit # Example to load a texture from assets/images/ texture = renderer.load_texture("assets/images/player_texture.png") For loading models, such as a cube (cube.obj), make sure you save them in the assets/models/ folder, and pass the model path to the load_model() method. python Copy Edit # Example to load a model vao = renderer.load_model("assets/models/cube.obj") 5. Putting Everything Together in main.py Finally, the main.py file serves as the entry point for your game. python Copy Edit import pygame as Infinit2D from renderer import Renderer # Import the renderer class to draw 3D objects
This function constructs the path for an image in the assets/images
folder and uses Pygame
to load it. If the image is successfully loaded, it returns the image surface, which can then be used in the game.
3. Placing Python Scripts for Your Game Logic
In your code/
folder, you should place your main game script and any other scripts that handle different game systems, like physics, input, or AI.
- Main script (
main.py
): This is the entry point for your game. It initializes the game, loads assets, and controls the main game loop. - Game logic scripts (
game_logic.py
): These are additional Python files that handle specific game mechanics like player movement, collisions, etc.
Here’s an example of the main.py
script:
python CopyEdit import pygame as Infinit2D from game_logic import GameLogic # Import game logic from another script # Initialize Pygame Infinit2D.init() # Set up the screen dimensions WIDTH, HEIGHT = 800, 600 screen = Infinit2D.display.set_mode((WIDTH, HEIGHT)) Infinit2D.display.set_caption("Infinit Engine Game") # Game loop game_logic = GameLogic() # Instantiate game logic running = True while running: for event in Infinit2D.event.get(): if event.type == Infinit2D.QUIT: running = False # Update game logic game_logic.update() # Clear screen screen.fill((255, 255, 255)) # Background color (white) # Render game objects game_logic.render(screen) # Refresh screen Infinit2D.display.flip() # Control frame rate Infinit2D.time.Clock().tick(60) Infinit2D.quit()
In this main.py
script, the GameLogic
class is imported from a separate Python file (game_logic.py
) and used to handle game updates and rendering.
4. Handling Assets and Code in the IDE
In your Infinit Engine, you already have functionality for importing assets and saving Python code. Here’s how to structure the asset import process:
- Importing an Asset (Image):
- Use the
filedialog
to choose and import images into the engine. - Store the image in the
assets/images/
folder.
- Use the
python CopyEdit def import_asset(): global imported_image file_path = filedialog.askopenfilename(filetypes=[("Image files", "*.png;*.jpg;*.jpeg;*.bmp;*.gif")]) if file_path: try: # Get the file name and save the image to the assets/images/ folder asset_name = os.path.basename(file_path) destination_path = os.path.join(ASSETS_FOLDER, 'images', asset_name) with open(file_path, 'rb') as src_file: with open(destination_path, 'wb') as dest_file: dest_file.write(src_file.read()) messagebox.showinfo("Import Successful", f"Image imported to {destination_path}") except Exception as e: messagebox.showerror("Import Error", f"Failed to import image: {e}")
- Accessing and Using Imported Assets:
- After importing an asset, you can access it from the
assets/images/
folder in your code. - For example, you can call
load_image()
to load the image into the game’s rendering system.
- After importing an asset, you can access it from the
5. Compiling and Running Your Game
If you want to compile your game into an executable, the Infinit Engine has a feature to compile Python code using PyInstaller
. You already have a function in your engine that allows for compiling Python code into a standalone .exe
file.
python CopyEdit def compile_to_exe(): code = code_editor.get("1.0", tk.END) if not code.strip(): messagebox.showwarning("Warning", "Code editor is empty. Please write code before compiling.") return # Save the code to a temporary file temp_file_path = os.path.join(os.path.expanduser("~"), "Desktop", "temp_code.py") try: with open(temp_file_path, "w") as temp_file: temp_file.write(code) # Run PyInstaller to compile the code compile_command = f"pyinstaller --onefile --distpath {os.path.expanduser('~')}/Desktop --workpath {os.path.expanduser('~')}/Desktop --specpath {os.path.expanduser('~')}/Desktop {temp_file_path}" subprocess.run(compile_command, shell=True, check=True) messagebox.showinfo("Compilation Successful", "Your executable has been created on the Desktop.") except Exception as e: messagebox.showerror("Compilation Error", f"Failed to compile the code: {e}")
This function will save the code from the IDE, and run PyInstaller to package your code into an executable .exe
file.
Conclusion
By structuring your Infinit Engine project with these best practices and utilizing the features already present in the engine, you'll be able to manage your assets, code, and resources efficiently. The key is to:
- Organize your files: Place your assets (images, models, sounds) in dedicated folders and Python scripts in a
code/
folder. - Access assets correctly: Use functions to load assets based on the folder structure.
- Use the built-in IDE to import, edit, and save code, while managing assets easily.
This structure will help you build games more effectively and scale them up as you add more features.
Get INFINIT ENGINE
INFINIT ENGINE
Game Engine, IDE
Status | Released |
Category | Tool |
Author | TatorTillInfinity |
Genre | Adventure, Platformer |
Tags | 2D, 3D, 3D Platformer, First-Person, Game engine, Pixel Art, Retro, Singleplayer |
More posts
- Infinit Graphics11 days ago
- Theme Editor29 days ago
- Name Change38 days ago
- Infinit Engine Updates44 days ago
- IE Code51 days ago
Leave a comment
Log in with itch.io to leave a comment.