学习python编程,在新东方少儿编程官网的自由创作平台做的一些作品。
可以在线运行,效果如下(在新页面中打开链接):
代码如下(用到平台自定义的xdf库):
from xdf import * import math W = 768 H = 1024 FRAME_RATE = 60 setFrameRate(FRAME_RATE) rotSpeed = 0.3 speed = 3 speedScale = 1.0 x = W / 2 y = H / 2 class Circle: def __init__(self): self.lineW = 10 line(self.lineW) self.r = 100 self.r2 = 30 self.x = 0 self.y = 0 self.rotation = 0 self.speedX = 0 self.speedY = 0 self.speedRot = 0 self.visible = True self.lastVisible = True self.c1 = circle(0, 0, self.r, 'transparent', 'black') self.box = box(self.r, 0, self.lineW, self.r2 * 2, 'white') self.reset() pass def reset(self): self.visible = True r = self.r r2 = self.r2 x = r + random(W - r * 2) y = r + random(H - r * 2) rot = random(360) self.rotation = rot self.x = x self.y = 0 self.speedRot = (1 - (random(2) - 1) * 2) * rotSpeed * speedScale ang = ang2rad(random(360)) self.speedX = speed * speedScale * math.cos(ang) self.speedY = speed * speedScale * math.sin(ang) self.refresh() pass def touch(self): pass def untouch(self): pass def touching(self): pass def tap(self): pass def loop(self): self.x += self.speedX self.y += self.speedY self.rotation = (self.rotation + self.speedRot) % 360 if self.x < 0: self.x = 0 self.speedX = -self.speedX elif self.x > W: self.x = W self.speedX = -self.speedX if self.y < 0: self.y = 0 self.speedY = -self.speedY elif self.y > H: self.y = H self.speedY = -self.speedY pass def refresh(self): if self.visible != self.lastVisible: self.lastVisible = self.visible if self.visible: self.c1.show() self.box.show() else: self.c1.hide() self.box.hide() if not self.visible: return self.c1.move(self.x, self.y) self.c1.rotate(self.rotation) rad = ang2rad(self.rotation) r0 = self.r - self.lineW / 2 self.box.move(self.x + r0 * math.cos(rad), self.y + r0 * math.sin(rad)) self.box.rotate(self.rotation) pass pass class Hero: def __init__(self): self.x = 0 self.y = 0 self.lx = 0 self.ly = 0 self.r = 10 self.c1 = circle(0, 0, self.r, "red") self.score = 0 self.scoreTf = text("", 0, 30, 30) self.overTf = text("点击任意位置重新开始", W/2, H/2, 50, 'red', 'center') self.isDrag = False self.reset() pass def reset(self): self.score = 0 self.x = W / 2 self.y = H / 2 self.lx = self.x self.ly = self.y self.overTf.hide() self.refresh() self.isOver = False self.isDrag = False self.refresh() pass def touch(self): if self.c1.hits(x, y): self.isDrag = True pass def untouch(self): self.isDrag = False pass def touching(self): if self.isDrag: r = 100 #if (x > r and x < W - r) or (y > r and y < H - r): self.lx = self.x self.ly = self.y self.x = x self.y = y pass def tap(self): pass def loop(self): pass def refresh(self): self.c1.move(self.x, self.y) self.scoreTf.change("Score:" + str(self.score)) self.c1.front() self.c1.front() self.scoreTf.front() self.overTf.front() pass def gameOver(self): self.isOver = True self.overTf.show() pass pass class CircleManager: def __init__(self): self.arr = [] self.pool = [] self.isOver = False self.count = 0 self.reset() pass def reset(self): global speedScale speedScale = 1.0 self.count = 0 self.isOver = False for c in reversed(self.arr): self.removeCircle(c) #self.addCircle() pass def touch(self): pass def untouch(self): pass def touching(self): pass def tap(self): if self.isOver: self.reset() h.reset() pass def loop(self): if not self.isOver: self.count += 1 if self.count > FRAME_RATE * 5: self.count = 0 self.addCircle() if len(self.arr) == 0: self.count = max(self.count, FRAME_RATE * 4) pass if self.isOver: return for c in self.arr: c.loop() for c in self.pool: c.loop() # check hit circle for c1 in self.arr: for c2 in self.arr: if c1 != c2: self.checkHit(c1, c2) pass pass pass # check hit hero for c in reversed(self.arr): if self.chekHitHero(h, c): self.gameOver() h.gameOver() return pass # check in circle for c in reversed(self.arr): self.checkIn(h, c) pass def checkIn(self, h, c): dx = h.x - c.x dy = h.y - c.y r = c.r - h.r if dx * dx + dy * dy < r * r: h.score += 1 self.removeCircle(c) pass def chekHitHero(self, h, c): dx = h.x - c.x dy = h.y - c.y r1 = c.r - h.r r2 = c.r + h.r d = dx * dx + dy * dy if d > r1 * r1 and d < r2 * r2: ang = (rad2ang(math.atan2(dy, dx)) + 360) % 360 a0 = c.rotation % 360 da = abs(ang - a0) if da > 180: da -= 180 da0 = rad2ang(c.r2 / c.r) return da > da0 return False def checkHit(self, c1, c2): dx = c1.x - c2.x dy = c1.y - c2.y r = c1.r + c2.r if dx * dx + dy * dy < r * r: dvx = c1.speedX - c2.speedX dvy = c1.speedY - c2.speedY dv = dx * dvx + dy * dvy if dv < 0: d = dx * dx + dy * dy dv = dv / d c1.speedX -= dv * dx c1.speedY -= dv * dy c2.speedX += dv * dx c2.speedY += dv * dy pass pass pass def refresh(self): for c in self.arr: c.refresh() for c in self.pool: c.refresh() pass def gameOver(self): self.isOver = True pass def addCircle(self): c = self.getCircle() self.arr.append(c) global speedScale speedScale *= 1.05 pass def removeCircle(self, c): self.arr.remove(c) self.pool.append(c) c.visible = False pass def getCircle(self): if len(self.pool): c = self.pool.pop() c.reset() return c return Circle() pass pass def ang2rad(ang): return math.pi * ang / 180 def rad2ang(rad): return 180 * rad / math.pi def touch(): for sp in spArr: sp.touch() pass pass def untouch(): for sp in spArr: sp.untouch() pass pass def touching(): for sp in spArr: sp.touching() pass pass def tap(): for sp in spArr: sp.tap() pass pass def isOver(): return h.isOver c = CircleManager() h = Hero() spArr = [c, h] def loop(): for sp in spArr: sp.loop() pass for sp in spArr: sp.refresh() pass pass
也可以下载代码,本地python环境运行(用pygame封装了xdf库)。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。