diff --git a/README.md b/README.md index 351c360..9f0481a 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ New CFFI API static bindings. Faster, fewer bugs and easier to maintain than ctypes. +# Advert + +[RetroWar: 8-bit Party Battle](https://retrowar.net) is out now. Defeat up to 15 of your friends in a tournament of 80s-inspired retro mini games. + # Install **Windows 10 (64 bit): Python 3.6 - 3.7** @@ -91,9 +95,9 @@ which we supply for Windows/Mac/Linux. See test_dynamic.py for how to use. -## raylib.richlib +## richlib -A very easy to use library on top of static bindings, modelled after Pygame Zero. +[A simplified API for Raylib for use in education and to enable beginners to create 3d games](https://github.com/electronstudio/richlib) # Platforms tested diff --git a/raylib/richlib/__init__.py b/raylib/richlib/__init__.py deleted file mode 100755 index 12c4038..0000000 --- a/raylib/richlib/__init__.py +++ /dev/null @@ -1,372 +0,0 @@ -""" Richlib, simple access to Raylib -""" -__version__ = '0.1' - -from ..static import ffi, rl -#from ..dynamic import ffi, raylib as rl -from ..colors import * - -import sys - -data_dir = "" - -from ..pyray import PyRay - -pyray = PyRay() - -camera = ffi.new("struct Camera3D *") -camera.position = (0.0, 100, 100) -camera.target = (0.0, 0.0, 0.0) -camera.up = (0, 1, 0) -camera.fovy = 45 -camera.type = rl.CAMERA_PERSPECTIVE - -mod = sys.modules['__main__'] - - -class Vector(list): - @property - def x(self): - return self[0] - - @x.setter - def x(self, value): - self[0] = value - - @property - def y(self): - return self[1] - - @y.setter - def y(self, value): - self[1] = value - - @property - def z(self): - return self[2] - - @z.setter - def z(self, value): - self[2] = value - - @property - def w(self): - return self[3] - - @w.setter - def w(self, value): - self[3] = value - -class Color(list): - def __init__(self, s): - if isinstance(s, str): - super().__init__(globals()[s.upper()]) - else: - super().__init__(s) - if len(self) == 3: - self.append(255) - - @property - def r(self): - return self[0] - - @r.setter - def r(self, value): - self[0] = value - - @property - def g(self): - return self[1] - - @g.setter - def g(self, value): - self[1] = value - - @property - def b(self): - return self[2] - - @b.setter - def b(self, value): - self[2] = value - - @property - def a(self): - return self[3] - - @a.setter - def a(self, value): - self[3] = value - - -def clear(color=BLACK): - rl.ClearBackground(Color(color)) - - -class Shape: - @property - def color(self): - return self._color - - @color.setter - def color(self, value): - self._color = Color(value) - - @property - def pos(self): - return self._pos - - @pos.setter - def pos(self, value): - self._pos = Vector(value) - - @property - def wire_color(self): - return self._wire_color - - @wire_color.setter - def wire_color(self, value): - self._wire_color = Color(value) - - @property - def x(self): - return self.pos.x - - @x.setter - def x(self, value): - self.pos.x = value - - @property - def y(self): - return self.pos.y - - @y.setter - def y(self, value): - self.pos.y = value - - @property - def z(self): - return self.pos.z - - @z.setter - def z(self, value): - self.pos.z = value - - -class Box(Shape): - def __init__(self, position, size, color=RED, wires=True, wire_color=DARKGRAY): - self.pos = position - self.size = size - self.color = color - self.wire_color = wire_color - self.wires = wires - - # def __getattr__(self, item): - # return self.pos.item - # - # def __setattr__(self, key, value): - # self.pos.key = value - - @property - def size(self): - return self._size - - @size.setter - def size(self, value): - print("setting size ", value, type(value)) - self._size = Vector(value) - - def get_bounding_box(self): - return ( - ( - self.pos.x - self.size.x / 2, - self.pos.y - self.size.y / 2, - self.pos.z - self.size.z / 2, - ), - ( - self.pos.x + self.size.x / 2, - self.pos.y + self.size.y / 2, - self.pos.z + self.size.z / 2, - ) - ) - - def draw(self): - #print("draw color ",self.color) - rl.DrawCubeV(self.pos, self.size, self.color) - if self.wires: - rl.DrawCubeWiresV( - self.pos, self.size, self.wire_color - ) - - def check_collision(self, other): - if isinstance(other, Sphere): - r = rl.CheckCollisionBoxSphere( - self.get_bounding_box(), other.pos, other.radius - ) - return r - elif isinstance(other, Box): - return rl.CheckCollisionBoxes(self.get_bounding_box(), other.get_bounding_box()) - elif isinstance(other, Actor): - return self.check_collision(other.collision_sphere) - - -class Sphere(Shape): - def __init__(self, position, radius, color=RED, wires=True, wire_color=DARKGRAY): - self.pos = position - self.radius = radius - self.color = color - self.wire_color = wire_color - self.wires = wires - - def draw(self): - rl.DrawSphere(self.pos, self.radius, self.color) - if self.wires: - rl.DrawSphereWires(self.pos, self.radius, 32, 32, self.wire_color) - - def check_collision(self, other): - if isinstance(other, Sphere): - return rl.CheckCollisionSpheres( - self.pos, self.radius, other.pos, other.radius - ) - elif isinstance(other, Box): - return rl.CheckCollisionBoxSphere( - other.get_bounding_box(), self.pos, self.radius - ) - elif isinstance(other, Actor): - return self.check_collision(other.collision_sphere) - - -class Actor(Shape): - def __init__(self, model_file, position=Vector([0, 0, 0]), collision_radius=1, texture_file="", - rotation_axis=Vector([0, 1, 0]), rotation_angle=0, scale=Vector([1, 1, 1]), color=WHITE, wires=False, - wire_color=DARKGRAY): - #super().__init__(position, collision_radius, color, wires, wire_color) - - self.pos = position - self.color = color - self.wire_color = wire_color - self.wires = wires - - self.model_file = model_file - if texture_file == "": - texture_file = model_file + "_diffuse" - self.texture_file = texture_file - self.scale = scale - self.rotation_axis = rotation_axis - self.rotation_angle = rotation_angle - self.collision_radius = collision_radius - self.collision_sphere = Sphere(position, collision_radius, RED) - - self.loaded = False - - def load_data(self): - self.loaded = True - print("*** DATA_DIR=", data_dir) - self.model = rl.LoadModel((data_dir + self.model_file + '.obj').encode('utf-8')) - texture = rl.LoadTexture((data_dir + self.texture_file + '.png').encode('utf-8')) - self.model.materials[0].maps[rl.MAP_DIFFUSE].texture = texture - - def calc_bounding_box(self): - bb = rl.MeshBoundingBox(self.model.meshes[0]) - - bb.min.x *= self.scale.x - bb.min.y *= self.scale.y - bb.min.z *= self.scale.z - bb.max.x *= self.scale.x - bb.max.y *= self.scale.y - bb.max.z *= self.scale.z - - bb.min.x += self.pos.x - bb.min.y += self.pos.y - bb.min.z += self.pos.z - bb.max.x += self.pos.x - bb.max.y += self.pos.y - bb.max.z += self.pos.z - return bb - - def calc_collision_sphere(self): - centre_x = (self.bounding_box.max.x + self.bounding_box.min.x)/2 - centre_y = (self.bounding_box.max.y + self.bounding_box.min.y)/2 - centre_z = (self.bounding_box.max.z + self.bounding_box.min.z)/2 - sphere = Sphere((centre_x, centre_y, centre_z), self.collision_radius, RED) - return sphere - - def draw(self): - if not self.loaded: - self.load_data() - self.bounding_box = self.calc_bounding_box() - self.collision_sphere = self.calc_collision_sphere() - rl.DrawModelEx(self.model, self.pos, self.rotation_axis, self.rotation_angle, self.scale, self.color) - if self.wires: - rl.DrawBoundingBox(self.bounding_box, self.wire_color) - self.collision_sphere.draw() - - def check_collision(self, other): - return self.collision_sphere.check_collision(other) - -def run(): - screen_width = 800 - screen_height = 450 - title = "RayLibPyZero" - - if hasattr(mod, "WIDTH"): - screen_width = mod.WIDTH - - if hasattr(mod, "HEIGHT"): - screen_height = mod.HEIGHT - - if hasattr(mod, "TITLE"): - title = mod.TITLE - - if hasattr(mod, "DATA_DIR"): - global data_dir - data_dir = mod.DATA_DIR - - rl.SetConfigFlags(rl.FLAG_VSYNC_HINT + rl.FLAG_MSAA_4X_HINT) - - rl.InitWindow(screen_width, screen_height, title.encode('utf-8')) - - rl.SetTargetFPS(60) - - if hasattr(mod, "CAMERA"): - rl.SetCameraMode(camera[0], mod.CAMERA) - - if hasattr(mod, "init"): - mod.init() - - while not rl.WindowShouldClose(): - if hasattr(mod, "update"): - mod.update() - rl.UpdateCamera(camera) - if rl.IsKeyPressed(rl.KEY_F): - rl.ToggleFullscreen() - if rl.IsKeyPressed(rl.KEY_ESCAPE): - rl.Exit() - rl.BeginDrawing() - if hasattr(mod, "draw2dbackground"): - mod.draw2dbackground() - rl.BeginMode3D(camera[0]) - if hasattr(mod, "draw3d"): - mod.draw3d() - rl.EndMode3D() - if hasattr(mod, "draw2d"): - mod.draw2d() - if hasattr(mod, "draw"): - mod.draw() - rl.EndDrawing() - rl.CloseWindow() - - -class Keyboard: - def __getattr__(self, kname): - # return is a reserved word, so alias enter to return - if kname == 'enter': - kname = 'return' - kname = kname.upper() - if not kname.startswith("KEY_"): - kname = "KEY_" + kname - - return rl.IsKeyDown(getattr(rl, kname)) - - -keyboard = Keyboard() diff --git a/test_richlib.py b/test_richlib.py deleted file mode 100644 index afb81b4..0000000 --- a/test_richlib.py +++ /dev/null @@ -1,55 +0,0 @@ -from raylib.richlib import * - - -WIDTH=800 -HEIGHT=640 -#CAMERA=CAMERA_FIRST_PERSON -DATA_DIR="examples/models/resources/models/" - -player = Box((0, 10, 20), (10, 20, 10), 'green') -enemy_box = Box((-40, 10, 0), (20, 20, 20), (150,0,0)) -enemy_sphere = Sphere((40, 15, 0), 15, 'gray') -castle = Actor("castle", collision_radius=15) -castle.z=-50 -castle.scale.y=2 -castle.scale.x=1 -castle.scale.z=1 - - -#def init(): -# set_camera_mode(camera, CAMERA_FIRST_PERSON) - -def update(): - if keyboard.right: - player.pos.x += 2 - elif keyboard.left: - player.pos.x -= 2 - elif keyboard.down: - player.pos.z += 2 - elif keyboard.up: - player.pos.z -= 2 - - if player.check_collision(enemy_box) or player.check_collision(enemy_sphere) or player.check_collision(castle): - player.color = 'red' - else: - player.color = 'green' - - -def draw3d(): - clear('white') - enemy_box.draw() - enemy_sphere.draw() - player.draw() - castle.draw() - pyray.draw_grid(10, 10) - - -def draw2d(): - pyray.draw_text("Move player with cursors to collide", 220, 40, 20, (255,0,0,255)) - rl.DrawText(b"Move player with cursors to collide", 220, 80, 20, (255,0,0,255)) - #prl.DrawFPS(10, 10) - #pyray.foo(10,10) - pyray.draw_fps(20,20) - - -run()