I'm faced with a logic error where the sprite simply doesn't move regardless of input.
My code will be below so no context is left out, it's fairly short.
Is there a better way of moving the sprite apart from the blit?
I've seen somewhere stuff about updating the sprite or some such, done quite differently to simply blitting it.
import pygame
pygame.init()
import random
import math
screen=pygame.display.set_mode([700,400])
black = ( 0, 0, 0)
white = ( 255, 255, 255)
red = ( 255, 0, 0)
player_x=350
player_y=200
player_x_vel=0
player_y_vel=0
rot_player=pygame.image
pi=math.pi
class Player(pygame.sprite.Sprite):
def __init__(self):
global player
pygame.sprite.Sprite.__init__(self)
self.pos=(350,200)
self.image=pygame.image.load("arrowtest.png").convert()
self.rect=self.image.get_rect()
screen=pygame.display.get_surface()
self.area=screen.get_rect()
self.speed=10
self.state="still"
self.reinit()
def reinit(self):
self.state="still"
self.movepos=[0,0]
def update(self):
newpos=self.rect.move(self.movepos)
if self.area.contains(newpos):
self.rect=newpos
pygame.event.pump()
def moveup(self):
self.movepos[1]-=(self.speed)
self.state="moveup"
def movedown(self):
self.movepos[1]+=(self.speed)
self.state="movedown"
def moveleft(self):
self.movepos[0]-=(self.speed)
self.state="moveleft"
def moveright(self):
self.movepos[0]+=(self.speed)
self.state="moveright"
def moveupright(self):
self.movepos[1]-=(self.speed)
self.movepos[0]+=(self.speed)
def moveupleft(self):
self.movepos[1]-=(self.speed)
self.movepos[0]-=(self.speed)
def movedownright(self):
self.movepos[1]+=(self.speed)
self.movepos[0]+=(self.speed)
def movedownleft(self):
self.movepos[1]+=(self.speed)
self.movepos[0]-=(self.speed)
def angleplayer(self):
mouse_pos=pygame.mouse.get_pos()
dx=mouse_pos[0]-player_x
dy=mouse_pos[1]-player_y
rads=math.atan2(-dy, dx)
rads %= 2*pi
angle = math.degrees(rads)
print angle
rot_player.image=pygame.transform.rotate(player.image, angle-90)
done=False
clock=pygame.time.Clock()
while done==False:
player = Player()
for event in pygame.event.get():
if event.type == pygame.QUIT:
done=True
if event.type == pygame.MOUSEBUTTONDOWN:
fired_pos=pygame.mouse.get_pos()
fired=True
if event.type == pygame.KEYDOWN:
player.angleplayer()
if event.key == pygame.K_w:
player.moveup()
if event.key == pygame.K_s:
player.movedown()
if event.key == pygame.K_a:
player.moveleft()
if event.key == pygame.K_d:
player.moveright()
print "co ords", player_x,player_y
print "x vel", player_x_vel
print "y vel", player_y_vel
if event.type == pygame.KEYUP:
player.movepos=[0,0]
player.state="still"
player.angleplayer()
screen.fill(white)
screen.blit(player.image, player.pos)
clock.tick(20)
pygame.display.flip()
pygame.quit()
Thanks in advance
First of all, you are creating a new player every iteration of your main loop:
...
while done == False:
player = Player()
...
You want to create the player once, so move the creation outside the loop:
...
player = Player()
while not done:
...
Second: To get the position of the player, you use player.pos:
...
screen.blit(player.image, player.pos)
...
but you never update player.pos (it's always (350,200)), you only change self.rect:
def update(self):
newpos=self.rect.move(self.movepos)
if self.area.contains(newpos):
self.rect=newpos
pygame.event.pump()
either use player.rect to get the player position, or update player.pos accordingly:
def update(self):
newpos=self.rect.move(self.movepos)
if self.area.contains(newpos):
self.rect = newpos
self.pos = self.rect.topleft
# don't call pygame.event.pump() here. Doesn't make any sense :-)
Third, you update the player position in the update function, but you never call it. Call it before drawing the player:
...
while not done:
...
player.update()
screen.fill(white)
screen.blit(player.image, player.pos)
...
You can simplify your code alot by setting movepos directly and removing the move... functions.
working example:
import pygame
pygame.init()
colors = pygame.color.THECOLORS
screen = pygame.display.set_mode([700,400])
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.surface.Surface((32,32))
self.image.fill(colors['green'])
self.rect = self.image.get_rect().move(350, 200)
self.speed = 4
def update(self):
dx, dy = self.movepos[0] * self.speed, self.movepos[1] * self.speed
self.rect = self.rect.move(dx, dy)
done=False
clock = pygame.time.Clock()
player = Player()
while not done:
if pygame.event.get(pygame.QUIT):
break
pressed = pygame.key.get_pressed()
l, r, u, d = [pressed[k] for k in pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_s]
player.movepos = -l + r, -u + d
player.update()
screen.fill(colors['white'])
screen.blit(player.image, player.rect.topleft)
pygame.display.flip()
clock.tick(60)
You have a lot of move functions. Try combining them into a simple two function class like this example:
class Puck(pygame.sprite.Sprite):
def __init__(self, image_file, speed, location):
pygame.sprite.Sprite.__init__(self) #call Sprite initializer
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = location
The two main controllers are the self.rect.left and self.rect.top. By changing their values, you can move the sprites like in this example.
#Name of varible# = Puck('#Image File#', [#value of self.rect.left#, value of self.rect.top]
Then you can use events to change them like:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
exit(0)
elif event.type == pygame.KEYDOWN:
if event.key == K_UP:
random.rect.top =random.rect.top - 75
elif event.key == K_LEFT:
random.rect.left = random.rect.left - 75
elif event.key == K_DOWN:
random.rect.top = random.rect.top + 75
elif event.key == K_RIGHT:
randoml.rect.left = randoml.rect.left + 75
elif event.key == K_w:
random.rect.top = random.rect.top - 50
elif event.key == K_a:
random.rect.left = random.rect.left - 50
elif event.key == K_s:
random.rect.top = random.rect.top + 50
elif event.key == K_d:
random.rect.left = random.rect.left + 50
This should be able to move your sprite.
Related
import pygame, os, sys
from pygame import *
pygame.init()
RED = ( 255, 0, 0)
class WPawn():
def __init__(self, x, y):
self.x = x
self.y = y
self.image = pygame.transform.scale(pygame.image.load('wpawn.png'), (100,100))
self.move_x = 0
self.move_y = 0
def event_handler(self):
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_UP:
self.move_y = -100
if event.key == K_DOWN:
self.move_y = 100
elif event.type == KEYUP:
if event.key in (K_UP, K_DOWN):
self.move_y = 0
def update(self, screen):
self.y = self.y + self.move_y
def draw(self, screen):
screen.blit(self.image, (self.x, self.y))
class Game():
def __init__(self):
screen_width = 900
screen_height = 900
self.screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption ("Chess Project")
self.pawn1 = WPawn(50,650)
self.pawn2 = WPawn(150,650)
self.pawn3 = WPawn(250,650)
self.pawn4 = WPawn(350,650)
self.pawn5 = WPawn(450,650)
self.pawn6 = WPawn(550,650)
self.pawn7 = WPawn(650,650)
self.pawn8 = WPawn(750,650)
def play(self):
clock = pygame.time.Clock()
RUNNING = True
while RUNNING:
for event in pygame.event.get():
if event.type == pygame.QUIT:
RUNNING = False
clock.tick(30)
self.pawn1.event_handler()
self.pawn2.event_handler()
self.pawn3.event_handler()
self.pawn4.event_handler()
self.pawn5.event_handler()
self.pawn6.event_handler()
self.pawn7.event_handler()
self.pawn8.event_handler()
self.pawn1.update(self.screen)
self.pawn2.update(self.screen)
self.pawn3.update(self.screen)
self.pawn4.update(self.screen)
self.pawn5.update(self.screen)
self.pawn6.update(self.screen)
self.pawn7.update(self.screen)
self.pawn8.update(self.screen)
self.screen.fill(RED)
self.pawn1.draw(self.screen)
self.pawn2.draw(self.screen)
self.pawn3.draw(self.screen)
self.pawn4.draw(self.screen)
self.pawn5.draw(self.screen)
self.pawn6.draw(self.screen)
self.pawn7.draw(self.screen)
self.pawn8.draw(self.screen)
pygame.display.update()
Game().play()
pygame.quit()
The KEY_UP event (or whatever) is consumed when you process it. So whichever WPawn class gets the event first will move.
Generally an event-driven program has only one event loop.
It may be easier to make this work by handling the event processing outside of the game objects. Have the single event loop handle record the key press, then move each WPawn that you wish to be moved.
Perhaps something like:
event = pygame.event.get()
if event.type == K_DOWN:
foreach pawn in all_pawns:
pawn.moveDown()
elif event.type == K_UP:
foreach pawn in all_pawns:
pawn.moveUp()
I'm trying to use time.Time() to control the fire rate of my projectiles, but after putting in the time logic, my player can no longer shoot any projectiles at all. How can I make it so that my player only fires once every half a second or so?
The following is a workable example;
main game module
import pygame
from constants import *
from player import Player
from Projectile import Projectiles
import time
pygame.init()
screen = pygame.display.set_mode([500, 500])
pygame.display.set_caption('Labyrinth')
# Spawn player
player = Player(50, 50)
all_sprites_list = pygame.sprite.Group()
all_sprites_list.add(player)
projectile_list = pygame.sprite.Group()
clock = pygame.time.Clock()
done = False
# ----- Event Loop
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == ord('a'):
player.changespeed(-3, 0)
elif event.key == ord('d'):
player.changespeed(3, 0)
elif event.key == ord('w'):
player.changespeed(0, -3)
elif event.key == ord('s'):
player.changespeed(0, 3)
elif event.key == pygame.K_LEFT:
projectile = Projectiles(player.rect.x, player.rect.y, -5, 0)
elif event.key == pygame.K_RIGHT:
projectile = Projectiles(player.rect.x, player.rect.y, 5, 0)
elif event.key == pygame.K_UP:
projectile = Projectiles(player.rect.x, player.rect.y, 0, -5)
elif event.key == pygame.K_DOWN:
projectile = Projectiles(player.rect.x, player.rect.y, 0, 5)
try:
if projectile:
if time.Time() - last_shot > player.fire_rate:
projectile_list.add(projectile)
last_shot = time.Time()
except:
pass
elif event.type == pygame.KEYUP:
if event.key == ord('a'):
player.changespeed(3, 0)
elif event.key == ord('d'):
player.changespeed(-3, 0)
elif event.key == ord('w'):
player.changespeed(0, 3)
elif event.key == ord('s'):
player.changespeed(0, -3)
# ----- Game Logic
all_sprites_list.update()
projectile_list.update()
screen.fill(GREEN)
all_sprites_list.draw(screen)
projectile_list.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
player module
from constants import *
import pygame
import time
from datetime import datetime, timedelta
class Player(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface([15, 15])
self.image.fill(BLACK)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.fire_rate = 1
self.change_x = 0
self.change_y = 0
def changespeed(self, x, y):
self.change_x += x
self.change_y += y
def update(self):
self.rect.x += self.change_x
self.rect.y += self.change_y
projectile module
import pygame
from constants import *
class Projectiles(pygame.sprite.Sprite):
def __init__(self, x, y, x_speed, y_speed):
super().__init__()
self.image = pygame.Surface([4, 4])
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.x_speed = x_speed
self.y_speed = y_speed
def update(self):
self.rect.x += self.x_speed
self.rect.y += self.y_speed
constants module defines a few colours. Any help is much appreciated!
Well, strictly speaking, the answer is that you have time.Time() in a try block, and it should be time.time() (all lowercase). This throws an exception, so any time time.Time() - last_shot > player.fire_rate is evaluated, the try block isn't run. This would have been more apparent if you had caught the exception and thrown an error message rather than just passing.
There likely are further issues, but a more in-depth analysis of your code is difficult, as I don't see you initializing last_shot anywhere, nor player.fire_rate. The "minimal complete example" standard isn't just for the answerers, but for the asker as well. Basic debugging in isolating the issue as much as possible.
As another note, your while loop appears to contain nothing but a for loop, making it redundant. If you're doing that to just have the program run through the loop over and over again until the appropriate time, then time.sleep() would be probably be a better way to do that.
A try with a bare except is an anti-pattern and should almost never be used, because it hides all errors in the try clause and makes the code hard to debug. I'd remove it and rearrange the event handling code.
When an arrow key gets pressed, only change the velocity vector depending on the key instead of creating new projectile instances. Then check again if any of the arrow keys were pressed and if the timer is finished, create a projectile instance and pass the current velocity vector.
import pygame as pg
from pygame.math import Vector2
BULLET_IMG = pg.Surface((9, 9))
BULLET_IMG.fill(pg.Color('aquamarine2'))
class Projectile(pg.sprite.Sprite):
def __init__(self, pos, vel):
super().__init__()
self.image = BULLET_IMG
self.rect = self.image.get_rect(center=pos)
self.vel = Vector2(vel)
def update(self):
self.rect.move_ip(self.vel)
def main():
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
projectiles = pg.sprite.Group()
previous_time = pg.time.get_ticks()
speed = 12
vel = Vector2(speed, 0)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
# Only change the velocity vector.
if event.key == pg.K_LEFT:
vel = Vector2(-speed, 0)
elif event.key == pg.K_RIGHT:
vel = Vector2(speed, 0)
elif event.key == pg.K_UP:
vel = Vector2(0, -speed)
elif event.key == pg.K_DOWN:
vel = Vector2(0, speed)
# If an arrow keys was pressed, create a new projectile.
if event.key in (pg.K_LEFT, pg.K_RIGHT, pg.K_UP, pg.K_DOWN):
current_time = pg.time.get_ticks()
# We're ready to fire when 500 ms have passed.
if current_time - previous_time > 500:
previous_time = current_time
# Now create the projectile instance and pass
# the position and the velocity.
projectiles.add(Projectile(pg.mouse.get_pos(), vel))
projectiles.update()
screen.fill((30, 30, 30))
projectiles.draw(screen)
pg.display.update()
clock.tick(60)
if __name__ == '__main__':
main()
pg.quit()
I cant seem to get my sprite to move left or right after moving it to a class. I am using pygame. I have a velocity variable and add to that to my x for my shape yet it still doesnt move. Any help would be really appreciated. Movement was working before i decided to put all my the things to do with the player into a class.
import pygame
import Constants
from pygame.locals import *
pygame.init()
pygame.display.set_caption("Platformer")
window = pygame.display.set_mode((Constants.SCREEN_WIDTH, Constants.SCREEN_HEIGHT))
clock = pygame.time.Clock()
all_sprite_list = pygame.sprite.Group()
class player:
def __init__(self,velocity):
self.velocity = velocity
def location(self,x,y):
self.x = x
self.y = y
self.xVel = 0
def keys(self):
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.xVel = - self.velocity
elif event.key == pygame.K_RIGHT:
self.xVel = self.velocity
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
self.xVel = 0
def move(self):
self.x = + self.xVel
def draw(self):
display = pygame.display.get_surface()
pygame.draw.rect(window,(255,255,255),[self.x,self.y,20,40])
def do(self):
self.keys()
self.move()
self.draw()
P = player(10)
P.location(Constants.SCREEN_WIDTH/2,0)
#Map
def draw_map():
window.fill(Constants.BLUE)
#sprites
def draw_player():
player = Player(50,50)
all_sprite_list.add(player)
#Game loop
def game_loop():
GameQuit = False
while not GameQuit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
GameQuit = True
draw_map()
P.do()
pygame.display.update()
clock.tick(30)
#game initialisation
game_loop()
pygame.quit()
quit()
`
The problem is that pygame.event.get() clears all events from the event queue, so when your player calls it, all events are already gone. From the docs
This will get all the messages and remove them from the queue. If a type or sequence of types is given only those messages will be removed from the queue.
You can solve this by specifying which events should be removed from the event queue e.g.
for event in pygame.event.get(QUIT):
GameQuit = True
The other events should still be in the queue for your player to use
Leon Z. has already explained that pygame.event.get() empties the event queue. I usually pass the events from the event loop to the objects that need the events. You could also assign the list that pygame.event.get() returns to a variable and then pass this variable to the player instance: events = pygame.event.get().
BTW, there was a little mistake in the move method: = + instead of +=.
import pygame
from pygame.locals import *
pygame.init()
pygame.display.set_caption("Platformer")
window = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
all_sprite_list = pygame.sprite.Group()
class player:
def __init__(self,velocity):
self.velocity = velocity
def location(self,x,y):
self.x = x
self.y = y
self.xVel = 0
def keys(self, event):
"""Handle the events that get passed from the event loop."""
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.xVel = -self.velocity
elif event.key == pygame.K_RIGHT:
self.xVel = self.velocity
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
self.xVel = 0
def move(self):
self.x += self.xVel # Add the self.xVel to self.x.
def draw(self):
display = pygame.display.get_surface()
pygame.draw.rect(display, (255,255,255), [self.x, self.y, 20, 40])
def do(self):
self.move()
self.draw()
P = player(10)
P.location(window.get_width()/2, 0)
def draw_map():
window.fill(pygame.Color('blue'))
def draw_player():
player = Player(50,50)
all_sprite_list.add(player)
def game_loop():
GameQuit = False
while not GameQuit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
GameQuit = True
# Pass the event to all objects that need it.
P.keys(event)
draw_map()
P.do()
pygame.display.update()
clock.tick(30)
game_loop()
pygame.quit()
I am trying to move this rectangle to make Pong. I had it working before but I messed up the code.
Could anyone help me make it move and possibly make my code look cleaner?
Again, I made it move, but the problem seems to be in the Update method.
Possibly the ScreenSide parameter???...
import pygame, sys, random
from pygame.locals import *
pygame.init()
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((800, 600))
rectImg1 = 'Rect.jpg'
rectImg2 = 'Rect2.jpg'
RIGHT = "RIGHT"
LEFT = "LEFT"
WHITE = (255,255,255)
FPS = 30
PADDLE_SPEED = 5
BALL_SPEED = 10
fpsClock = pygame.time.Clock()
xPos = 0
yPos = 0
leftY = 20
rightY = 20
class Paddle(pygame.sprite.Sprite):
def __init__(self, screenSide):
pygame.sprite.Sprite.__init__(self)
self.screenSide = screenSide
if self.screenSide == LEFT:
self.image = pygame.image.load(rectImg1).convert_alpha()
self.rect = self.image.get_rect()
self.rect.x = 20
self.rect.y = 20
def update(self):
if self.screenSide == LEFT:
self.y = leftY
allSpritesGroup = pygame.sprite.Group()
paddle = Paddle(LEFT)
allSpritesGroup.add(paddle)
#code to make it move
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if paddle.screenSide == LEFT:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_s:
paddle.y += PADDLE_SPEED
elif event.key == pygame.K_w:
paddle.y -= PADDLE_SPEED
elif event.type == pygame.KEYUP:
if event.key == pygame.K_s or event.key == pygame.K_w:
paddle.y == 0
screen.fill((255,255,255))
allSpritesGroup.draw(screen)
allSpritesGroup.update()
pygame.display.flip()
fpsClock.tick(FPS)
pygame.quit()
Just a guess but your problem might be in:
elif event.type == pygame.KEYUP:
if event.key == pygame.K_s or event.key == pygame.K_w:
paddle.y == 0
This looks more like a comparison and if not then you're setting the y to 0 whenever you let go of a key.
Also, You're right about the update function:
def update(self):
if self.screenSide == LEFT:
self.y = leftY
You're constantly setting the y to 20 so it won't move since every time it updates its moved to 20.
Your event handling is broken. The KEYDOWN and KEYUP events are outside of the event loop because of this line if paddle.screenSide == LEFT:. You also need to update paddle.rect.y not paddle.y and you should do that in the class not with global variables. I'd give the paddles a self.y_speed attribute which you set in the event loop and then use it to update the self.rect.y position each frame in the update method. And remove the screenSide checks and just pass the image and position to the sprites during the instantiation.
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
screen_rect = screen.get_rect()
rectImg1 = pygame.Surface((30, 50))
rectImg1.fill((20, 20, 120))
rectImg2 = pygame.Surface((30, 50))
rectImg2.fill((120, 10, 20))
WHITE = (255,255,255)
FPS = 30
PADDLE_SPEED = 5
fpsClock = pygame.time.Clock()
class Paddle(pygame.sprite.Sprite):
def __init__(self, image, pos):
pygame.sprite.Sprite.__init__(self)
self.image = image
self.rect = self.image.get_rect(topleft=pos)
self.y_speed = 0
def update(self):
self.rect.y += self.y_speed
allSpritesGroup = pygame.sprite.Group()
paddle = Paddle(rectImg1, (20, 20))
paddle2 = Paddle(rectImg2, (750, 20))
allSpritesGroup.add(paddle, paddle2)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_s:
paddle.y_speed = PADDLE_SPEED
elif event.key == pygame.K_w:
paddle.y_speed = -PADDLE_SPEED
elif event.type == pygame.KEYUP:
if event.key == pygame.K_s or event.key == pygame.K_w:
paddle.y_speed = 0
allSpritesGroup.update()
screen.fill(WHITE)
allSpritesGroup.draw(screen)
pygame.display.flip()
fpsClock.tick(FPS)
I am attempting to build a simple game with two sprites. I can't figure out how to add code that detects if a sprite is touching the other. I am also having trouble understanding the countless tutorials on this topic. If you could try and explain this to me as simply as possible that would be amazing!
import pygame
import sys
from pygame.locals import *
pygame.init()
black = (0, 0, 0)
white = (255, 255, 255)
bg = black
square = pygame.image.load('square.png')
square1 = pygame.image.load('square1.png')
screen = pygame.display.set_mode((640, 400))
UP = 'UP'
DOWN = 'DOWN'
LEFT = 'LEFT'
RIGHT = 'RIGHT'
direction = RIGHT
movex, movey, movex1, movey1 = 100, 100, 200, 200
class player1(pygame.sprite.Sprite):
"""Player 1"""
def __init__(self, xy):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('square.png')
self.rect = self.image.get_rect()
class player2(pygame.sprite.Sprite):
"""Player 2"""
def __init__(self, xy):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('square1.png')
self.rect = self.image.get_rect()
while True:
screen.fill(black)
collide = pygame.sprite.collide_mask(player1, player2)
if collide == True:
print 'collision!'
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_w:
movey -= 10
elif event.key == K_s:
movey += 10
elif event.key == K_a:
movex -= 10
elif event.key == K_d:
movex += 10
if event.key == K_UP:
movey1 -= 10
elif event.key == K_DOWN:
movey1 += 10
elif event.key == K_LEFT:
movex1 -= 10
elif event.key == K_RIGHT:
movex1 += 10
if event.type == QUIT:
pygame.quit()
sys.exit()
screen.blit(square, (movex, movey))
screen.blit(square1, (movex1, movey1))
pygame.display.update()
Some issues first:
pygame.sprite.collide_mask never returns True. It returns a point or None. So your check collide == True will never be evaluate to True
pygame.sprite.collide_mask excepts two Sprite instances, but you call it with class objects as arguments (collide_mask(player1, player2))
You only need pygame.sprite.collide_mask when you want to do pixel perfect collision detection
You actually don't use the classes player1 and player2 in the rest of your code
If you're using the Sprite class, a simply way for collision detection is to use the Group class. But since you only have two Sprites, you can simple check for an intersection of their Rects using colliderect.
I've updated your code to make use of the Sprite class:
import pygame
import sys
from pygame.locals import *
pygame.init()
black = (0, 0, 0)
white = (255, 255, 255)
screen = pygame.display.set_mode((640, 400))
class Player(pygame.sprite.Sprite):
def __init__(self, image, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(image)
self.rect = self.image.get_rect(x=x, y=y)
player1, player2 = Player('square.png', 100, 100), Player('square1.png', 200, 200)
players = pygame.sprite.Group(player1, player2)
while True:
screen.fill(black)
if player1.rect.colliderect(player2.rect):
print 'collision!'
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_w:
player1.rect.move_ip(0, -10)
elif event.key == K_s:
player1.rect.move_ip(0, 10)
elif event.key == K_a:
player1.rect.move_ip(-10, 0)
elif event.key == K_d:
player1.rect.move_ip(10, 0)
if event.key == K_UP:
player2.rect.move_ip(0, -10)
elif event.key == K_DOWN:
player2.rect.move_ip(0, 10)
elif event.key == K_LEFT:
player2.rect.move_ip(-10, 0)
elif event.key == K_RIGHT:
player2.rect.move_ip(10, 0)
if event.type == QUIT:
pygame.quit()
sys.exit()
players.draw(screen)
pygame.display.update()
Collision detection is a broad topic, but this should get you started.