Created
July 27, 2021 13:35
-
-
Save downthecrop/10d5f9ffa4abaf56afa8ef772b1ba928 to your computer and use it in GitHub Desktop.
infinite world gen but still a mess
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,pyglet,time,threading | |
from pyglet.gl import * | |
from pyglet.window import * | |
from pyglet import image | |
from random import randrange | |
FACES=[(0,1,0),(0,-1,0),(-1,0,0),(1,0,0),(0,0,1),(0,0,-1),(0,0,0)] | |
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 | |
CURRENTBLOCK = "dirt" | |
TEXTURES = {} | |
BLOCKS = { | |
"dirt":"dirt.png", | |
"grass":"grass_top.png", | |
"stone":"stone.png", | |
} | |
@eel.expose | |
def say_hello_py(block): | |
global CURRENTBLOCK | |
CURRENTBLOCK = block | |
def new_crosshair(w,h): | |
return pyglet.text.Label('+',font_name='Times New Roman',font_size=36,x=w/2,y=h/2) | |
def get_tex(f): | |
d = BLOCKS[f] | |
TEXTURES[f] = pyglet.graphics.TextureGroup(pyglet.image.load(d).get_texture()) | |
glEnable(GL_TEXTURE_2D) | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) | |
def cube_vertices(pos, n=.5): | |
x,y,z = pos | |
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 | |
] | |
class World: | |
def __init__(self,x=16,y=16,z=16): | |
self.batch = pyglet.graphics.Batch() | |
self._shown = {} | |
self.blocks = {} | |
self.chunks = set() | |
def add_block(self,pos,id): | |
self.blocks[pos] = id | |
self.show_block(pos,id) | |
self.check_neighbors(pos) | |
def del_block(self,pos): | |
self.blocks.pop(pos) | |
self._shown.pop(pos).delete() | |
self.check_neighbors(pos) | |
def show_block(self,pos,block_type): | |
try: | |
self._shown[pos] = self.batch.add(24, GL_QUADS, TEXTURES[block_type],('v3f/static', cube_vertices(pos)),('t2f/static', TEX)) | |
except Exception as e: | |
print(e) | |
get_tex(block_type) | |
print("getting tex",block_type) | |
self.show_block(pos,block_type) | |
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 = (round(x), round(y), round(z)) | |
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,self.blocks[block]) | |
elif 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.blocks: | |
return True | |
return False | |
def gen_chunk(self,pos): | |
chunk_x = int(pos[0]/16) | |
chunk_z = int(pos[2]/16) | |
x,y,z = 0,0,0 | |
if (chunk_x,chunk_z) not in self.chunks: | |
self.chunks.add((chunk_x,chunk_z)) | |
print("gen chunk at",chunk_x,chunk_z) | |
while z < 16: | |
while x < 16: | |
y_max = 6 + randrange(2) | |
while y < y_max: | |
if y == y_max-1: id = "grass" | |
elif y < 3: id = "stone" | |
else: id = "dirt" | |
self.add_block((chunk_x*16+x,y,chunk_z*16+z),id) | |
y += 1 | |
x += 1 | |
y = 0 | |
x = 0 | |
z += 1 | |
class Player: | |
def __init__(self, pos=(0, 0, 0), rot=(0, 0)): | |
self.pos = list(pos) | |
self.rot = list(rot) | |
self.speed = .05 | |
class Window(pyglet.window.Window): | |
def __init__(self, *args, **kwargs): | |
super().__init__(*args, **kwargs) | |
x,y,z = 16,16,16 | |
self.lock = True | |
self.hud_position = self.width/2-364 | |
self.fps_display = pyglet.window.FPSDisplay(self) | |
self.hud = image.load('hud.png') | |
self.active = image.load('active.png') | |
self.crosshair = new_crosshair(self.width,self.height) | |
self.keys = key.KeyStateHandler() | |
self.push_handlers(self.keys) | |
self.hud_offset = 0 | |
self.world = World() | |
self.player = Player((35,12,35),(-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: | |
rot = self.player.rot | |
rot[0] += dy/8 | |
rot[1] -= dx/8 | |
if rot[0]>90: rot[0] = 90 | |
elif rot[0] < -90: rot[0] = -90 | |
def on_mouse_scroll(self, x, y, scroll_x, scroll_y): | |
if (scroll_y > 0): self.active_indicator(-80) | |
else: self.active_indicator(80) | |
def on_mouse_press(self, x, y, button, pos): | |
hit,previous = self.world.hit_test(self.player.pos,self.sight_vector(self.player)) | |
if button == 4 and previous: self.world.add_block(previous,CURRENTBLOCK) | |
elif button == 1 and hit: self.world.del_block(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.M: eel.init('web'); eel.start('craft.html') | |
def gen_rad_chunks(self,pos): | |
x,y,z = pos | |
self.world.gen_chunk((x,y,z)) | |
self.world.gen_chunk((x-16,y,z)) | |
self.world.gen_chunk((x+16,y,z)) | |
self.world.gen_chunk((x,y,z+16)) | |
self.world.gen_chunk((x,y,z-16)) | |
self.world.gen_chunk((x+16,y,z+16)) | |
self.world.gen_chunk((x+16,y,z-16)) | |
self.world.gen_chunk((x-16,y,z+16)) | |
self.world.gen_chunk((x-16,y,z-16)) | |
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 | |
_pos = pos.copy() | |
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 sight_vector(self,player): | |
y,x = player.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 active_indicator(self,move): | |
self.hud_offset += move | |
if (self.hud_offset > 650): self.hud_offset = 0 | |
elif (self.hud_offset < 0): self.hud_offset = 640 | |
def draw_focused_block(self): | |
block = self.world.hit_test(self.player.pos, self.sight_vector(self.player))[0] | |
if block: | |
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) | |
pyglet.graphics.draw(24, GL_QUADS, ('v3f', cube_vertices(block))) | |
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) | |
def game_loop(self,dt): | |
self.player_movement() | |
self.gen_rad_chunks(self.player.pos) | |
def draw_hud(self): | |
self.crosshair.draw() | |
self.active.blit(self.hud_position+self.hud_offset, 0, 0) #Front | |
self.hud.blit(self.hud_position, 0, 0) #HUD | |
def on_draw(self): | |
self.clear() | |
self.set3d() | |
self.push() | |
self.world.batch.draw() | |
self.draw_focused_block() | |
self.set2d() | |
self.draw_hud() | |
self.fps_display.draw() | |
glPopMatrix() | |
if __name__ == '__main__': | |
window = Window(1280,720, caption='Cropcraft', vsync=True, resizable=True) | |
@window.event | |
def on_resize(width, height): | |
window.crosshair = new_crosshair(width,height) | |
window.hud_position = width/2-364 | |
#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, 10.0) | |
glFogf(GL_FOG_END, 24.0) | |
#Skybox/Void color | |
glClearColor(0.5, 0.69, 1.0, 1) | |
pyglet.app.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment