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.
Related
I am having problems with making a homing algorithm to move an enemy towards a player in a game. For some reason, the algorithm works sometimes, but as you move the player around, the enemy gets to points where it just stops even though there is still a difference between the player x and y variables and the enemy x and y variables (which the code should be applying to the enemy at all times). If you run the code you'll see what I mean.
Here is my code:
import pygame
import sys, os, random
from pygame.locals import *
from pygame import mixer
import math
clock = pygame.time.Clock()
screen_width = 700
screen_height = 700
screen = pygame.display.set_mode((screen_width, screen_height))
player_rect = pygame.Rect(200, 200, 10, 10)
moving_left = False
moving_right = False
moving_down = False
moving_up = False
hunter_rect = pygame.Rect(500, 500, 48, 60)
player_rect.x = 300
player_rect.y = 200
while True:
screen.fill((50, 50, 50))
#screen.blit(player, (player_rect.x, player_rect.y))
#screen.blit(hunter, (hunter_rect.x, hunter_rect.y))
pygame.draw.rect(screen, (255, 255, 255), player_rect)
pygame.draw.rect(screen, (255, 0, 0), hunter_rect)
#### getting the change in y and the change in x from enemy to player ###
ychange = (hunter_rect.y - player_rect.y)/100
xchange = (hunter_rect.x - player_rect.x)/100
hunter_rect.x -= xchange
hunter_rect.y -= ychange
if moving_left:
player_rect.x -= 4
if moving_right:
player_rect.x += 4
if moving_up:
player_rect.y -= 4
if moving_down:
player_rect.y += 4
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
pygame.quit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if event.key == K_a:
moving_left = True
if event.key == K_d:
moving_right = True
if event.key == K_s:
moving_down = True
if event.key == K_w:
moving_up = True
if event.type == KEYUP:
if event.key == K_a:
moving_left = False
if event.key == K_d:
moving_right = False
if event.key == K_w:
moving_up = False
if event.key == K_s:
moving_down = False
pygame.display.update()
clock.tick(60)
Since pygame.Rect is supposed to represent an area on the screen, a pygame.Rect object can only store integral data.
The coordinates for Rect objects are all integers. [...]
The fraction part of the movement gets lost when the movement is add to the position of the rectangle.
If you want to store object positions with floating point accuracy, you have to store the location of the object in separate variables and to synchronize the pygame.Rect object. round the coordinates and assign it to the location (e.g. .topleft) of the rectangle:
hunter_rect = pygame.Rect(500, 500, 48, 60)
hunter_x, hunter_y = hunter_rect.topleft
# [...]
while True:
# [...]
hunter_x -= xchange
hunter_y -= ychange
hunter_rect.topleft = round(hunter_x), round(hunter_y)
# [...]
I'm trying to make the snake game in python, but sadly my snake and my apples aren't appearing on the screen, all i see is a gray screen with nothing on it, can you help me out? thanks!
P.S - i would like an explanation as well about why my current code isn't working so i would avoid it in the future, thanks again.
import pygame, sys, random, time
from pygame.locals import *
pygame.init()
mainClock = pygame.time.Clock()
windowWidth = 500
windowHeight = 500
windowSurface = pygame.display.set_mode((windowWidth, windowHeight), 0, 32)
red = (255, 0, 0)
green = (0, 255, 0)
color = (100, 100, 100)
snakeHead = [250, 250]
snakePosition = [[250, 250],[240, 250],[230, 250]]
applePosition = [random.randrange(1,50)*10,random.randrange(1,50)*10]
def collisionBoundarias(snakeHead):
if snakeHead[0] >= 500 or snakeHead[0] < 0 or snakeHead[1] >= 500 or snakeHead[1] < 0:
return 1
else:
return 0
def collisionSelf(SnakePosition):
snakeHead = snakePosition[0]
if snakeHead in snakePosition[1:]:
return 1
else:
return 0
while True:
windowSurface.fill(color)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.type == pygame.K_RIGHT or event.key == pygame.K_d:
snakeHead[0] += 10
if event.type == pygame.K_LEFT or event.key == pygame.K_a:
snakeHead[0] -= 10
if event.type == pygame.K_UP or event.type == pygame.K_w:
snakeHead[1] += 10
if event.type == pygame.K_DOWN or event.type == pygame.K_s:
snakeHead[1] -= 10
def displaySnake(snakePosition):
for position in snakePosition:
pygame.draw.rect(windowSurface ,red,pygame.Rect(position[0],position[1],10,10))
def display_apple(windowSurface, applePosition, apple):
windowSurface.blit(apple ,(applePosition[0], applePosition[1]))
snakePosition.insert(0,list(snakeHead))
snakePosition.pop()
def displayFinalScore(displayText, finalScore):
largeText = pygame.font.Font('freesansbold.ttf',35)
TextSurf = largeText.render(displayText, True, (255, 255, 255))
TextRect = TextSurf.get_rect()
TextRect.center = ((windowWidth/2),(windowHeight/2))
windowSurface.blit(TextSurf, TextRect)
pygame.display.update()
time.sleep(2)
def collisionApple(applePosition, score):
applePosition = [random.randrange(1,50)*10,random.randrange(1,50)*10]
score += 1
return applePosition, score
if snakeHead == applePosition:
applePosition, score = collisionApple(applePosition, score)
snakePosition.insert(0,list(snakeHead))
pygame.display.update()
clock = pygame.time.Clock()
clock.tick(20)
As mentioned in the comments, the objects don't appear because you never draw them by calling the displaySnake and display_apple functions. It also makes no sense to define these functions in the while loop again and again.
Here's a fixed version of the code. I've changed the movement code, so that the snake moves continually each frame. (It could still be improved, but I tried to keep it simple.)
import pygame, sys, random, time
from pygame.locals import *
pygame.init()
mainClock = pygame.time.Clock()
windowWidth = 500
windowHeight = 500
windowSurface = pygame.display.set_mode((windowWidth, windowHeight), 0, 32)
clock = pygame.time.Clock()
red = (255, 0, 0)
green = (0, 255, 0)
color = (100, 100, 100)
snakeHead = [250, 250]
snakePosition = [[250, 250],[240, 250],[230, 250]]
applePosition = [random.randrange(1,50)*10,random.randrange(1,50)*10]
apple = pygame.Surface((10, 10))
apple.fill(green)
score = 0
speed = 10
# Define a velocity variable (a list or better a pygame.Vector2).
velocity = pygame.Vector2(speed, 0)
def collisionBoundarias(snakeHead):
return snakeHead[0] >= 500 or snakeHead[0] < 0 or snakeHead[1] >= 500 or snakeHead[1] < 0
def collisionApple(applePosition, score):
applePosition = [random.randrange(1,50)*10,random.randrange(1,50)*10]
score += 1
return applePosition, score
def displaySnake(snakePosition):
for position in snakePosition:
pygame.draw.rect(windowSurface, red, pygame.Rect(position[0], position[1], 10, 10))
def display_apple(windowSurface, applePosition, apple):
windowSurface.blit(apple, (applePosition[0], applePosition[1]))
while True:
# Event handling.
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
# Replace `type` with `key`.
if event.key == pygame.K_RIGHT or event.key == pygame.K_d:
velocity.x = speed
velocity.y = 0
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
velocity.x = -speed
velocity.y = 0
if event.key == pygame.K_UP or event.key == pygame.K_w:
velocity.x = 0
velocity.y = -speed
if event.key == pygame.K_DOWN or event.key == pygame.K_s:
velocity.x = 0
velocity.y = speed
# Game logic.
snakeHead[0] += velocity.x # Update the x-position every frame.
snakeHead[1] += velocity.y # Update the y-position every frame.
snakePosition.insert(0, snakeHead)
snakePosition.pop()
if snakeHead == applePosition:
applePosition, score = collisionApple(applePosition, score)
snakePosition.insert(0, snakeHead)
# Drawing.
windowSurface.fill(color)
displaySnake(snakePosition)
display_apple(windowSurface, applePosition, apple)
pygame.display.update()
clock.tick(20)
#sprites
import random, sys, time, math, pygame
from pygame.locals import *
from pygame import mixer # Load the required library
FPS = 30 # frames per second to update the screen
fpsClock = pygame.time.Clock()
WINWIDTH = 1500 # width of the program's window, in pixels
WINHEIGHT = 1000 # height in pixels
HALF_WINWIDTH = int(WINWIDTH / 2)
HALF_WINHEIGHT = int(WINHEIGHT / 2)
moveX,moveY=0,0
move2X,move2Y=0,0
GRASSCOLOR = (24, 255, 0)
WHITE = (255, 255, 255)
PURPLE = (128, 0, 128)
RED = (255, 0, 0)
pygame.init()
global FPSCLOCK, DISPLAYSURF, self
DISPLAYSURF = pygame.display.set_mode((WINWIDTH, WINHEIGHT))
pygame.display.set_icon(pygame.image.load('god.png'))
pygame.display.set_caption('Smash Bros Melee')
BASICFONT = pygame.font.Font('freesansbold.ttf', 32)
class Sprite:
def __init__(self,x,y):
self.x=x
self.y=y
self.width=50
self.height=50
self.i0= pygame.image.load('ryanrenolds.jpeg')
self.timeTarget=10
self.timeNum=0
self.currentImage=0
def render(self):
DISPLAYSURF.blit(self.i0, (self.x, self.y))
player=Sprite(0,0)
class Sprite2:
def __init__(self,x,y):
self.x=x
self.y=y
self.width=50
self.height=50
self.i0= pygame.image.load('ArkhamKnight.png')
self.i1= pygame.image.load('Black-Panther.png')
self.timeTarget=10
self.timeNum=0
self.currentImage=0
def update(self):
self.timeNum+=1
if (self.timeNum==self.timeTarget):
if (self.currentImage==0):
self.currentImage+=1
else:
self.currentImage=0
self.timeNum=0
self.render()
def render(self):
if(self.currentImage==0):
DISPLAYSURF.blit(self.i0, (self.x, self.y))
else:
DISPLAYSURF.blit(self.i1, (self.x, self.y))
player2=Sprite2(200,300)
def checkCollision(Sprite, Sprite2):
col = Sprite.rect.colliderect(Sprite2.rect)
if col == True:
sys.exit()
while True:
for event in pygame.event.get():
if event.type == KEYUP:
if event.key == K_a:
moveX = moveX - 0
elif event.key == K_d:
moveX == False
elif event.key == K_w:
moveY == False
elif event.key == K_s:
moveY == False
if (event.type==pygame.KEYDOWN):
if (event.key==pygame.K_a):
moveX = moveX - 5
elif (event.key==pygame.K_d):
moveX = moveX + 5
elif (event.key==pygame.K_w):
moveY = moveY - 5
elif (event.key==pygame.K_s):
moveY = moveY + 5
elif (event.key==pygame.K_ESCAPE):
pygame.quit()
sys.exit()
if event.type == KEYUP:
if event.key == K_LEFT:
move2X = move2X - 0
elif event.key == K_RIGHT:
move2X == False
elif event.key == K_UP:
move2Y == False
elif event.key == K_DOWN:
move2Y == False
if (event.type==pygame.KEYDOWN):
if (event.key==pygame.K_LEFT):
move2X = move2X - 5
elif (event.key==pygame.K_RIGHT):
move2X = move2X + 5
elif (event.key==pygame.K_UP):
move2Y = move2Y - 5
elif (event.key==pygame.K_DOWN):
move2Y = move2Y + 5
elif (event.key==pygame.K_o):
player=Sprite(0,0)
player2=Sprite2(200,300)
elif (event.key==pygame.K_ESCAPE):
pygame.quit()
sys.exit()
DISPLAYSURF.fill(PURPLE)
player.x+=moveX
player.y+=moveY
player2.x+=move2X
player2.y+=move2Y
player.render()
player2.update()
checkCollision(Sprite, Sprite2)
pygame.display.update()
fpsClock.tick(FPS)
pygame.quit()
sys.exit()
how do i get to wear my sprites will collide my collide direct code asks for three arguements when i used self in the parameters but when i took self out it says that class Sprite has no attribute 'rect'
This the error i keep getting how do i fix this to where my game works to where my sprites will exit the game if they collide with each other
Traceback (most recent call last):
File "C:\Python27\Sprites\sprites.py", line 159, in
checkCollision(Sprite, Sprite2)
File "C:\Python27\Sprites\sprites.py", line 88, in checkCollision
col = Sprite.rect.colliderect(Sprite2.rect)
AttributeError: class Sprite has no attribute 'rect'
You don't have the attribute rect in your Sprite class, which is causing this problem. You also need an attribute rect in your Sprite2 class. You can do this by using the get_rect() method.
You can do this in your Sprite class by entering this in the __init__(self)
self.rect = self.i0.get_rect()
And for the Sprite2 class you can do this (because displayed image can change, put this in the update().)
if self.currentImage == 0:
self.rect = self.i0.get_rect()
elif self.currentImage == 1:
self.rect = self.i1.get_rect()
I hope this helps.
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'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.