Created
July 20, 2021 15:20
-
-
Save downthecrop/53e4af21f3ea0ce4d9f9345d0c4280e8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import eel | |
import math | |
import threading | |
import pyglet | |
from pyglet.gl import * | |
from pyglet.window import * | |
from pyglet import image | |
#pic = image.load('picture.png') | |
#pic2 = image.load('dirt.png') | |
@eel.expose | |
def say_hello_py(self): | |
print("called from JS") | |
global bottom | |
bottom = get_tex("grass_top.png") | |
glEnable(GL_TEXTURE_2D) | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) | |
FACES = [ | |
( 0, 1, 0), | |
( 0,-1, 0), | |
(-1, 0, 0), | |
( 1, 0, 0), | |
( 0, 0, 1), | |
( 0, 0,-1), | |
] | |
TEX = ( | |
0, 0, 1, | |
0, 1, 1, | |
0, 1, 0, | |
0, 1, 0, | |
1, 1, 0, | |
1, 0, 0, | |
1, 0, 1, | |
1, 0, 1, | |
0, 0, 1, | |
0, 1, 1, | |
0, 1, 0, | |
0, 1, 0, | |
1, 1, 0, | |
1, 0, 0, | |
1, 0, 1, | |
1, 0, 1 | |
) | |
def get_tex(f): | |
return pyglet.graphics.TextureGroup(pyglet.image.load(f).get_texture()) | |
bottom = get_tex("dirt.png") | |
glEnable(GL_TEXTURE_2D) | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) | |
def cube_vertices(x, y, z, n=.5): | |
return [ | |
x-n,y+n,z-n, x-n,y+n,z+n, x+n,y+n,z+n, x+n,y+n,z-n, # top | |
x-n,y-n,z-n, x+n,y-n,z-n, x+n,y-n,z+n, x-n,y-n,z+n, # bottom | |
x-n,y-n,z-n, x-n,y-n,z+n, x-n,y+n,z+n, x-n,y+n,z-n, # left | |
x+n,y-n,z+n, x+n,y-n,z-n, x+n,y+n,z-n, x+n,y+n,z+n, # right | |
x-n,y-n,z+n, x+n,y-n,z+n, x+n,y+n,z+n, x-n,y+n,z+n, # front | |
x+n,y-n,z-n, x-n,y-n,z-n, x-n,y+n,z-n, x+n,y+n,z-n, # back | |
] | |
def normalize(pos): | |
x,y,z = pos | |
return (round(x), round(y), round(z)) | |
class World: | |
def __init__(self,x,y,z): | |
#self.bottom = self.get_tex('dirt.png') | |
self.batch = pyglet.graphics.Batch() | |
self._shown = {} | |
self.shown = set() | |
self.blocks = set() | |
self.gen_world(x,y,z) | |
def add_block(self,pos): | |
x,y,z = pos | |
self.blocks.add(pos) | |
self.show_block(pos) | |
self.check_neighbors(pos) | |
def get_tex(self,f): | |
return pyglet.graphics.TextureGroup(pyglet.image.load(f).get_texture()) | |
def del_block(self,pos): | |
self.blocks.remove(pos) | |
self.shown.remove(pos) | |
self.check_neighbors(pos) | |
self._shown.pop(pos).delete() | |
def show_block(self,pos): | |
x,y,z = pos | |
self.shown.add(pos) | |
self._shown[pos] = self.batch.add(24, GL_QUADS, bottom,('v3f/static', cube_vertices(x, y, z)),('t2f/static', TEX)) | |
def hide_block(self,pos): | |
self.shown.remove(pos) | |
self._shown.pop(pos).delete() | |
def hit_test(self, pos, vector,m=8): | |
dx, dy, dz = vector | |
previous = None | |
for _ in range(m*4): | |
x,y,z = pos | |
block = normalize(pos) | |
if block != previous and block in self.shown: | |
return block, previous | |
previous = block | |
pos = x + dx / m, y + dy / m, z + dz / m | |
return None, None | |
def check_neighbors(self, pos): | |
x,y,z = pos | |
for dx, dy, dz in FACES: | |
block = (x + dx, y + dy, z + dz) | |
if block not in self.blocks: | |
continue | |
elif self.exposed(block): | |
if block not in self.shown: | |
self.show_block(block) | |
else: | |
if block in self.shown: | |
self.hide_block(block) | |
def exposed(self, pos): | |
x,y,z = pos | |
for dx, dy, dz in FACES: | |
if (x + dx, y + dy, z + dz) not in self.shown: | |
return True | |
return False | |
def gen_world(self,x_max,y_max,z_max): | |
x,y,z = 0,0,0 | |
while z < z_max: | |
while y < y_max: | |
while x < x_max: | |
self.blocks.add((x,y,z)) | |
x += 1 | |
x = 0 | |
y += 1 | |
y = 0 | |
z += 1 | |
for block in self.blocks: | |
x,y,z = block | |
if x == x_max-1 or x == 0: | |
self.show_block(block) | |
elif y == y_max-1 or y == 0: | |
self.show_block(block) | |
elif z == z_max-1 or z == 0: | |
self.show_block(block) | |
class Player: | |
def __init__(self, pos=(0, 0, 0), rot=(0, 0)): | |
self.pos = list(pos) | |
self.rot = list(rot) | |
def mouse_motion(self, dx, dy): | |
dx/= 8 | |
dy/= 8 | |
self.rot[0] += dy | |
self.rot[1] -= dx | |
if self.rot[0]>90: self.rot[0] = 90 | |
elif self.rot[0] < -90: self.rot[0] = -90 | |
def sight_vector(self): | |
y,x = self.rot | |
m = math.cos(math.radians(y)) | |
dy = math.sin(math.radians(y)) | |
dx = math.cos(math.radians(-x - 90)) * m | |
dz = math.sin(math.radians(-x - 90)) * m | |
return (dx, dy, dz) | |
def update(self,keys,s=0.5): | |
rotY = -self.rot[1]/180*math.pi | |
dx, dz = math.sin(rotY), math.cos(rotY) | |
if keys[key.W]: | |
self.pos[0] += dx*s | |
self.pos[2] -= dz*s | |
if keys[key.S]: | |
self.pos[0] -= dx*s | |
self.pos[2] += dz*s | |
if keys[key.A]: | |
self.pos[0] -= dz*s | |
self.pos[2] -= dx*s | |
if keys[key.D]: | |
self.pos[0] += dz*s | |
self.pos[2] += dx*s | |
if keys[key.SPACE]: | |
self.pos[1] += s | |
if keys[key.LSHIFT]: | |
self.pos[1] -= s | |
class Window(pyglet.window.Window): | |
def __init__(self, *args, **kwargs): | |
super().__init__(*args, **kwargs) | |
self.lock = True | |
glob = "" | |
x,y,z = 16,16,16 | |
self.keys = key.KeyStateHandler() | |
self.push_handlers(self.keys) | |
self.fps_display = pyglet.window.FPSDisplay(self) | |
pyglet.clock.schedule(self.update) | |
self.label = pyglet.text.Label('+', | |
font_name='Times New Roman', | |
font_size=36, | |
x=self.width//2, | |
y=self.height//2, | |
anchor_x='center', anchor_y='center') | |
self.world = World(16,16,16) | |
self.player = Player((x-10,y+5,z-10),(-90,0)) | |
def gui(self): | |
eel.init('web') | |
eel.start('craft.html') | |
def push(self,pos,rot): | |
glPushMatrix() | |
rot = self.player.rot | |
x,y,z = self.player.pos | |
glRotatef(-rot[0],1,0,0) | |
glRotatef(-rot[1],0,1,0) | |
glTranslatef(-x, -y, -z) | |
def clean(self): | |
glLoadIdentity() | |
glMatrixMode(GL_PROJECTION) | |
glLoadIdentity() | |
def set3d(self): | |
self.clean() | |
gluPerspective(70, self.width/self.height, 0.05, 1000) | |
glMatrixMode(GL_MODELVIEW) | |
def set2d(self): | |
self.clean() | |
glOrtho(0, float(self.width),0, float(self.height), 0, 1) | |
glMatrixMode(GL_MODELVIEW) | |
def on_mouse_motion(self,x,y,dx,dy): | |
if self.lock: self.player.mouse_motion(dx,dy) | |
def on_mouse_press(self, x, y, button, pos): | |
hit,previous = self.world.hit_test(self.player.pos,self.player.sight_vector()) | |
if button == 4: | |
if previous: | |
self.world.add_block(previous) | |
print("PLACED:",previous) | |
elif button == 1: | |
if hit: | |
self.world.del_block(hit) | |
print("BROKE:",hit) | |
def on_key_press(self, KEY, _MOD): | |
if KEY == key.ESCAPE: | |
self.close() | |
elif KEY == key.E: | |
self.lock = not self.lock | |
self.set_exclusive_mouse(self.lock) | |
elif KEY == key.J: | |
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) | |
elif KEY == key.X: | |
print(self.world.hit_test(self.player.pos,self.player.sight_vector())) | |
print(self.player.sight_vector()) | |
elif KEY == key.M: | |
self.gui() | |
glEnable(GL_TEXTURE_2D) | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEARE) | |
def draw_focused_block(self): | |
block = self.world.hit_test(self.player.pos, self.player.sight_vector())[0] | |
if block: | |
x, y, z = block | |
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) | |
pyglet.graphics.draw(24, GL_QUADS, ('v3f', cube_vertices(x, y, z))) | |
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) | |
def update(self,dt): | |
self.player.update(self.keys) | |
def on_draw(self): | |
self.clear() | |
self.set3d() | |
self.push(self.player.pos,self.player.rot) | |
self.world.batch.draw() | |
self.draw_focused_block() | |
self.set2d() | |
self.label.draw() | |
self.fps_display.draw() | |
#https://pyglet.readthedocs.io/en/latest/modules/image/index.html | |
#pic2.blit(10, 10, 0) #Front | |
#pic.blit(10, 10, 0) #Back | |
glPopMatrix() | |
if __name__ == '__main__': | |
window = Window(width=1280, height=720, caption='Cropcraft', vsync=True) | |
glClearColor(0.5,0.7,1,1) | |
glEnable(GL_DEPTH_TEST) | |
glEnable(GL_CULL_FACE) | |
glFrontFace(GL_CCW) | |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) | |
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) | |
glEnable(GL_FOG) | |
glFogfv(GL_FOG_COLOR, (GLfloat * 4)(0.5, 0.69, 1.0, 1)) | |
glHint(GL_FOG_HINT, GL_FASTEST) | |
glFogi(GL_FOG_MODE, GL_LINEAR) | |
glFogf(GL_FOG_START, 40.0) | |
glFogf(GL_FOG_END, 60.0) | |
pyglet.app.run() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment