学习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库)。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。