学习python编程,在新东方少儿编程官网的自由创作平台做的一些作品。
可以在线运行,效果如下(在新页面中打开链接):
代码如下(用到平台自定义的xdf库):
from xdf import * keys = {} def keydown(key, keyCode): keys[str(key)] = True #print(key, 'down') def keyup(key, keyCode): key = str(key) if key in keys: keys[key] = False #print(key, 'up') def isDown(key): return (key in keys) and keys[key] class Sprite: def __init__(self, dis): self.id = 0 self.x = 0 self.y = 0 self.w = 1 self.h = 1 self.visible = True self.dis = dis def front(self): self.dis.front() def move(self, x, y): self.x = x self.y = y def change(self, value): self.dis.change(value) def update(self, pVisible): self.dis.move(self.x, self.y) if pVisible and self.visible: self.dis.show() else: self.dis.hide() class SpriteSheet(Sprite): def __init__(self, arr, config): self.isPlaying = True self.isFlag = False self.currentFrame = 0 self.totalFrames = len(arr) self.stamps = [] self.config = config self.flipped = False self.flipArr = [] for i in range(len(arr)): sp = stamp(arr[i]) self.stamps.append(sp) sp.hide() self.flipArr.append(False) Sprite.__init__(self, self.stamps[0]) def play(self): self.isPlaying = True def stop(self): self.isPlaying = False def gotoAndStop(self, n): self.currentFrame = n; self.stop() def gotoAndPlay(self, n): self.currentFrame = n; self.play() def nextFrame(self): self.currentFrame = self.currentFrame + 1 if self.isFlag: if self.currentFrame > self.flagEnd: self.currentFrame = self.flagStart elif self.currentFrame >= self.totalFrames: self.currentFrame = 0 def playFlag(self, flag): if flag in self.config: a = self.config[flag] self.flagStart = a[0] self.flagEnd = a[1] self.isFlag = True self.gotoAndPlay(self.flagStart); def clearPlayFlag(self): self.isFlag = False def update(self, pVisible = True): if self.isPlaying: self.nextFrame() for i in range(len(self.stamps)): self.stamps[i].hide() self.dis = self.stamps[self.currentFrame] if self.flipped != self.flipArr[self.currentFrame]: self.flipArr[self.currentFrame] = self.flipped self.dis.flip() super().update(pVisible) class Container: def __init__(self): self.children = [] self.visible = True def show(self): self.visible = True def hide(self): self.visible = False def update(self, pVisible = True): for i in range(len(self.children)): self.children[i].update(pVisible and self.visible) class HMenuLayer(Container): def __init__(self): Container.__init__(self) self.bg = Sprite(stamp('https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782826_265032.jpg')) self.gamename = Sprite(stamp('https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782791_842716.png')) self.shuoming = Sprite(stamp('https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782905_431833.png')) self.btn = Sprite(stamp('https://code-file.xdf.cn/files/dingdangweb/20230606/1686021917093_359914.png')) self.bg.move(384, 512) self.gamename.move(184, 312) self.shuoming.move(380, 700) self.btn.move(380, 860) self.btn.dis.tap = self.onStart self.children = [self.bg, self.gamename, self.shuoming, self.btn] def onStart(self): gameStart() class HOverlayer(Container): def __init__(self): Container.__init__(self) self.bg = Sprite(stamp('https://code-file.xdf.cn/files/dingdangweb/20230606/1686023293202_314981.png')) self.scoreBg = Sprite(stamp('https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782909_737697.png')) self.tfCj = Sprite(text('成绩', 384, 420, 20, '#00FF66', 'center')) self.tfFloor = Sprite(text('00', 384, 500, 30, '#FF9900', 'center')) self.tfScore = Sprite(text('00', 384, 540, 30, '#FF6666', 'center')) self.btn = Sprite(stamp('https://code-file.xdf.cn/files/dingdangweb/20230606/1686028239057_123081.png')) self.bg.move(384, 512) self.scoreBg.move(384, 512) self.tfCj.move(384, 420) self.tfFloor.move(384, 500) self.tfScore.move(384, 540) self.btn.move(384, 595) self.btn.dis.tap = self.onRestart self.children = [self.bg, self.scoreBg, self.tfCj, self.tfFloor, self.tfScore, self.btn] self.setScore(0,0) def setScore(self, floor, score): self.tfFloor.change('层数:' + str(floor)) self.tfScore.change('分数:' + str(score)) def onRestart(self): gameRestart() class HLadderLayer(Container): def __init__(self): Container.__init__(self) self.pool = [] self.reset() self.id = 1 def update(self, pVisible = True): super().update(pVisible) for i in range(len(self.pool)): self.pool[i].visible = False self.pool[i].update(pVisible) def setYoffset(self, value): for i in range(len(self.children)): lad = self.children[i] lad.y += value while self.children[0].y > 1024 + 25: lad = self.children.pop(0) self.pool.append(lad) while self.children[-1].y > 0: self.addLadder(self.children[-1].y - 100) def reset(self): self.id = 1 while len(self.children): self.pool.append(self.children.pop()) for i in range(9): self.addLadder(1024 - 200 -i*100) def getLadders(self): return self.children def createLadder(self): if len(self.pool): return self.pool.pop() lad = Sprite(stamp('https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782879_239311.png')) lad.w = 220 lad.h = 20 return lad def addLadder(self, y): lad = self.createLadder() lad.x = random(80, 688) lad.y = y lad.visible = True self.children.append(lad) lad.id = self.id self.id += 1 class HBgLayer(Container): def __init__(self): Container.__init__(self) self.bg = Sprite(stamp('https://code-file.xdf.cn/files/dingdangweb/20230606/1686017783064_242131.jpg')) self.ground = Sprite(stamp('https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782879_375451.png')) self.bg.x = 384 self.ground.x = 384 self.ground.w = 480 self.ground.h = 24 self.qiangArr = [] self.children = [self.bg, self.ground] for i in range(3): qiangR = Sprite(stamp('https://code-file.xdf.cn/files/dingdangweb/20230606/1686032051227_921808.png')) qiangL = Sprite(stamp('https://code-file.xdf.cn/files/dingdangweb/20230606/1686032051231_983939.png')) self.qiangArr.append(qiangL) self.qiangArr.append(qiangR) qiangL.x = 80 qiangR.x = 688 self.children.append(qiangL) self.children.append(qiangR) self.reset() def update(self, pVisible = True): super().update(pVisible) for i in range(len(self.qiangArr)): self.qiangArr[i].front() def reset(self): self.bg.y = -176 self.ground.visible = True self.ground.y = 1012 for i in range(3): qiangL = self.qiangArr[i * 2] qiangR = self.qiangArr[i * 2 + 1] qiangL.y = 744 - 560*i qiangR.y = 744 - 560*i def setYoffset(self, value): for i in range(3): qy = self.qiangArr[2*i].y if qy > 744: qy -= 560 * 3 self.qiangArr[2*i].y = self.qiangArr[2*i + 1].y = qy if self.ground.visible: self.ground.y += value if self.ground.y > 1024+200+25: self.ground.visible = False self.bg.y += value * 0.2 if self.bg.y > 1200: self.bg.y -= 800 def getGround(self): return self.ground class Hero(Container): def __init__(self): Container.__init__(self) self.w = 40 #156 self.h = 100 #112 self.sp = SpriteSheet( [ 'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782884_441334.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782789_777162.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782868_528853.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782879_421421.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782894_144746.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782864_319894.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782867_785734.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782864_084225.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782894_974575.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782845_061008.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782804_792339.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782871_063850.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782827_010127.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782783_055114.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782783_165885.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782845_347436.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782845_099353.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782866_974514.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782789_491249.png' ,'https://code-file.xdf.cn/files/dingdangweb/20230606/1686017782864_583559.png' ], { 'stand': [0, 4], 'run': [5, 10], 'jump': [11, 13], 'jump2': [14, 19] } ) self.x = 0 self.y = 0 self.speedX = 0 self.speedY = 0 self.inSpace = False self.state = "" self.MAX_SPEED = 20 self.AX = 2 self.FY = -25 self.children = [self.sp] self.reset() def update(self, pVisible=True): self.sp.x = self.x self.sp.y = self.y super().update(pVisible) def setScale(self, sc): if sc < 0: self.sp.flipped = True else: self.sp.flipped = False def runLeft(self): if not self.inSpace: self.run() self.setScale(-1) self.speedX -= self.AX if self.speedX < -self.MAX_SPEED: self.speedX = -self.MAX_SPEED def runRight(self): if not self.inSpace: self.run() self.setScale(1) self.speedX += self.AX if self.speedX > self.MAX_SPEED: self.speedX = self.MAX_SPEED def jumpUp(self): if not self.inSpace: self.speedY = self.FY - abs(self.speedX / self.MAX_SPEED)*35 if self.speedY < -40: self.jump2() else: self.jump() def jump(self): if self.changeState('jump'): self.inSpace = True def jump2(self): if self.changeState('jump2'): self.inSpace = True def run(self): self.changeState('run') def stand(self): self.changeState('stand') def changeState(self, state): if self.state != state: self.sp.playFlag(state) self.state = state return True return False def reset(self): self.speedX = 0 self.speedY = 0 self.inSpace = False self.stand() self.x = 384 self.y = 1024-56 def hitTest(self, sp): rect0 = Rect(self.x, self.y, self.w, self.h) rect1 = Rect(sp.x, sp.y, sp.w, sp.h) flag = not (rect1.left > rect0.right or rect1.right < rect0.left or rect1.top > rect0.bottom or rect1.bottom < rect0.top ) and self.speedY > 0 and self.y < sp.y if flag: self.y = sp.y - sp.h / 2 - self.h / 2 self.speedY = 0 return flag class Rect: def __init__(self, x, y, w, h): self.x = x self.y = y self.w = w self.h = h self.left = x - w / 2 self.top = y - h / 2 self.right = x + w / 2 self.bottom = y + h /2 class FlyText(Sprite): def __init__(self, tf): Sprite.__init__(self, tf) self.life = 0 self.step = 0 def flyText(self, text, life, x, y, dy): self.change(text) self.life = life self.x = x self.y = y self.step = dy / life def update(self, pVisible): self.life = max(0, self.life-1) self.visible = self.life > 0 if self.life > 0: self.y += self.step super().update(pVisible) self.front() class HGameLayer(Container): def __init__(self): Container.__init__(self) self.autoMove = False self.score = 0 self.floor = 0 self.isRunning = False self.bgLayer = HBgLayer() self.ladderLayer = HLadderLayer() self.hero = Hero() self.tfFloor = Sprite(text('00', 0, 0, 40, '#FF6600')) self.tfScore = Sprite(text('00', 0, 0, 40, '#FF6600')) self.tfFloor.move(10, 50) self.tfScore.move(10, 100) self.flyTf = FlyText(text('00', 0, 0, 50, '#FF0000')) self.ladderLayer.setYoffset(0) self.children = [self.bgLayer, self.ladderLayer, self.hero, self.tfFloor, self.tfScore, self.flyTf] def setScore(self, floor, score): self.tfFloor.change('层数:' + str(floor)) self.tfScore.change('分数:' + str(score)) def update(self, pVisible = True): super().update(pVisible) self.tfFloor.front() self.tfScore.front() self.setScore(self.floor, self.score) #print('is run', self.isRunning) if not self.isRunning: return hero = self.hero if isDown('39') or yaogan.isRight(): hero.runRight() elif isDown('37') or yaogan.isLeft(): hero.runLeft() if isDown('38') or isDown('32') or yaogan.isSpace(): hero.jumpUp() hero.x += hero.speedX hero.speedX *= 0.90 if hero.x > 558: hero.x = 558 hero.speedX *= 0.5 elif hero.x < 210: hero.x = 210 hero.speedX *= 0.5 if abs(hero.speedX) < 0.5: hero.speedX = 0 hero.speedY += 2 hero.y += hero.speedY hero.inSpace = True fallFlag = hero.speedY > 2 if hero.speedY > 0: # 检测地板 # print('hit test floor') ground = self.bgLayer.getGround() if hero.hitTest(ground): hero.inSpace = False if fallFlag: pass else: # 检测梯子 ladders = self.ladderLayer.getLadders() for i in range(len(ladders)): ladder = ladders[i] # print('hit test ladder') if hero.hitTest(ladder): hero.inSpace = False if fallFlag: pass ind = ladder.id if self.floor < ind: step = ind - self.floor if step > 3: self.score += 10 self.flyTf.flyText('连跳' + str(step) + '层', 40, hero.x, hero.y, -300) self.floor = ind self.score += step * 10 if hero.y < 512: self.autoMove = True if self.autoMove: self.bgLayer.setYoffset(2) self.ladderLayer.setYoffset(2) if hero.y < 400: step = min(40, 400 - hero.y) hero.y += step self.bgLayer.setYoffset(step) self.ladderLayer.setYoffset(step) if not hero.inSpace: if hero.speedX: hero.run() else: hero.stand() if self.autoMove and hero.y > 1024: self.stop() self.gameOver() def gameOver(self): gameOver() def reset(self): self.bgLayer.reset() self.ladderLayer.reset() self.hero.reset() self.autoMove = False self.floor = 0 self.score = 0 def start(self): self.reset() self.isRunning = True def stop(self): self.isRunning = False gameLayer = HGameLayer() menuLayer = HMenuLayer() overLayer = HOverlayer() gameLayer.visible = False overLayer.visible = False def hideAll(): gameLayer.visible = False overLayer.visible = False menuLayer.visible = False def gameRestart(): hideAll() menuLayer.visible = True yaogan.show() def gameStart(): hideAll() gameLayer.visible = True gameLayer.start() yaogan.show() def gameOver(): hideAll() overLayer.visible = True overLayer.setScore(gameLayer.floor, gameLayer.score) yaogan.hide() def loop(): menuLayer.update() overLayer.update() gameLayer.update() yaogan.front() from xdf import * class Yaogan: def __init__(self): y0 = 1024-100 x0 = 100 x1 = 768-100 self.x0 = x0 self.y0 = y0 self.x1 = x1 self.c1 = circle(x0, y0, 100, 'transparent', 'blue') self.c2 = circle(x0, y0, 30, 'red') self.c3 = circle(x1, y0, 100, 'rgb(255, 0, 0, 0.5)') self.isDown1 = False self.isDown3 = False self.dp = [0, 0] self.visible = True def hide(self): self.c1.move(0, 1300) self.c2.move(0, 1300) self.c3.move(0, 1300) def show(self): self.c1.move(self.x0, self.y0) self.c2.move(self.x0, self.y0) self.c3.move(self.x1, self.y0) def front(self): self.c1.front() self.c2.front() self.c3.front() def isLeft(self): return self.dp[0] < -10 def isRight(self): return self.dp[0] > 10 def isSpace(self): return self.isDown3 def touch(self, x, y): if self.c1.hits(x, y): self.isDown1 = True elif self.c3.hits(x, y): self.isDown3 = True def touching(self, x, y): if self.c1.hits(x, y): self.c2.move(x, y) self.dp = [x - self.x0, y - self.y0] def untouch(self, x, y): if self.c1.hits(x, y) or x <= 768 / 2: self.isDown1 = False self.c2.move(self.x0, self.y0) self.dp = [0, 0] elif self.c3.hits(x, y) or x > 768 / 2: self.isDown3 = False yaogan = Yaogan() yaogan.hide() def touch(): yaogan.touch(x, y) def untouch(): yaogan.untouch(x, y) def touching(): yaogan.touching(x, y)
也可以下载代码,本地python环境运行(用pygame封装了xdf库)。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。