用户:
afcc2查看:2 回复:3 评论:2 创建时间:2021-09-17T10:10:45
python代码 哪里有个纹理文件(1.png)你就把那张图片改名叫1.png。 代码要用海龟编辑器另存为桌面,1.png也要放桌面!!!!!
""" from zifan.site version 1.1.0 python 3.x """ import sys import random import time import numba as nb
from collections import deque from pyglet import image from pyglet.gl import * from pyglet.graphics import TextureGroup from pyglet.window import key, mouse import math
TICKS_PER_SEC = 60
SECTOR_SIZE = 16
GAMETYPES = False # 是否开启冰雪世界
SEED = random.randint(10, 1000000)#656795(种子"akioi") # 世界种子 print('seed:', SEED)
GTIME = 0 # 当前世界时间 GDAY = 0.0005 GNIGHT = 0.0015
WALKING_SPEED = 5 # 走路速度 RUNNING_SPEED = 8 # 跑步速度 FLYING_SPEED = 15 # 飞行速度
GRAVITY = 35.0 # 重力 MAX_JUMP_HEIGHT = 1.25 # 最大跳跃速度 JUMP_SPEED = math.sqrt(2 * GRAVITY * MAX_JUMP_HEIGHT) TERMINAL_VELOCITY = 35 # 终端速度
PLAYER_HEIGHT = 2 # 玩家高度
WORLDLEN = 128 # 世界长度
TEXTURE_PATH = '1.png' # 纹理文件
def cube_vertices(x, y, z, n): # 返回立方体的顶点,大小为2n。 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 tex_coord(x, y, n=8): # 返回纹理的边界顶点。 m = 1.0 / n dx = x * m dy = y * m return dx, dy, dx + m, dy, dx + m, dy + m, dx, dy + m
if GAMETYPES: GRASS = tex_coords((4, 0), (0, 1), (1, 3)) else: GRASS = tex_coords((1, 0), (0, 1), (0, 0)) SAND = tex_coords((1, 1), (1, 1), (1, 1)) DIRT = tex_coords((0, 1), (0, 1), (0, 1)) STONE = tex_coords((2, 0), (2, 0), (2, 0)) ENDSTONE = tex_coords((2, 1), (2, 1), (2, 1)) if GAMETYPES: WATER = tex_coords((3, 1), (3, 1), (3, 1)) else: WATER = tex_coords((0, 4), (0, 4), (0, 4)) WOOD = tex_coords((0, 2), (0, 2), (3, 0)) LEAF = tex_coords((0, 3), (0, 3), (0, 3)) BRICK = tex_coords((1, 2), (1, 2), (1, 2)) PUMKEY = tex_coords((2, 2), (3, 3), (2, 3)) MELON = tex_coords((2, 4), (2, 4), (1, 4)) CLOUD = tex_coords((3, 2), (3, 2), (3, 2)) TNT = tex_coords((4, 2), (4, 3), (4, 1))
# 立方体的6个面 FACES = [ (0,1,0), (0,-1,0), (-1,0,0), (1,0,0), (0,0,1), (0,0,-1), ]
random.seed(SEED)
@nb.jit(nopython=True, fastmath=True) def Noise(x, y): n = x + y * 57 n = (n * 8192) ^ n return(1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fff喵824.0)
@nb.jit(nopython=True, fastmath=True) def SmoothedNoise(x, y): corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16 sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8 center = Noise(x, y) / 4 return corners + sides + center
@nb.jit(nopython=True, fastmath=True) def Cosine_Interpolate(a, b, x): ft = x * 3.1415927 f = (1 - math.cos(ft)) * 0.5 return a*(1-f) + b*f
@nb.jit(nopython=True, fastmath=True) def Linear_Interpolate(a, b, x): return a*(1-x) + b*x
def InterpolatedNoise(x, y): integer_X = int(x) fractional_X = x - integer_X integer_Y = int(y) fractional_Y = y - integer_Y v1 = SmoothedNoise(integer_X, integer_Y) v2 = SmoothedNoise(integer_X + 1, integer_Y) v3 = SmoothedNoise(integer_X, integer_Y + 1) v4 = SmoothedNoise(integer_X + 1, integer_Y + 1) i1 = Cosine_Interpolate(v1, v2, fractional_X) i2 = Cosine_Interpolate(v3, v4, fractional_X) return Cosine_Interpolate(i1, i2, fractional_Y)
def PerlinNoise(x, y): noise = 0 p = persistence n = Number_Of_Octaves for i inrange(n): frequency = pow(2,i) amplitude = pow(p,i) noise = noise + InterpolatedNoise(x * frequency, y * frequency) * amplitude return noise
class Model(object):
def__init__(self):
self.batch = pyglet.graphics.Batch() self.group = TextureGroup(image.load(TEXTURE_PATH).get_texture()) # 纹理列表 self.world = {} # 地图 self.shown = {} # 显示的方块 self._shown = {} # 显示的纹理 self.sectors = {} self.queue = deque() self.dfy = self._initialize()
def tree(self, y, x, z): # 生成树 th = random.randint(4, 6) ts = random.randint(th // 2, 4) for i inrange(y, y + th): self.add_block((x, i, z), WOOD, immediate=False) for dy inrange(y + th, y + th + 2): for dx inrange(x - ts, x + ts + 1): for dz inrange(z - ts, z + ts + 1): self.add_block((dx, dy, dz), LEAF, immediate=False) for dy inrange(y + th + 2, y + th + ts + 2): ts -= 1 for dx inrange(x - ts, x + ts + 1): for dz inrange(z - ts, z + ts + 1): self.add_block((dx, dy, dz), LEAF, immediate=False)
def _initialize(self): # 初始化世界 hl = WORLDLEN // 2 mn = 0 quality = 4 gmap = [[0 for x in range(0, WORLDLEN)]for z in range(0, WORLDLEN)] for x inrange(0, WORLDLEN): for z inrange(0, WORLDLEN): gmap[x - hl][z - hl] += round(PerlinNoise(x / quality, z / quality) * quality) mn = min(mn, gmap[x - hl][z - hl]) for x inrange(-hl, hl): for z inrange(-hl, hl): gmap[x][z] += abs(mn) if gmap[x][z] < 2: self.add_block((x, -1, z), random.choice([SAND, STONE])) self.add_block((x, 0, z), WATER) if GAMETYPES: self.add_block((x, 1, z), WATER) else: self._show_block((x, 1, z), WATER) else: for y inrange(-1, gmap[x][z]): self.add_block((x, y, z), DIRT) self.add_block((x, gmap[x][z], z), GRASS) self.add_block((x, -2, z), ENDSTONE) for x inrange(-hl, hl,4): for z inrange(-hl, hl,4): if x == 0and z == 0: continue if random.randint(0,3) == 1and gmap[x][z] > 1: self.tree(gmap[x][z] + 1, x, z) for i inrange(x, x + 4): for j inrange(z, z + 4): self._show_block((i, 30, j), CLOUD) elif random.randint(0,4) == 2and gmap[x][z] > 2: self.add_block((x, gmap[x][z] + 1, z), random.choice([PUMKEY, MELON])) return gmap[0][0] + abs(mn) + 2
def hit_test(self, position, vector, max_distance=8): m = 8 x, y, z = position dx, dy, dz = vector previous = None for _ inrange(max_distance * m): key = normalize((x, y, z)) if key != previous and key in self.world: return key, previous previous = key x, y, z = x + dx / m, y + dy / m, z + dz / m returnNone,None
def exposed(self, position): x, y, z = position for dx, dy, dz in FACES: if(x + dx, y + dy, z + dz)notin self.world: returnTrue returnFalse
def add_block(self, position, texture, immediate=True): if position in self.world: self.remove_block(position, immediate) self.world[position] = texture self.sectors.setdefault(sectorize(position), []).append(position) if immediate: if self.exposed(position): self.show_block(position) self.check_neighbors(position)
def remove_block(self, position, immediate=True): del self.world[position] self.sectors[sectorize(position)].remove(position) if immediate: if position in self.shown: self.hide_block(position) self.check_neighbors(position)
def check_neighbors(self, position): x, y, z = position for dx, dy, dz in FACES: key = (x + dx, y + dy, z + dz) if key notin self.world: continue if self.exposed(key): if key notin self.shown: self.show_block(key) else: if key in self.shown: self.hide_block(key)
def show_block(self, position, immediate=True): texture = self.world[position] self.shown[position] = texture if immediate: self._show_block(position, texture) else: self._enqueue(self._show_block, position, texture)
def _show_block(self, position, texture): x, y, z = position vertex_data = cube_vertices(x, y, z, 0.5) texture_data = list(texture) self._shown[position] = self.batch.add(24, GL_QUADS, self.group, ('v3f/static', vertex_data), ('t2f/static', texture_data))
def hide_block(self, position, immediate=True): self.shown.pop(position) if immediate: self._hide_block(position) else: self._enqueue(self._hide_block, position)
def _hide_block(self, position): self._shown.pop(position).delete()
def show_sector(self, sector): for position in self.sectors.get(sector,[]): if position notin self.shown and self.exposed(position): self.show_block(position, False)
def hide_sector(self, sector): for position in self.sectors.get(sector,[]): if position in self.shown: self.hide_block(position, False)
def change_sectors(self, before, after): before_set = set() after_set = set() pad = 4 for dx inrange(-pad, pad + 1): for dy in[0]: for dz inrange(-pad, pad + 1): if dx ** 2 + dy ** 2 + dz ** 2 > (pad + 1) ** 2: continue if before: x, y, z = before before_set.add((x + dx, y + dy, z + dz)) if after: x, y, z = after after_set.add((x + dx, y + dy, z + dz)) show = after_set - before_set hide = before_set - after_set for sector in show: self.show_sector(sector) for sector in hide: self.hide_sector(sector)
def _enqueue(self, func, *args): self.queue.append((func, args))
def _dequeue(self): func, args = self.queue.popleft() func(*args)
def process_queue(self): start = time.perf_counter() while self.queue and time.perf_counter() - start < 1.0 / TICKS_PER_SEC: self._dequeue()
def process_entire_queue(self): while self.queue: self._dequeue()
def__init__(self, *args, **kwargs): super(Window, self).__init__(*args, **kwargs) self.exclusive = False self.flying = False # 是否在飞行 self.walking = True # 是否在走路 self.jumping = False # 是否在跳 self.model = Model() self.strafe = [0, 0] self.position = (0, self.model.dfy, 0) self.rotation = (0, 0) self.sector = None self.reticle = None self.dy = 0 self.inventory = [GRASS, DIRT, STONE, SAND, WOOD, BRICK, PUMKEY, MELON, TNT] self.block = self.inventory[0] self.num_keys = [ key._1, key._2, key._3, key._4, key._5, key._6, key._7, key._8, key._9, key._0] self.label = pyglet.text.Label('', font_name='Arial', font_size=18, x=10, y=self.height - 10, anchor_x='left', anchor_y='top', color=(0, 0, 0, 255)) pyglet.clock.schedule_interval(self.update, 1.0 / TICKS_PER_SEC)
def set_exclusive_mouse(self, exclusive): super(Window, self).set_exclusive_mouse(exclusive) self.exclusive = exclusive
def get_sight_vector(self): x, y = self.rotation 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 get_motion_vector(self): ifany(self.strafe): x, y = self.rotation strafe = math.degrees(math.atan2(*self.strafe)) y_angle = math.radians(y) x_angle = math.radians(x + strafe) if self.flying: m = math.cos(y_angle) dy = math.sin(y_angle) if self.strafe[1]: dy = 0.0 m = 1 if self.strafe[0] > 0: dy *= -1 dx = math.cos(x_angle) * m dz = math.sin(x_angle) * m else: dy = 0.0 dx = math.cos(x_angle) dz = math.sin(x_angle) else: dy = 0.0 dx = 0.0 dz = 0.0 return(dx, dy, dz)
def update(self, dt): # 刷新 global GTIME global GNIGHT global GDAY glClearColor(0.5 - GTIME * 0.01, 0.69 - GTIME * 0.01, 1.0 - GTIME * 0.01, 1) setup_fog() GTIME += GDAY if GTIME < 23 else GNIGHT if GTIME > 50: GTIME = 50 GNIGHT = -GNIGHT GDAY = -GDAY elif GTIME < 0: GTIME = 0 GNIGHT = -GNIGHT GDAY = -GDAY self.model.process_queue() sector = sectorize(self.position) if sector != self.sector: self.model.change_sectors(self.sector, sector) if self.sector isNone: self.model.process_entire_queue() self.sector = sector m = 8 dt = min(dt, 0.2) if self.jumping: if self.dy == 0: self.dy = JUMP_SPEED for _ inrange(m): self._update(dt / m)
def _update(self, dt): speed = FLYING_SPEED if self.flying else WALKING_SPEED if self.walking else RUNNING_SPEED d = dt * speed dx, dy, dz = self.get_motion_vector() dx, dy, dz = dx * d, dy * d, dz * d ifnot self.flying: self.dy -= dt * GRAVITY self.dy = max(self.dy, -TERMINAL_VELOCITY) dy += self.dy * dt x, y, z = self.position x, y, z = self.collide((x + dx, y + dy, z + dz), PLAYER_HEIGHT) self.position = (x, y, z)
def collide(self, position, height): pad = 0.25 p = list(position) np = normalize(position) for face in FACES: for i inrange(3): ifnot face[i]: continue d = (p[i] - np[i]) * face[i] if d < pad: continue for dy inrange(height): op = list(np) op[1] -= dy op[i] += face[i] iftuple(op)notin self.model.world: continue p[i] -= (d - pad) * face[i] if face == (0,-1,0)or face == (0,1,0): self.dy = 0 break returntuple(p)
def TNTboom(self, x, y, z): # TNT爆炸 self.model.remove_block((x, y, z)) bf = 4 s = 0 for dy inrange(y - bf, y): for i inrange(x - s, x + s): for j inrange(z - s, z + s): if(i, dy, j)in self.model.world: if j == z-s or j == z+s-1or i == x-s or i == x+s-1: if random.randint(0,1): if self.model.world[(i, dy, j)] == TNT: self.TNTboom(i, dy, j) continue if self.model.world[(i, dy, j)] != ENDSTONE: self.model.remove_block((i, dy, j)) else: if self.model.world[(i, dy, j)] == TNT: self.TNTboom(i, dy, j) continue if self.model.world[(i, dy, j)] != ENDSTONE: self.model.remove_block((i, dy, j)) s += 1 s = bf for i inrange(x - s, x + s): for j inrange(z - s, z + s): if(i, y, j)in self.model.world: if j == z-s or j == z+s-1or i == x-s or i == x+s-1: if random.randint(0,1): if self.model.world[(i, y, j)] == TNT: self.TNTboom(i, y, j) continue self.model.remove_block((i, y, j)) else: if self.model.world[(i, y, j)] == TNT: self.TNTboom(i, y, j) continue self.model.remove_block((i, y, j)) for dy inrange(y + 1, y + s + 1): for i inrange(x - s, x + s): for j inrange(z - s, z + s): if(i, dy, j)in self.model.world: if j == z-s or j == z+s-1or i == x-s or i == x+s-1: if random.randint(0,1): if self.model.world[(i, dy, j)] == TNT: self.TNTboom(i, dy, j) continue if self.model.world[(i, dy, j)] != ENDSTONE: self.model.remove_block((i, dy, j)) else: if self.model.world[(i, dy, j)] == TNT: self.TNTboom(i, dy, j) continue if self.model.world[(i, dy, j)] != ENDSTONE: self.model.remove_block((i, dy, j)) s -= 1
def on_mouse_press(self, x, y, button, modifiers): if self.exclusive: vector = self.get_sight_vector() block, previous = self.model.hit_test(self.position, vector) if(button == mouse.RIGHT)or \ ((button == mouse.LEFT)and(modifiers & key.MOD_CTRL)): if previous: # 鼠标右击 x, y, z = self.position flag = True for i inrange(0, PLAYER_HEIGHT): if previous == normalize((x, y - i, z)): flag = False break if flag: self.model.add_block(previous, self.block) elif button == pyglet.window.mouse.LEFT and block: # 鼠标左击 texture = self.model.world[block] if texture == TNT: self.TNTboom(block[0], block[1], block[2]) elif texture != ENDSTONE: self.model.remove_block(block) else: self.set_exclusive_mouse(True)
def on_mouse_motion(self, x, y, dx, dy): if self.exclusive: m = 0.15 x, y = self.rotation x, y = x + dx * m, y + dy * m y = max(-90, min(90, y)) self.rotation = (x, y)
def on_key_press(self, symbol, modifiers): # 键盘按键 if symbol == key.W: self.strafe[0] -= 1 elif symbol == key.S: self.strafe[0] += 1 elif symbol == key.A: self.strafe[1] -= 1 elif symbol == key.D: self.strafe[1] += 1 elif symbol == key.SPACE: self.jumping = True elif symbol == key.R: self.walking = not self.walking elif symbol == key.ESCAPE: self.set_exclusive_mouse(False) elif symbol == key.E: self.set_exclusive_mouse(False) elif symbol == key.TAB: self.flying = not self.flying elif symbol in self.num_keys: index = (symbol - self.num_keys[0]) % len(self.inventory) self.block = self.inventory[index]
def on_key_release(self, symbol, modifiers): # 键盘松键 if symbol == key.W: self.strafe[0] += 1 elif symbol == key.S: self.strafe[0] -= 1 elif symbol == key.A: self.strafe[1] += 1 elif symbol == key.D: self.strafe[1] -= 1 elif symbol == key.SPACE: self.jumping = False
def on_resize(self, width, height): # label self.label.y = height - 10 # reticle if self.reticle: self.reticle.delete() x, y = self.width // 2, self.height // 2 n = 10 self.reticle = pyglet.graphics.vertex_list(4, ('v2i',(x - n, y, x + n, y, x, y - n, x, y + n)) )
def set_2d(self): # 3d模式 width, height = self.get_size() glDisable(GL_DEPTH_TEST) viewport = self.get_viewport_size() glViewport(0, 0, max(1, viewport[0]), max(1, viewport[1])) glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(0, max(1, width), 0, max(1, height), -1, 1) glMatrixMode(GL_MODELVIEW) glLoadIdentity()
def set_3d(self): # 3d模式 width, height = self.get_size() glEnable(GL_DEPTH_TEST) viewport = self.get_viewport_size() glViewport(0, 0, max(1, viewport[0]), max(1, viewport[1])) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(65.0, width / float(height), 0.1, 60.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() x, y = self.rotation glRotatef(x, 0, 1, 0) glRotatef(-y, math.cos(math.radians(x)), 0, math.sin(math.radians(x))) x, y, z = self.position glTranslatef(-x, -y, -z)
def on_draw(self): # 绘制 self.clear() self.set_3d() glColor3d(1, 1, 1) self.model.batch.draw() self.draw_focused_block() self.set_2d() self.draw_label() self.draw_reticle()
def draw_focused_block(self): vector = self.get_sight_vector() block = self.model.hit_test(self.position, vector)[0] if block: x, y, z = block vertex_data = cube_vertices(x, y, z, 0.51) glColor3d(0, 0, 0) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) pyglet.graphics.draw(24, GL_QUADS, ('v3f/static', vertex_data)) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
def draw_label(self): x, y, z = self.position self.label.text = '%02d (%.2f, %.2f, %.2f) %d / %d' % ( pyglet.clock.get_fps(), x, y, z, len(self.model._shown),len(self.model.world)) self.label.draw()
def draw_reticle(self): glColor3d(0, 0, 0) self.reticle.draw(GL_LINES)
def setup_light(): # 初始化光照 gamelight = 5.0 - GTIME / 10 glLightfv(GL_LIGHT0, GL_AMBIENT, (GLfloat * 4)(gamelight, gamelight, gamelight, 1.0)) glLightfv(GL_LIGHT0, GL_DIFFUSE, (GLfloat * 4)(gamelight, gamelight, gamelight, 1.0)) glLightfv(GL_LIGHT0, GL_SPECULAR, (GLfloat * 4)(1.0, 1.0, 1.0, 1.0)) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0)
def setup(): # 初始化 glClearColor(0.5 - GTIME * 0.01, 0.69 - GTIME * 0.01, 1.0 - GTIME * 0.01, 1) glEnable(GL_CULL_FACE) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) setup_fog()
def main(): window = Window(width=800, height=600, caption='Python Minecraft', resizable=True) window.set_exclusive_mouse(True) setup() pyglet.app.run()
if __name__ == '__main__': main()


`丶丶老※点点工作室※imgsrc="https://static.codemao.cn/emoji/codemao/%E7%BC%96%E7%A8%8B%E7%8C%AB_%E7%82%B9%E8%B5%9E.gif"alt="emotion_编程猫_点赞"
点赞0
评论