Image Smudging, Lack of transparency, Right & Down movement not working [duplicate] - python

This question already has answers here:
how to make image/images disappear in pygame?
(1 answer)
How do I delete rect object from screen once player collides with it?
(1 answer)
Closed 23 days ago.
I am new at using objects in python and brand new at Pygame. I am trying to make a game where a player moves around the screen eating objects. However, I am unable to get the consumed objects to disappear, the moving object is smudging and not transparent. The Downward and Rightward movement keys also produce no result.
This is the code for the movement:
def move(self):
if self.dir != '':
if self.dir == 'd' and self.rect.bottom < self.height:
self.rect.top += self.speed
if self.dir == 'u' and self.rect.top > 0:
self.rect.top -= self.speed
if self.dir == 'l' and self.rect.left > 0:
self.rect.left -= self.speed
if self.dir == 'r' and self.rect.right < self.width:
self.rect.right += self.speed
the code for image transparency:
self.surface = pygame.image.load("images/player.png").convert_alpha()
This is how I am drawing the player and the consumable:
def draw(self):
self.screen.blit(self.surface, self.rect)
and the main update code that is inside the game loop:
def update(self):
for f in self.foods[:]:
if self.player.rect.colliderect(f.rect):
self.foods.remove(f)
self.foods.append(Consumable(
self.screen, WIDTH*random.randint(1, 9)//10, HEIGHT*random.randint(1, 9)//10))
self.eaten += 1
for f in self.foods:
f.draw()
if self.eaten == 10:
self.won = True
self.player.move()
self.player.draw()
pygame.display.update()
pygame.display.flip()
This is the full game code:
import pygame
import random
import time
from pygame.locals import *
pwidth = 250
pheight = 250
class Consumable(pygame.sprite.Sprite):
def __init__(self, screen, centerx, centery):
super(Consumable, self).__init__()
self.surface = pygame.image.load("images/food.jpeg")
self.rect = self.surface.get_rect()
self.rect.centerx = centerx
self.rect.centery = centery
self.screen = screen
def draw(self):
self.screen.blit(self.surface, self.rect)
class player(pygame.sprite.Sprite):
def __init__(self, screen, centerx, centery):
super(player, self).__init__()
self.surface = pygame.image.load("images/player.png").convert_alpha()
self.screen = screen
self.speed = 10
self.dir = ''
self.rect = self.surface.get_rect()
self.rect.centerx = centerx
self.rect.centery = centery
self.width = self.rect.width
self.height = self.rect.height
def draw(self):
self.screen.blit(self.surface, self.rect)
def move(self):
if self.dir != '':
if self.dir == 'd' and self.rect.bottom < self.height:
self.rect.top += self.speed
if self.dir == 'u' and self.rect.top > 0:
self.rect.top -= self.speed
if self.dir == 'l' and self.rect.left > 0:
self.rect.left -= self.speed
if self.dir == 'r' and self.rect.right < self.width:
self.rect.right += self.speed
class Game:
def __init__(self, screen):
self.screen = screen
self.screen.fill((0, 0, 0))
self.icon = pygame.image.load("images/icon.jpeg")
pygame.display.set_icon(self.icon)
self.foods = []
self.eaten = 0
for i in range(4):
self.foods.append(Borgar(
self.screen, WIDTH*random.randint(1, 9)//10, HEIGHT*random.randint(1, 9)//10))
for f in self.foods:
f.draw()
self.player = player(screen, WIDTH//2, HEIGHT//2)
self.mainclock = pygame.time.Clock()
self.start_time = time.perf_counter()
self.end_time = -1
self.won = False
def update(self):
pickedUp = False
for f in self.foods[:]:
if self.player.rect.colliderect(f.rect):
self.foods.remove(f)
self.foods.append(Borgar(
self.screen, WIDTH*random.randint(1, 9)//10, HEIGHT*random.randint(1, 9)//10))
pickedUp = True
self.eaten += 1
print(self.eaten)
for f in self.foods:
f.draw()
if self.eaten == 10:
self.won = True
self.end_time = time.perf_counter()
print("You won")
print("time taken: {:.2f}".format(self.end_time-self.start_time))
self.player.move()
self.player.draw()
pygame.display.update()
pygame.display.flip()
def _handle_events(self):
for event in pygame.event.get():
if event.type == QUIT:
raise SystemExit
if event.type == KEYDOWN:
if event.key == K_BACKSPACE or event.key == K_ESCAPE or event.key == ord('q'):
raise SystemExit
if event.key == K_LEFT or event.key == ord('a'):
self.player.dir = 'l'
if event.key == K_RIGHT or event.key == ord('d'):
self.player.dir = 'r'
if event.key == K_UP or event.key == ord('w'):
self.player.dir = 'u'
if event.key == K_DOWN or event.key == ord('s'):
self.player.dir = 'd'
if event.type == KEYUP:
# End repetition.
if event.key == K_LEFT or event.key == ord('a'):
self.player.dir = ''
if event.key == K_RIGHT or event.key == ord('d'):
self.player.dir = ''
if event.key == K_UP or event.key == ord('w'):
self.player.dir = ''
if event.key == K_DOWN or event.key == ord('s'):
self.player.dir = ''
def run(self):
while True:
self.mainclock.tick(60)
self._handle_events()
self.update()
if self.won:
raise SystemExit
pygame.display.flip()
pygame.init()
display = pygame.display.set_mode((800, 600), pygame.RESIZABLE)
WIDTH, HEIGHT = pygame.display.get_window_size()
pygame.display.set_caption("Game")
game = Game(display)
game.run()
Here is what happens when I run the game:
game screenshot
I would really appreciate any help possible.

Related

How to adjust the direction of movement of bullet sprites?

In my program, when the keys are pressed, the image of the ship is flipped. I decided to bind the direction of the bullets to the flags of the ship's position. But I ran into the problem that all bullets take the direction of the ship when they are already fired. I need to keep the coordinate of the sprite when it is drawn.
import sys
import pygame
from settings import Settings
from rocket import Rocket
from bullet import Bullet
class Cosmos:
"""Главный класс игры Cosmos"""
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
pygame.display.set_caption('Cosmos')
self.fon_image = pygame.image.load('image/Fon.png')
self.fon = self.fon_image.get_rect()
self.settings = Settings()
self.rocket = Rocket(self.screen, self.settings)
self.bullets = pygame.sprite.Group()
def key_event(self):
"""Обрабатывает нажатие клавиш"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
sys.exit()
elif event.key == pygame.K_d:
self.rocket.move_RIGHT = True
elif event.key == pygame.K_a:
self.rocket.move_LEFT = True
elif event.key == pygame.K_w:
self.rocket.move_UP = True
elif event.key == pygame.K_s:
self.rocket.move_DOWN = True
elif event.key == pygame.K_SPACE:
self.fire_bullet()
elif event.type == pygame.KEYUP:
if event.key == pygame.K_d:
self.rocket.move_RIGHT = False
elif event.key == pygame.K_a:
self.rocket.move_LEFT = False
elif event.key == pygame.K_w:
self.rocket.move_UP = False
elif event.key == pygame.K_s:
self.rocket.move_DOWN = False
def fire_bullet(self):
"""Создание нового снаряда и включение его в группу"""
new_bullet = Bullet(self.screen, self.settings, self.rocket)
self.bullets.add(new_bullet)
def run_game(self):
"""Обновляет события игры"""
while True:
self.screen.blit(self.fon_image, self.fon)
self.key_event()
self.rocket.update_rocket()
for bullet in self.bullets.sprites():
bullet.draw_bullet()
self.bullets.update(bullet)
self.rocket.draw_rocket()
pygame.display.flip()
game = Cosmos()
game.run_game()
from pygame.sprite import Sprite
class Bullet(Sprite):
"""Класс для управления снарядами, выпущенными кораблем"""
def __init__(self, screen, settings, rocket):
super().__init__()
self.screen = screen
self.settings = settings
self.rocket = rocket
self.color = self.settings.bullets_color
self.rect = pygame.Rect(0, 0, self.settings.bullets_width, self.settings.bullets_height)
self.rect.midtop = rocket.rect.midtop
self.y = float(self.rect.y)
self.x = float(self.rect.x)
def update(self, bullet):
"""Перемещение снаряда"""
if self.rocket.image == self.rocket.image_right:
bullet.x += 2
if self.rocket.image == self.rocket.image_left:
bullet.x -= 2
if self.rocket.image == self.rocket.image_up:
bullet.y -= 2
if self.rocket.image == self.rocket.image_down:
bullet.y += 2
self.rect.x = self.x
self.rect.y = self.y
def draw_bullet(self):
"""Рисует снаряд"""
pygame.draw.rect(self.screen, self.color, self.rect)
import pygame
class Rocket:
"""Класс для управления кораблём"""
def __init__(self, screen, settings):
self.screen = screen
self.screen_rect = screen.get_rect()
self.settings = settings
self.image = pygame.image.load('image/pixil-frame-0.png')
self.rect = self.image.get_rect()
self.rect.center = self.screen_rect.center
self.x = float(self.rect.x)
self.y = float(self.rect.y)
self.move_RIGHT = False
self.move_LEFT = False
self.move_UP = False
self.move_DOWN = False
self.image_right = pygame.transform.rotate(self.image, -90)
self.image_left = pygame.transform.rotate(self.image, 90)
self.image_up = pygame.transform.rotate(self.image, 0)
self.image_down = pygame.transform.rotate(self.image, 180)
def update_rocket(self):
"""Флаги управления кораблём"""
if self.move_RIGHT and self.rect.right < self.screen_rect.right:
self.image = self.image_right
self.x += self.settings.rocket_speed
if self.move_LEFT and self.rect.left > self.screen_rect.left:
self.image = self.image_left
self.x -= self.settings.rocket_speed
if self.move_UP and self.rect.top > self.screen_rect.top:
self.image = self.image_up
self.y -= self.settings.rocket_speed
if self.move_DOWN and self.rect.bottom < self.screen_rect.bottom:
self.image = self.image_down
self.y += self.settings.rocket_speed
self.rect.x = self.x
self.rect.y = self.y
def draw_rocket(self):
"""Обновляет позицию корабля"""
self.screen.blit(self.image, self.rect)
The problem here is that in Bullet.update, you use the current image of the rocket to determine in which direction the bullet is going. This means that any change of this image results in a change of direction. Instead of doing this, you should save the current direction upon creating a new Bullet instance and then use this saved direction to determine the direction of the rocket.
A possible implementation:
class Bullet(Sprite):
"""Класс для управления снарядами, выпущенными кораблем"""
def __init__(self, screen, settings, rocket):
super().__init__()
self.screen = screen
self.settings = settings
self.rocket = rocket
self.color = self.settings.bullets_color
self.rect = pygame.Rect(0, 0, self.settings.bullets_width, self.settings.bullets_height)
self.rect.midtop = rocket.rect.midtop
self.y = float(self.rect.y)
self.x = float(self.rect.x)
if self.rocket.image == self.rocket.image_right:
self.direction = "right"
elif self.rocket.image == self.rocket.image_left:
self.direction = "left"
elif self.rocket.image == self.rocket.image_up:
self.direction = "up"
elif self.rocket.image == self.rocket.image_down:
self.direction = "down"
def update(self, bullet):
"""Перемещение снаряда"""
if self.direction == "right":
bullet.x += 2
if self.direction == "left":
bullet.x -= 2
if self.direction == "up":
bullet.y -= 2
if self.direction == "down":
bullet.y += 2
self.rect.x = self.x
self.rect.y = self.y
def draw_bullet(self):
"""Рисует снаряд"""
pygame.draw.rect(self.screen, self.color, self.rect)

I need to be able to pause the whole game, but only my car sprite pauses when I press the p key on my keyboard

I implemented a pause feature in my game in the while loop at the end of my code, but the problem is that only my car sprite pauses. I have tried a bunch of different ways setting up my pause code but none of the ways I arrange it seems to pause the whole game.
I want to be able to pause my whole game when I press the p key on my keyboard, not just my car sprite. Can someone please tell me how I can fix this code? The code that will pause the whole game will be nice. Please, the rearranged code that will pause the whole game will help. Also I don't just want the answer, I want a quick explanation of why only my car sprite would pause instead of the whole game.
My code:
import random
import pygame
import pygame.freetype
pygame.init()
#screen settings
WIDTH = 1000
HEIGHT = 400
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("AutoPilot")
screen.fill((255, 255, 255))
#fps
FPS = 120
clock = pygame.time.Clock()
#load images
bg = pygame.image.load('background/street.png').convert_alpha() # background
bullets = pygame.image.load('car/bullet.png').convert_alpha()
debris_img = pygame.image.load('debris/cement.png')
#define game variables
shoot = False
#player class
class Player(pygame.sprite.Sprite):
def __init__(self, scale, speed):
pygame.sprite.Sprite.__init__(self)
self.bullet = pygame.image.load('car/bullet.png').convert_alpha()
self.bullet_list = []
self.speed = speed
#self.x = x
#self.y = y
self.moving = True
self.frame = 0
self.flip = False
self.direction = 0
self.score = 0
#load car
self.images = []
img = pygame.image.load('car/car.png').convert_alpha()
img = pygame.transform.scale(img, (int(img.get_width()) * scale, (int(img.get_height()) * scale)))
self.images.append(img)
self.image = self.images[0]
self.rect = self.image.get_rect()
self.update_time = pygame.time.get_ticks()
self.movingLeft = False
self.movingRight = False
self.rect.x = 465
self.rect.y = 325
#draw car to screen
def draw(self):
screen.blit(self.image, (self.rect.centerx, self.rect.centery))
#move car
def move(self):
#reset the movement variables
dx = 0
dy = 0
#moving variables
if self.movingLeft and self.rect.x > 33:
dx -= self.speed
self.flip = True
self.direction = -1
if self.movingRight and self.rect.x < 900:
dx += self.speed
self.flip = False
self.direction = 1
#update rectangle position
self.rect.x += dx
self.rect.y += dy
#shoot
def shoot(self):
bullet = Bullet(self.rect.centerx + 18, self.rect.y + 30, self.direction)
bullet_group.add(bullet)
#check collision
def collision(self, debris_group):
for debris in debris_group:
if debris.health > 0 and pygame.sprite.spritecollide(debris, bullet_group, True):
debris.health -= 1
if debris.health <= 0:
self.score += 1
#player stats/score
def stats(self):
myfont = pygame.font.SysFont('comicsans', 30)
scoretext = myfont.render("Score: " + str(self.score), 1, (0,0,0))
screen.blit(scoretext, (100,10))
#bullet class
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, direction):
pygame.sprite.Sprite.__init__(self)
self.speed = 5
self.image = bullets
self.rect = self.image.get_rect()
self.rect.center = (x,y)
self.direction = direction
def update(self):
self.rect.centery -= self.speed
#check if bullet has gone off screen
if self.rect.centery < 1:
self.kill()
#debris class
class Debris(pygame.sprite.Sprite):
def __init__(self,scale,speed):
pygame.sprite.Sprite.__init__(self)
self.scale = scale
self.x = random.randrange(100,800)
self.speed_y = 10
self.y = 15
self.speed = speed
self.vy = 0
self.on_ground = True
self.move = True
self.health = 4
self.max_health = self.health
self.alive = True
self.velocity = random.randrange(1,2)
self.speed_x = random.randrange(-3,3)
self.moving_down = True
self.is_destroyed = False
#load debris
self.image = debris_img
self.rect = self.image.get_rect()
self.rect.x = random.randrange(100, 800)
self.rect.y = random.randrange(-150, -100)
self.rect.center = (self.x,self.y)
#load explosion
self.img_explosion_00 = pygame.image.load('explosion/0.png').convert_alpha()
self.img_explosion_00 = pygame.transform.scale(self.img_explosion_00, (self.img_explosion_00.get_width() * 2,
self.img_explosion_00.get_height() * 2))
self.img_explosion_01 = pygame.image.load('explosion/1.png').convert_alpha()
self.img_explosion_01 = pygame.transform.scale(self.img_explosion_01, (self.img_explosion_01.get_width() * 2,
self.img_explosion_01.get_height() * 2))
self.img_explosion_02 = pygame.image.load('explosion/2.png').convert_alpha()
self.img_explosion_02 = pygame.transform.scale(self.img_explosion_02, (self.img_explosion_02.get_width() * 2,
self.img_explosion_02.get_height() * 2))
self.img_explosion_03 = pygame.image.load('explosion/3.png').convert_alpha()
self.img_explosion_03 = pygame.transform.scale(self.img_explosion_03, (self.img_explosion_03.get_width() * 2,
self.img_explosion_03.get_height() * 2))
#explosion list
self.anim_explosion = [self.img_explosion_00,
self.img_explosion_01,
self.img_explosion_02,
self.img_explosion_03]
self.anim_index = 0
self.frame_len = 20 #frames before explosion animation disappears
#spawn new debris
def spawn_new_debris(self):
self.rect.x = random.randrange(100, 800)
self.rect.y = random.randrange(-150, -100)
self.velocity = random.randrange(1, 2)
self.speed_x = random.randrange(-3, 3)
#respawn debris when they go of the screen
def boundaries(self):
if self.rect.left > WIDTH + 10 or self.rect.right < -10 or self.rect.top > HEIGHT + 10:
self.spawn_new_debris()
#update image
def update(self):
self.rect.y += self.velocity
self.rect.x += self.speed_x
self.boundaries()
if self.health <= 0:
max_index = len(self.anim_explosion) - 1
if self.anim_index > max_index:
self.kill()
else:
if self.frame_len == 0:
self.image = self.anim_explosion[self.anim_index]
self.anim_index += 1
self.frame_len = 20
else:
self.frame_len -= 1
#make debris fall down
def falldown(self):
self.rect.centery += self.velocity
if self.moving_down and self.rect.y > 350:
self.kill()
######################CAR/DEBRIS##########################
player = Player(1,5)
##########################################################
#groups
bullet_group = pygame.sprite.Group()
debris_group = pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
for x in range(100):
d = Debris(1, 5)
debris_group.add(d)
all_sprites.add(d)
#game runs here
run = True
paused = False
while run:
#draw street
screen.blit(bg, [0, 0])
#update groups
bullet_group.update()
bullet_group.draw(screen)
debris_group.update()
debris_group.draw(screen)
#draw car
player.draw()
player.move()
player.collision(debris_group)
player.stats()
#update all sprites
all_sprites.update()
all_sprites.draw(screen)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#pause game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused = not paused
if paused == True:
continue
#check if key is down
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if event.key == pygame.K_a:
player.movingLeft = True
if event.key == pygame.K_d:
player.movingRight = True
if event.key == pygame.K_SPACE:
player.shoot()
shoot = True
#check if key is up
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
player.movingLeft = False
if event.key == pygame.K_d:
player.movingRight = False
#update the display
pygame.display.update()
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
Move your
for event in pygame.event.get():
right below the while loop, and move your
if paused:
continue
below the for loop, like so:
run = True
paused = False
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#pause game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused = not paused
#check if key is down
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if event.key == pygame.K_a:
player.movingLeft = True
if event.key == pygame.K_d:
player.movingRight = True
if event.key == pygame.K_SPACE:
player.shoot()
shoot = True
#check if key is up
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
player.movingLeft = False
if event.key == pygame.K_d:
player.movingRight = False
if paused:
continue
#draw street
screen.blit(bg, [0, 0])
#update groups
bullet_group.update()
bullet_group.draw(screen)
debris_group.update()
debris_group.draw(screen)
#draw car
player.draw()
player.move()
player.collision(debris_group)
player.stats()
#update all sprites
all_sprites.update()
all_sprites.draw(screen)
#update the display
pygame.display.update()
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
The reason only your car sprite paused when you pressed the q key is because, as you can see in your original code here:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#pause game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused = not paused
if paused == True:
continue
you put the
if paused == True:
continue
inside the for loop, not the while loop, so the lines that move the car would be blocked, but the rest of the code within the while loop will still get executed.

How do you move a sprite up and down?

I've been at it for a while, and I cannot seem to figure out why my sprite is not moving up or down when the program is run.
Player Sprite Class
def __init__(self,name,x,y):
pygame.sprite.Sprite.__init__(self)
self.name = str(name)
self.speed = 5
self.image = pygame.image.load(name+'.png').convert_alpha()
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def move_up(self):
self.rect.y -= self.speed
def move_down(self):
self.rect.y += self.speed
def move_left(self):
self.rect.x -= self.speed
def move_right(self):
self.rect.x += self.speed
def update(self):
self.screen.blit(self.image,(self.rect))
Main File / Loop
class Console:
def __init__(self,width,height):
pygame.init()
self.w = width
self.h = height
self.clock = pygame.time.Clock()
self.screen = pygame.display.set_mode((self.w,self.h))
self.screenName = pygame.display.set_caption("Star's Labyrinth")
class Background(pygame.sprite.Sprite):
def __init__(self,image_file,x,y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
def main():
gameExit = False
game_display = Console(1024,576)
game_display.screen
starboy = Player("starboy",200,200)
background = Background("background.png",0,0)
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
starboy.move_left()
elif event.key == pygame.K_d:
starboy.move_right()
elif event.type == pygame.K_w:
starboy.move_up()
elif event.type == pygame.K_s:
starboy.move_down()
print(pygame.event.get())
game_display.screen.blit(background.image,background.rect)
starboy.update
game_display.screen.blit(starboy.image,(starboy.rect.x,starboy.rect.y))
pygame.display.update()
game_display.clock.tick(30)
I have tried different types of commands trying to figure out whether it's a variable or function problem. Also is there a way I can make it move without having to tap the key.
In the event loop you're checking if the event.type is pygame.K_w or pygame.K_s, but you have to check if the event.key is equal to these constants. Change
elif event.type == pygame.K_w:
starboy.move_up()
elif event.type == pygame.K_s:
starboy.move_down()
to:
elif event.key == pygame.K_w:
starboy.move_up()
elif event.key == pygame.K_s:
starboy.move_down()
You also forgot the parentheses behind starboy.update.

Animation using PyGame, Pyganim and classes [duplicate]

This question already has answers here:
Why is my PyGame application not running at all?
(2 answers)
Why is nothing drawn in PyGame at all?
(2 answers)
How to run multiple while loops at a time in Pygame
(1 answer)
Pygame window freezes when it opens
(1 answer)
Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?
(1 answer)
Closed 2 years ago.
so my issue is with my player class, I'm still trying to understand classes.
So, basically, I'm using this player movement code from one of Pyganim's examples but I can't seem to implement it into this player class of mine, probably because I don't really understand classes.
For starters. My player never gets displayed now, every thing worked before I tried to add classes. I've probably just over complicated things trying to use this movement. My code is:
import pygame, sys, random, pyganim
from pygame.locals import *
class Scene(object):
screen = pygame.display.set_mode((800, 600))
class Intro(Scene):
def __init__(self):
self.c = (32, 32, 100)
def draw(self):
Scene.screen.fill(self.c)
def update(self):
# since scenes are classes, they have a state that we can modify
r,g,b = self.c
r += 1
g += 1
b += 2
if r > 255: r = 0
if g > 255: g = 0
if b > 255: b = 0
self.c = r, g, b
def handle(self, event):
# move to Menu-scene when space is pressed
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
# returning a scene from handle or update changes the current scene
return Menu()
class Menu(Scene):
def draw(self):
# draw menu
Scene.screen.fill((200, 200, 100))
def update(self):
pass
# do something
def handle(self, event):
# handle menu input
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
return Game()
if event.key == pygame.K_b:
return Intro()
class Game(Scene):
def draw(self):
Scene.screen.fill((0,0,0))
bg = pygame.image.load('C:\\Users\\PAx\\Desktop\\stuff\\fort.png')
Scene.screen.blit(pygame.transform.scale(bg,(400,300)),(0,0))
def update(self):
pass
def handle(self, event):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
return meun()
class Player(pygame.sprite.Sprite):
def __init__(self):
self.UP = 'up'
self.DOWN = 'down'
self.LEFT = 'left'
self.RIGHT = 'right'
self.direction = DOWN # player starts off facing down (front)
# load the "standing" sprites (these are single images, not animations)
self.playerWidth, playerHeight = front_standing.get_size()
# creating the PygAnimation objects for walking/running in all directions
self.animTypes = 'back_run back_walk front_run front_walk left_run left_walk'.split()
self.animObjs = {}
for animType in animTypes:
self.imagesAndDurations = [('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_%s.%s.gif' % (animType, str(num).rjust(3, '0')), 1) for num in range(6)]
self.animObjs[animType] = pyganim.PygAnimation(imagesAndDurations)
# create the right-facing sprites by copying and flipping the left-facing sprites
self.animObjs['right_walk'] = animObjs['left_walk'].getCopy()
self.animObjs['right_walk'].flip(True, False)
self.animObjs['right_walk'].makeTransformsPermanent()
self.animObjs['right_run'] = animObjs['left_run'].getCopy()
self.animObjs['right_run'].flip(True, False)
self.animObjs['right_run'].makeTransformsPermanent()
# have the animation objects managed by a conductor.
# With the conductor, we can call play() and stop() on all the animtion
# objects at the same time, so that way they'll always be in sync with each
# other.
self.moveConductor = pyganim.PygConductor(animObjs)
self.x = 100
self.y = 100
self.WALKRATE = 10
self.RUNRATE = 18
self.pygame.sprite.Sprite.__init__(self) #init the Pygame sprite
#load all images
#load the player image
self.front_standing = pygame.image.load('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_front.gif')
self.back_standing = pygame.image.load('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_back.gif')
self.left_standing = pygame.image.load('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_left.gif')
self.right_standing = pygame.transform.flip(left_standing, True, False)
self.running = moveUp = moveDown = moveLeft = moveRight = False
def update(self):
for event in pygame.event.get():
if event.key == KEYDOWN:
if event.key in (K_LSHIFT, K_RSHIFT):
# player has started running
running = True
if event.key == K_UP:
moveUp = True
moveDown = False
if not moveLeft and not moveRight:
# only change the direction to up if the player wasn't moving left/right
direction = UP
elif event.key == K_DOWN:
moveDown = True
moveUp = False
if not moveLeft and not moveRight:
direction = DOWN
elif event.key == K_LEFT:
moveLeft = True
moveRight = False
if not moveUp and not moveDown:
direction = LEFT
elif event.key == K_RIGHT:
moveRight = True
moveLeft = False
if not moveUp and not moveDown:
direction = RIGHT
elif event.type == KEYUP:
if event.key in (K_LSHIFT, K_RSHIFT):
# player has stopped running
running = False
if event.key == K_UP:
moveUp = False
# if the player was moving in a sideways direction before, change the direction the player is facing.
if moveLeft:
direction = LEFT
if moveRight:
direction = RIGHT
elif event.key == K_DOWN:
moveDown = False
if moveLeft:
direction = LEFT
if moveRight:
direction = RIGHT
elif event.key == K_LEFT:
moveLeft = False
if moveUp:
direction = UP
if moveDown:
direction = DOWN
elif event.key == K_RIGHT:
moveRight = False
if moveUp:
direction = UP
if moveDown:
direction = DOWN
if moveUp or moveDown or moveLeft or moveRight:
# draw the correct walking/running sprite from the animation object
moveConductor.play() # calling play() while the animation objects are already playing is okay; in that case play() is a no-op
if running:
if direction == UP:
animObjs['back_run'].blit(screen, (x, y))
elif direction == DOWN:
animObjs['front_run'].blit(screen, (x, y))
elif direction == LEFT:
animObjs['left_run'].blit(screen, (x, y))
elif direction == RIGHT:
animObjs['right_run'].blit(screen, (x, y))
else:
# walking
if direction == UP:
animObjs['back_walk'].blit(screen, (x, y))
elif direction == DOWN:
animObjs['front_walk'].blit(screen, (x, y))
elif direction == LEFT:
animObjs['left_walk'].blit(screen, (x, y))
elif direction == RIGHT:
animObjs['right_walk'].blit(screen, (x, y))
# actually move the position of the player
if running:
rate = RUNRATE
else:
rate = WALKRATE
if moveUp:
y -= rate
if moveDown:
y += rate
if moveLeft:
x -= rate
if moveRight:
x += rate
else:
# standing still
moveConductor.stop() # calling stop() while the animation objects are already stopped is okay; in that case stop() is a no-op
if direction == UP:
Scene.screen.blit(back_standing, ((x, y)))
elif direction == DOWN:
Scene.screen.blit(front_standing, ((x, y)))
elif direction == LEFT:
screen.blit(left_standing, ((x, y)))
elif direction == RIGHT:
screen.blit(right_standing, (x, y))
# make sure the player does move off the screen
if x < 0:
x = 0
if x > WINDOWWIDTH - playerWidth:
x = WINDOWWIDTH - playerWidth
if y < 0:
y = 0
if y > WINDOWHEIGHT - playerHeight:
y = WINDOWHEIGHT - playerHeight
pygame.init()
clock = pygame.time.Clock()
Scene.screen = pygame.display.set_mode((800, 600))
scene = Intro()
while True:
if pygame.event.get(pygame.QUIT): break
for e in pygame.event.get():
scene = scene.handle(e) or scene
scene = scene.update() or scene
scene.draw()
Player.update(scene)
pygame.display.flip()
clock.tick(20)
This is the new and working code.
I changed handle and update and added a lot of self where needed. Wasn't sure how to add in draw() this could probably be cleaned up and written better but at least it works.
import pygame, sys, random, pyganim
from pygame.locals import *
class Scene(object):
screen = pygame.display.set_mode((800, 600))
class Intro(Scene):
def __init__(self):
self.c = (32, 32, 100)
def draw(self):
Scene.screen.fill(self.c)
def update(self):
# since scenes are classes, they have a state that we can modify
r,g,b = self.c
r += 1
g += 1
b += 2
if r > 255: r = 0
if g > 255: g = 0
if b > 255: b = 0
self.c = r, g, b
def handle(self, event):
# move to Menu-scene when space is pressed
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
# returning a scene from handle or update changes the current scene
return Menu()
class Menu(Scene):
def draw(self):
# draw menu
Scene.screen.fill((200, 200, 100))
def update(self):
pass
# do something
def handle(self, event):
# handle menu input
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
return Game()
if event.key == pygame.K_b:
return Intro()
class Game(Scene):
def draw(self):
Scene.screen.fill((0,0,0))
bg = pygame.image.load('C:\\Users\\PAx\\Desktop\\stuff\\fort.png')
Scene.screen.blit(pygame.transform.scale(bg,(400,300)),(0,0))
def update(self):
pass
def handle(self, event):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
return Menu()
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.UP = 'up'
self.DOWN = 'down'
self.LEFT = 'left'
self.RIGHT = 'right'
self.front_standing = pygame.image.load('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_front.gif')
self.back_standing = pygame.image.load('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_back.gif')
self.left_standing = pygame.image.load('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_left.gif')
self.right_standing = pygame.transform.flip(self.left_standing, True, False)
self.running = self.moveUp = self.moveDown = self.moveLeft = self.moveRight = False
self.direction = self.DOWN # player starts off facing down (front)
# load the "standing" sprites (these are single images, not animations)
self.playerWidth, self.playerHeight = self.front_standing.get_size()
# creating the PygAnimation objects for walking/running in all directions
self.animTypes = 'back_run back_walk front_run front_walk left_run left_walk'.split()
self.animObjs = {}
for self.animType in self.animTypes:
self.imagesAndDurations = [('C:\\Users\PAx\\Desktop\\stuff\\gameimages\\crono_%s.%s.gif' % (self.animType, str(num).rjust(3, '0')), 1) for num in range(6)]
self.animObjs[self.animType] = pyganim.PygAnimation(self.imagesAndDurations)
# create the right-facing sprites by copying and flipping the left-facing sprites
self.animObjs['right_walk'] = self.animObjs['left_walk'].getCopy()
self.animObjs['right_walk'].flip(True, False)
self.animObjs['right_walk'].makeTransformsPermanent()
self.animObjs['right_run'] = self.animObjs['left_run'].getCopy()
self.animObjs['right_run'].flip(True, False)
self.animObjs['right_run'].makeTransformsPermanent()
# have the animation objects managed by a conductor.
# With the conductor, we can call play() and stop() on all the animtion
# objects at the same time, so that way they'll always be in sync with each
# other.
self.moveConductor = pyganim.PygConductor(self.animObjs)
self.x = 100
self.y = 100
self.WALKRATE = 10
self.RUNRATE = 18
self.WINDOWWIDTH = 640
self.WINDOWHEIGHT = 480
#load all images
#load the player image
def update(self, scene):
if self.moveUp or self.moveDown or self.moveLeft or self.moveRight:
# draw the correct walking/running sprite from the animation object
self.moveConductor.play() # calling play() while the animation objects are already playing is okay; in that case play() is a no-op
if self.running:
if self.direction == self.UP:
self.animObjs['back_run'].blit(Scene.screen, (self.x, self.y))
elif self.direction == self.DOWN:
self.animObjs['front_run'].blit(Scene.screen, (self.x, self.y))
elif self.direction == self.LEFT:
self.animObjs['left_run'].blit(Scene.screen, (self.x, self.y))
elif self.direction == self.RIGHT:
self.animObjs['right_run'].blit(Scene.screen, (self.x, self.y))
else:
# walking
if self.direction == self.UP:
self.animObjs['back_walk'].blit(Scene.screen, (self.x, self.y))
elif self.direction == self.DOWN:
self.animObjs['front_walk'].blit(Scene.screen, (self.x, self.y))
elif self.direction == self.LEFT:
self.animObjs['left_walk'].blit(Scene.screen, (self.x, self.y))
elif self.direction == self.RIGHT:
self.animObjs['right_walk'].blit(Scene.screen, (self.x, self.y))
# actually move the position of the player
if self.running:
rate = self.RUNRATE
else:
rate = self.WALKRATE
if self.moveUp:
self.y -= rate
if self.moveDown:
self.y += rate
if self.moveLeft:
self.x -= rate
if self.moveRight:
self.x += rate
else:
# standing still
self.moveConductor.stop() # calling stop() while the animation objects are already stopped is okay; in that case stop() is a no-op
if self.direction == self.UP:
Scene.screen.blit(self.back_standing, ((self.x, self.y)))
elif self.direction == self.DOWN:
Scene.screen.blit(self.front_standing, ((self.x, self.y)))
elif self.direction == self.LEFT:
Scene.screen.blit(self.left_standing, ((self.x, self.y)))
elif self.direction == self.RIGHT:
Scene.screen.blit(self.right_standing, (self.x, self.y))
# make sure the player does move off the screen
if self.x < 0:
self.x = 0
if self.x > self.WINDOWWIDTH - self.playerWidth:
self.x = self.WINDOWWIDTH - self.playerWidth
if self.y < 0:
self.y = 0
if self.y > self.WINDOWHEIGHT - self.playerHeight:
self.y = self.WINDOWHEIGHT - self.playerHeight
def handle(self, event):
if event.type == KEYDOWN:
if event.key in (K_LSHIFT, K_RSHIFT):
# player has started running
running = True
if event.key == K_UP:
self.moveUp = True
self.moveDown = False
if not self.moveLeft and not self.moveRight:
# only change the direction to up if the player wasn't moving left/right
self.direction = self.UP
elif event.key == K_DOWN:
self.moveDown = True
self.moveUp = False
if not self.moveLeft and not self.moveRight:
self.direction = self.DOWN
elif event.key == K_LEFT:
self.moveLeft = True
self.moveRight = False
if not self.moveUp and not self.moveDown:
self.direction = self.LEFT
elif event.key == K_RIGHT:
self.moveRight = True
self.moveLeft = False
if not self.moveUp and not self.moveDown:
self.direction = self.RIGHT
elif event.type == KEYUP:
if event.key in (K_LSHIFT, K_RSHIFT):
# player has stopped running
self.running = False
if event.key == K_UP:
self.moveUp = False
# if the player was moving in a sideways direction before, change the direction the player is facing.
if self.moveLeft:
self.direction = self.LEFT
if self.moveRight:
self.direction = self.RIGHT
elif event.key == K_DOWN:
self.moveDown = False
if self.moveLeft:
self.direction = self.LEFT
if self.moveRight:
self.direction = self.RIGHT
elif event.key == K_LEFT:
self.moveLeft = False
if self.moveUp:
self.direction = self.UP
if self.moveDown:
self.direction = self.DOWN
elif event.key == K_RIGHT:
self.moveRight = False
if self.moveUp:
self.direction = self.UP
if self.moveDown:
self.direction = self.DOWN
pygame.init()
clock = pygame.time.Clock()
Scene.screen = pygame.display.set_mode((800, 600))
player = Player()
scene = Intro()
while True:
if pygame.event.get(pygame.QUIT): break
for e in pygame.event.get():
scene = scene.handle(e) or scene
player.handle(e) or scene
scene = scene.update() or scene
scene.draw()
player.update(scene)
pygame.display.flip()
clock.tick(20)

Increasing Pygame Image size after collision?

So I'm just learning how to work with classes and getting them to work between each different class. I'm trying to design a game where the user moves around and picks up food and each time the user picks up a piece of food the size of the character increases. I've done something similar before but now that there are classes involved I seem to have a hard time finding which class this should be part of. I added within the sprite update method that if it collides with a cherry then the size of the player should increase by 5 pixels each time. using the code :
self.Player.surface = pygame.transform.scale(self.Player.surface, (pwidth+5, pheight+5))
self.rect = self.Player.surface.get_rect()
Each time the game runs the player size doesn't change and for some reason the game no longer ends after the player has eaten a certain amount of cherries so I was just wondering if I was using a wrong method of changing the size of the player perhaps there may be an easier way to do so? Heres the rest of the code incase it helps at all.
import pygame, glob, random, time
from pygame.locals import *
from LabelClass import *
# CONSTANTS
WIDTH = 400 # Window width
HEIGHT = 400 # Window height
BLACK = (0,0,0) # Colors
WHITE = (255,255,255)
BACKGR = BLACK # Background Color
FOREGR = WHITE # Foreground Color
FPS = 40 # Frames per second
pwidth = 40
pheight = 40
class Food:
def __init__(self,screen,centerx,centery):
self.screen = screen
self.surface = pygame.image.load('cherry.png')
self.rect = self.surface.get_rect()
self.rect.centerx = centerx
self.rect.centery = centery
def draw(self):
self.screen.blit(self.surface,self.rect)
#pygame.display.update([self.rect])
class Player:
def __init__(self, screen, centerx,
centery, speed, backcolor):
self.surface = pygame.image.load('player.png')
self.rect = self.surface.get_rect()
self.rect.centerx = centerx
self.rect.centery = centery
self.speed = speed
self.screen = screen
self.backcolor = backcolor
self.dir = ''
def draw(self):
self.screen.blit(self.surface,self.rect)
#pygame.display.update([self.rect])
def move(self):
if self.dir != '':
if self.dir == 'd' and self.rect.bottom < HEIGHT:
self.rect.top += self.speed
if self.dir == 'u' and self.rect.top > 0:
self.rect.top -= self.speed
if self.dir == 'l' and self.rect.left > 0:
self.rect.left -= self.speed
if self.dir == 'r' and self.rect.right < WIDTH:
self.rect.right += self.speed
def jump(self,top,left):
self.rect.top = top
self.rect.left = left
class SpritesGame:
def __init__(self,screen):
self.screen = screen
screen.fill(BLACK)
pygame.display.update()
music_file = getRandomMusic()
pygame.mixer.music.load(music_file)
pygame.mixer.music.play(-1,0.0)
self.music = True
self.Foods = [ ]
self.Eaten = 0
for i in range(20):
self.Foods.append(
Food(self.screen,
WIDTH*random.randint(1,9)//10,
HEIGHT*random.randint(1,9)//10))
for f in self.Foods:
f.draw()
self.Player = Player(screen,WIDTH//2,HEIGHT//2,6,BLACK)
self.PickUpSound = pygame.mixer.Sound('pickup.wav')
self.PlaySound = True
self.startTime = time.clock()
self.endTime = -1
self.Won = False
def update(self):
self.screen.fill(BLACK)
pickedUp = False
for f in self.Foods[:]:
if self.Player.rect.colliderect(f.rect):
self.Foods.remove(f)
self.Foods.append(Food(self.screen,WIDTH*random.randint(1,9)//10,HEIGHT*random.randint(1,9)//10))
pickedUp = True
self.Eaten += 1
self.Player.surface = pygame.transform.scale(self.Player.surface, (pwidth+5, pheight+5))
self.rect = self.Player.surface.get_rect()
#self.rect.center = center
print self.Eaten
if pickedUp and self.PlaySound:
self.PickUpSound.play()
for f in self.Foods:
f.draw()
if self.Eaten == 40:
self.Won = True
self.endTime = time.clock()
self.Player.move()
self.Player.draw()
pygame.display.update()
def toggleMusic(self):
self.music = not self.music
if self.music:
pygame.mixer.music.play(-1,0.0)
else:
pygame.mixer.music.stop()
def run(self):
stop = False
while not stop:
for event in pygame.event.get():
if event.type == QUIT:
stop = True
if event.type == KEYDOWN: # Keeps moving as long as key down
if event.key == K_LEFT or event.key == ord('a'):
self.Player.dir = 'l'
if event.key == K_RIGHT or event.key == ord('d'):
self.Player.dir = 'r'
if event.key == K_UP or event.key == ord('w'):
self.Player.dir = 'u'
if event.key == K_DOWN or event.key == ord('s'):
self.Player.dir = 'd'
if event.type == KEYUP:
if event.key == ord('q'):
stop = True
if event.key == K_ESCAPE:
stop = True
if event.key == K_LEFT or event.key == ord('a'): # End repetition.
self.Player.dir = ''
if event.key == K_RIGHT or event.key == ord('d'):
self.Player.dir = ''
if event.key == K_UP or event.key == ord('w'):
self.Player.dir = ''
if event.key == K_DOWN or event.key == ord('s'):
self.Player.dir = ''
if event.key == ord('x'):
top = random.randint(0,
HEIGHT - self.Player.rect.height)
left = random.randint(0,
WIDTH - self.Player.rect.width)
self.Player.jump(top,left)
if event.key == ord('m'):
self.toggleMusic()
if event.key == ord('p'):
self.PlaySound = not self.PlaySound
mainClock.tick(FPS)
self.update()
if self.Won:
stop = True # END OF WHILE
if self.Won:
self.screen.fill(BLACK)
pygame.display.update()
msg = (str((int(self.endTime)
-int(self.startTime)))
+" seconds to finish. Hit Q.")
L2 = Label(display,WIDTH//2,HEIGHT*7//8,26,msg,WHITE,BLACK)
L2.draw()
stop = False
while not stop:
for event in pygame.event.get():
if event.type == KEYUP:
if event.key == ord('q'):
stop = True
pygame.event.get()
pygame.mixer.music.stop()
def getRandomMusic():
mfiles = glob.glob("*.wav")
mfiles.append(glob.glob("*.mid"))
r = random.randint(0,len(mfiles)-1)
return mfiles[r]
def OpeningScreen(screen):
screen.fill(BLACK)
pygame.display.update()
L1 = Label(display,WIDTH//2,HEIGHT*7//8,26,"Hit Q to Quit, P to Play.",WHITE, BLACK)
L1.draw()
# Properly initiate pygame
pygame.init()
# pygame.key.set_repeat(INT,INT)
# Set the clock up
mainClock = pygame.time.Clock()
# Initialize Display
display = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption('Sprites and Sounds V06')
OpeningScreen(display)
stop = False
while not stop:
for event in pygame.event.get():
if event.type == QUIT:
stop = True
if event.type == KEYUP:
if event.key == ord('p'):
game = SpritesGame(display)
game.run()
OpeningScreen(display)
if event.key == ord('q'):
stop = True
pygame.quit()
Surface.get_rect() will always return a rect starting at (0,0), and you also are modifying SpritesGame.rect. I think you should change
self.rect = self.Player.surface.get_rect()
to
self.Player.rect.inflate_ip(5, 5)

Categories

Resources