Created
July 22, 2021 17:51
-
-
Save downthecrop/054685885530ece5ee1c8ffd71507018 to your computer and use it in GitHub Desktop.
Cropcraft with GUI
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,math,threading,pyglet | |
from pyglet.gl import * | |
from pyglet.window import * | |
from pyglet import image | |
hud = image.load('hud.png') | |
active = image.load('active.png') | |
offset = 0 | |
@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.batch = pyglet.graphics.Batch() | |
self._shown = {} | |
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 del_block(self,pos): | |
self.blocks.remove(pos) | |
self.check_neighbors(pos) | |
self._shown.pop(pos).delete() | |
def show_block(self,pos): | |
x,y,z = 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.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) | |
self.speed = .2 | |
def mouse_motion(self, dx, dy): | |
self.rot[0] += dy/8 | |
self.rot[1] -= dx/8 | |
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) | |
class Window(pyglet.window.Window): | |
def __init__(self, *args, **kwargs): | |
super().__init__(*args, **kwargs) | |
x,y,z = 16,16,16 | |
self.lock = True | |
self.fps_display = pyglet.window.FPSDisplay(self) | |
self.keys = key.KeyStateHandler() | |
self.push_handlers(self.keys) | |
self.world = World(x,y,z) | |
self.player = Player((x-10,y+5,z-10),(-90,0)) | |
pyglet.clock.schedule(self.game_loop) | |
def push(self): | |
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_scroll(self, x, y, scroll_x, scroll_y): | |
self.move_active(-80) if (scroll_y > 0) else self.move_active(80) | |
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 and previous: | |
self.world.add_block(previous) | |
print("PLACED:",previous) | |
elif button == 1 and hit: | |
self.world.del_block(hit) | |
print("BROKE:",hit) | |
def on_key_press(self, KEY, _MOD): | |
if KEY == key.ESCAPE: | |
self.close() | |
if KEY == key.E: | |
self.lock = not self.lock | |
self.set_exclusive_mouse(self.lock) | |
if KEY == key.J: | |
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) | |
if KEY == key.X: | |
print(self.world.hit_test(self.player.pos,self.player.sight_vector())) | |
print(self.player.sight_vector()) | |
if KEY == key.M: | |
eel.init('web') | |
eel.start('craft.html') | |
glEnable(GL_TEXTURE_2D) | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEARE) | |
def player_movement(self): | |
rotY = -self.player.rot[1]/180*math.pi | |
dx, dz = math.sin(rotY), math.cos(rotY) | |
keys = self.keys | |
pos = self.player.pos | |
s = self.player.speed | |
if keys[key.W]: pos[0] += dx*s; pos[2] -= dz*s | |
if keys[key.S]: pos[0] -= dx*s; pos[2] += dz*s | |
if keys[key.A]: pos[0] -= dz*s; pos[2] -= dx*s | |
if keys[key.D]: pos[0] += dz*s; pos[2] += dx*s | |
if keys[key.SPACE]: pos[1] += s | |
if keys[key.LSHIFT]: pos[1] -= s | |
def move_active(self,move): | |
global offset; offset += move | |
if (offset > 650): offset = 0 | |
elif (offset < 0): offset = 640 | |
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 game_loop(self,dt): | |
self.player_movement() | |
def label_draw(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') | |
label.draw() | |
def on_draw(self): | |
self.clear() | |
self.set3d() | |
self.push() | |
self.world.batch.draw() | |
self.draw_focused_block() | |
self.set2d() | |
self.label_draw() | |
self.fps_display.draw() | |
active.blit(self.width/2-364+offset, 0, 0) #Front | |
hud.blit(self.width/2-364, 0, 0) #HUD | |
glPopMatrix() | |
if __name__ == '__main__': | |
window = Window(1280,720, caption='Cropcraft', vsync=True, resizable=True) | |
#Face Culling | |
glEnable(GL_DEPTH_TEST) | |
glEnable(GL_CULL_FACE) | |
glFrontFace(GL_CCW) | |
#FOG | |
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) | |
#Skybox/Void color | |
glClearColor(0.5,0.7,1,1) | |
pyglet.app.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment