Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/markusmoenig/metalray
Code games in Swift and C in this "down to the metal" game framework for Xcode
https://github.com/markusmoenig/metalray
game-development game-engine ios macos metal raylib swift tvos xcode
Last synced: about 14 hours ago
JSON representation
Code games in Swift and C in this "down to the metal" game framework for Xcode
- Host: GitHub
- URL: https://github.com/markusmoenig/metalray
- Owner: markusmoenig
- License: mit
- Created: 2023-08-21T08:11:27.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2023-08-31T08:29:36.000Z (over 1 year ago)
- Last Synced: 2024-05-01T23:43:54.635Z (8 months ago)
- Topics: game-development, game-engine, ios, macos, metal, raylib, swift, tvos, xcode
- Language: Swift
- Homepage: https://moenig.io
- Size: 1.04 MB
- Stars: 9
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: Readme.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
## metalRay
**metalRay** is a bare bones game framework for the Apple ecosystem. If you want to code games close to the Metal with a convenient API (in the tradition of frameworks like [raylib](https://raylib.com)) you will feel right at home.
You can write games in Swift and in C directly in Xcode while being able to create C style interoperable memory structures and pass them to your Metal shaders.
*metalRay* focuses right now on 2D drawing, 3D support will be integrated once 2D is stable.
## Features
* Use drawing functions, textures and shaders with an easy to use API.
* Share memory (C style structs) between Swift, C and Metal.
* System device events can be easily queried in the game update functions.
* Draw text using SDF textures.
* Support for 2D physics and Tiled are incoming.
* Games / Apps can be deployed easily to macOS, iOS and tvOS using Xcode.## Why ?
I like to write games low level, and all the popular convenience frameworks out there (SDL2, raylib etc.) are not based on Metal but OpenGL, which makes iOS and tvOS compatibility problematic.
And being nostalgic, I also really enjoy coding in C again sometimes. Especially for implementing some of the classics. Get your hands dirty!
Being able to deploy your games easily to macOS, iOS and tvOS is a major advantage compared to the mostly limited cross-platform alternatives.
#### Downsides
* The API is implemented in Swift, however with a C style calling convention to make it work in both Swift and C. So no swiftiniess and functions return -1 if something goes wrong (and not null). Texts are passed as C Strings (use *toCStr()* to convert Strings to C strings).
* While it is super convenient to code your game directly in Xcode, the downside is that merging your fork of this repo can be a bit tedious (when updated). Basically keep your files limited to the *Game* folder and merge everything outside the *Game* folder (Swift, C, Metal, .h) files.## How to use
Fork this repository and open the Xcode project. All game related functions are inside the **Game** folder
* **game.swift**. The Swift based game entry point. Use the initGame(), updateGame() and deinitGame() functons.
* **game.c** The corresponding C file with InitGame(), UpdateGame() and DeinitGame().
* **header.h**. Implement C like structures here. These structures can be used in Swift and C as well as in Metal.
By default the Swift functions are called. If you want to implement (or mix) with the C code, call the C functions from there. See the example default code.
Place all your resources somewhere in the *Game* folder.
The Xcode project contains targets for macOS, iOS and tvOS.
I will soon add some Swift and C examples to the project.
## Status
- [x] Render Targets
- [x] Textures
- [x] Rectangle Drawing
- [x] SDF Text Drawing
- [x] Input Events Partially implemented (macOS, iOS, tvOS)
- [ ] SDF based Shapes
- [ ] Custom Shaders
- [ ] 2D Physics
- [ ] Tiled Import
- [ ] 3D Support---
## Structures used in the API
Loaned from raylib.
```c
// Color, 4 components, R8G8B8A8 (32bit)
typedef struct Color {
unsigned char r; // Color red value
unsigned char g; // Color green value
unsigned char b; // Color blue value
unsigned char a; // Color alpha value
} Color;// Vector2, 2 components
typedef struct Vector2 {
float x; // Vector x component
float y; // Vector y component
} Vector2;// Vector3, 3 components
typedef struct Vector3 {
float x; // Vector x component
float y; // Vector y component
float z; // Vector z component
} Vector3;// Vector4, 4 components
typedef struct Vector4 {
float x; // Vector x component
float y; // Vector y component
float z; // Vector z component
float w; // Vector w component
} Vector4;// Rectangle, 4 components
typedef struct Rectangle {
float x; // Rectangle top-left corner position x
float y; // Rectangle top-left corner position y
float width; // Rectangle width
float height; // Rectangle height
} Rectangle;
```These structures are used in the API and can be created from both Swift and C and passed to Metal shaders.
---
## Window / Events
```swift
// Returns the size of the screen / device
GetScreenSize() -> Vector2;// Left mouse click or touch event
HasTap() -> Bool;// Left mouse double click or double touch event
HasDoubleTap() -> Bool;// Left mouse is down or ongoing touch event
HasTouch() -> Bool;// Left mouse up or touch up event
HasTouchEnded() -> Bool;// Current mouse or touch event position in window / device
GetTouchPos() -> Vector2;
```## Drawing
```swift
// Starts drawing, if you change the render target you need to end drawing to your current target first.
BeginDrawing();
// End drawing
EndDrawing();// Sets the current font
SetFont(name: CString);
// Returns the size of the given text
GetTextSize(text: CString, size: Float) -> Vector2
// Draws the text of the given size at the given position
DrawText(pos: Vector2, text: CString, size: Float, color: Color);// Clears the current render target in the given color
Clear(color: Color);
// Draws a rectangle of the given color
DrawRect(rect: Rectangle, color: Color);
// Draws a rotated (around its center) rectangle of the given color
DrawRectRotCenter(rect: Rectangle, color: Color, rot: Int);
// More to come
```## Textures
```swift
// Creates an RGBA8 texture of the given width and height and returns its id. Returns -1 if unsuccessful.
CreateTexture(width: Int, height: Int) -> Int;
// Load an image in the Xcode project into a texture and returns its id. Returns -1 if unsuccessful.
LoadTexture(name: CString) -> Int;// Makes the texture of the given id the new render target. Use 0 to switch back to the default viewport. Make sure to end and restart drawing.
SetTarget(id: Int) -> Bool;// Makes the texture of the given id the new texture. All drawing functions will replace the color value with the interpolated texture value. Use 0 to disable texture support (needs to be called before EndDrawing() too).
SetTexture(id: Int) -> Bool;
```