mainloop中的pygame事件键

时间:2018-04-17 20:05:18

标签: python python-3.x pygame

我在游戏中一直致力于键检测,但我得到的一个问题是我收到了这个错误。

Traceback (most recent call last):

File "C:/Users/Desktop/problem.py", line 433, in <module>
    mainting()
  File "C:/Users/natha/Desktop/problem.py", line 316, in mainting
    if event.key == pygame.K_p:
AttributeError: 'Event' object has no attribute 'key''

我试图缩进以尝试解决错误,但这没有任何区别。解决此错误的解决方案是什么?我也查看了其他问题,并尝试了他们的建议,但我无法解决问题。

以下是使用和已经删除的定义。

import pygame
import sys
from os import path
import math
from tkinter import *


pygame.init()
DS = pygame.display.set_mode((900, 600))
W, H = DS.get_size()
clock = pygame.time.Clock()
FPS = 60
PLAYER_IMAGE = pygame.Surface((15, 27))
PLAYER_IMAGE.fill((70, 240, 120))
IMAGE1 = pygame.Surface((20,20))
IMAGE1.fill((255,255,255))
#
ENEMY_IMAGE = pygame.Surface((20,20))
ENEMY_IMAGE.fill((255,255,255))
IMAGE2 = pygame.Surface((15,27))
IMAGE2.fill((0,0,255))
st = pygame.font.SysFont("comicsans ms", 20)
lf = pygame.font.SysFont("comicsans ms", 120)
#bolt_image = pygame.image.load('bolt power up.png')
WHITE = (255,255,255)
BLACK = (0,0,0)
BLUE = (0,0,255)
RED = (178,34,34)

class Platform(pygame.sprite.Sprite):
    def __init__(self, x, y, w, h):
        super(Platform, self).__init__()
        self.image = pygame.Surface((w, h))
        self.image.fill((90, 90, 120))
        self.rect = self.image.get_rect(topleft=(x, y))



class Level:

    def __init__(self):
        self.platforms = pygame.sprite.Group()
        for x, y, width, height in self.level:
            platform = Platform(x, y, width, height)
            self.platforms.add(platform)

    def shift_vertical(self, amount):  # Renamed this to `shift_vertical`.
            for sprite in self.platforms:
                sprite.rect.y += amount


    def shift(self, amount):
        for sprite in self.platforms:
            sprite.rect.y -= amount
        for Enemy in self.platforms:
            Enemy.rect.y -= amount

    def shift_horizontal(self, amount):
        for sprite in self.platforms:
            sprite.rect.x
class LVL_01(Level):

    def __init__(self):
        self.level = [
            (20, 20, 150, 20), (120, 200, 100, 20), (400, 440, 100, 20),
            (40, 100, 200, 20), (320, 300, 150, 20), (520, 550, 100, 20),
            (60, 100, 140, 20), (300, 200, 100, 20),(200,470,100,20),
            (40, 100, 100, 20), (350, 300, 150, 20), (95, 550, 150, 20),
            (250, 20, 150, 20), (450, 100, 150, 20), (710,20,100,20),
            (60, 20, 140, 20), (425, 200, 100, 20), (370, 350, 50, 20),
            (200, 100, 50, 20), (200, 370, 70, 20),(800,300,100,20),
            (780,130,50,20),(350,105,50,20),(310,550,100,20),
            (200, 100, 50, 20), (200, 370, 70, 20),(730,385,75,20),
            (600, -545, 50, 20), (780, -750, 50, 20), (350, -105, 50, 20),
            (40,460,75,20),(510,380,85,20),(650,450,70,20),(600,200,100,20),
            (80,305,100,20),(715,550,100,20),(460,20,100,20),
            (150,-105,150,20),(465,-105,100,20),(615,-105,100,20),(21,-195,50,20),
            (45,-60,100,20),(350,-230,75,20),(760,-239,80,20),(665,100,75,20),
            (450,-300,75,20),(118,-290,90,20),(300,-300,90,20),(100,-205,90,20),
            (765,-350,90,20),

        ]
        Level.__init__(self)


