在游戏中进行OOP游戏,键盘事件和控制

时间:2017-10-08 14:45:31

标签: python oop pygame

我一直在制作游戏,有点'arkanoid' 我所拥有的是一个球和一个桨。

这是我尝试使用OOP制作的第一款游戏,所以我非常感谢您的所有评论。我创建了一个Objectmanager类来管理游戏中的所有对象,现在我不知道在哪里放置键盘控制和玩家球拍移动。

  1. 为Objectmanager编写了keyevent方法并将event.key传递给它,然后操纵了paddle - 效果不是很好。
  2. 同样的方法,但传递pygame.key.getpressed()并检查Objectmanager中的按钮
  3. 两种方式都会使桨叶以不良方式移动或在我希望它停止时不停止。

    我认为1.更好,但我无法完美,所以我要求你提供一些建议。 我会在一个循环中轻松制作它,但我真的想学习OOP,我不知道我是应该把它放在Objectmanager还是在主循环中。 我还想把Paddle放到主循环中,而不是放入Objectmanager。你怎么看?谢谢你们。

    import random, pygame, sys, math, itertools
    from pygame.locals import *
    #            R    G    B
    BLACK    = (  0,   0,   0)
    GRAY     = (100, 100, 100)
    NAVYBLUE = ( 60,  60, 100)
    WHITE    = (255, 255, 255)
    RED      = (255,   0,   0)
    GREEN    = (  0, 255,   0)
    BLUE     = (  0,   0, 255)
    YELLOW   = (255, 255,   0)
    ORANGE   = (255, 128,   0)
    PURPLE   = (255,   0, 255)
    CYAN     = (  0, 255, 255)
    BALLSIZE = 15
    BALLSPEED = 5
    FPS = 60
    PADDLEWIDTH = 80
    PADDLEHEIGHT = 20
    
    class Ball:
        def __init__(self):
            self.middle = [250,250]
            self.angle = math.radians(random.randint(1, 360))
            self.speed = BALLSPEED
        def update(self):
            xspeed = self.speed * math.sin(self.angle)
            yspeed = self.speed * math.cos(self.angle)
            deltax = round(xspeed)
            deltay = round(yspeed)
            self.middle[0] += deltax
            if self.middle[0] <= 0 or self.middle[0] >= 500:
                self.middle[0] -= 2*deltax
                self.angle = 2*math.pi - self.angle
            self.middle[1] += deltay
            if self.middle[1] <= 0 or self.middle[1] >= 500:
                self.middle[1] -= 2*deltay
                self.angle = math.pi - self.angle
        def draw(self,surface):
            pygame.draw.circle(surface,WHITE,self.middle,BALLSIZE)
    
    class Paddle:
        def __init__(self):
            self.middle = [250,480]
            self.deltax = 0
        def update(self):
            self.middle[0] += self.deltax
        def rect(self):
            return pygame.Rect(self.middle[0]-(PADDLEWIDTH/2),self.middle[1]-(PADDLEHEIGHT/2),PADDLEWIDTH,PADDLEHEIGHT)
        def moveleft(self):
            self.deltax -= 10
        def moveright(self):
            self.deltax += 10
        def stop(self):
            self.deltax = 0
        def draw(self,surface):
            pygame.draw.rect(surface,WHITE,self.rect())
            pygame.draw.rect(surface, GRAY, self.rect(),4)
    
    class ObjectManager:
        def __init__(self):
            self.balls = [Ball(),]
            self.paddle = Paddle()
        def add(self,object):
            if type(object) == Ball:
                self.balls.append(object)
    
        def update(self):
            for object in itertools.chain(self.balls,(self.paddle,)):
                object.update()
        def keyevent(self,keys):
            if keys[K_RIGHT]:
                self.paddle.moveright()
            elif keys[K_LEFT]:
                self.paddle.moveleft()
            else:
                self.paddle.stop()
        def draw(self,surface):
            for object in itertools.chain(self.balls,(self.paddle,)):
                object.draw(surface)
    
    class Game:
        def __init__(self):
            pygame.init()
            self.FPS = FPS
            self.fpsClock = pygame.time.Clock()
            DISPLAYSURF = pygame.display.set_mode((500,500),0,32)
            pygame.display.set_caption('arkanoid')
            manager = ObjectManager()
    
            while True:
                for event in pygame.event.get():
                    if event.type == QUIT:
                        pygame.quit()
                        sys.exit()
                    elif event.type == KEYDOWN:
                        if event.key == K_ESCAPE:
                            pygame.quit()
                            sys.exit()
    
                manager.keyevent(pygame.key.get_pressed())
                manager.update()
    
                DISPLAYSURF.fill(BLACK)
                manager.draw(DISPLAYSURF)
                pygame.display.update()
                self.fpsClock.tick(self.FPS)
    game = Game()
    

2 个答案:

答案 0 :(得分:1)

的ObjectManager:

def keydown(self,key):
    if key == K_RIGHT:
        self.paddle.moveright()
    elif key == K_LEFT:
        self.paddle.moveleft()
def keyup(self):
    self.paddle.stop()

主循环:

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()
            else:
                manager.keydown(event.key)
        else:
            manager.keyup()
你觉得怎么样?这很好用,当我发布我的问题时,我就是这样做的。

答案 1 :(得分:1)

您的ObjectManager应该只负责您的自定义GameObject,它可以是定义move(), update()等的抽象类或接口。 (你的球和桨可以继承/实施)。

所以从我的角度来看,我认为你应该在主循环中处理事件。 (创建一个EventManager也是一个选项。)你应该问问自己这个班级负责什么?并让他们尽可能简单地分开关注。

此外,我会将颜色放入一系列词汇中,例如:

['black':{'R':0,'G':0,'B':0}]

这样您就可以更轻松地在运行时更改颜色,例如选择随机颜色。