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