why I get different results - python

Why I get different results when I use method update of group sprite objects during drawing to the screen. When thru calling method I get only one row of sprites and when I run for loop and move y axis of every sprite by one I get the whole swarm (several rows) moving down.
Here is the code
drop.py
import pygame
from pygame.sprite import Sprite
class Drop(Sprite):
"""Class that represent single drop in rain"""
def __init__(self, settings, screen):
"""Initialize drop and sets its starting position"""
super().__init__()
self.screen = screen
self.settings = settings
#Load drop image and sets its rect attribute
self.image = pygame.image.load('images/drop.bmp')
self.rect = self.image.get_rect()
#Start each drop on top-left on the screen
self.rect.x = self.rect.width
self.rect.y = self.rect.height
#store drop exact position
self.y = float(self.rect.y)
def update(self):
self.y += 1
self.rect.y = self.y
I have all functions stored in separate file. Just to keep it less cluttered. Where in function update_screen() is in comments described in code the problem I do not understand why makes difference looping thru sprites and that way changing y axis and getting whole group of them moving, but when I use method of sprite object .update() they are in group I get only partial group moving on screen.
func_rain.py
import pygame
import sys
from drop import Drop
from time import sleep
def create_rain(settings, screen, drops):
"""Create a fleet of drops."""
#Create an drop and find the number of drops in a row and number rows
drop = Drop(settings, screen)
number_drops_x = get_number_drops_x(settings, drop.rect.width)
number_rows = get_number_rows(settings, drop.rect.height)
for row_number in range(number_rows):
for drop_number in range (number_drops_x):
create_drop(settings, screen, drops, drop_number, row_number)
def get_number_drops_x(settings, drop_width):
"""Determine the number of drops that fit in a row."""
available_space_x = settings.screen_width - 2 * drop_width
number_drops_x = int(available_space_x / (2 * drop_width))
return number_drops_x
def get_number_rows(settings, drop_height):
"""Determine the number of rows of drops that fit on the screen."""
available_space_y = (settings.screen_height - drop_height)
number_rows = int(available_space_y / (2 * drop_height))
return number_rows
def create_drop(settings, screen, drops, drop_number, row_number):
"""Create drop and place it in the row"""
drop = Drop(settings, screen)
drop_width = drop.rect.width
drop.x = drop_width + 2 * drop_width * drop_number
drop.rect.x = drop.x
drop.rect.y = drop.rect.height + 2 * drop.rect.height * row_number
drops.add(drop)
def check_keydown_events(event):
"""Respond to key presses"""
if event.key == pygame.K_q:
sys.exit()
def check_events():
"""Respond to keypress and mouse events"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event)
def update_screen(settings, screen, drops):
"""Update images on the screen and flip to the new screen."""
# Redraw the screen during each pass through the loop.
screen.fill(settings.bg_color)
#This loop
for drop in drops:
drop.rect.y += 1
"""Here is the problem!!!!!! if I use for loop just above I get whole group
consisting from 5 rows of drops (image has resolution 50*62 pix). But when
I use drops.update() commented below (no for loop) I get on screen only
one row of drops."""
#drops.update()
drops.draw(screen)
pygame.display.flip()
rain_settings.py
class Settings():
"""A class to store all ran settings"""
def __init__(self):
#Screen settings
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (100, 100, 100)
And last main file.
rain.py
import pygame
from rain_settings import Settings
import func_rain as fr
from pygame.sprite import Group
def run_rain():
"""Initialize pygame and screen object"""
pygame.init()
settings = Settings()
screen = pygame.display.set_mode(
(settings.screen_width, settings.screen_height))
drops = Group()
fr.create_rain(settings, screen, drops)
while True:
fr.check_events()
fr.update_screen(settings, screen, drops)
run_rain()
I would really appreciate If someone can explain me what I'm doing wrong. I can't figure it out. please

So I've been playing around and I get the movement of sprites thru class method update to work.
def update(self):
self.rect.y += 1
Altho it still remains to me a mystery why directly changing the self.rect.y works and indirect change on y attribute don't.

Related

How to call a particular object's method and have affect only on that object which is a value of a key of a dictionary in pygame?

I am a new learner of programming. I am practiceing python and writing a litle game using pygame. I have ten circle on the pygame window and each have a counter. I want to increase the counter by 1 when it's circle is clicked. I first created group using .sprite.Group(), but I could not get the desired result. Because then the counter does not even get update. So I create two list, one for the circle and one for the counter. And for each circle in the circle list I created a dictionary taking the circle as the key and each counter in the circle list is the value of the circle. Now when the circle got clicked then the all counter gets updated, not the counter that the circle holds. But goal is to get the specific counter updated for it's circle.
(hole == circle)
dig_hole.py(This is the main file.)
import pygame
import sys
from pygame.sprite import Group
from counter import Counter
from hole import Hole
from settings import Settings
class DigHole:
def __init__(self):
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
pygame.display.set_caption("Dig Hole")
pygame.display.set_icon(Hole(self).image)
self.count = Counter(self)
self.counter_group = list()
self.holes = list()
self.dict = dict()
self._create_holes()
self.hole = Hole(self)
self.mouse_pos = (0, 0)
def run_dig_hole(self):
while True:
self._check_events()
self._update_screen()
def _check_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
self.mouse_pos = pygame.mouse.get_pos()
self._check_hole_clicked_events(self.mouse_pos)
def _check_hole_clicked_events(self, mouse_pos):
for key in self.dict:
if key.rect.collidepoint(mouse_pos):
self.dict[key].count_clock += 1
self.dict[key].prep_counter()
self.count.prep_counter()
def _create_holes(self):
for row_number in range(2):
for hole_number in range(5):
self._create_hole(row_number, hole_number)
for hole in self.holes:
counter = Counter(self)
counter.counter_rect.midbottom = hole.rect.midtop
self.counter_group.append(counter)
for hole in self.holes:
for counter in self.counter_group:
self.dict[hole] = counter
def _create_hole(self, row_number, hole_number):
hole = Hole(self)
hole_width, hole_height = hole.rect.size
available_space_x = self.settings.screen_width - (2 * hole_width)
available_space_y = self.settings.screen_height - (2 * hole_height)
hole.x =(((available_space_x // 5) - hole_width) // 2) + (available_space_x // 5) * hole_number
hole.rect.x = hole.x
hole.rect.y = 2 * hole.rect.height + (available_space_y - (4 * hole_height)) * row_number
self.holes.append(hole)
def _update_screen(self):
self.screen.fill(self.settings.bg_color)
for key in self.dict:
key.draw()
for key in self.dict:
self.dict[key].counter_rect.midbottom = key.rect.midtop
self.dict[key].show_counter()
self.count.show_counter()
pygame.display.flip()
if __name__ == '__main__':
dh = DigHole()
dh.run_dig_hole()
hole.py
import pygame
from pygame.sprite import Sprite
class Hole():
def __init__(self, dh):
# super().__init__()
self.screen = dh.screen
self.image = pygame.image.load("images/circle.bmp")
self.rect = self.image.get_rect()
self.rect.x = self.rect.width
self.rect.y = self.rect.height
self.x = float(self.rect.x)
def draw(self):
self.screen.blit(self.image, self.rect)
counter.py
import pygame.font
from pygame.sprite import Sprite
class Counter():
def __init__(self, dh):
# super().__init__()
self.screen = dh.screen
self.screen_rect = self.screen.get_rect()
self.settings = dh.settings
self.count_clock = 0
self.text_color = (30, 30, 30)
self.font = pygame.font.SysFont(None, 48)
self.prep_counter()
def prep_counter(self):
counter_str = str(self.count_clock)
self.counter_image = self.font.render(counter_str, True, self.text_color, self.settings.bg_color)
self.counter_rect = self.counter_image.get_rect()
self.counter_rect.right = self.screen_rect.right - 20
self.counter_rect.top = 20
def show_counter(self):
self.screen.blit(self.counter_image, self.counter_rect)
Thank you.This is the window of the progeam. Here all circles are gets update but one is clicked.
The issue is that, in _create_holes, you set the counters of each circle to be the same Counter object.
for hole in self.holes:
for counter in self.counter_group:
self.dict[hole] = counter
Unrolling the inner loop, this is the same as
for hole in self.holes:
self.dict[hole] = self.counter_group[0]
self.dict[hole] = self.counter_group[1]
self.dict[hole] = self.counter_group[2]
...
self.dict[hole] = self.counter_group[-1]
The first assignments are all immediately overwritten, so this code is setting every self.dict value to self.counter_group[-1]. What you want to do instead is
for hole, counter in zip(self.holes, self.counter_group):
self.dict[hole] = counter
which iterates over both self.holes and self.counter_group simultaneously. In your case, you can actually rewrite this as
self.dict = dict(zip(self.holes, self.counter_group))
which is nicer.
I’m not sure, but I think you intend self.count to be a total. If this is the case, it won’t quite work: you’re missing a line from _check_hole_clicked_events. It should look like this:
def _check_hole_clicked_events(self, mouse_pos):
for key in self.dict:
if key.rect.collidepoint(mouse_pos):
self.dict[key].count_clock += 1
self.dict[key].prep_counter()
self.count.count_clock += 1
self.count.prep_counter()
As a side note, I noticed you also wrote list() and dict() to create empty lists and dicts. It’s more efficient and idiomatic just to write literals ([] and {}).

Having problems creating an animation from a sprite sheet in pygame

I am relatively new to Python and started messing around with pygame a few days ago. I made a sprite sheet in photoshop and I am trying to use it to animate the player in the game. The sprite sheet has 8 images, 4 for walking left and 4 for walking right. I want to show these animations at the correct time. I have tried many different methods I've found online but I haven't managed to get any working and I am still quite confused about it.
This is the Char class that controls the character's movement and sprite. I tried indexing the sprite and changing the index in the update method but I understand this isn't possible but I've left it in to show what I was trying to do. Any help would be appreciated!
import pygame, sys
from pygame.sprite import Sprite
class Char(Sprite):
def __init__(self, pf_game):
"""initialise char and set its starting location"""
self.screen = pf_game.screen
self.settings = pf_game.settings
self.screen_rect = pf_game.screen.get_rect()
self.dog_sprite = pygame.image.load('images/dog_sprite_sheet.bmp').convert()
self.current_sprite = 0
self.dog_image = self.dog_sprite[self.current_sprite]
self.rect = self.dog_image.get_rect()
# start new char at the bottom of centre of the screen
self.rect.midbottom = self.screen_rect.midbottom
#store a decimal value for the ships horizontal position
self.x = float(self.rect.x)
self.y = float(self.rect.y)
#movement flags
self.moving_right = False
self.moving_left = False
self.is_jump = False
def update(self):
"""Update the chars position based on movement flags"""
#update the chars x value and create animation for moving right
if self.moving_right and self.rect.right<self.screen_rect.right:
if self.current_sprite == 7:
self.current_sprite = 4
self.dog_image = self.dog_sprite[self.current_sprite]
self.current_sprite+=1
self.x+= self.settings.char_speed
#update the chars x value and create animation for moving left
if self.moving_left and self.rect.left>0:
if self.current_sprite == 3:
self.current_sprite = 0
self.dog_image = self.dog_sprite[self.current_sprite]
self.current_sprite+=1
self.x-= self.settings.char_speed
#update rect object from self.x
self.rect.x = self.x
self.rect.y = self.y
def blitme(self):
"""Draw the char at its curretn loaction"""
self.screen.blit(self.dog_image, self.rect)
edit:
I found a spritesheet class that seems to do what I want on http://www.pygame.org/wiki/Spritesheet. I am running into an error though when I try and input the coordinates. I get the error images_at() got multiple values for argument 'colorkey'. When i remove the colorkey I get the error images_at() takes from 2 to 3 positional arguments but 5 were given.
This is the code I am using.
self.dog_sprite=spritesheet.spritesheet('dog_sprite_sheet.bmp')
self.left_images=[]
self.right_images=[]
self.left_images=self.dog_sprite.images_at((0,0,19,19),(20,0,19,19),(39,0,19,19),(58,0,19,19), colorkey=(255, 255, 255))
self.right_images=self.dog_sprite.images_at((77,0,19,19),(96,0,19,19),(115,0,19,19),(134,0,19,19), colorkey=(255, 255, 255))
this may help:
def anim(anim_count):
if anim_count < 6:
screen.blit('anim1.png', player_position)
if anim_count > 6 and anim_count < 12:
screen.blit('anim2.png', player_position)
you should call anim at every frame, and then apply 1 to anim_count

Python programming trouble

I was programming a game and I did not know how to program in python 3.7 so I had to get a book called Code This Game, book from OddDot. And When I got to chapter 6 I was learning how to create a group for the enemy sprites. and every time I ran the program all it drew was the background image and the grid(because the book is not only teaching me how to code in Python, while I am learning I am making a game from the book while I learn from the book.) it did not draw the group of Vampire Pizzas in the right column if fact it doesn't even draw them at all. I have tried redoing the chapter over and over again and I can't do it
here is my code
#Import Libraries
import pygame
from pygame import *
from random import randint
#Initialize pygame
pygame.init()
#Define constant variables
WINDOW_WIDTH = 1100
WINDOW_HEIGHT = 600
WINDOW_RES = (WINDOW_WIDTH, WINDOW_HEIGHT)
#Define Tile Parameters
WIDTH = 100
HEIGHT = 100
#Define Tile colors
WHITE = (255, 255, 255)
#Set up rates
SPAWN_RATE = 360
#This is the code where the game window will show up
GAME_WINDOW = display.set_mode(WINDOW_RES)
display.set_caption('Attack of the Vampire Pizzaas!')
#---------------------------------------------------------
#Set up the enemy image
pizza_img = image.load('vampire.png')
pizza_surf = Surface.convert_alpha(pizza_img)
VAMPIRE_PIZZA = transform.scale(pizza_surf, (HEIGHT, WIDTH))
#Create a subclass of Sprite called VampireSprite
class VampireSprite(sprite.Sprite):
#Set up enemy instances
def __init__(self):
super().__init__()
self.speed = 2
self.lane = randint(0, 4)
all_vampires.add(self)
self.image = VAMPIRE_PIZZA.copy()
y = 50 + self.lane * 100
self.rect = self.image.get_rect(center = (1100, y))
def update(self, game_window):
game_window.blit(self.image, (self.rect.x, self.rect.y))
#Set up the background image
background_img = image.load('restaurant.jpg')
background_surf = Surface.convert_alpha(background_img)
BACKGROUND = transform.scale(background_surf, WINDOW_RES)
#------------------------------------------------------
all_vampires = sprite.Group()
#Initialile and draw background grid
tile_color = WHITE
for row in range(6):
for column in range(11):
draw.rect(BACKGROUND, tile_color, (WIDTH * column,
HEIGHT * row, WIDTH, HEIGHT),1)
GAME_WINDOW.blit(BACKGROUND, (0, 0))
#---------------------------------------------------------
#Start The Main Game Loop
#Game Loop
game_running = True
while game_running:
#Check for Events
for event in pygame.event.get():
if event.type == QUIT:
game_running = False
#Spawn vampire pizza sprites
if randint(1, SPAWN_RATE) == 1:
VampireSprite()
#Update displays
for vampire in all_vampires:
vampire.update(GAME_WINDOW)
display.update()
#End of the Main game loop
#---------------------------------------------------------
#Clean up game
pygame.quit()
I don't know if I am doing something wrong or what
If my eyes are working fine(I guess) the code is valid
Make sure that the pygame version you are using is the one compatible with Python 3.7 and not older versions such as Python 2.
I had the same issue while working my way through this fun coding book. Comparing the code from the book's website and my own code I found the issue was incorrect spacing while defining the update() function within the VampireSprite class.
# Create a subclass of Sprite called VampireSprite
class VampireSprite(sprite.Sprite):
# Set up enemy instances
def __init__(self):
super().__init__()
self.Speed = 2
self. Lane = randint(0, 4)
all_vampires.add(self)
self.image = VAMPIRE_PIZZA.copy()
y = 50 + self.lane * 100
self.rect = self.image.get_rect(center = (1100, y))
def update(self, game_window):
game_window.blit(self.image, (self.rect.x, self.rect.y))
The correct code is:
# Create an enemy class
class VampireSprite(sprite.Sprite):
# This function creates an instance of the enemy
def __init__(self):
super().__init__()
self.speed = 2
self.lane = randint(0, 4)
all_vampires.add(self)
self.image = VAMPIRE_PIZZA.copy()
y = 50 + self.lane * 100
self.rect = self.image.get_rect(center=(1100, y))
# This function moves the enemies from right to left and destroys them after they've left the screen
def update(self, game_window):
game_window.blit(self.image, (self.rect.x, self.rect.y))

I want to make a game with Pygame.But my arrow can't shoot from the right position

Python version: 3.8.1
System: Windows7-32bit
see the title,i want to make a game,but i ,meet a problem.Arrows fired by players do not appear in the correct position.No matter how the player's position changes, the arrow will always shoot from one position.
I didn't used a group,because I find it not enough to make game.
Please help me!
There are some code:
steve_vs_monsters.py
import pygame
from settings import Settings
import key_event
from steve import Steve
from update_screen import screen_update
from arrow import Arrow
def run_game():
""" """
--snip--
#
steve = Steve(a_settings,screen)
arrow = Arrow(a_settings,screen,steve)
#
arrows = []
#
while True:
#
key_event.check_events(steve,arrow,arrows)
#
update_screen(a_settings,screen,steve,arrow,arrows)
run_game()
arrow.py
import pygame
class Arrow():
""" """
def __init__(self,a_settings,screen,steve):
""" """
--snip--
#
self.rect.centerx = steve.rect.centerx
self.rect.bottom = steve.rect.top
self.rect.left = steve.rect.right
#
self.center = float(self.rect.centerx)
def draw_arrow(self,arrows):
""" """
for a_arrow in arrows:
self.screen.blit(self.image,a_arrow[0:2])
def update_rect(self,steve,arrows):
for a_arrow in arrows:
a_arrow[0] += float(self.a_settings.arrow_speed)
if a_arrow[0] > self.screen_rect.right:
arrows.remove(a_arrow)
update_screen.py
import pygame
def update_screen(a_settings,screen,steve,arrow,arrows):
""" """
screen.fill(a_settings.bg_color)
steve.update_rect()
arrow.update_rect(steve,arrows)
steve.draw_steve()
arrow.draw_arrow(arrows)
#
pygame.display.flip()
key_event.py
import sys
import pygame
def check_keydown_events(event,steve,arrow,arrows):
""" """
if event.key == pygame.K_t:
sys.exit()
--snip--
elif event.key==pygame.K_SPACE and len(arrows)<=4:
arrows.append([arrow.center,arrow.rect.bottom,arrow.rect.left])
--snip--
def check_events(steve,arrow,arrows):
""" """
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event,steve,arrow,arrows)
--snip--
It looks like the code initially creates a single arrow that takes the position from steve's rectangle. This arrow is then used as the base-position for creating new arrows when K_SPACE is pressed.
I think that the current rectangle of steve should be used to create a new instance of Arrow, rather than an existing instance.
For example:
def check_keydown_events(event,steve,arrow,arrows):
""" """
if event.key == pygame.K_t:
sys.exit()
--snip--
elif event.key==pygame.K_SPACE and len(arrows)<=4:
#arrows.append( [arrow.center, arrow.rect.bottom, arrow.rect.left] )
arrows.append( [steve.center, steve.rect.top, steve.rect.right] )
This way the new arrow is always created to where steve is positioned now, rather than positioned initially.
It's not clear to me why top/bottom and left/right is swapped when that first Arrow is created, but I have modified the code to use this method too.
Personally, I would modify the Arrow class such that it takes x and y co-ordinates, and the speed as simple parameters:
class Arrow():
""" """
def __init__( self, arrow_image, x_pos, y_pos, speed ):
self.image = arrow_image
self.rect = arrow_image.get_rect()
self.speed = speed
self.rect.centerx = x_pos
self.rect.centery = y_pos
def update( self ):
self.rect.centerx += self.speed
#staticmethod
def draw_arrow_set( screen, all_arrows ):
for a in all_arrows:
screen.blit( a.image, a.rect )
#staticmethod
def update_arrow_set( all_arrows, screen_rect ):
for a in all_arrows:
a.update()
if ( a.rect.centerx > screen_rect.right ):
all_arrows.remove( a ) # doesn't this cause problems?
Then it is more flexible:
if ( steve_facing_left ):
# facing left
x_start = steve.rect.x # start on Steve's left side
arrows.append( Arrow( left_arrow_image, x_start, steve.rect.centery, -1 ) )
else:
# facing right
x_start = steve.rect.x + steve.rect.width # start on Steve's right side
arrows.append( Arrow( right_arrow_image, x_start, steve.rect.centery, 1 ) )
And then later on:
arrows.append( Arrow( super_arrow_image, x_start, y_start, 3 ) )

Problems with Sprites Appearing and Collision with Rotated Objects; Pygame object is not iterable

I'm currently trying to make pixel perfect collisions between my pong ball and my player's paddle using the mask and collide_rect functions. I made my own checkCollision function in the pong class which would check for pixel perfect collision. However, right now, I can't even get the Sprites to work or appear on the screen because my "Pong object is not iterable.
Here is my pong class with the important features: (I will post additional code if needed)
class Pong(pygame.sprite.Sprite):
def __init__(self, screensize):
pygame.sprite.Sprite.__init__(self)
self.screensize = screensize
self.centerx = screensize[0] // 2
self.centery = screensize[1] // 2
self.radius = 25
self.rect = pygame.Rect(self.centerx-self.radius,
self.centery-self.radius,
self.radius*2, self.radius*2)
self.pokeimage = pygame.image.load("pokeball.png")
self.pokeimage = pygame.transform.scale(self.pokeimage, (self.radius, self.radius))
#Create the mask
self.mask = pygame.mask.from_surface(self.pokeimage)
def checkCollision(self, player_paddle, ai_paddle):
col = pygame.sprite.collide_rect(self, player_paddle)
return col
def collisionFormula(self, player_paddle, ai_paddle):
if self.checkCollision(self, player_paddle):
def collision_checks(self, player_paddle, ai_paddle):
#if the ball hits the top or bottom of the screen, change the y direction
if self.rect.top <= 0 or self.rect.bottom >= self.screensize[1] - 1:
self.direction[1] *= -1
#if the pong hits the paddles, change how the pong ball moves
if self.rect.colliderect(player_paddle.rect) or self.rect.colliderect(ai_paddle.rect):
self.collisionFormula(player_paddle, ai_paddle)
def update(self, player_paddle, ai_paddle):
self.update_ball_position()
self.reset_ball()
self.collision_checks(player_paddle, ai_paddle)
In my PlayerPaddle class, I do the same mask initialization.
class PlayerPaddle(pygame.sprite.Sprite):
def __init__(self, screensize):
pygame.sprite.Sprite.__init__(self)
self.screensize = screensize
self.centerx = 50
self.centery = screensize[1]//2
self.height = 100
self.width = 20
self.imageMaster = pygame.image.load("naruto.png").convert_alpha()
self.imageMaster = pygame.transform.scale(self.imageMaster, (self.width, self.height))
self.image = self.imageMaster
#mask
self.mask = pygame.mask.from_surface(self.image)
def turnLeft(self):
self.dir += 45
if self.dir > 360:
self.dir = 45
def turnRight(self):
self.dir -= 45
if self.dir < 0:
self.dir = 315
def update(self):
#Rotate functions
oldCenter = self.rect.center
self.image = pygame.transform.rotate(self.imageMaster, self.dir)
self.rect = self.image.get_rect()
self.rect.center = oldCenter
And here is my main function:
def main():
pygame.init()
screensize = (640,700)
screen = pygame.display.set_mode(screensize)
background = pygame.Surface(screen.get_size())
background.fill((0, 255, 0))
clock = pygame.time.Clock()
pong = Pong(screensize)
player_paddle = PlayerPaddle(screensize)
ai_paddle = AIPaddle(screensize)
paddleSprite = pygame.sprite.Group(player_paddle)
pongSprite = pygame.sprite.Group(pong)
while running:
running = True
#object updating phase
ai_paddle.update(pong, player_paddle)
player_paddle.update()
pong.update(player_paddle, ai_paddle)
if pygame.sprite.spritecollide(player_paddle, pong, False, pygame.sprite.collide_mask):
print("Collided")
#rendering phase
ai_paddle.render(screen)
player_paddle.render(screen)
pong.render(screen)
paddleSprite.clear(screen, background)
paddleSprite.update()
paddleSprite.draw(screen)
pongSprite.clear(screen,background)
pongSprite.update()
pongSprite.draw(screen)
pygame.display.flip()
pygame.quit()
main()
I made two "group" objects (the pong and the player_paddle) but I'm not sure why I'm even failing to run the program. Additionally, I know the collision will not work because the pong ball will hit the rectangle of the original image, but not the rotated image, but I'm not sure why that will happen if I use the built in sprite function. Thanks.
Read documentation for spritecollide
Find sprites in a group that intersect another sprite.
spritecollide(sprite, group, dokill, collided = None) -> Sprite_list
Second argument has to be group (pygame.sprite.Group), not single Sprite.
It can be group event with one sprite. But you use pong which is single sprite, not group.
See documentation for collide_mask
Collision detection between two sprites, using masks.
collide_mask(SpriteLeft, SpriteRight) -> point
It checks collision between two sprites using mask.
EDIT: in your code you have problem with
spritecollide(player_paddle, pong,...)
because pong is single Sprite, not Group.
With pong you should use collide_mask
collide_mask(player_paddle, pong)
You can use spritecollidewith pongSprite which is Group
spritecollide(player_paddle, pongSprite,...)`
BTW: you could use better names ie. pong_group instead of pongSprite.
And eventually pong_sprite instead of pong (but pong is OK, too).

Categories