I've been working on key detection in my game, but an issue I get is that i get this error.
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''
I've tried to indent to try and solve the error but it does not make a difference. What is the solution that will resolve this error? I have also looked at other questions and tried what they have suggested but I cannot get a solution to the problem.
Here are the definitions which are used and have been cut down.
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)
This is the part where the issue occurs
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()
All your tests involving event.key
should be inside the block started by elif event.type == pygame.KEYDOWN:
- otherwise it just tries to fetch the attribute key
for all events - and any event that is not keyboard related, such as mouse movement, or timer, don't have a key
attribute.
Simply re-indent your program so that the tests for "keys" are only executed when the event type is "KEYDOWN" and it should work.
Its because your indentation is wrong.
Heres the correct code:
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()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.