import pyglet from pyglet.gl import * from pyglet.window import key import math import os from PIL import Image from anarchmap import AnarchMap assets_folder = '../anarch/assets/' class LevelModel: def get_tex(self, file): try: tex = pyglet.image.load(file).get_texture() glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) except: return None return pyglet.graphics.TextureGroup(tex) def add_block(self, x, y, z, wall_tex, ceil_color=0, floor_color=0): X, Y, Z = x+1, y+1, z+1 tex_coords = ('t2f', (0, 0, 1, 0, 1, 1, 0, 1)) white = [255]*4 self.batch.add(4, GL_QUADS, self.wall_textures[wall_tex], ('v3f', (X, y, z, x, y, z, x, Y, z, X, Y, z)), tex_coords) # back self.batch.add(4, GL_QUADS, self.wall_textures[wall_tex], ('v3f', (x, y, Z, X, y, Z, X, Y, Z, x, Y, Z)), tex_coords) # front self.batch.add(4, GL_QUADS, self.wall_textures[wall_tex], ('v3f', (x, y, z, x, y, Z, x, Y, Z, x, Y, z)), tex_coords) # left self.batch.add(4, GL_QUADS, self.wall_textures[wall_tex], ('v3f', (X, y, Z, X, y, z, X, Y, z, X, Y, Z)), tex_coords) # right self.batch.add(4, GL_QUADS, None, ('v3f', (x, y, z, X, y, z, X, y, Z, x, y, Z)), ('c4b', white * 4)) # bottom self.batch.add(4, GL_QUADS, None, ('v3f', (x, Y, Z, X, Y, Z, X, Y, z, x, Y, z)), ('c4b', white * 4)) # top def add_entity(self, x, z, texture, is_item=True): y=3 X, Y, Z = x+1, y+1, z+1 tex_coords = ('t2f', (0, 0, 1, 0, 1, 1, 0, 1)) self.batch.add(4, GL_QUADS, texture, ('v3f', (X, y, Z, X, y, z, X, Y, z, X, Y, Z)), tex_coords) def __init__(self, basepath): self.base_path = basepath self.batch = pyglet.graphics.Batch() self.entity_group = pyglet.graphics.NullGroup() # build lists of textures idxs = range(16) filename_template = os.path.join(self.base_path, 'wall_texture{}.png') self.wall_textures = list(map(lambda x: self.get_tex(filename_template.format(x)), idxs)) item_images = [ '', 'item_barrel.png', 'item_health.png', 'item_bullets.png', 'item_rockets.png', 'item_plasma.png', 'item_tree.png', 'item_finish.png', 'item_teleport.png', 'item_terminal.png', 'item_column.png', 'item_ruin.png', 'item_lamp.png', 'item_card.png', ] monster_images = [ 'monster_spider.png', 'monster_destroyer.png', 'monster_warrior.png', 'monster_plasmabot.png', 'monster_ender.png', 'monster_turret.png', 'monster_exploder.png', ] self.item_textures = list(map(lambda x: self.get_tex(os.path.join(self.base_path, x)), item_images)) self.monster_textures = list(map(lambda x: self.get_tex(os.path.join(self.base_path, x)), monster_images)) def load_level_image(self, file): self.ceiling_color = 0xff0000 self.floor_color = 0x0000ff self.map = AnarchMap(file) # TODO: set background image (background[0|1|2].png) from "background" + map.backgroundTex + ".png" for x in range(64): for z in range(64): item = self.map.levelMap[x][z] if not item[0]: continue else: tile_index = self.map.defineName(item[0]) floor_tex = self.map.floorDict[item[0]][0] floor_ht = self.map.floorDict[item[0]][1] ceil_tex = self.map.ceilDict[item[0]][0] ceil_ht = self.map.ceilDict[item[0]][1] # print("tile: %s, %s, %s" % (tile_index, item[0], floor_ht)) self.add_block(0-x, floor_ht / 4, 0-z, floor_tex) self.add_block(0-x, 8 - ceil_ht / 4, 0-z, ceil_tex) for e in self.map.elements: # if below a certain value, it's from itemSprites tex_index = e[0] is_item = True # idk if e[0] == 0: return # skip non-visible door locks TODO: draw lock indicator if e[0] == 15 or e[0] == 16 or e[0] == 17: continue # use single texture for card TODO: draw card color indicator if e[0] == 12 or e[0] == 13 or e[0] == 14: tex_index = 12 # "blocker" if e[0] == 19: tex_index = 11 if e[0] > 19: tex_index = e[0] - 32 is_item = False if is_item: texture = self.item_textures[tex_index] else: texture = self.monster_textures[tex_index] print("adding entity %s at (%s, %s), is_item=%s" % (tex_index, e[1], e[2], is_item)) self.add_entity(0-e[1], 0-e[2], texture) def draw(self): self.batch.draw() class Camera: 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 update(self,dt,keys): sens = 0.5 s = dt*10 rotY = -self.rot[1]/180*math.pi dx, dz = s*math.sin(rotY), s*math.cos(rotY) if keys[key.W]: self.pos[0] += dx*sens self.pos[2] -= dz*sens if keys[key.S]: self.pos[0] -= dx*sens self.pos[2] += dz*sens if keys[key.A]: self.pos[0] -= dz*sens self.pos[2] -= dx*sens if keys[key.D]: self.pos[0] += dz*sens self.pos[2] += dx*sens if keys[key.SPACE]: self.pos[1] += s if keys[key.LSHIFT]: self.pos[1] -= s class Window(pyglet.window.Window): def push(self,pos,rot): glPushMatrix() rot = self.player.rot pos = self.player.pos glRotatef(-rot[0],1,0,0) glRotatef(-rot[1],0,1,0) glTranslatef(-pos[0], -pos[1], -pos[2]) def Projection(self): glMatrixMode(GL_PROJECTION) glLoadIdentity() def Model(self): glMatrixMode(GL_MODELVIEW) glLoadIdentity() def set2d(self): self.Projection() gluPerspective(0, self.width, 0, self.height) self.Model() def set3d(self): self.Projection() gluPerspective(70, self.width/self.height, 0.05, 1000) self.Model() def setLock(self, state): self.lock = state self.set_exclusive_mouse(state) lock = False mouse_lock = property(lambda self:self.lock, setLock) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.set_minimum_size(300,200) self.keys = key.KeyStateHandler() self.push_handlers(self.keys) pyglet.clock.schedule(self.update) self.model = LevelModel(assets_folder) self.model.load_level_image('testlvl1.gif') self.player = Camera(self.model.map.playerStart, (-30,0)) self.debugLabel = pyglet.text.Label('Player pos: ', x=self.width//2, y=self.height//2) def on_mouse_motion(self,x,y,dx,dy): if self.mouse_lock: self.player.mouse_motion(dx,dy) def on_key_press(self, KEY, _MOD): if KEY == key.ESCAPE: self.close() elif KEY == key.E: self.mouse_lock = not self.mouse_lock def update(self, dt): self.player.update(dt, self.keys) self.debugLabel.text = 'Player pos: ' + str(self.player.pos[0]) def on_draw(self): self.clear() self.set3d() self.push(self.player.pos,self.player.rot) self.model.draw() self.set2d() self.debugLabel.draw() glPopMatrix() if __name__ == '__main__': window = Window(width=400, height=300, caption='AnarchMap', resizable=True) glClearColor(0.5,0.7,1,1) glEnable(GL_DEPTH_TEST) #glEnable(GL_CULL_FACE) pyglet.app.run()