def blockCreate(LoC, color): #initialize fill fill = Image.open("img" + os.sep + "block_%s.png" % color) fillX, fillY = fill.size fillL = fill.load() #initialize LoC L = len(LoC) minX, minY = maxX, maxY = LoC[0] for (x, y) in LoC: minX = min(minX, x) maxX = max(maxX, x) minY = min(minY, y) maxY = max(maxY, y) #initialize block img = Image.new("RGBA", (maxX - minX, maxY - minY), (255, 255, 255, 255)) imgL = img.load() for i in xrange(maxX - minX): for j in xrange(maxY - minY): r, g, b, alpha = fillL[(i + minX) % fillX, (j + minY) % fillY] for k in xrange(L): if p.det(LoC[k], LoC[(k + 1) % L], p.vadd((i, j), (minX, minY))) > 0: alpha = 0 break imgL[i, j] = (r, g, b, alpha) return img
def exitMe(self, wp, i): epsilon = 2 P = self.LoC[i] Q = self.LoC[(i + 1) % len(self.LoC)] R = (wp.x, wp.y) nextR = p.vadd(R, wp.v) det = p.det(P, Q, R) d = p.dist(P, Q) # check edge collision checkDist = (d * (wp.r - wp.maxSpeed - epsilon) <= det <= d * (wp.r + epsilon))
def update(self): #if not in universe if not (0 < self.x < self.width and 0 < self.y < self.height): self.health = 0 #check health if self.health == 0: #play death sound subprocess.Popen(["python", self.path + os.sep + "aud" + os.sep + "death.py"]) self.health = self.health / self.mhu * self.mhu if self.isParticle: #no wave positions self.posList = None #velocity affected by gravity self.v = p.vadd(self.v, self.g) if p.dist(self.v) >= self.maxSpeed: #then transform to wave self.isParticle = False self.r = 12 self.g = (0, 0) self.v = p.fixNorm(self.v, self.maxSpeed) if not self.collision: #gravity has effect self.g = self.gravity #select image to draw #select particle image if self.v[0] < 0: self.img = self.imgL elif self.v[0] > 0: self.img = self.imgR #change position (self.x, self.y) = p.vadd((self.x, self.y), self.v) if not self.isParticle: #then draw ray if self.posList == None: self.posList = [(self.x, self.y)] else: self.posList.append(p.vadd(p.sprod(self.posList[-1], 2/3.0), p.sprod((self.x, self.y), 1/3.0))) self.posList.append(p.sprod(p.vadd(self.posList[-1], (self.x, self.y)), 0.5)) self.posList.append((self.x, self.y)) while len(self.posList) > self.mrl: del self.posList[0: 3]
def move_up(self): if not self.collision: #cannot jump in the air return False subprocess.Popen(["python", self.path + os.sep + "aud" + os.sep + "jump.py"]) (P, Q) = self.collision (x, y) = p.vsub(Q, P) if self.collision and x <= 0 and abs(x) >= abs(y): #surface angle leq 45, can jump impDir = p.orthogonal((x, y)) self.v = p.vadd(self.v, p.fixNorm(impDir, self.maxJump)) self.collision = False return True
def update(self): if not self.isActive: return None if p.dist(self.P, self.pathList[self.index]) < 2: #then near this position, guard moves towards next target self.index = (self.index + 1) % self.L self.target = self.pathList[self.index] dist = p.dist(self.P, self.target) direction = p.vsub(self.target, self.P) if direction[0] < 0: self.imgDir = 0 elif direction[0] > 0: self.imgDir = 1 move = p.fixNorm(direction, min(self.stride, dist)) self.P = p.vadd(self.P, move)
def checkVertexCollision(self, wp, i): epsilon = 2 P = self.LoC[i] R = (wp.x, wp.y) # check vertex collision with P checkDist = p.dist(P, R) <= wp.r + epsilon if checkDist: #move particle back to proper location self.calibrateParticleVertex(wp, P, R) L = len(self.LoC) Q = self.LoC[(i + 1) % L] S = self.LoC[(i - 1) % L] u = p.fixNorm(p.vsub(Q, P)) v = p.fixNorm(p.vsub(P, S)) w = p.vadd(u, v) if wp.isParticle: self.particleVertexCollision(wp, P) else: self.waveVertexCollision(wp, w) wp.collision = ((0, 0), w)
def collision(self, wp): #check if in bounding box if not (self.minX - wp.r <= wp.x <= self.maxX + wp.r and self.minY - wp.r <= wp.y <= self.maxY + wp.r): return False epsilon = 2 L = len(self.LoC) if self.inMe: inside = True #still inside for i in xrange(L): P = self.LoC[i] Q = self.LoC[(i + 1) % L] R = (wp.x, wp.y) nextR = p.vadd((wp.x, wp.y), wp.v) det = p.det(P, Q, nextR) #if moving away from wall, continue if p.det(P, Q, R) >= det: continue inside &= (det <= p.dist(P, Q) * (epsilon - wp.r)) if not inside: break #to retain values of P, Q if inside: return True #because collision #otherwise check for internal reflection base = p.vsub(Q, P) if not p.refract(wp.v, base, self.rIndex, 1): wp.v = p.reflect(wp.v, base) return True #otherwise if not complete exit, return collision true if det < p.dist(P, Q) * wp.r: return True #otherwise complete exit, change angle self.inMe = False wp.v = p.fixNorm(p.refract(wp.v, p.vsub((0, 0), base), self.rIndex, 1), wp.maxSpeed) return False else: #check each individual side for i in xrange(L): if self.checkEdgeCollision(wp, i): return True for i in xrange(L): if self.checkVertexCollision(wp, i): return True return False
def checkEdgeCollision(self, wp, i): epsilon = 2 P = self.LoC[i] Q = self.LoC[(i + 1) % len(self.LoC)] R = (wp.x, wp.y) nextR = p.vadd(R, wp.v) det = p.det(P, Q, R) d = p.dist(P, Q) # check edge collision checkDist = (d * (wp.r - wp.maxSpeed - epsilon) <= det <= d * (wp.r + epsilon)) checkAngle1 = (p.distSq(P, Q) + p.distSq(Q, R) - p.distSq(P, R)) / p.dist(P, Q) / p.dist(Q, R) > 0 checkAngle2 = (p.distSq(P, Q) + p.distSq(P, R) - p.distSq(Q, R)) / p.dist(P, Q) / p.dist(P, R) > 0 checkDir = p.det(P, Q, R) + epsilon >= p.det(P, Q, nextR) if checkDist and checkAngle1 and checkAngle2 and checkDir: #move particle back to proper location self.calibrateParticleEdge(wp, P, Q, R) #calculate new velocity/gravity if wp.isParticle: self.particleEdgeCollision(wp, P, Q) else: self.waveEdgeCollision(wp, P, Q) wp.collision = (P, Q) return True
def calibrateParticleEdge(self, wp, P, Q, R): if wp.isParticle: base = p.vsub(Q, P) perPt = p.perPt(P, Q, R) #ensure particle not in wall (wp.x, wp.y) = p.vadd(perPt, p.fixNorm(p.orthogonal(base), wp.r))
def calibrateParticleVertex(self, wp, P, R): (wp.x, wp.y) = p.vadd(P, p.fixNorm(p.vsub(R, P), wp.r))