学习python编程,在新东方少儿编程官网的自由创作平台做的一些作品。
可以在线运行,效果如下(在新页面中打开链接):
代码如下(用到平台自定义的xdf库):
from xdf import *
import math
W = 768
H = 1024
G = 0.85
JUMPF = -16
SPEED = 0.18
fill("cat-r-bg@004G")
setFrameRate(40)
levels = [
["w",150,201,"d",96,914,"c",102,135,"s",706,70,"k",342,933,"w",604,455,"s",362,389,"s",553,924,"w",177,715,"w",384,994],
["w",140,206,"d",351,914,"c",115,140,"s",650,210,"k",541,933,"w",730,475,"s",60,662,"s",79,933,"w",122,734,"w",384,994],
["w",584,155,"b",100,155,"d",337,914,"c",70,88,"s",67,631,"k",696,355,"w",-144,414,"s",686,525,"s",98,931,"w",206,697,"w",384,994,"w",824,414,"e",340,414],
["w",184,166,"b",668,166,"d",175,915,"c",48,95,"s",519,434,"k",48,229,"w",-149,520,"s",450,927,"s",86,721,"w",220,785,"w",384,994,"w",819,520,"e",335,520],
["w",-15,204,"b",265,710,"a",626,617,"d",139,915,"c",102,135,"s",702,139,"k",728,452,"w",924,204,"s",90,642,"s",273,930,"w",-219,710,"w",384,994,"w",1021,511,"w",749,710],
["w",174,170,"b",390,637,"a",537,901,"d",689,915,"c",43,100,"s",606,376,"k",713,576,"w",945,439,"s",651,743,"s",50,935,"w",-94,637,"w",384,994,"w",874,637],
["w",-114,165,"e",370,165,"a",410,550,"d",690,915,"c",49,94,"s",701,98,"k",717,403,"w",854,165,"s",47,576,"s",616,867,"w",948,465,"w",384,994,"a",587,546,"w",-79,640,"w",889,640,"b",405,640],
["w",0,187,"a",69,901,"d",80,534,"c",50,117,"s",393,537,"k",712,926,"f",768,187,"w",978,616,"s",694,546,"s",83,761,"w",-213,614,"w",384,994,"w",-166,824,"w",973,824],
["w",-41,201,"f",928,666,"d",97,393,"c",54,135,"s",303,376,"k",85,924,"w",-28,473,"s",61,729,"s",657,917,"w",-25,798,"w",384,994],
["w",50,200,"a",503,102,"d",297,611,"c",67,129,"s",296,481,"k",393,938,"f",818,200,"w",600,691,"s",124,570,"s",702,859,"w",384,994],
["a",687,365,"d",530,914,"c",102,130,"s",63,269,"k",66,933,"f",384,200,"s",44,697,"s",529,833,"w",384,994,"f",384,460,"h",384,755,"a",383,904],
["w",115,185,"a",315,647,"d",96,667,"c",67,118,"s",342,386,"k",591,930,"f",2,743,"s",587,716,"s",74,924,"w",384,994,"f",4,460,"f",883,185]
]
def checkHitRectCircle(dx, dy, w, h, r):
if dy < h and dx < r + w:
return True
if dx < w and dy < r + h:
return True
if dx > w and dy > h and dx < w + r and dy < h + r and dx * dx + dy * dy < r * r:
return True
return False
class Sprite:
def __init__(self, src, x = 0, y = 0, size = None, name = ''):
self.stamp = stamp(src, x, y, size)
self.src = src
self.name = name
self.x = x
self.y = y
self.speedY = 0
self.visible = True
self.onClick = None
self.removed = False
self.bd = None
self.isStand = False
pass
def change(self, src):
self.src = src
self.stamp.change(src)
def reset(self):
pass
def front(self):
self.stamp.front()
pass
def update(self):
pass
def refresh(self, parent):
if self.removed:
if not self.stamp.hidden:
self.stamp.hide()
return
if self.visible and parent.visible:
if self.stamp.hidden:
self.stamp.show()
else:
if not self.stamp.hidden:
self.stamp.hide()
if not self.stamp.hidden:
self.stamp.move(parent.x + self.x, parent.y + self.y)
pass
def tap(self):
if self.visible and self.stamp.hits(x, y):
if self.onClick:
self.onClick()
return True
return False
pass
class Layer:
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y
self.children = []
self.pool = []
self.visible = True
pass
def addSp(self, src, x = 0, y = 0, size = None, name = ''):
for sp in self.pool:
if sp.src == src:
self.pool.remove(sp)
self.children.append(sp)
sp.x = x
sp.y = y
sp.name = name
if sp.src != src:
sp.stamp.change(src)
# todo size
sp.removed = False
sp.visible = True
sp.speedY = 0
sp.front()
return sp
sp = Sprite(src, x, y, size, name)
self.children.append(sp)
return sp
def clear(self):
self.pool.extend(self.children)
self.children.clear()
pass
def removeSp(self, sp):
self.pool.append(sp)
self.children.remove(sp)
sp.removed = True
def update(self):
pass
def refresh(self):
for sp in self.children:
sp.refresh(self)
for sp in self.pool:
sp.removed = True
sp.refresh(self)
pass
def tap(self):
if self.visible:
for sp in reversed(self.children):
if sp.visible and sp.tap():
return True
return False
pass
class Home(Layer):
def __init__(self):
Layer.__init__(self, W / 2, H / 2)
self.addSp("car-r-name@004B", 0, -150)
self.addSp("cat-r-cat@003v", 0, 0)
self.addSp("cat-r-stt@004F", 0, 150)
pass
def tap(self):
if abs(x - self.x) < 138 and abs(y - self.y - 150) < 61:
game.showMenu()
self.visible = False
return True
return False
pass
class LevelSelectMenu(Layer):
def __init__(self):
Layer.__init__(self, W / 2, H / 2)
self.bg = self.addSp("cat-r-menu@0049", 0, 0)
self.locks = []
self.stars = []
for j in range(3):
for i in range(4):
self.locks.append(self.addSp("cat-r-lock@004A", -118+19 + i * 66, -52+19+50*j))
for k in range(3):
self.stars.append(self.addSp("cat-r-star@004C", -118+19 + i * 66 + 12 * k - 12, -52+19+50*j+13, 12))
pass
def updateRecords(self, records):
for sp in self.locks:
sp.visible = True
for sp in self.stars:
sp.visible = False
b = True
for i in range(12):
self.locks[i].visible = not b
if records[i] == 0:
b = False
for j in range(3):
if j < records[i]:
self.stars[i * 3 + j].visible = True
pass
def update(self):
super().update()
pass
def refresh(self):
super().refresh()
pass
def tap(self):
for i in range(len(self.locks)):
sp = self.locks[i]
if not sp.visible:
x0 = x - self.x - sp.x
y0 = y - self.y - sp.y
if abs(x0) < 19 and abs(y0) < 19:
#print(i, sp.src[7:], x0//1, y0//1)
game.startLevel(i)
self.visible = False
return True
else:
break
pass
pass
class Gamelayer(Layer):
def __init__(self):
Layer.__init__(self)
self.pool = []
self.cat = None
self.grayCat = None
self.door = None
self.starNum = 0
self.count = 0
self.hasKey = False
self.state = 0
pass
def tap(self):
if self.state != 0:
return False
for sp in self.children:
if not sp.visible:
continue
dx = x - sp.x
dy = y - sp.y
if sp.name == 'r':
if abs(dx) < 50 and abs(dy) < 50:
game.restart()
return True
elif sp.name == 'm':
if abs(dx) < 50 and abs(dy) < 50:
game.backToMenu()
return True
pass
elif sp.name == 'c':
if dx * dx + dy * dy < (36+10) * (36+10):
if self.grayCat == None and (abs(self.cat.x - self.cat.ox) > 36 or abs(self.cat.y - self.cat.oy) > 36):
self.grayCat = self.addSp("cat-r-catg@003w", self.cat.x, self.cat.y, None, "g")
self.cat.x = self.cat.ox
self.cat.y = self.cat.oy
self.cat.speed = self.cat.ospeed
self.cat.speedY = 0
return True
elif sp.name == 'b':
if abs(dx) < 100 and abs(dy) < 30:
sp.name = "e"
sp.change("cat-r-wd4@004g")
return True
pass
elif sp.name == 'e':
if abs(dx) < 100 and abs(dy) < 30:
sp.name = "b"
sp.change("cat-r-wd3@004f")
return True
pass
elif sp.name == 'f':
if abs(dx) < 384 and abs(dy) < 30:
sp.name = "h"
sp.change("cat-r-wd6@004i")
return True
pass
elif sp.name == 'h':
if abs(dx) < 384 and abs(dy) < 30:
sp.name = "f"
sp.change("cat-r-wd5@004h")
return True
pass
elif sp.name == 'g':
if dx * dx + dy * dy < 36 * 36:
self.grayCat = None
self.removeSp(sp)
return True
pass
self.jumpCat()
return False
def jumpCat(self):
if not self.cat.isStand:
return
self.cat.speedY = JUMPF
self.cat.isStand = False
def moveCrab(self):
for sp in self.children:
if not sp.visible:
continue
if sp.name == 'd' or sp.name == 'a':
sp.speedY += G
sp.y += sp.speedY
sz = 66 if sp.name == 'a' else 56
if self.hitFloor(sp, sz, sz):
sp.y -= sp.speedY
sp.speedY = 0
sp.isStand = True
pass
def hitFloor(self, sp0, w, h):
for sp in self.children:
dx = sp.x - sp0.x
dy = sp.y - sp0.y
if sp.name == 'w':
if abs(dx) < (w + 384) and abs(dy) < (h + 30):
return True
if sp.name == 'b':
if abs(dx) < (w + 100) and abs(dy) < (h + 30):
return True
if sp.name == 'f':
if abs(dx) < (w + 384) and abs(dy) < (h + 30):
return True
if sp.name == 'g':
if abs(dx) < (w + 36) and abs(dy) < (h + 36):
return True
return False
def moveCat(self):
cat = self.cat
# rotate
cat.rotation += cat.speed
cat.stamp.rotate(cat.rotation * 180 / 3.141592653)
# move x
cat.speedX = cat.speed * 36
cat.x += cat.speedX
if self.checkCatHitFloor():
cat.x -= cat.speedX
cat.speed = -cat.speed
if cat.x >= 768 - 36 and cat.speed > 0:
cat.x = 768 - 36
cat.speed = -cat.speed
elif cat.x < 36 and cat.speed < 0:
cat.x = 36
cat.speed = -cat.speed
# move y
cat.speedY += G
cat.y += cat.speedY
cat.isStand = False
if self.checkCatHitFloor():
cat.y -= cat.speedY
cat.speedY = 0
cat.isStand = True
pass
def checkCatHitFloor(self):
cat = self.cat
for sp in self.children:
dx = sp.x - cat.x
dy = sp.y - cat.y
if sp.name == 'w':
if abs(dx) < (36 + 384) and abs(dy) < (36 + 30):
return True
if sp.name == 'b':
if abs(dx) < (36 + 100) and abs(dy) < (36 + 30):
return True
if sp.name == 'f':
if abs(dx) < (36 + 384) and abs(dy) < (36 + 30):
return True
if sp.name == 'g':
if abs(dx) < (36 + 36) and abs(dy) < (36 + 36):
return True
return False
def checkCatHit(self):
# check clission
cat = self.cat
for sp in self.children:
if not sp.visible:
continue
dx = sp.x - cat.x
dy = sp.y - cat.y - cat.speedY
sd = dx * dx + dy * dy
if sp.name == 'd': #门
if self.hasKey and sd < (36 + 56 - 10) * (36 + 56 - 10):
self.complete(sp)
elif sp.name == 'k': #钥匙
if sd < (36 + 29) * (36 + 29):
sp.visible = False
self.hasKey = True
elif sp.name == 's': #星星
if sd < (36 + 29) * (36 + 29):
sp.visible = False
self.starNum += 1
elif sp.name == 'a': #螃蟹
if sd < (36 + 66) * (36 + 66):
self.fail()
pass
#print(sp.name)
pass
def update(self):
super().update()
if not self.cat:
return
if self.state == 0:
self.moveCat()
self.moveCrab()
self.checkCatHit()
elif self.state == 1:
self.count += 1
if self.count == 8:
game.complete(self.starNum)
elif self.state == 2:
self.count += 1
if self.count == 10:
game.gameOver()
elif self.state == 3:
self.count += 1
if self.count == 20:
self.state = 0
self.count = 0
pass
def fail(self):
self.state = 2
def complete(self, door):
self.state = 1
self.openDoor()
pass
def refresh(self):
super().refresh()
pass
def start(self, arr):
self.initLevel(arr)
self.visible = True
pass
def openDoor(self):
self.door.change("cat-r-door@004M")
pass
def initLevel(self, arr):
self.cat = None
self.door = None
self.grayCat = None
self.starNum = 0
self.count = 0
self.hasKey = False
self.state = 3
self.clear()
for i in range(0, len(arr), 3):
s = arr[i]
x = arr[i+1]
y = arr[i+2]
if s == 'w':
self.addSp("cat-r-w1@004I", x, y, None, s)
elif s == 'd':
self.door = self.addSp("cat-r-dor1@004N", x, y, None, s)
elif s =='c':
self.cat = self.addSp("cat-r-cat@003v", x, y, None, s)
self.cat.speed = SPEED
self.cat.speedX = self.cat.speed * 36
self.cat.rotation = 0
self.cat.speedY = 0
self.cat.ox = self.cat.x
self.cat.oy = self.cat.y
self.cat.ospeed = self.cat.speed
elif s =='s':
self.addSp("cat-r-star@004C", x, y, None, s)
elif s =='k':
self.addSp("cat-r-key@003z", x, y, None, s)
elif s =='a':
self.addSp("cat-r-crab@0046", x, y, None, s)
elif s =='b':
self.addSp("cat-r-wd3@004f", x, y, None, s)
elif s =='e':
self.addSp("cat-r-wd4@004g", x, y, None, s)
elif s =='f':
self.addSp("cat-r-wd5@004h", x, y, None, s)
elif s =='h':
self.addSp("cat-r-wd6@004i", x, y, None, s)
self.addSp("cat-r-menu@003s", 50, 50, None, "m")
self.addSp("cat-r-rst@003t", 150, 50, None, "r")
self.cat.front()
pass
pass
class CompleteLayer(Layer):
def __init__(self):
Layer.__init__(self, W / 2, H / 2)
self.addSp("cat-r-comp@003x", 0, 0)
self.stars = [
self.addSp("cat-r-star@004C", -52, -38, 40),
self.addSp("cat-r-star@004C", -3, -54, 60),
self.addSp("cat-r-star@004C", 46, -38, 40)
]
pass
def setStar(self, num):
for st in self.stars:
st.visible = False
for i in range(num):
self.stars[i].visible = True
pass
def update(self):
super().update()
pass
def refresh(self):
super().refresh()
pass
def tap(self):
rects = [[-51, 103, 48], [-3, 103, 48], [45, 103, 48]]
for rect in rects:
x0 = x - self.x - (-51)
y0 = y - self.y - 103
i = int((x0 + 24) / 48)
if abs(y0) < 24 and i >= 0 and i <= 2:
self.visible = False
if i == 0:
game.goHome()
elif i == 1:
game.backToMenu()
elif i == 2:
game.nextLevel()
return True
return False
pass
class Game:
def __init__(self):
self.homeLayer = Home()
self.menuLayer = LevelSelectMenu()
self.gameLayer = Gamelayer()
self.compLayer = CompleteLayer()
self.layers = [self.homeLayer, self.menuLayer, self.gameLayer, self.compLayer]
#self.records = [1,1,1,1,1,1,1,1,1,1,1,1]
self.records = [0,0,0,0,0,0,0,0,0,0,0,0]
self.level = 0
self.hideAll()
self.homeLayer.visible = True
pass
def hideAll(self):
for layer in self.layers:
layer.visible = False
pass
def update(self):
for layer in self.layers:
layer.update()
pass
def refresh(self):
for layer in self.layers:
layer.refresh()
pass
def tap(self):
for layer in self.layers:
if layer.visible and layer.tap():
break
pass
def complete(self, keyNum):
self.records[self.level] = keyNum
self.hideAll()
self.compLayer.setStar(keyNum)
self.compLayer.visible = True
pass
def showMenu(self):
self.hideAll()
self.menuLayer.updateRecords(self.records)
self.menuLayer.visible = True
pass
def gameOver(self):
self.restart()
pass
def startLevel(self, level):
self.level = level
self.start()
pass
def goHome(self):
self.hideAll()
self.homeLayer.visible = True
pass
def backToMenu(self):
self.hideAll()
self.menuLayer.updateRecords(self.records)
self.menuLayer.visible = True
pass
def nextLevel(self):
if self.level < 11:
self.level += 1
self.start()
pass
def start(self):
self.hideAll()
self.gameLayer.visible = True
self.gameLayer.start(levels[self.level])
pass
def restart(self):
self.start()
pass
pass
game = Game()
def tap():
game.tap()
pass
def loop():
game.update()
game.refresh()
pass
也可以下载代码,本地python环境运行(用pygame封装了xdf库)。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。