在python的太空入侵者游戏中试图限制射击次数

2024-06-26 14:33:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为我的CS101类做一个项目,我不能使用pygame,但我需要做一个太空入侵者风格的游戏。我试图限制玩家一次可以在屏幕上的投篮次数,这样玩家就不能仅仅通过发送空格键来赢得比赛

import time
import graphics
import random

window_width = 800
num_bad_guys = 10

def create_good_guy(window):
    goodGuy = graphics.Image(graphics.Point (400,500), "scout-idle-16.gif")
    goodGuy.draw(window)
    return goodGuy

def create_bad_guy(window):
    badGuyList = []
    for index in range(num_bad_guys):
        badGuy = graphics.Image(graphics.Point(index*70+50, 70), "enchantress-melee-1.gif")
        badGuyList.append(badGuy)
        badGuy.draw(window)
    return badGuyList

class rect:
    def __init__ (self, pict):
        '''
        pict should be a zelle graphics.image file
        '''
        self.pict = pict
        pass

    def right(self):
        return self.pict.getAnchor().getX() + self.pict.getWidth()/2
    def left(self):
        return self.pict.getAnchor().getX() - self.pict.getWidth()/2
    def top(self):
        return self.pict.getAnchor().getY() - self.pict.getHeight()/2
    def bottom(self):
        return self.pict.getAnchor().getY() + self.pict.getHeight()/2

def overlap(r1,r2):
    '''Overlapping rectangles overlap both horizontally & vertically
    edited from the original to work with the rect class below '''
    hoverlaps = True
    voverlaps = True
    if (r1.left() > r2.right()) or (r1.right() < r2.left()):
        hoverlaps = False
    if (r1.top() > r2.bottom()) or (r1.bottom() < r2.top()):
        voverlaps = False
    return hoverlaps and voverlaps

def event_loop(win, goodGuy, badGuys):
    deltaX = 5
    deltaY = 5
    dX = 0
    dY = 5
    currNumBadGuys = num_bad_guys
    gShotList = []
    bShotList = []
    bShotCount = 0
    score = 0
    scoreText = graphics.Text(graphics.Point(100, 20), "Current Score: %d" %score)
    scoreText.draw(win)
    scoreText.setSize(15)
    while True:
        bShotCount = bShotCount + 1
        goodGuy.move(dX, 0)
        time.sleep(0.03)
        keyPressed = win.checkKey()
        if keyPressed == 'Left':
            dX = -5
        elif keyPressed == 'Right':
            dX = 5
        if goodGuy.getAnchor().getX()-(goodGuy.getWidth()/2)<=0 or \
                goodGuy.getAnchor().getX()+(goodGuy.getWidth()/2)>=window_width:
            dX = -dX
        if keyPressed == 'space':
            goodShot = graphics.Image(graphics.Point(goodGuy.getAnchor().getX(),goodGuy.getAnchor().getY()), 'shot4.gif')
            gShotList.append(goodShot)
            goodShot.draw(win)
        if len(gShotList) != 0:
            for shot in gShotList:
                shot.move(0, -dY)
                gShotRec = rect(shot)
                for guy in badGuys:
                    badGuyRec = rect(guy)
                    if overlap(gShotRec, badGuyRec):
                        shot.undraw()
                        gShotList.remove(shot)
                        guy.undraw()
                        badGuys.remove(guy)
                        currNumBadGuys = currNumBadGuys-1
                        score = score+5
                        scoreText.setText("Current Score: %s" %score)
                        if currNumBadGuys == 0:
                            winning = graphics.Text(graphics.Point(400,300), "You Win!")
                            winning.setSize(25)
                            winning.draw(win)
                            time.sleep(3)
                            return
        if badGuys[0].getAnchor().getX()-(badGuys[0].getWidth()/2)<=0 or \
                badGuys[currNumBadGuys-1].getAnchor().getX()+(badGuys[currNumBadGuys-1].getWidth()/2)>=window_width:
            deltaX = -deltaX
        randomGuy = random.choice(badGuys)
        if bShotCount > 100:
                bShotCount = 0
                badShot = graphics.Image(graphics.Point(randomGuy.getAnchor().getX(), randomGuy.getAnchor().getY()), 'shot5.gif')
                bShotList.append(badShot)
                badShot.draw(win)
        for shot in bShotList:
            shot.move(0, deltaY)
            bShotRec = rect(shot)
            goodGuyRec = rect(goodGuy)
            if overlap(bShotRec, goodGuyRec):
                shot.undraw()
                goodGuy.undraw()
                losing = graphics.Text(graphics.Point(400,300), "You Lose!")
                losing.setSize(25)
                losing.draw(win)
                time.sleep(3)
                return
        for guy in badGuys:
            guy.move(deltaX, 0)

def main():
    win = graphics.GraphWin("Battle Royale", window_width, 600)
    villian = create_bad_guy(win)
    hero = create_good_guy(win)
    event_loop(win, hero, villian)
    win.close()

if __name__ == '__main__':
    main()

Tags: selfreturnifdefwindowwinpointshot
2条回答

我建议您通过在一旁创建几个helper函数来分解巨大的event\u循环函数

对于您的问题,我认为如果您在添加新快照之前测试gShotList中活动的快照数,您应该能够限制一次可以触发的快照

        (...)
        if keyPressed == 'space':
            goodShot = graphics.Image(graphics.Point(goodGuy.getAnchor().getX(),goodGuy.getAnchor().getY()), 'shot4.gif')

        if len(gShotList) < max_simultaneous_shots:
            gShotList.append(goodShot)

        goodShot.draw(win)

        (...)

这可能会起到预期的作用

请注意max_simultaneous_shots必须在某个地方初始化(或者硬编码以测试概念)

可以在事件处理程序中限制空格键的快照数。在创建新快照对象之前,请检查gShotList的长度。如果长度小于您的最大放炮数(给这个常量一次屏幕上您想要的最大放炮数的值),则将该放炮添加到列表中。否则什么也不做。现在你只需要从列表中删除镜头,当他们离开屏幕或咬什么东西,死了

相关问题 更多 >