def __setstate__(self, state): (self.id, self.生命, self.魔力, 速度x, 速度y, 速度z, 位置x, 位置y, 位置z, 面角0, 面角1, self.行走方向, self.生, self.在走) = struct.unpack('i11f2?', state[0]) self.基础速度 = vec(速度x, 速度y, 速度z) self.位置 = vec(位置x, 位置y, 位置z) self.面角 = [面角0, 面角1]
def 球动(self, x0, y0, x1, y1): d = 配置.控制球大小 p = self.控制球.mapFromParent(QPoint(x1, y1)) if 0 <= p.x() <= d and 0 <= p.y() <= d: v = (vec(p.x(), p.y()) - vec(d / 2, d / 2)).normalize() self.glWidget.球控制 = [-v.y, -v.x] if d / 3 <= p.x() <= d / 3 * 2 and d / 3 <= p.y() <= d / 3 * 2: net_client.udp_send(('跳', 0, '开始施法'))
def 眼睛(self): x, y, z = self.位置 眼睛 = vec(x + self.形状.x / 2, y + self.形状.y / 2, z + self.视高) if self.在走: t = time.clock() * 20 眼睛 += vec(0, 0, sin(t + pi / 4) / 70) # 视角摇晃 if self.行走方向 == 0: 眼睛 += self.行走速度 * 0.015 return 眼睛
def loadObjectModel(filePath): verts = [] tris = [] vcount = 0 tricount = 0 with open(filePath, 'r') as f: for line in f: if line[0] == 'v': words = line.rstrip().split(' ') verts.append( vec(float(words[1]), float(words[2]), float(words[3]))) vcount = vcount + 1 if line[0] == 'f': words = line.rstrip().split(' ') # -1 as verts are 1-indexed in obj format i1 = words[1] i2 = words[2] i3 = words[3] i1 = int(i1) i2 = int(i2) i3 = int(i3) v1 = verts[i1 - 1] v2 = verts[i2 - 1] v3 = verts[i3 - 1] tris.append([v1, v2, v3]) tricount = tricount + 1 return tris
def rayTriangleIntersection(r0, r, v1, v2, v3): intersection = vec(0.0, 0.0, 0.0) # Test if ray intersects plane triangle lies in # Plane defined by (p-p0).n = 0 # p0 can be any point in the triangle, e.g. any of the vertices, we choose as v1 # Also need n, given by cross product of two edges of triangle, i.e. v1->v2, v1->v3 then normalized p0 = v1 u = v2 - v1 v = v3 - v1 n = vec.cross(v2 - v1, v3 - v1) n = vec.normalize(n) # Equation of ray is p = r0 + rd # Sub into plane equation # => ((r0 + rd) - p0).n = 0 # => (r0 - p0).n + d(r.n) = 0 # => d = (p0-r0).n / r.n r0p0 = p0 - r0 if (vec.dot(r, n) == 0): return (False, intersection) d = vec.dot(r0p0, n) / vec.dot(r, n) # If d = 0 ray and plane are parallel -> ignore # Otherwise, we have an intersection at r0 + dr if (d != 0.0): intersection = r0 + d * r if pointInTriangle(intersection, v1, v2, v3): return (True, intersection) else: return (False, intersection)
class 箭(虚无, 单位): 空气阻力系数 = 0.1 重力系数 = 0.5 形状 = vec(0, 0, 0) 模型 = pywavefront.Wavefront('obj/arrow.obj') @property def 面向(self): return self.速度
def act(self): c = self.owner.中心 for i in range(-3, 4): for j in range(-3, 4): for k in range(-3, 4): if i in (-3, 3) or j in (-3, 3) or k in (-3, 3): t = c + vec(i, j, k) if t.intize not in env.主世界: env.主世界.放块(*t.intize, block.雪块)
def generateParticles(self, model, isStatic): print "Beginning particle generation\n" self.generateRayOrigins(isStatic) totalRays = len(self.rayOrigins) rayCounter = 0 lastPercentage = -1 for rayOrigin in self.rayOrigins: rayCounter = rayCounter + 1 percentageComplete = int(100 * float(rayCounter) / float(totalRays)) if percentageComplete != lastPercentage: lastPercentage = percentageComplete print("Ray casting " + str(percentageComplete) + "% complete") intersections = [] for tri in model: result, intersection = rayTriangleIntersection( rayOrigin, self.rayDirection, tri[0], tri[1], tri[2]) if result: intersections.append(intersection) if (intersections): # Fill volume with fluid particles # Sort intersections by z-values and generate pairs of intersections intersections.sort(key=lambda x: x.z) intersections = zip(*(iter(intersections), ) * 2) for pair in intersections: # Generate particles between the two intersections of each pair zstart = pair[0].z zend = pair[1].z numzvals = int((zend - zstart) / 0.0125) zvals = np.linspace(zstart, zend, numzvals) for zval in zvals: if isStatic: self.staticParticles.append( vec(rayOrigin.x, rayOrigin.y, zval)) else: self.particles.append( vec(rayOrigin.x, rayOrigin.y, zval))
def generateRayOrigins(self, isStatic): print "Generating ray origins\n" self.rayOrigins = [] if isStatic: rayDensity = 160 else: rayDensity = 80 for x in np.linspace(-0.5, 0.5, rayDensity): for y in np.linspace(-0.5, 0.5, rayDensity): self.rayOrigins.append(vec(x, y, self.rayz))
class 爆炸特效(虚无, 单位): 重力系数 = 0 形状 = vec(1, 1, 1) def __init__(self): super().__init__() self.效果.append(effect.限时生命(0.6)) def draw(self): for _ in range(20): x, y, z = rd(-1.0, 1.0), rd(-1.0, 1.0), rd(-1.0, 1.0) with temp_translate(x, y, z): with temp_scale(1 / 8, 1 / 8, 1 / 8): gl_list.画gl_list(2)
def tp(self, t): super().tp(t) if not env.客户端: self.物品栏.tp(t) 预加载距离 = 20 t = tuple(self.位置 + ran_vec() * 预加载距离 * random.random()) env.主世界.预生成地形((int(t[0]), int(t[1]))) try: if not env.客户端: self.物品栏.清理() for i, u in copy.copy(env.主世界.物品池).items(): x, y, z = u[0] if (vec(x, y, z) - self.中心).mo < 1.5: self.物品栏.加(u[1]) del env.主世界.物品池[i] except Exception as e: print(e)
class 球(单位): def __init__(self): super().__init__() self.效果.append(effect.限时生命(15)) def die(self): x, y, z = self.中心 for i in range(50): particle.particle(14, x, y + 0.2, z, speed=0.8, t=rd(0.3, 1), size=0.2, 重力系数=0.1) super().die() 模型 = pywavefront.Wavefront('obj/ball.obj') 形状 = vec(0.64, 0.64, 0.64)
class 炮(虚无, 单位): 重力系数 = 0.05 形状 = vec(0, 0, 0) def __init__(self): super().__init__() self.效果.append(effect.限时生命(3)) def tp(self, t): super().tp(t) if self.位置.intize in env.主世界: self.die() def die(self): super().die() self.召唤(爆炸特效) def draw(self): with temp_scale(1 / 8, 1 / 8, 1 / 8): with temp_translate(-0.5, -0.5, -0.5): gl_list.画gl_list(7)
def 爆炸(v): x, y, z = v for i in range(150): particle.particle(14, x, y, z, speed=5, t=rd(0.3, 1.3), size=0.3, 重力系数=0.15) for i in env.主世界.单位池: u = env.主世界.单位池[i] if (v - u.位置).mo < 4: u.基础速度 -= (v - u.位置).normalize() * 8 u.基础速度.z += 4 x, y, z = v.intize for dx in range(-3, 4): for dy in range(-3, 4): for dz in range(-3, 4): if (vec(x + dx, y + dy, z + dz) - v).mo < 3: env.主世界.去块(x + dx, y + dy, z + dz)
class 圣剑(虚无, 单位): 重力系数 = 1 形状 = vec(0.2, 0.2, 1) def tp(self, t): super().tp(t) if self.着地: self.die() def die(self): 情形.爆炸(self.位置) super().die() def draw(self): x, y, z = self.位置 for i in range(3): particle.particle(14, x, y, z, speed=0.6, t=rd(0.5, 2.5), size=0.3, 重力系数=0.1)
from vec import * v1 = vec([0.0, 2.0, 3.0, 4.0]) print(v1) #v1.x = 12.0 print("v1:", v1) print("v1.size:", v1.size) print("v1.value:", v1.value) # call __add__ v2 = v1 + 2.0 print("use __add__ v2 + 2.0 =", v2) # call __radd__ v2 = 2.0 + v1 print("use __radd__ 2.0 + v2 =", v2) # call __sub__ v2 = v1 - 2.0 print("use __sub__ v2 - 2.0 =", v2) # call __rsub__ v2 = 2.0 - v1 print("use __rsub__ 2.0 - v2 =", v2) # v3 = v2 + v1 # print("v2 + v1 = v3", v2, "+", v1, "=", v3) # v3 = v2 * 2.0 # print("v3 * 2.0 =", v3.x, v3.y, v3.z, v3.w) # v4 = v3 - 1.5 # print("v4 - 1.5 =", v4.x, v4.y, v4.z, v4.w) # v5 = v4 / 0.75
class 人(生物): 视高 = 1.5 跳跃高度 = 1.25 形状 = vec(0.6, 0.6, 1.8) 腿脚速度 = 3 照片 = '48035702' def __init__(self): super().__init__() self.物品栏 = 物品栏.物品栏(self) @property def 装备(self): return self.物品栏.在用的 # 我TM在逗你 def 使用装备(self, s): exec('self.装备.%s()' % s) def draw(self): super().draw() x, y, z = self.眼睛 - self.位置 glTranslatef(x, y, 0) # with points(color=(1,1,1),size=20): # glVertex3f(0,0,1) glRotatef(self.面角[0] / pi * 180 - 90, 0, 0, 1) glTranslatef(-x, -y, 0) glBindTexture(GL_TEXTURE_2D, env.m[self.照片]) with quads(): glTexCoord2f(0, 0) glVertex3f(0, self.形状.y / 2, 0) glTexCoord2f(0, 1) glVertex3f(0, self.形状.y / 2, self.形状.z) glTexCoord2f(1, 1) glVertex3f(self.形状.x, self.形状.y / 2, self.形状.z) glTexCoord2f(1, 0) glVertex3f(self.形状.x, self.形状.y / 2, 0) with quads(): glTexCoord2f(0, 0) glVertex3f(0, self.形状.y / 2, 0) glTexCoord2f(1, 0) glVertex3f(self.形状.x, self.形状.y / 2, 0) glTexCoord2f(1, 1) glVertex3f(self.形状.x, self.形状.y / 2, self.形状.z) glTexCoord2f(0, 1) glVertex3f(0, self.形状.y / 2, self.形状.z) glTranslatef(x, y, 0) glRotatef(-(self.面角[0] / pi * 180 - 90), 0, 0, 1) glTranslatef(-x, -y, 0) def tp(self, t): super().tp(t) if not env.客户端: self.物品栏.tp(t) 预加载距离 = 20 t = tuple(self.位置 + ran_vec() * 预加载距离 * random.random()) env.主世界.预生成地形((int(t[0]), int(t[1]))) try: if not env.客户端: self.物品栏.清理() for i, u in copy.copy(env.主世界.物品池).items(): x, y, z = u[0] if (vec(x, y, z) - self.中心).mo < 1.5: self.物品栏.加(u[1]) del env.主世界.物品池[i] except Exception as e: print(e)
class 羊(自动的, 生物): 形状 = vec(0.4, 0.4, 0.4) 自动器 = 自动.自动走 腿脚速度 = 1 跳跃高度 = 1.2
def 触摸屏拖动(self, x0, y0, x1, y1): t = vec(x0, y0) - vec(x1, y1) if 配置.镜头反转: t *= -1 self.glWidget.鼠标位移改变镜头(t.x, t.y)
class 单位(): 生 = True 重力系数 = 1 空气阻力系数 = 0 形状 = vec(1, 1, 1) 视高 = 0 模型 = None 腿脚速度 = 2 跳跃高度 = 1 # 因为积分不满所以实际上达不到 在走 = False def __init__(self): self.id = -1 self.基础速度 = vec(0, 0, 0) self.位置 = vec(0, 0, 0) self.效果 = h_list(self) def __getstate__(self): return { 0: struct.pack('i6f?', self.id, self.基础速度.x, self.基础速度.y, self.基础速度.z, self.位置.x, self.位置.y, self.位置.z, self.生) } def __setstate__(self, state): (self.id, 速度x, 速度y, 速度z, 位置x, 位置y, 位置z, self.生) = struct.unpack('i6f?', state[0]) self.基础速度 = vec(速度x, 速度y, 速度z) self.位置 = vec(位置x, 位置y, 位置z) def tp(self, t): self.物理(t) for i in self.效果: i.tp(t) de(self.效果, lambda i: not i.生) # 233333 if self.位置.z < -100: self.die() def 物理(self, t): # 高度 self.基础速度.z -= env.G * self.重力系数 * t if self.空气阻力系数: self.基础速度 *= (1 - self.空气阻力系数)**t self.位置.z += self.速度.z * t if self.着地: self.基础速度.z = max(0, self.基础速度.z) self.位置.z = intt(self.位置.z) + 0.999 if self.基础速度.mo > (4 * t): self.基础速度 -= self.基础速度 * (4 * t) else: self.基础速度 = vec(0, 0, 0) if self.碰撞: self.基础速度.z = min(0, self.基础速度.z) # 水平 x, y, z = self.位置 self.位置.x += self.速度.x * t self.位置.y += self.速度.y * t if self.碰撞: self.位置.x, self.位置.y = x, y self.基础速度.x = 0 self.基础速度.y = 0 @property def 中心(self): return self.位置 + self.形状 * 0.5 @property def 面向(self): a, b = self.面角 return vec(cos(b) * cos(a), cos(b) * sin(a), sin(b)) @property def 行走速度(self): v = vec(self.面向.x, self.面向.y, 0).normalize() return v.adjust_angle(self.行走方向) * self.腿脚速度 @property def 速度(self): if self.在走: return self.基础速度 + self.行走速度 return self.基础速度 @property def 眼睛(self): x, y, z = self.位置 眼睛 = vec(x + self.形状.x / 2, y + self.形状.y / 2, z + self.视高) if self.在走: t = time.clock() * 20 眼睛 += vec(0, 0, sin(t + pi / 4) / 70) # 视角摇晃 if self.行走方向 == 0: 眼睛 += self.行走速度 * 0.015 return 眼睛 @property def 着地(self): return any((i.intize in env.主世界 for i in self.位置.角枚举(self.形状, True))) @property def 碰撞(self): return any( (i.intize in env.主世界 for i in (self.位置 + vec(0, 0, 0.002)).角枚举(self.形状 - vec(0, 0, 0.004)))) @property def 靠墙(self): return any((i.intize in env.主世界 for i in ( self.位置 + vec(-0.01, -0.01, 0.002)).角枚举(self.形状 + vec(+0.02, +0.02, -0.004)))) @property def 所面向的块(self): v1 = self.眼睛 v2 = self.面向 for _ in range(100): p = v1.intize if p in env.主世界: return p v1 += v2 * 0.03 return None def die(self): self.生 = False def draw(self): if self.模型: v = tuple(self.面向) with temp_translate(*tuple(self.形状 * 0.5)): with temp_vec_rotate(np.array([0, 1., 0]), np.array(v)): pywavefront.visualization.draw(self.模型) return x, y, z = self.形状 line_box(0, 0, 0, x, y, z) def 召唤(self, u, pos=None): if callable(u): u = u() if pos == None: u.位置 = self.眼睛 else: u.位置 = pos env.主世界.单位池.加(u)
def __init__(self): self.rayz = 0.5 self.rayDirection = vec(0, 0, -1) self.particles = [] self.staticParticles = [] self.rayOrigins = []
def act(self): self.owner.效果.append( effect.空中力(5.2, lambda t: vec(0, 0, 19.6) * ((5.2 - t) / 5.2))) self.owner.基础速度.z = 17
def 靠墙(self): return any((i.intize in env.主世界 for i in ( self.位置 + vec(-0.01, -0.01, 0.002)).角枚举(self.形状 + vec(+0.02, +0.02, -0.004))))
def 碰撞(self): return any( (i.intize in env.主世界 for i in (self.位置 + vec(0, 0, 0.002)).角枚举(self.形状 - vec(0, 0, 0.004))))
def 行走速度(self): v = vec(self.面向.x, self.面向.y, 0).normalize() return v.adjust_angle(self.行走方向) * self.腿脚速度
def 面向(self): a, b = self.面角 return vec(cos(b) * cos(a), cos(b) * sin(a), sin(b))