# defines the player, what it will look like and attributes that will help it to move
class Player(pygame.sprite.Sprite):

    def __init__(self, pos, level):
        super(Player, self).__init__()
        self.image = PLAYER_IMAGE
        self.image1 = IMAGE1
        self.rect = self.image.get_rect(center=pos)
        self._vx = 0
        self._vy = 0
        self._spritex = pos[0]
        self._spritey = pos[1]
        self.level = level
        self._gravity = .9
        # A vector as a camera.
        self.camera = pygame.math.Vector2()
    # Shows the movement
    def update(self):
        self.grav()
        self.dead()
        self.HighScore()
        self._spritex += self._vx
        self.rect.centerx = self._spritex
        # collision detection
        block_hit_list = pygame.sprite.spritecollide(self, self.level, False)
        for block in block_hit_list:
            if self._vx > 0:
                self.rect.right = block.rect.left
            elif self._vx < 0:
                self.rect.left = block.rect.right
            self._spritex = self.rect.centerx

        self._vy += self._gravity
        self._spritey += self._vy
        self.rect.centery = self._spritey
        # collision detection when player jumps
        block_hit_list = pygame.sprite.spritecollide(self, self.level, False)
        for block in block_hit_list:
            if self._vy > 0:
                self.rect.bottom = block.rect.top
            elif self._vy < 0:
                self.rect.top = block.rect.bottom
            self._spritey = self.rect.centery
            self._vy = 0
            if self.rect.y >= H - self.rect.height and self._vy >= 0:
                self._vy = 0
                self.rect.y = H - self.rect.height


    # defines the jumping
    def jump(self):
        self.rect.y += 2
        platform_hit_list = pygame.sprite.spritecollide(self, self.level, False)
        self.rect.y -= 2

        # if its okay to jump the speed shall be set upwards.
        if len(platform_hit_list) > 0 or self.rect.bottom >= H:
            self._vy = -19
    # Applies the gravity
    def grav(self):

        if self._vy == 0:
            self._vy = 1
        else:
            self._vy += .35

    # checks if the sprite is dead
    def dead(self):
        # See if we are on the ground.
        if self.rect.y >= H - self.rect.height and self._vy >= 0:
            self._vy = 0
            self.rect.bottom = H
            # You have to update the _spritey pos as well.
            self._spritey = self.rect.centerx
            Player.kill(self)
    # creates a highscore for the player which will be saved onto the textfile
    def HighScore(self):
        pygame.font.init()
        # self.st = pygame.font.SysFont("comicsans ms", 20)
        # self.text_rect,self.text_rect = text_objects('score :',(W/4,H/4),self.st)

        self.dir = path.dirname(__file__)


        with open(path.join(self.dir, 'highscore.txt'), 'w') as f:
            try:
                self.highscore = int(f.read())

            except:
                self.highscore =0

class Powerup(pygame.sprite.Sprite):
     def __init__(self):
         super(Powerup, self).__init__()
         self.bolt = bolt
         self._vy = 5
         self._vx = 5
         self.player = player
         pygame.Rect = (rect)

     def update(self):
         self.player.rect.y += 2
         if self.bolt.rect.colliderect(self.player.rect):
             shift = (self._vx, self._vy)
             # Move the player's rect.
             self.player.rect.x += self._vx
             self.player.rect.y += self._vy
             # Adjust the actual position as well.
             self.player._spritex = self.player.rect.centerx
             self.player._spritey = self.player.rect.centery
             # And the camera.
             self.player.camera.x -= self._vx
             self.player.camera.y -= self._vy
             # Move the platform.
             self.player.rect =+ shift
