main.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. import pyglet
  2. from pyglet.gl import *
  3. from pyglet.window import key
  4. import math
  5. import os
  6. from PIL import Image
  7. from anarchmap import AnarchMap
  8. assets_folder = '../anarch/assets/'
  9. class LevelModel:
  10. def get_tex(self, file):
  11. try:
  12. tex = pyglet.image.load(file).get_texture()
  13. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
  14. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
  15. except:
  16. return None
  17. return pyglet.graphics.TextureGroup(tex)
  18. def add_block(self, x, y, z, wall_tex, ceil_color=0, floor_color=0):
  19. X, Y, Z = x+1, y+1, z+1
  20. tex_coords = ('t2f', (0, 0, 1, 0, 1, 1, 0, 1))
  21. white = [255]*4
  22. 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
  23. 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
  24. 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
  25. 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
  26. self.batch.add(4, GL_QUADS, None, ('v3f', (x, y, z, X, y, z, X, y, Z, x, y, Z)), ('c4b', white * 4)) # bottom
  27. self.batch.add(4, GL_QUADS, None, ('v3f', (x, Y, Z, X, Y, Z, X, Y, z, x, Y, z)), ('c4b', white * 4)) # top
  28. def add_entity(self, x, z, texture, is_item=True):
  29. y=3
  30. X, Y, Z = x+1, y+1, z+1
  31. tex_coords = ('t2f', (0, 0, 1, 0, 1, 1, 0, 1))
  32. self.batch.add(4, GL_QUADS, texture, ('v3f', (X, y, Z, X, y, z, X, Y, z, X, Y, Z)), tex_coords)
  33. def __init__(self, basepath):
  34. self.base_path = basepath
  35. self.batch = pyglet.graphics.Batch()
  36. self.entity_group = pyglet.graphics.NullGroup()
  37. # build lists of textures
  38. idxs = range(16)
  39. filename_template = os.path.join(self.base_path, 'wall_texture{}.png')
  40. self.wall_textures = list(map(lambda x: self.get_tex(filename_template.format(x)), idxs))
  41. item_images = [
  42. '',
  43. 'item_barrel.png',
  44. 'item_health.png',
  45. 'item_bullets.png',
  46. 'item_rockets.png',
  47. 'item_plasma.png',
  48. 'item_tree.png',
  49. 'item_finish.png',
  50. 'item_teleport.png',
  51. 'item_terminal.png',
  52. 'item_column.png',
  53. 'item_ruin.png',
  54. 'item_lamp.png',
  55. 'item_card.png',
  56. ]
  57. monster_images = [
  58. 'monster_spider.png',
  59. 'monster_destroyer.png',
  60. 'monster_warrior.png',
  61. 'monster_plasmabot.png',
  62. 'monster_ender.png',
  63. 'monster_turret.png',
  64. 'monster_exploder.png',
  65. ]
  66. self.item_textures = list(map(lambda x: self.get_tex(os.path.join(self.base_path, x)), item_images))
  67. self.monster_textures = list(map(lambda x: self.get_tex(os.path.join(self.base_path, x)), monster_images))
  68. def load_level_image(self, file):
  69. self.ceiling_color = 0xff0000
  70. self.floor_color = 0x0000ff
  71. self.map = AnarchMap(file)
  72. # TODO: set background image (background[0|1|2].png) from "background" + map.backgroundTex + ".png"
  73. for x in range(64):
  74. for z in range(64):
  75. item = self.map.levelMap[x][z]
  76. if not item[0]:
  77. continue
  78. else:
  79. tile_index = self.map.defineName(item[0])
  80. floor_tex = self.map.floorDict[item[0]][0]
  81. floor_ht = self.map.floorDict[item[0]][1]
  82. ceil_tex = self.map.ceilDict[item[0]][0]
  83. ceil_ht = self.map.ceilDict[item[0]][1]
  84. # print("tile: %s, %s, %s" % (tile_index, item[0], floor_ht))
  85. self.add_block(0-x, floor_ht / 4, 0-z, floor_tex)
  86. self.add_block(0-x, 8 - ceil_ht / 4, 0-z, ceil_tex)
  87. for e in self.map.elements:
  88. # if below a certain value, it's from itemSprites
  89. tex_index = e[0]
  90. is_item = True
  91. # idk
  92. if e[0] == 0:
  93. return
  94. # skip non-visible door locks TODO: draw lock indicator
  95. if e[0] == 15 or e[0] == 16 or e[0] == 17:
  96. continue
  97. # use single texture for card TODO: draw card color indicator
  98. if e[0] == 12 or e[0] == 13 or e[0] == 14:
  99. tex_index = 12
  100. # "blocker"
  101. if e[0] == 19:
  102. tex_index = 11
  103. if e[0] > 19:
  104. tex_index = e[0] - 32
  105. is_item = False
  106. if is_item:
  107. texture = self.item_textures[tex_index]
  108. else:
  109. texture = self.monster_textures[tex_index]
  110. print("adding entity %s at (%s, %s), is_item=%s" % (tex_index, e[1], e[2], is_item))
  111. self.add_entity(0-e[1], 0-e[2], texture)
  112. def draw(self):
  113. self.batch.draw()
  114. class Camera:
  115. def __init__(self, pos=(0, 0, 0), rot=(0, 0)):
  116. self.pos = list(pos)
  117. self.rot = list(rot)
  118. def mouse_motion(self, dx, dy):
  119. dx/= 8
  120. dy/= 8
  121. self.rot[0] += dy
  122. self.rot[1] -= dx
  123. if self.rot[0]>90:
  124. self.rot[0] = 90
  125. elif self.rot[0] < -90:
  126. self.rot[0] = -90
  127. def update(self,dt,keys):
  128. sens = 0.5
  129. s = dt*10
  130. rotY = -self.rot[1]/180*math.pi
  131. dx, dz = s*math.sin(rotY), s*math.cos(rotY)
  132. if keys[key.W]:
  133. self.pos[0] += dx*sens
  134. self.pos[2] -= dz*sens
  135. if keys[key.S]:
  136. self.pos[0] -= dx*sens
  137. self.pos[2] += dz*sens
  138. if keys[key.A]:
  139. self.pos[0] -= dz*sens
  140. self.pos[2] -= dx*sens
  141. if keys[key.D]:
  142. self.pos[0] += dz*sens
  143. self.pos[2] += dx*sens
  144. if keys[key.SPACE]:
  145. self.pos[1] += s
  146. if keys[key.LSHIFT]:
  147. self.pos[1] -= s
  148. class Window(pyglet.window.Window):
  149. def push(self,pos,rot):
  150. glPushMatrix()
  151. rot = self.player.rot
  152. pos = self.player.pos
  153. glRotatef(-rot[0],1,0,0)
  154. glRotatef(-rot[1],0,1,0)
  155. glTranslatef(-pos[0], -pos[1], -pos[2])
  156. def Projection(self):
  157. glMatrixMode(GL_PROJECTION)
  158. glLoadIdentity()
  159. def Model(self):
  160. glMatrixMode(GL_MODELVIEW)
  161. glLoadIdentity()
  162. def set2d(self):
  163. self.Projection()
  164. gluPerspective(0, self.width, 0, self.height)
  165. self.Model()
  166. def set3d(self):
  167. self.Projection()
  168. gluPerspective(70, self.width/self.height, 0.05, 1000)
  169. self.Model()
  170. def setLock(self, state):
  171. self.lock = state
  172. self.set_exclusive_mouse(state)
  173. lock = False
  174. mouse_lock = property(lambda self:self.lock, setLock)
  175. def __init__(self, *args, **kwargs):
  176. super().__init__(*args, **kwargs)
  177. self.set_minimum_size(300,200)
  178. self.keys = key.KeyStateHandler()
  179. self.push_handlers(self.keys)
  180. pyglet.clock.schedule(self.update)
  181. self.model = LevelModel(assets_folder)
  182. self.model.load_level_image('testlvl1.gif')
  183. self.player = Camera(self.model.map.playerStart, (-30,0))
  184. self.debugLabel = pyglet.text.Label('Player pos: ', x=self.width//2, y=self.height//2)
  185. def on_mouse_motion(self,x,y,dx,dy):
  186. if self.mouse_lock: self.player.mouse_motion(dx,dy)
  187. def on_key_press(self, KEY, _MOD):
  188. if KEY == key.ESCAPE:
  189. self.close()
  190. elif KEY == key.E:
  191. self.mouse_lock = not self.mouse_lock
  192. def update(self, dt):
  193. self.player.update(dt, self.keys)
  194. self.debugLabel.text = 'Player pos: ' + str(self.player.pos[0])
  195. def on_draw(self):
  196. self.clear()
  197. self.set3d()
  198. self.push(self.player.pos,self.player.rot)
  199. self.model.draw()
  200. self.set2d()
  201. self.debugLabel.draw()
  202. glPopMatrix()
  203. if __name__ == '__main__':
  204. window = Window(width=400, height=300, caption='AnarchMap', resizable=True)
  205. glClearColor(0.5,0.7,1,1)
  206. glEnable(GL_DEPTH_TEST)
  207. #glEnable(GL_CULL_FACE)
  208. pyglet.app.run()