The simplest is to use self.rect
in Snow
and compare with window rect which you can get dis.get_rect()
dis_rect = dis.get_rect()
if snowman.rect.left < dis_rect.left:
snowman.rect.left = dis_rect.left:
if snowman.rect.right > dis_rect.right:
snowman.rect.right = dis_rect.right:
if snowman.rect.top < dis_rect.top:
snowman.rect.top = dis_rect.top:
if snowman.rect.bottom < dis_rect.bottom:
snowman.rect.bottom = dis_rect.bottom:
but this also need to keep position in self.rect
instead of self.x
, self.y
def move_right(self):
self.move(10, 0)
def move_left(self):
self.move(-10, 0)
def move_up(self):
self.move(0, -10)
def move_down(self):
self.move(0, 10)
def move(self, dx, dy):
self.rect.x += dx
self.rect.y += dy
BTW: there is no need to use prefix snow
in functions and variables in Snow
. Later it can be simpler when all objects have the same names of functions - ie. .move_left()
- because you can put all of objects on list and use for
-loop to run the same function for all of objects. PyGame has even pygame.sprite.Group()
for this.
Rect
has also method to detect
collision with point
snowman.rect.colliderect(mouse_pos)
which you can use to detect mouse on object or click on button
collision with other rect
snowman.rect.colliderect(zombie.rect)
but it gives only True/False but it doesn't give information if it was collision on left, right, top or bottom - so common method is to check it in two steps. First move left/right and check collision - and if there was collision then: if speed_x > 0 (so you move right) then collision on right, if speed_y < 0 (so you move left) then collision on left. Second move top/bottom and check collision again - and if there was collision then: if speed_y > 0 (so you move down) then collision on bottom, if speed_y < 0 (so you move up) then collision on top.
EDIT:
Full working code
import pygame
#from pygame.math import Vector2
# --- constants --- # PEP8: `UPPER_CASE_NAME` for constants
DIS_WIDTH = 1000 # PEP8: spaces around `=`
DIS_HEIGHT = 1000
WHITE = (255, 255, 255)
CYAN = (153, 255, 255)
RED = (255, 0, 0)
GREEN = ( 0, 255, 0)
BLUE = ( 0, 0, 255)
# --- classes --- # PEP8: `CamelCaseName` for classes
# PEP8: `lower_case_name` for functions
class Snow:
def __init__(self, x, y, color):
#self.image = pygame.image.load("Snowperson1.png")
self.image = pygame.Surface((25, 75))
self.image.fill(color)
self.rect = self.image.get_rect(centerx=x, centery=y)
self.vel_x = 0
self.vel_y = 0
def draw(self, window):
window.blit(self.image, self.rect)
def move_right(self):
self.vel_x = 10
def move_left(self):
self.vel_x = -10
def move_up(self):
self.vel_y = -10
def move_down(self):
self.vel_y = 10
def update(self, zombie):
#print(self.vel_x, self.vel_y)
# --- X ---
self.rect.x += self.vel_x
# window border - left,right
if self.rect.left < dis_rect.left:
self.rect.left = dis_rect.left
if self.rect.right > dis_rect.right:
self.rect.right = dis_rect.right
# collisions with zombie - left,right
if self.rect.colliderect(zombie.rect):
if self.vel_x > 0:
self.rect.right = zombie.rect.left
elif self.vel_x < 0:
self.rect.left = zombie.rect.right
# --- Y ---
self.rect.y += self.vel_y
# window border - top,bottom
if self.rect.top < dis_rect.top:
self.rect.top = dis_rect.top
if self.rect.bottom > dis_rect.bottom:
self.rect.bottom = dis_rect.bottom
# collisions with zombie - top,bottom
if self.rect.colliderect(zombie.rect):
if self.vel_y > 0:
self.rect.bottom = zombie.rect.top
elif self.vel_y < 0:
self.rect.top = zombie.rect.bottom
# --- main ---
pygame.init()
dis = pygame.display.set_mode((DIS_WIDTH, DIS_HEIGHT))
dis_rect = dis.get_rect()
pygame.display.set_caption("Snowperson game")
pygame.key.set_repeat(100, 100) # PEP8: space after comma
# - objects -
snowman = Snow(50, 50, BLUE) # PEP8: space after `,`
zombie = Snow(150, 150, GREEN) # PEP8: space after `,`
# - mainloop -
while True:
# - draw -
dis.fill(CYAN)
snowman.draw(dis)
zombie.draw(dis)
pygame.draw.rect(dis, RED, (0, 0, 1000, 1000), 2)
pygame.display.flip()
# - move -
snowman.vel_x = 0
snowman.vel_y = 0
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
if event.key==pygame.K_ESCAPE:
pygame.quit()
elif event.key == pygame.K_UP:
snowman.move_up()
elif event.key == pygame.K_DOWN:
snowman.move_down()
elif event.key == pygame.K_RIGHT:
snowman.move_right()
elif event.key == pygame.K_LEFT:
snowman.move_left()
# - update - move and check collision -
snowman.update(zombie)
```
Rect()
to have rectangle hitbox and use functionscolliderect()
,collidepoint()
to detect collision. You can even keep few Rect() to check every region separatelly. And finally PyGame can usemask
(black&white image) to detect collisions - but this can make more CPU power. \$\endgroup\$def x(self): self.x
anddef y(self): self.y
- first it would needreturn
to get value, second class can't have at the same time variable with namex
and method with namex
. Method will replace variable. \$\endgroup\$pygame.Rect.colliderect
(to detect collision with otherRect
) andpygame.Rect.collidepoint
(to detect collision with mouse position) in pygame.Rect(). You can also getRect()
forwindow
and usepygame.Rect.contain
to check if object is fully insidewindow
\$\endgroup\$snow
in functions/variables in classShow
. It will be simpler to keep objects on list and run the same functions for all objects - ie..move_left()
(for obj in [snowman, zombie]: obj.move_left()
) \$\endgroup\$