# creates the enemy class, what it will look like and the attributes it will have
class enemy(pygame.sprite.Sprite):

    def __init__(self, pos, level):
        super(enemy, self).__init__()
        self.image = ENEMY_IMAGE
        self.image1 = IMAGE2
        self.rect = self.image.get_rect(center=pos)
        self._x = 0
        self._y = 0
        self._enemyx = pos[0]
        self._enemyy = pos[1]
        self.level = level
        self._gravity = .9
        # A vector as a camera.


    def update(self):
        self.grav()
        self.dead()

        self._enemyx += self._x
        self.rect.centerx = self._enemyx
        # collision detection for enemy
        block_hit_list = pygame.sprite.spritecollide(self, self.level, False)
        for block in block_hit_list:
            if self._x > 0:
                self.rect.right = block.rect.left
            elif self._x < 0:
                self.rect.left = block.rect.right
            self._enemyx = self.rect.centerx

        self._y += self._gravity
        self._enemyy += self._y
        self.rect.centery = self._enemyy
        # collision detection when enemy jumps
        block_hit_list = pygame.sprite.spritecollide(self, self.level, False)
        for block in block_hit_list:
            if self._y > 0:
                self.rect.bottom = block.rect.top
            elif self._y < 0:
                self.rect.top = block.rect.bottom
            self._enemyy = self.rect.centery
            self._y = 0
            if self.rect.y >= H - self.rect.height and self._y >= 0:
                self._y = 0
                self.rect.y = H - self.rect.height

        # for block in block_hit_list:
             # block.rect.x += self.force
    # this will make the enemy jump
    def jump(self):
        self.rect.y += 2
        platform_hit_list = pygame.sprite.spritecollide(self, self.level, False)
        self.rect.y -= 2

        # If the enemy can jump the speed shall be set upwards.
        if len(platform_hit_list) > 0 or self.rect.bottom >= H:
            self._y = -19
    # calculates the effect of gravity
    def grav(self):

        if self._y == 0:
            self._y = 1
        else:
            self._y += .35

    # checks if the enemy is dead
    def dead(self):
        # See if the enemy on the ground.
        if self.rect.y >= H - self.rect.height and self._y >= 0:
            self._y = 0
            self.rect.bottom = H
            # spritey's position has to be updated as well.
            self._spritey = self.rect.centerx
            enemy.kill(self)

这是问题发生的部分

def mainting():
        active_sprite_group = pygame.sprite.Group()
        level_list = [LVL_01()]
        current_level_index = 0
        current_level = level_list[current_level_index]

        player = Player([131, 557], current_level.platforms)
        Enemy = enemy([600, 540], current_level.platforms)
        DS = pygame.display.set_mode((900, 600))
        W, H = DS.get_size()
        clock = pygame.time.Clock()
        FPS = 60

        # definitions of classes made into variables so that they can be used later on
        active_sprite_group = pygame.sprite.Group()
        level_list = [LVL_01()]
        current_level_index = 0
        current_level = level_list[current_level_index]

        # score = HighScore()
        player = Player([131, 557], current_level.platforms)
        Enemy = enemy([600, 540], current_level.platforms)
        # image = bolt_image([350,400])


        intro = True

        while intro:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    quit()



                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT:
                          player._vx = -3

                if event.key == pygame.K_p:



                    print('paused')
                    pygame.display.update()

                if event.key == pygame.K_r or not player.alive():

                    print('gameover')
                    pygame.display.flip()

                    elif event.key == pygame.K_RIGHT:
                    player._vx = 3
                    Enemy.go_left()
                elif event.key == pygame.K_UP:
                    player.jump()



            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT and player._vx < 0:
                    player._vx = 0
            elif event.key == pygame.K_RIGHT and player._vx > 0:
                player._vx = 0

        active_sprite_group.update()

        # Shift the platforms vertically.
        if player.rect.y <= 100:
            diff = player.rect.y - 100
            player.rect.y = 100
            # You have to update the _spritex pos as well.
            player._spritey = player.rect.centery
            current_level.shift_vertical(-diff)

        active_sprite_group.draw(DS)

        # We have to iterate with a for loop because the camera offset
        # has to be added to the rect coords.

        pygame.display.flip()

        clock.tick(FPS)
    mainting()
    pygame.quit()

2 个答案:

答案 0 :(得分:3)

涉及event.key的所有测试都应该elif event.type == pygame.KEYDOWN:开始的块内 - 否则它只是尝试为所有事件获取属性key - 并且任何与键盘无关的事件(如鼠标移动或计时器)都没有key属性。

只需重新缩进程序,以便只在事件类型为“KEYDOWN”时才执行“键”测试,并且它应该有效。

答案 1 :(得分:2)

因为你的缩进是错误的。

见下正确的代码:

            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                      player._vx = -3

                if event.key == pygame.K_p:



                    print('paused')
                    pygame.display.update()

                if event.key == pygame.K_r or not player.alive():

                    print('gameover')
                    pygame.display.flip()

                    elif event.key == pygame.K_RIGHT:
                        player._vx = 3
                        Enemy.go_left()
                    elif event.key == pygame.K_UP:
                        player.jump()