Python game keys are not responding - python

I am trying to implement a Python game (aliens.py from the PyGame package) but when I run it, I can't move my player or do any shooting...
I run it on Mac OS X, python3 and have a french keyboard. Could this have anything to do the fact that it does not take any of my keyboard commands?
On the screen of my terminal I see:
^[ (when I press esc),
^[[D (when I press the left arrow),
^[[C (when I press the right arrow),
^[[A (when I press the upwards arrow),
^[[B (when I press the downwards arrow
...
Is this normal? It does not help replacing K_RIGHT with ^[[C.
#!/usr/bin/env python
import random, os.path
#import basic pygame modules
import pygame
from pygame.locals import *
#see if we can load more than standard BMP
if not pygame.image.get_extended():
raise SystemExit("Sorry, extended image module required")
#game constants
MAX_SHOTS = 2 #most player bullets onscreen
ALIEN_ODDS = 22 #ances a new alien appears
BOMB_ODDS = 60 #chances a new bomb will drop
ALIEN_RELOAD = 12 #frames between new aliens
SCREENRECT = Rect(0, 0, 940, 480)
SCORE = 0
main_dir = os.path.split(os.path.abspath(__file__))[0]
def load_image(file):
"loads an image, prepares it for play"
file = os.path.join(main_dir, 'data', file)
try:
surface = pygame.image.load(file)
except pygame.error:
raise SystemExit('Could not load image "%s" %s'%(file, pygame.get_error()))
return surface.convert()
def load_images(*files):
imgs = []
for file in files:
imgs.append(load_image(file))
return imgs
class dummysound:
def play(self): pass
def load_sound(file):
if not pygame.mixer: return dummysound()
file = os.path.join(main_dir, 'data', file)
try:
sound = pygame.mixer.Sound(file)
return sound
except pygame.error:
print ('Warning, unable to load, %s' % file)
return dummysound()
# each type of game object gets an init and an
# update function. the update function is called
# once per frame, and it is when each object should
# change it's current position and state. the Player
# object actually gets a "move" function instead of
# update, since it is passed extra information about
# the keyboard
class Player(pygame.sprite.Sprite):
speed = 10
bounce = 24
gun_offset = -11
images = []
def __init__(self):
pygame.sprite.Sprite.__init__(self, self.containers)
self.image = self.images[0]
self.rect = self.image.get_rect(midbottom=SCREENRECT.midbottom)
self.reloading = 0
self.origtop = self.rect.top
self.facing = -1
def move(self, direction):
if direction: self.facing = direction
self.rect.move_ip(direction*self.speed, 0)
self.rect = self.rect.clamp(SCREENRECT)
if direction < 0:
self.image = self.images[0]
elif direction > 0:
self.image = self.images[1]
self.rect.top = self.origtop - (self.rect.left//self.bounce%2)
def gunpos(self):
pos = self.facing*self.gun_offset + self.rect.centerx
return pos, self.rect.top
class Alien(pygame.sprite.Sprite):
speed = 13
animcycle = 12
images = []
def __init__(self):
pygame.sprite.Sprite.__init__(self, self.containers)
self.image = self.images[0]
self.rect = self.image.get_rect()
self.facing = random.choice((-1,1)) * Alien.speed
self.frame = 0
if self.facing < 0:
self.rect.right = SCREENRECT.right
def update(self):
self.rect.move_ip(self.facing, 0)
if not SCREENRECT.contains(self.rect):
self.facing = -self.facing;
self.rect.top = self.rect.bottom + 1
self.rect = self.rect.clamp(SCREENRECT)
self.frame = self.frame + 1
self.image = self.images[self.frame//self.animcycle%3]
class Explosion(pygame.sprite.Sprite):
defaultlife = 12
animcycle = 3
images = []
def __init__(self, actor):
pygame.sprite.Sprite.__init__(self, self.containers)
self.image = self.images[0]
self.rect = self.image.get_rect(center=actor.rect.center)
self.life = self.defaultlife
def update(self):
self.life = self.life - 1
self.image = self.images[self.life//self.animcycle%2]
if self.life <= 0: self.kill()
class Shot(pygame.sprite.Sprite):
speed = -11
images = []
def __init__(self, pos):
pygame.sprite.Sprite.__init__(self, self.containers)
self.image = self.images[0]
self.rect = self.image.get_rect(midbottom=pos)
def update(self):
self.rect.move_ip(0, self.speed)
if self.rect.top <= 0:
self.kill()
class Bomb(pygame.sprite.Sprite):
speed = 9
images = []
def __init__(self, alien):
pygame.sprite.Sprite.__init__(self, self.containers)
self.image = self.images[0]
self.rect = self.image.get_rect(midbottom=
alien.rect.move(0,5).midbottom)
def update(self):
self.rect.move_ip(0, self.speed)
if self.rect.bottom >= 470:
Explosion(self)
self.kill()
class Score(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.font = pygame.font.Font(None, 20)
self.font.set_italic(1)
self.color = Color('white')
self.lastscore = -1
self.update()
self.rect = self.image.get_rect().move(10, 450)
def update(self):
if SCORE != self.lastscore:
self.lastscore = SCORE
msg = "Score: %d" % SCORE
self.image = self.font.render(msg, 0, self.color)
def main(winstyle = 0):
# Initialize pygame
pygame.init()
if pygame.mixer and not pygame.mixer.get_init():
print ('Warning, no sound')
pygame.mixer = None
# Set the display mode
winstyle = 0 # |FULLSCREEN
bestdepth = pygame.display.mode_ok(SCREENRECT.size, winstyle, 32)
screen = pygame.display.set_mode(SCREENRECT.size, winstyle, bestdepth)
#Load images, assign to sprite classes
#(do this before the classes are used, after screen setup)
img = load_image('player1.gif')
Player.images = [img, pygame.transform.flip(img, 1, 0)]
img = load_image('explosion1.gif')
Explosion.images = [img, pygame.transform.flip(img, 1, 1)]
Alien.images = load_images('alien1.gif', 'alien2.gif', 'alien3.gif')
Bomb.images = [load_image('bomb.gif')]
Shot.images = [load_image('shot.gif')]
#decorate the game window
icon = pygame.transform.scale(Alien.images[0], (32, 32))
pygame.display.set_icon(icon)
pygame.display.set_caption('Pygame Aliens')
pygame.mouse.set_visible(0)
#create the background, tile the bgd image
bgdtile = load_image('background.gif')
background = pygame.Surface(SCREENRECT.size)
for x in range(0, SCREENRECT.width, bgdtile.get_width()):
background.blit(bgdtile, (x, 0))
screen.blit(background, (0,0))
pygame.display.flip()
#load the sound effects
boom_sound = load_sound('boom.wav')
shoot_sound = load_sound('car_door.wav')
if pygame.mixer:
music = os.path.join(main_dir, 'data', 'house_lo.wav')
pygame.mixer.music.load(music)
pygame.mixer.music.play(-1)
# Initialize Game Groups
aliens = pygame.sprite.Group()
shots = pygame.sprite.Group()
bombs = pygame.sprite.Group()
all = pygame.sprite.RenderUpdates()
lastalien = pygame.sprite.GroupSingle()
#assign default groups to each sprite class
Player.containers = all
Alien.containers = aliens, all, lastalien
Shot.containers = shots, all
Bomb.containers = bombs, all
Explosion.containers = all
Score.containers = all
#Create Some Starting Values
global score
alienreload = ALIEN_RELOAD
kills = 0
clock = pygame.time.Clock()
#initialize our starting sprites
global SCORE
player = Player()
Alien() #note, this 'lives' because it goes into a sprite group
if pygame.font:
all.add(Score())
while player.alive():
#get input
for event in pygame.event.get():
if event.type == QUIT or \
(event.type == KEYDOWN and event.key == K_ESCAPE):
return
keystate = pygame.key.get_pressed()
# clear/erase the last drawn sprites
all.clear(screen, background)
#update all the sprites
all.update()
#handle player input
direction = keystate[K_RIGHT] - keystate[K_LEFT]
player.move(direction)
firing = keystate[K_SPACE]
if not player.reloading and firing and len(shots) < MAX_SHOTS:
Shot(player.gunpos())
shoot_sound.play()
player.reloading = firing
# Create new alien
if alienreload:
alienreload = alienreload - 1
elif not int(random.random() * ALIEN_ODDS):
Alien()
alienreload = ALIEN_RELOAD
# Drop bombs
if lastalien and not int(random.random() * BOMB_ODDS):
Bomb(lastalien.sprite)
# Detect collisions
for alien in pygame.sprite.spritecollide(player, aliens, 1):
boom_sound.play()
Explosion(alien)
Explosion(player)
SCORE = SCORE + 1
player.kill()
for alien in pygame.sprite.groupcollide(shots, aliens, 1, 1).keys():
boom_sound.play()
Explosion(alien)
SCORE = SCORE + 1
for bomb in pygame.sprite.spritecollide(player, bombs, 1):
boom_sound.play()
Explosion(player)
Explosion(bomb)
player.kill()
#draw the scene
dirty = all.draw(screen)
pygame.display.update(dirty)
#cap the framerate
clock.tick(40)
if pygame.mixer:
pygame.mixer.music.fadeout(1000)
pygame.time.wait(1000)
pygame.quit()
#call the "main" function if running this script
if __name__ == '__main__': main()

Event KEYDOWN sends values unicode, key, mod and you can display it to see what codes (numeric values) uses your keyboard.
if event.type == KEYDOWN;
print('key:', event.key)
print('unicode:', event.uniconde)
print('mod:', event.mod)
And then you can use them to test your keys and move objects.

It is surely due to keyboard keys problem , just go to this documentation and find out proper keyword for your respective keyboard button:
"https://www.pygame.org/docs/ref/key.html"

Related

Mask collisions doing funky stuff when i make the camera follow the player

I'm making a racing game with almost realistic cars in pygame. I made the cars succesfully and I want to make the car move a bit slower when it's not touching the drive way. For that, I want to use pygame mask collisions. Instead of using bounding boxes, they use the pixels and count them based on how many pixels of something are touching something. This all works correctly, but when I use the cam.follow_object(player) function, the game behaves very weird and there rise unexplainable bugs.
I included each individual picture and file, but I also included it on github because I know it's annoying to download all images one by one.
Assets:
app.py:
import pygame
from pygame.locals import *
from random import choice, randint
import math, car, ui, pySave, camera, level
pygame.init()
# Basic Variables
screen_width = 1000
screen_height = 1000
fps = 80
screen = pygame.display.set_mode((screen_width, screen_height))
clock = pygame.time.Clock()
cam = camera.Camera(1, screen)
#cam.zoom_game(1.55)
stage = "home"
# Loading Images
images = {
"start" : pygame.transform.scale(pygame.image.load("road_texture.png"), (200*cam.zoom, 75*cam.zoom)).convert_alpha(),
"bcg" : pygame.transform.scale(pygame.image.load("map2.png"), (1000*cam.zoom, 1000*cam.zoom)).convert_alpha(),
"car" : pygame.image.load("car.png").convert_alpha()
}
# Functionality Functions
def play_game():
global stage
stage = "game"
# Instansiating stuff
pos_save = pySave.Save_Manager("saved_info", "pos")
start_button = ui.Button((500,500), images["start"], play_game, text="startgame")
test_car = car.CarSprite(images["car"], 400, 400,[2, 2.3, 2.7], 0.013, rotations=360, camera=cam)
speedometer = ui.TextWithBackground((100,50), (100,950), images["start"])
level = level.Level(images["bcg"], test_car,cam,pos = (0,100))
# Groups and Lists
car_group = pygame.sprite.Group()
# Adding to Groups
car_group.add(test_car)
# Game Functions
def render():
if stage == "home":
screen.fill((255,255,255))
start_button.update("Start Game")
start_button.draw(screen)
elif stage == "game":
screen.fill((0,76,18))
level.update(screen)#screen.blit(images["bcg"], (0-cam.scroll[0],0-cam.scroll[1]))
car_group.update()
car_group.draw(screen)
#cam.follow(test_car, )
#speedometer.draw(screen)
speedometer.update(screen,round(test_car.speed*60,2) , " km/h")
#cam.zoom_game(2)
def collisions():
pass
run = True
while run:
clock.tick_busy_loop(80)
render()
collisions()
for event in pygame.event.get():
if event.type == QUIT:
run = False
pos_save.save("x", test_car.rect.x)
pos_save.save("y", test_car.rect.y)
pos_save.apply()
print(f"Quit with {round(clock.get_fps(), 2)} FPS")
quit()
pygame.display.update()
car.py:
import pygame
from pygame.locals import *
from random import choice, randint
import math, camera
class CarSprite( pygame.sprite.Sprite ):
def __init__( self, car_image, x, y, max_speed, accel,rot_speed=[1.8, 2.2, 3] ,rotations=360, camera="" ):
pygame.sprite.Sprite.__init__(self)
self.rotated_images = {}
self.min_angle = ( 360 / rotations )
for i in range( rotations ):
rotated_image = pygame.transform.rotozoom( pygame.transform.scale(car_image, (12*camera.zoom,25*camera.zoom)), 360-90-( i*self.min_angle ), 1 )
self.rotated_images[i*self.min_angle] = rotated_image
self.min_angle = math.radians( self.min_angle )
self.image = self.rotated_images[0]
self.rect = self.image.get_rect()
self.rect.center = ( x, y )
self.reversing = False
self.heading = 0
self.speed = 0
self.velocity = pygame.math.Vector2( 0, 0 )
self.position = pygame.math.Vector2( x, y )
self.speed_hardening = 1
self.acc = False
self.steer_strenght_acc = rot_speed[0]
self.steer_strength_normal= rot_speed[1]
self.steer_strength_drift= rot_speed[2]
self.steer_strength = rot_speed[1]
self.drift_point = 0.00
self.accel = accel
self.max_speed = self.accel * 150
self.cam = camera
def turn( self, ori=1 ):
if self.speed > 0.1 or self.speed < 0. :
self.heading += math.radians( self.steer_strenght * ori )
image_index = int((self.heading + self.min_angle / 2) / self.min_angle) % len(self.rotated_images)
image = self.rotated_images[image_index]
if self.image is not image:
x,y = self.rect.center
self.image = image
self.rect = self.image.get_rect()
self.rect.center = (x,y)
def accelerate( self):
self.speed += self.accel
def brake( self ):
if self.speed > 0:
self.speed -= self.accel * 3
if abs(self.speed) < 0.1:
self.speed = 0
self.velocity.from_polar((self.speed, math.degrees(self.heading)))
def move(self):
keys = pygame.key.get_pressed()
if keys[K_w]:
self.accelerate()
if keys[K_s]:
self.brake()
if keys[K_a]:
self.turn(-1)
if keys[K_d]:
self.turn()
if keys[pygame.K_s] or keys [pygame.K_w]:
self.acc = True
else:
self.acc = False
def update( self ):
self.move()
self.speed_hardening = self.speed / 100
self.speed = round(self.speed, 3)
if self.acc:
self.steer_strenght = self.steer_strenght_acc
else:
self.steer_strenght = self.steer_strength_normal
if self.speed > self.max_speed and not pygame.key.get_pressed()[K_SPACE] and not self.drift_point > 0:
self.speed += self.accel / 4 - self.speed_hardening / 2
if self.speed > self.max_speed * 1.8:
self.speed = self.max_speed * 1.8
if self.speed < -self.max_speed / 4:
self.speed = -self.max_speed / 4
if not pygame.key.get_pressed()[K_SPACE]:
self.velocity.from_polar((self.speed, math.degrees(self.heading)))
self.speed += self.drift_point
self.drift_point -= 0.0001
if self.drift_point < 0:
self.drift_point = 0
self.speed -= self.drift_point
else:
self.steer_strenght = self.steer_strength_drift
self.drift_point += 0.0001
if self.drift_point > self.accel / 1.5:
self.drift_point = self.accel / 1.5
if not self.acc and not self.speed < 0.04:
self.speed -= (self.accel / 2) + self.speed_hardening
if self.speed < 0.05:
self.speed = 0
self.position += self.velocity
self.rect.center = self.position
level.py
import pygame
from pygame.locals import *
from random import choice, randint
import math, car, ui, pySave, camera
screen_width = 1000
screen_height = 1000
class Level:
def __init__(self,image, car, camera, pos=(0,0)):
# Convert the images to a more suitable format for faster blitting
self.image = image.convert()
self.road = image
self.cam = camera
self.x,self.y = pos
self.bcg_mask = pygame.mask.from_surface(self.road)
self.car = car
self.get_car_mask()
def update(self, screen):
# Calculate the overlap between the car mask and the background mask
overlap = self.bcg_mask.overlap_mask(
self.car_mask,
(self.car.rect.x, self.car.rect.y)
)
self.x = 0 - self.cam.scroll[0]
self.y = 0 - self.cam.scroll[1]
# Fill the screen with the background color
screen.blit(self.road.convert_alpha(), (self.x, self.y))
screen.blit(overlap.to_surface(unsetcolor=(0,0,0,0), setcolor=(255,255,255,255)), (self.x, self.y))
# Print the overlap count to the console
print(overlap.count())
def get_car_mask(self):
# Convert the car image to a more suitable format for faster blitting
carimg = self.car.image.convert()
carimg.set_colorkey((0,0,0))
self.carimg = carimg
self.car_mask = pygame.mask.from_surface(self.carimg)
camera.py:
import pygame
from pygame.locals import *
class Camera:
def __init__(self, speed, screen):
self.scroll = [5,5]
self.speed = speed
self.screen = screen
self.zoom = 1
def move_on_command(self):
keys = pygame.key.get_pressed()
if keys[K_UP]:
self.scroll[1] -= self.speed
if keys[K_DOWN]:
self.scroll[1] += self.speed
if keys[K_RIGHT]:
self.scroll[0] += self.speed
if keys[K_LEFT]:
self.scroll[0] -= self.speed
def follow(self, obj, speed=12):
#self.scroll[0], self.scroll[1] = obj.rect.x, obj.rect.y
if (obj.rect.x - self.scroll[0]) != self.screen.get_width()/2:
self.scroll[0] += ((obj.rect.x - (self.scroll[0] + self.screen.get_width()/2)))
if obj.rect.y - self.scroll[1] != self.screen.get_height()/2:
self.scroll[1] += ((obj.rect.y - (self.scroll[1] + self.screen.get_height()/2)))
def zoom_game(self, zoom):
self.zoom = zoom
ui.py :
import pygame
from pygame.locals import *
from random import choice, randint
class Button:
def __init__(self, pos, image, action, click_times=1, dissapear=True , text="", textcolor = (255,255,255), fontsize=30):
self.image = image
self.rect = self.image.get_rect(center=pos)
self.clicked = False
self.clicked_times = click_times
self.dissapear = dissapear
self.dont_draw = False
self.function = action
self.text= text
if not self.text == "":
self.font = pygame.font.SysFont("Arial", fontsize, False, False)
self.color = textcolor
def update(self, var=""):
pressed = pygame.mouse.get_pressed()[0]
if not self.text == "":
self.text = self.font.render(f"{var}", 1, self.color)
self.text_rect = self.text.get_rect(center = self.rect.center)
if pressed and not self.clicked and not self.clicked_times <= 0 and self.rect.collidepoint(pygame.mouse.get_pos()):
self.function()
self.clicked = True
self.clicked_times -= 1
if not pressed:
self.clicked = False
if self.clicked_times <= 0:
if self.dissapear:
self.dont_draw = True
def draw(self, screen):
if not self.dont_draw:
screen.blit(self.image, (self.rect.x,self.rect.y))
screen.blit(self.text, (self.text_rect.x, self.text_rect.y))
class TextWithBackground:
def __init__(self, image_size, pos, image, fontsize=30, colour=(255, 255, 255)):
self.image = pygame.transform.scale(image, image_size)
self.rect = self.image.get_rect(center=pos)
self.font = pygame.font.SysFont("Arial", fontsize, False, False)
self.color = colour
self.text = self.font.render("", 1, self.color)
self.other_text = None
self.other_rect = None
def update(self, screen, variable, othertext=""):
self.text = self.font.render(f"{variable}", 1, self.color)
self.text_rect = self.text.get_rect(center=self.rect.center)
if othertext:
self.other_text = self.font.render(f"{othertext}", 1, self.color)
self.other_rect = self.other_text.get_rect(topleft=(self.rect.center[0] - 5, self.rect.center[1] - 5))
screen.blit(self.image, (self.rect.x, self.rect.y))
screen.blit(self.text, (self.rect.x, self.rect.y))
if self.other_text:
screen.blit(self.other_text, (self.other_rect.x, self.other_rect.y))
Here you can find my images:
car.png
map2.png
road_texture.png
See PyGame collision with masks. You need to calculate the offset between the car and the map when you get the overlap area of the masks:
class Level:
# [...]
def update(self, screen):
self.x = 0 - self.cam.scroll[0]
self.y = 0 - self.cam.scroll[1]
# Calculate the overlap between the car mask and the background mask
offset = (self.car.rect.x - self.x, self.car.rect.y - self.y)
overlap = self.bcg_mask.overlap_mask(self.car_mask, offset)
# Fill the screen with the background color
screen.blit(self.road.convert_alpha(), (self.x, self.y))
screen.blit(overlap.to_surface(unsetcolor=(0,0,0,0), setcolor=(255,255,255,255)), (self.x, self.y))
# Print the overlap count to the console
print(overlap.count())

PongGame reinforcement learning with stable-baselines and pygame

I'm trying write PongGame AI with pygame and stable-baselines. Environment is ready and working. For the agent, im using custom env documentation stable-baselines (https://stable-baselines.readthedocs.io/en/master/guide/custom_env.html)
But when i use check environment.py , error occuring which is
"assertion error: reset() method doesnt matching with observation space"
Game is working properly as i said but when i try make this with customEnv the error occuring which i wrote.
Traceback (most recent call last):
File "C:\Users\Goksel\anaconda3\envs\tensor37\lib\site-packages\spyder_kernels\py3compat.py", line 356, in compat_exec
exec(code, globals, locals)
File "c:\users\goksel\desktop\checkenv.py", line 9, in
check_env(env)
File "C:\Users\Goksel\anaconda3\envs\tensor37\lib\site-packages\stable_baselines\common\env_checker.py", line 214, in check_env
_check_returned_values(env, observation_space, action_space)
File "C:\Users\Goksel\anaconda3\envs\tensor37\lib\site-packages\stable_baselines\common\env_checker.py", line 99, in _check_returned_values
_check_obs(obs, observation_space, 'reset')
File "C:\Users\Goksel\anaconda3\envs\tensor37\lib\site-packages\stable_baselines\common\env_checker.py", line 89, in _check_obs
"method does not match the given observation space".format(method_name))
AssertionError: The observation returned by the reset() method does not match the given observation space
files and codes github link for those who want it:
https://github.com/RsGoksel/PongGame-AI.git
video resources which i used:
https://www.youtube.com/watch?v=uKnjGn8fF70&t=1493s
https://www.youtube.com/watch?v=eBCU-tqLGfQ&t=3551s
https://www.youtube.com/watch?v=bD6V3rcr_54&t=934s
import gym
from gym import spaces
import pygame
import random
import numpy as np
HEIGHT = 450
WIDTH = 600
screen = pygame.display.set_mode((WIDTH,HEIGHT))
white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
blue = (50,0,200)
def updatePaddle(action, paddleY):
if action == 0:
paddleY.rect.y -= 4
if action == 1:
return
if action == 2:
paddleY.rect.y += 4
if paddleY.rect.y < 0:
paddleY.rect.y = 0
if paddleY.rect.y > HEIGHT:
paddleY.rect.y = HEIGHT
return paddleY.rect.y
class PongEnv(gym.Env):
metadata = {'render.modes': ['human']}
class paddle(pygame.sprite.Sprite):
def __init__(self,color):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([WIDTH/40,HEIGHT/4.5])
self.image.fill(color)
self.rect = self.image.get_rect()
class ball(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([WIDTH/40,WIDTH/40])
self.image.fill(red)
self.rect = self.image.get_rect()
self.Xspeed = 3
self.Yspeed = 3
def __init__(self):
super(PongEnv, self).__init__()
self.reward = 0
self.done = False
self.score = 0
self.action_space = spaces.Discrete(3)
self.observation_space = spaces.Box(low=0, high=255,
shape=(1,HEIGHT, WIDTH), dtype=np.float32)
self.pedal1 = self.paddle(blue)
self.pedal2 = self.paddle(blue)
self.BALL = self.ball()
self.all_sprites = pygame.sprite.Group()
self.all_sprites.add(self.pedal1, self.pedal2, self.BALL)
#paddle1 and paddle2(bot) location
self.pedal1.rect.x = WIDTH/50 #25
self.pedal1.rect.y = random.randint(0,HEIGHT/10)*10 #300
self.pedal2.rect.x = 23*WIDTH/24 #575
self.pedal2.rect.y = random.randint(0,HEIGHT/10)*10
#ball location. at the beginning of each round, the ball's destination flank changes
self.BALL.rect.x = WIDTH/2
self.BALL.rect.y = HEIGHT/4 + random.randint(0, int(3/4*HEIGHT))
self.BALL.Xspeed = random.sample([-self.BALL.Xspeed,self.BALL.Xspeed],1)[0]
self.BALL.Yspeed = random.sample([-self.BALL.Yspeed,self.BALL.Yspeed],1)[0]
def step(self, action):
self.BALL.rect.x += self.BALL.Xspeed
self.BALL.rect.y += self.BALL.Yspeed
self.pedal2.rect.y = self.BALL.rect.y - (WIDTH/40)
if action==0:
#self.pedal1.rect.y -+= 4
updatePaddle(0, self.pedal1)
if action==2:
updatePaddle(2, self.pedal1)
#if ball hits pedal1, score for paddle because its is exactly what we want
if self.pedal1.rect.colliderect(self.BALL.rect):
self.BALL.Xspeed *= -1
self.score += 5
self.reward = self.score
#collider with paddle2
if self.pedal2.rect.colliderect(self.BALL.rect):
self.BALL.Xspeed *= -1
#control for ball and boundries
if self.BALL.rect.y > HEIGHT - (WIDTH/40) or self.BALL.rect.y < WIDTH/200: #435 or self.top.rect.y < 3
self.BALL.Yspeed *= -1
#its negative score for agent.
if self.BALL.rect.x <= WIDTH/120: #self.pedal1.rect.x yazılabilirdi fakat const değişken ile
self.score -= 10
self.reward = self.score
done = True
self.observation = [self.pedal1.rect.x, self.pedal1.rect.y, self.BALL.rect.x, self.BALL.rect.y]
self.observation = np.array(self.observation)
info = {}
return self.observation, self.reward, self.done, info
def reset(self):
self.done = False
self.score = 0
self.pedal1.rect.x = WIDTH/50 #25
self.pedal1.rect.y = random.randint(0,HEIGHT/10)*10 #300
self.pedal2.rect.x = 23*WIDTH/24 #575
self.pedal2.rect.y = random.randint(0,HEIGHT/10)*10
self.BALL.rect.x = WIDTH/2
self.BALL.rect.y = HEIGHT/4 + random.randint(0, int(3/4*HEIGHT))
self.BALL.Xhiz = random.sample([-self.BALL.Xspeed,self.BALL.Xspeed],1)[0]
self.BALL.Yhiz = random.sample([-self.BALL.Yspeed,self.BALL.Yspeed],1)[0]
self.observation = [self.pedal1.rect.x, self.pedal1.rect.y, self.BALL.rect.x, self.BALL.rect.y]
self.observation = np.array(self.observation)
return self.observation # reward, done, info can't be included
def render(self, mode='human'):
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.init()
pygame.display.init()
while True:
pygame.time.delay(10)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.display.quit()
pygame.quit()
pygame.display.update()
self.ekran.fill(black)
self.all_sprites.draw(self.screen)
#self.step(0)
def close (self):
if self.screen is not None:
pygame.display.quit()
pygame.quit()
and other checkenv.py file:
from stable_baselines.common.env_checker import check_env
from Stable import PongEnv
env = PongEnv()
check_env(env)
error: AssertionError: The observation returned by the `reset()` method does not match the given observation space

Having trouble with a "NameError"

I'm new to classes, and this is my third attempt at making one. I've ran into a NameError which I really have no idea how to solve. Take a look at my program and see if you can help.
import random
import math
import pygame
import pickle
# initialise pygame
pygame.init()
# player class
class player(object):
def __init__(self, playerimage, playerX, playerY = 700, playerX_change = 0):
self.playerimage = pygame.image.load("Main Player.png")
self.playerX = 365
self.playerY = 700
self.playerX_change = 0
# laser class
# ready - bullet not on screen
# fire - bullet is shown on screen and is moving
class laser(object):
def __init__(self, laserimage, laserX, laserY, laserY_change):
self.laserimage = pygame.image.load("laser.png")
self.laserX = 0
self.laserY = 700
self.laserY_change = 10
self.laser_state = "ready"
# alien player / random movement = random.randint()
class alien(object):
def __init__(self, alienimage, alienX, alienY, alienX_change, alienY_change, amount_aliens):
self.alienimage = pygame.image.load("alien.png")
self.alienX = []
self.alienY = []
self.alienX_change = []
self.alienY_change = []
self.amount_aliens = 10
for i in range(ufo.amount_aliens):
ufo.alienimage.append(pygame.image.load('alien.png'))
ufo.alienX.append(random.randint(0, 735))
ufo.alienY.append(random.randint(50, 200))
ufo.alienX_change.append(3)
ufo.alienY_change.append(7)
score = 0
# define player
def main_player(x, y):
screen.blit(male.playerimage, (x, y))
# define laster
def fire_laser(x, y):
lasr.laser_state = "fire"
screen.blit(lasr.laserimage, (x + 16, y + 10))
# define alien
def alien(x, y, i):
screen.blit(ufo.alienimage[i], (x, y))
# collision detection
def hascollision(alienX, alienY, laserX, laserY):
distance = math.sqrt((math.pow(alienX - laserX, 2)) + (math.pow(alienY - laserY, 2)))
if distance < 27:
return True
else:
return False
#frames per second
clock = pygame.time.Clock()
# background
background = pygame.image.load('stars.png')
# display and screen title/icon
(width, height) = (800, 800)
screen = pygame.display.set_mode((width, height))
flip = pygame.display.flip()
pygame.display.set_caption("space fighters")
pygame.event.get()
icon = pygame.image.load('logo.png')
pygame.display.set_icon(icon)
from sys import exit
ufo = alien()
lasr = laser(0, 700, 32, 32)
male = player(365, 700,)
# loop of functions
executed = True
while executed:
screen.fill((63, 62, 63))
# image background
screen.blit(background, (0, 0))
for event in pygame.event.get():
# if key pressed, check which input, right or left?
if event.type == pygame.KEYDOWN:
print("key pressed")
if event.key == pygame.K_a:
male.playerX_change = -6
if event.key == pygame.K_s:
male.playerX_change = 6
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_s:
male.playerX_change = 0
if event.key == pygame.K_SPACE:
if lasr.laser_state is "ready":
lasr.laserX = male.playerX
fire_laser(lasr.laserX, lasr.laserY)
#frames per second is 60fps
clock.tick(60)
# bounrary algorithm, prevents player moving out/enemy.
male.playerX += male.playerX_change
if male.playerX <= 0:
male.playerX = 0
elif male.playerX >= 736:
male.playerX = 736
# boundry algorithm, make sure alien doesn't go out of bountry
for i in range(ufo.amount_aliens):
ufo.alienX[i] += ufo.alienX_change[i]
if ufo.alienX[i] <= 0:
ufo.alienX_change[i] = 4
ufo.alienY[i] += ufo.alienY_change[i]
elif ufo.alienX[i] >= 736:
ufo.alienX_change[i] = -4
ufo.alienY[i] += ufo.alienY_change[i]
# collision
collision = hascollision(ufo.alienX[i], ufo.alienY[i], lasr.laserX, lasr.laserY)
if collision:
lasr.laserY = 650
lasr.laser_state = "ready"
score += 5
print(score)
alienX[i] = random.randint(0, 735)
alienY[i] = random.randint(50, 200)
alien(ufo.alienX[i], ufo.alienY[i], i)
# movement of laser shot
if lasr.laserY <= 0:
lasr.laserY = 650
lasr.laser_state = "ready"
if lasr.laser_state is "fire":
fire_laser(lasr.laserX, lasr.laserY)
lasr.laserY -= lasr.laserY_change
# updates screen to show screen
main_player(male.playerX, male.playerY)
pygame.display.update()
pygame.quit()
This is the output of the error given by visual studio code (it is on line 39)
for i in range(ufo.amount_aliens):
NameError: name 'ufo' is not defined
The alien class is a bit mixed up. (Although it's hard to tell if this is just an indentation issue in the SO paste.) I'm going to assume that the list of ufos needs to be made outside the class, because this is the only thing that makes sense. Later on in the code, you declare an alien function which will occlude the alien class too. You will need to fix this first - it's best moved into the alien class as alien.draw()
So to make a bunch of aliens, create a list:
alien_image = pygame.image.load('alien.png')
all_ufos = []
for i in range( amount_aliens ):
x_pos = random.randint( 0, 735 )
y_pos = random.randint( 50, 200 )
x_speed = 3
y_speed = 7
all_ufos.append( alien( alien_image, x_pos, y_pos, x_speed, y_speed ) )
Remove the amount_aliens from the alien object, so that it now only represents a single alien.
class alien( object ):
def __init__( self, alienimage, alienX, alienY, alienX_change, alienY_change ):
self.alienimage = alienimage
self.alienX = alienX
self.alienY = alienY
self.alienX_change = alienX_change
self.alienY_change = alienY_change
And move the support functions into the alien class.
def draw( self, screen ):
""" Draw the alien to the screen """
screen.blit( self.alienimage, ( self.alienX, self.alienY ) )
def hasCollision( self, laserX, laserY ):
""" Has the laser at collided with this alien? """
distance = math.sqrt((math.pow(self.alienX - laserX, 2)) + (math.pow(self.alienY - laserY, 2)))
return ( distance < 27 ):
This allows your main loop to iterate over the list of aliens, doing stuff simply:
### Main Loop
while not exiting:
...
# paint all UFO sprites
for ufo in all_ufos:
ufo.draw( screen )
# check all lasers for collision
for laser in all_lasers:
for ufo in all_ufos:
if ( ufo.hasCollision( laser.laserX, laser.laserY ) ):
print( "*boom*" )
What you are doing here is re-creating some of the functionality of the PyGame Sprite and SpriteGroup Classes. It might be worth a quick read of the documentation on it.

pygame rect doesn't change position while i give it a new position and update it

okay so i'm fairly new to programming and i'm making a game based on the arcade game alien invasion. but i want to make an intro with moving text to show credits at the start because it's fun and good practice to learn. but i cant seem to make it work. i want the text to fly from the side of the screen to middle stop there then fly away again
so here is the function that draws the texts.
from Settings import *
import sys
class TextsObjects:
def __init__(self):
self.setting = Settings()
self.intro_settings = IntroSettings()
self.display_intro_1 = DisplayText(
self.intro_settings.intro_text_1,
self.intro_settings.intro_text_1_pos_x,
self.intro_settings.intro_text_1_pos_y,
self.intro_settings.font_size,
self.setting.light_grey
)
self.display_intro_2 = DisplayText(
self.intro_settings.intro_text_2,
self.intro_settings.intro_text_2_pos_x,
self.intro_settings.intro_text_2_pos_y,
self.intro_settings.font_size,
self.setting.light_grey
)
self.display_intro_title = DisplayText(
self.intro_settings.intro_text_title,
self.intro_settings.intro_text_title_pos_x,
self.intro_settings.intro_text_title_pos_y,
self.intro_settings.font_size,
self.setting.light_grey)
class Intro:
def __init__(self, screen, setting):
self.screen = screen
self.setting = setting
self.i_setting = IntroSettings()
self.intro_text = TextsObjects()
self.clock = pygame.time.Clock()
self.speed = 50 * setting.time
self.screen_c_left = setting.screen_width / 2 - self.speed / 2
self.screen_c_right = setting.screen_width / 2 + self.speed / 2
def intro_update(self):
# reset the background so you don't get multiple drawings onscreen
self.screen.fill(self.setting.dark_blueish)
if 0 <= self.i_setting.intro_text_1_pos_x <= \
self.setting.screen_width:
# Draw the first text
self.intro_text.display_intro_1.draw_me_with_shadow(
self.screen)
if self.screen_c_left < self.i_setting.intro_text_2_pos_x < \
self.screen_c_right:
# Draw the second text
self.intro_text.display_intro_2.draw_me_with_shadow(
self.screen)
pygame.display.update()
def show_intro(self):
self.i_setting.intro_text_1_pos_x += self.speed
# show the intro for self.intro_time amount of time
for frames in range(0, self.setting.fps * 3):
# test for events
for event in pygame.event.get():
print(event)
# when the window is closed stop the game loop
if event.type == pygame.QUIT:
sys.exit()
self.intro_update()
self.setting.clock.tick(self.setting.fps)
and here are the classes that are relevant:
class Settings:
def __init__(self):
# screen size
self.screen_width = 800
self.screen_height = 500
# set clock and fps
self.clock = pygame.time.Clock()
self.fps = 60
# calculate the seconds in every frame
self.time = 1 / self.fps
class IntroSettings:
def __init__(self):
self.setting = Settings()
self.font_size = 100
self.timer_font_size = 10
self.intro_text_1_pos_x = (self.setting.screen_width / 2) - 100
self.intro_text_1_pos_y = \
(self.setting.screen_height / 2 - self.font_size)
self.intro_text_1 = "A game by:"
self.intro_text_2_pos_x = (self.setting.screen_width / 2)
self.intro_text_2_pos_y = \
(self.setting.screen_height / 2 + self.font_size)
self.intro_text_2 = "Mark Olieman"
self.intro_text_title_pos_x = (self.setting.screen_width / 2)
self.intro_text_title_pos_y = (self.setting.screen_height + self.font_size)
self.intro_text_title = "Alien Invasion!"
self.intro_text_timer_pos_x = 20
self.intro_text_timer_pos_y = 20
self.speed = -2
class DisplayText:
def __init__(self, text, pos_x, pos_y, font_size, text_color):
self.font = pygame.font.Font("freesansbold.ttf", font_size)
self.text_surf = self.font.render(text, True, text_color)
self.text_rect = self.text_surf.get_rect()
self.text_rect.center = (pos_x, pos_y)
self.shadow_color = (0, 0, 0)
self.text_surf_shadow = self.font.render(text, True, self.shadow_color)
self.text_rect_shadow = self.text_surf.get_rect()
self.text_rect_shadow.center = (pos_x + 10, pos_y + 5)
def draw_me(self, screen):
screen.blit(self.text_surf, self.text_rect)
def draw_me_with_shadow(self, screen):
screen.blit(self.text_surf_shadow, self.text_rect_shadow)
screen.blit(self.text_surf, self.text_rect)
i am sorry for the amount of code but because i don't know where the problem lies i want you guys to have all the relevant information so at last here is my main game loop
import pygame
from Settings import *
from Entities import *
from Game_functions import *
from Menu import *
# make the modules available
setting = Settings()
screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))
pygame.display.set_caption("Alien Invasion, By Mark Olieman")
intro = Intro(screen, setting)
player = Player(screen, setting)
bullet = Bullet(screen, setting, player)
intro_set = IntroSettings()
# initizialize pygame
pygame.init()
pygame.mixer.init()
# initizialize the screen and set a caption
# function to start gaming
def gaming():
bullets = pygame.sprite.Group()
intro.show_intro()
intro_set.intro_text_1_pos_x += intro.speed
print(intro_set.intro_text_1_pos_x)
# Game Loop
while True:
# check events and make actions happen
events(bullets, player, screen, setting)
# update everything and draw bullets
update(player, setting, bullets, screen)
# update screen at certain fps
pygame.display.update()
setting.clock.tick(setting.fps)
# Start the game
gaming()
# Stop the game
pygame.quit()
I found two mistakes in Intro.show_intro()
you add speed before loop but you have to do it inside loop
you add speed to self.i_setting.intro_text_1_pos_x but you have to add
self.intro_text.display_intro_1.text_rect.x += self.speed
self.intro_text.display_intro_1.text_rect_shadow.x += self.speed
Correct version which moves text (and shadow) "A game by:"
def show_intro(self):
#self.i_setting.intro_text_1_pos_x += self.speed
# show the intro for self.intro_time amount of time
for frames in range(0, self.setting.fps * 3):
# test for events
for event in pygame.event.get():
print(event)
# when the window is closed stop the game loop
if event.type == pygame.QUIT:
sys.exit()
# you have to add speed inside loop
#self.i_setting.intro_text_1_pos_x += self.speed
self.intro_text.display_intro_1.text_rect.x += self.speed
self.intro_text.display_intro_1.text_rect_shadow.x += self.speed
self.intro_update()
self.setting.clock.tick(self.setting.fps)
There can be another problem - rect.x can keep only integer values but speed has value 0.83 so when you add 0.83 then it can be rounded to 1 so it may move faster then you expect - or it can move too far (or may move not so smooth as you expected). If speed will be smaller then 0.5 then it may even round it to 0 so it will not move.
You may have to keep position in separated values as float values, change them and copy to rect.x only before drawing.
Full code which I run in one file - I removed some imports and elements which I hadn't (ie, Player)
import sys
class TextsObjects:
def __init__(self):
self.setting = Settings()
self.intro_settings = IntroSettings()
self.display_intro_1 = DisplayText(
self.intro_settings.intro_text_1,
self.intro_settings.intro_text_1_pos_x,
self.intro_settings.intro_text_1_pos_y,
self.intro_settings.font_size,
self.setting.light_grey
)
self.display_intro_2 = DisplayText(
self.intro_settings.intro_text_2,
self.intro_settings.intro_text_2_pos_x,
self.intro_settings.intro_text_2_pos_y,
self.intro_settings.font_size,
self.setting.light_grey
)
self.display_intro_title = DisplayText(
self.intro_settings.intro_text_title,
self.intro_settings.intro_text_title_pos_x,
self.intro_settings.intro_text_title_pos_y,
self.intro_settings.font_size,
self.setting.light_grey)
class Intro:
def __init__(self, screen, setting):
self.screen = screen
self.setting = setting
self.i_setting = IntroSettings()
self.intro_text = TextsObjects()
self.clock = pygame.time.Clock()
self.speed = 150 * setting.time
print(self.speed)
self.screen_c_left = setting.screen_width / 2 - self.speed / 2
self.screen_c_right = setting.screen_width / 2 + self.speed / 2
def intro_update(self):
# reset the background so you don't get multiple drawings onscreen
self.screen.fill(self.setting.dark_blueish)
if 0 <= self.i_setting.intro_text_1_pos_x <= self.setting.screen_width:
# Draw the first text
self.intro_text.display_intro_1.draw_me_with_shadow(self.screen)
if self.screen_c_left < self.i_setting.intro_text_2_pos_x < self.screen_c_right:
# Draw the second text
self.intro_text.display_intro_2.draw_me_with_shadow(self.screen)
pygame.display.update()
def show_intro(self):
#self.i_setting.intro_text_1_pos_x += self.speed
# show the intro for self.intro_time amount of time
for frames in range(0, self.setting.fps * 3):
# test for events
for event in pygame.event.get():
print(event)
# when the window is closed stop the game loop
if event.type == pygame.QUIT:
sys.exit()
#self.i_setting.intro_text_1_pos_x += self.speed
self.intro_text.display_intro_1.text_rect.x += self.speed
self.intro_text.display_intro_1.text_rect_shadow.x += self.speed
self.intro_update()
self.setting.clock.tick(self.setting.fps)
class Settings:
def __init__(self):
# screen size
self.screen_width = 800
self.screen_height = 500
# set clock and fps
self.clock = pygame.time.Clock()
self.fps = 60
# calculate the seconds in every frame
self.time = 1 / self.fps
self.light_grey = (128,128,128)
self.dark_blueish = (0,0,255)
class IntroSettings:
def __init__(self):
self.setting = Settings()
self.font_size = 100
self.timer_font_size = 10
self.intro_text_1_pos_x = (self.setting.screen_width / 2) - 100
self.intro_text_1_pos_y = \
(self.setting.screen_height / 2 - self.font_size)
self.intro_text_1 = "A game by:"
self.intro_text_2_pos_x = (self.setting.screen_width / 2)
self.intro_text_2_pos_y = \
(self.setting.screen_height / 2 + self.font_size)
self.intro_text_2 = "Mark Olieman"
self.intro_text_title_pos_x = (self.setting.screen_width / 2)
self.intro_text_title_pos_y = (self.setting.screen_height + self.font_size)
self.intro_text_title = "Alien Invasion!"
self.intro_text_timer_pos_x = 20
self.intro_text_timer_pos_y = 20
self.speed = -2
class DisplayText:
def __init__(self, text, pos_x, pos_y, font_size, text_color):
self.font = pygame.font.Font("freesansbold.ttf", font_size)
self.text_surf = self.font.render(text, True, text_color)
self.text_rect = self.text_surf.get_rect()
self.text_rect.center = (pos_x, pos_y)
self.shadow_color = (0, 0, 0)
self.text_surf_shadow = self.font.render(text, True, self.shadow_color)
self.text_rect_shadow = self.text_surf.get_rect()
self.text_rect_shadow.center = (pos_x + 10, pos_y + 5)
def draw_me(self, screen):
screen.blit(self.text_surf, self.text_rect)
def draw_me_with_shadow(self, screen):
screen.blit(self.text_surf_shadow, self.text_rect_shadow)
screen.blit(self.text_surf, self.text_rect)
import pygame
#from Entities import *
#from Game_functions import *
#from Menu import *
# initizialize pygame
pygame.init()
pygame.mixer.init()
# make the modules available
setting = Settings()
screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))
pygame.display.set_caption("Alien Invasion, By Mark Olieman")
intro = Intro(screen, setting)
#player = Player(screen, setting)
#bullet = Bullet(screen, setting, player)
intro_set = IntroSettings()
# initizialize the screen and set a caption
# function to start gaming
def gaming():
bullets = pygame.sprite.Group()
intro.show_intro()
intro_set.intro_text_1_pos_x += intro.speed
print(intro_set.intro_text_1_pos_x)
# Game Loop
while True:
# check events and make actions happen
#events(bullets, player, screen, setting)
# update everything and draw bullets
#update(player, setting, bullets, screen)
# update screen at certain fps
pygame.display.update()
setting.clock.tick(setting.fps)
# Start the game
gaming()
# Stop the game
pygame.quit()

Pygame Collision Detection: AttributeError

I've been banging my head against this for a while. I am trying to make a game with PyGame and I got up to the collision segment and have been stuck for a while and have checked a few threads.
This is the code I have (removed other methods and conditional statements in between, but left the relevant parts). I am a little confused by the error because I do a self.imageRect = self.image.get_rect() in both classes init, yet I have this error. The error was specifically:
"AttributeError: 'Pebble' object has no attribute 'rect'" when the program attempts to carry out the collision detection part in the dog class. What have I been doing wrong?
import random
import pygame, sys
pygame.init()
clock = pygame.time.Clock() # fps clock
screenSize = WIDTH, HEIGHT = [800, 600]
screen = pygame.display.set_mode(screenSize)
background = pygame.Surface(screen.get_size())
bgColorRGB = [153, 204, 255]
background.fill(bgColorRGB)
pebbleGroup = pygame.sprite.Group()
pebbleSingle = pygame.sprite.GroupSingle()
dogSingle = pygame.sprite.GroupSingle()
#----------------------------------------------------------------------
class Dog(pygame.sprite.Sprite):
def __init__(self, path, speed):
pygame.sprite.Sprite.__init__(self) #call Sprite initializer
self.image = pygame.image.load(path) # load sprite from path/file loc.
self.imageRect = self.image.get_rect() # get bounds of image
self.imageWidth = self.image.get_width()
self.imageHeight = self.image.get_height()
self.speed = speed
# sets location of the image, gets the start location of object
# sets the start location as the image's left and top location
def setLocation(self, location):
self.imageRect.left, self.imageRect.top = location
def checkCollision(self, pebble, dogGroup):
if pygame.sprite.spritecollide(pebble, dogGroup, False):
print "collided"
#---------------------------------------------------------------------
class Pebble(pygame.sprite.Sprite):
def __init__(self, path, speed, location):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(path)
self.imageRect = self.image.get_rect()
self.imageWidth = self.image.get_width()
self.imageHeight = self.image.get_height()
self.imageRect.left, self.imageRect.top = location
self.speed = speed # initialize speed
self.isDragged = False
#----------------------------------------------------------------------
def startGame():
pebblePaths = ['images/pebble/pebble1.jpg', 'images/pebble/pebble2.jpg']
for i in range(3):
pebblePath = pebblePaths[random.randrange(0, len(pebblePaths))]
pebbleSpeed = [random.randrange(1, 7), 0]
pebbleLocation = [0, random.randrange(20, HEIGHT - 75)]
pebble = Pebble(pebblePath, pebbleSpeed, pebbleLocation)
pebbleGroup.add(pebble)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for pebble in pebbleGroup:
dog.checkCollision(pebble, dogSingle)
pygame.display.flip()
clock.tick(30) # wait a little before starting again
startGame()
It's expecting Sprite.rect, so change from
self.imageRect = self.image.get_rect()
#to
self.rect = self.image.get_rect()
Note
self.imageWidth = self.image.get_width()
self.imageHeight = self.image.get_height()
self.imageRect.left, self.imageRect.top = location
These are not necessary, since rect's have many properties, like self.rect.width or self.rect.topleft = location . Another useful one is centerx.
full list at: pygame Rect docs

Categories

Resources