Why doesn't my sprite move correctly in pygame? - python

My second game is a platformer. I drew all the spites, drew the background and the platform, but I cant move my character more than 45 pixels one way, even when it is supposed to move 5 pixels. I also copied some code from here and there, so I cant just search it up. This is very puzzling, please help.
Here is the code:
import sys
import pygame
screen = pygame.display.set_mode((1300, 700), pygame.RESIZABLE)
global bg
bg = pygame.image.load('Pictures/badground.png')
w = (0, 0, 0)
screen.fill(w)
screen.blit(bg, (0, 0))
level = 0
walking_l = (pygame.image.load('Pictures/walk_l.png'))
walking_r = (pygame.image.load('Pictures/walk_r.png'))
walking_l_2 = (pygame.image.load('Pictures/_stand.png'))
walking_r_2 = (pygame.image.load('Pictures/stand.png'))
stand = (pygame.image.load('Pictures/rstand.png'))
pf = (pygame.image.load('Pictures/platform.png'))
pygame.display.set_caption('Platformed')
class player(object):
def __init__(self, speed, width, height):
self.speed = speed
self.x = 650
self.y = 350
self.width = width
self.height = height
self.walk_l = False
self.walk_r = False
self.stand = True
self.jump = False
self.walk_count = 0
def reprint_win(self):
screen.fill(w)
screen.blit(bg, (0, 0))
def walk(self):
k = pygame.key.get_pressed()
if k[pygame.K_a]:
self.x -= self.speed
self.stand = False
self.walk_l = True
self.walk_r = False
self.jump = False
print(self.x)
screen.fill(w)
screen.blit(bg, (0, 0))
elif k[pygame.K_d]:
self.x += self.speed
self.stand = False
self.walk_r = True
self.walk_l = False
self.jump = False
print(self.y)
screen.fill(w)
screen.blit(bg, (0, 0))
elif k[pygame.K_w] and self.walk_r and not self.jump:
self.stand = False
self.walk_r = True
self.walk_l = False
self.jump = True
screen.fill(w)
screen.blit(bg, (0, 0))
else:
self.stand = True
self.walk_r = False
self.walk_l = False
self.jump = False
screen.fill(w)
screen.blit(bg, (0, 0))
while True:
for e in pygame.event.get():
man = player(5, 64, 64)
if e.type == pygame.QUIT:
sys.exit()
if e.type == pygame.KEYDOWN:
man.walk()
screen.blit(stand, (man.x, man.y))
pygame.display.update()
elif e.type == pygame.KEYDOWN:
man.walk()
screen.blit(stand, (man.x, man.y))
pygame.display.update()

The method walk() of the class player changes the instance attribute, but id doesn't draw anything.
Add a method draw, which draw the player dependent on the instance attributes:
class player(object):
# [...]
def walk(self):
self.stand, self.walk_l, self.walk_r, self.jump = False, False, False, False
k = pygame.key.get_pressed()
if k[pygame.K_a]:
self.x -= self.speed
self.walk_l = True
elif k[pygame.K_d]:
self.x += self.speed
self.walk_r = True
elif k[pygame.K_w] and self.walk_r and not self.jump:
self.jump = True
else:
self.stand = True
def draw(self, surf):
if self.walk_l:
surf.blit(walking_l, (self.x, self.y))
elif self.walk_r:
surf.blit(walking_r, (self.x, self.y))
else:
surf.blit(stand, (self.x, self.y))
You have to draw the entire scene in every frame. Do the drawing to the application loop rather then the event loop.
Furthermore the instance of palyer has to be created before the application loop and invoke man.mvoe() in every frame.
Use pygame.time.Clock() .tick() to control the frames per second:
man = player(5, 64, 64)
clock = pygame.time.Clock()
FPS = 60
while True:
clock.tick(FPS)
for e in pygame.event.get():
if e.type == pygame.QUIT:
sys.exit()
man.walk()
screen.blit(bg, (0, 0))
man.draw(screen)
pygame.display.update()

Related

Pygame (changing simple rectangle to image) [duplicate]

This question already has an answer here:
Replace a rectangle with an Image in Pygame
(1 answer)
Closed last year.
So I don't know how to turn the rectangle representing the player into an image (spaceship). I know it must be simple, but after a few hours with this I'm a little frustrated, so I'm looking for help :(
bg_color = pygame.Color('black')
text_color = pygame.Color('darkgrey')
obstacles_color = pygame.Color('darkred')
player_color = pygame.Color('yellow')
fps = 60
window_height = 1200
window_width = 1200
player_speed = 4
player_size = 8
player_max_up = 125
obstacle_spawn_rate = 1
obstacle_min_size = 3
obstacle_max_size = 6
obstacle_min_speed = 2
obstacle_max_speed = 2
class Player:
def __init__(self):
self.size = player_size
self.speed = player_speed
self.color = player_color
self.position = (window_width / 2, (window_height - (window_height / 10)))
def draw(self, surface):
r = self.get_rect()
pygame.draw.rect(surface, self.color, r)
def move(self, x, y):
newX = self.position[0] + x
newY = self.position[1] + y
if newX < 0 or newX > window_width - player_size:
newX = self.position[0]
if newY < window_height - player_max_up or newY > window_height - player_size:
newY = self.position[0]
self.position = (newX, newY)
def collision_detection(self, rect):
r = self.get_rect()
return r.colliderect(rect)
def get_rect(self):
return pygame.Rect(self.position, (self.size, self.size))
class Obstacles:
def __init__(self):
self.size = random.randint(obstacle_min_size, obstacle_max_size)
self.speed = random.randint(obstacle_min_speed, obstacle_max_speed)
self.color = obstacles_color
self.position = (random.randint(0, window_width - self.size), 0 - self.size)
def draw(self, surface):
r = self.get_rect()
pygame.draw.rect(surface, self.color, r)
def move(self):
self.position = (self.position[0], self.position[1] + self.speed)
def is_off_window(self):
return self.position[1] > window_height
def get_rect(self):
return pygame.Rect(self.position, (self.size, self.size))
class World:
def __init__(self):
self.reset()
def reset(self):
self.player = Player()
self.obstacles = []
self.gameOver = False
self.score = 0
self.obstacles_counter = 0
self.moveUp = False
self.moveDown = False
self.moveLeft = False
self.moveRight = False
def is_game_over(self):
return self.gameOver
def update(self):
self.score += 1
if self.moveUp:
self.player.move(0, - player_speed)
if self.moveUp:
self.player.move(0, player_speed)
if self.moveLeft:
self.player.move(-player_speed, 0)
if self.moveRight:
self.player.move(player_speed, 0)
for each in self.obstacles:
each.move()
if self.player.collision_detection(each.get_rect()):
self.gameOver = True
if each.is_off_window():
self.obstacles.remove(each)
self.obstacles_counter += 1
if self.obstacles_counter > obstacle_spawn_rate:
self.obstacles_counter = 0
self.obstacles.append(Obstacles())
def draw(self, surface):
self.player.draw(surface)
for each in self.obstacles:
each.draw(surface)
def movement_keys(self, event):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
self.moveUp = True
if event.key == pygame.K_DOWN:
self.moveDown = True
if event.key == pygame.K_LEFT:
self.moveLeft = True
if event.key == pygame.K_RIGHT:
self.moveRight = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
self.moveUp = False
if event.key == pygame.K_DOWN:
self.moveDown = False
if event.key == pygame.K_LEFT:
self.moveLeft = False
if event.key == pygame.K_RIGHT:
self.moveRight = False
def run():
pygame.init()
clock = pygame.time.Clock()
window = pygame.display.set_mode((window_height, window_width))
pygame.display.set_caption("Avoid Obstacles")
surface = pygame.Surface(window.get_size())
surface = surface.convert()
world = World()
font = pygame.font.SysFont("Times", 35, "bold")
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN and event.key == ord("r"):
world.reset()
else:
world.movement_keys(event)
if not world.is_game_over():
world.update()
window.fill(bg_color)
clock.tick(fps)
world.draw(window)
surface.blit(surface, (0, 0))
text = font.render("Score {0}".format(world.score), 1, text_color)
window.blit(text, (1, 1))
if world.is_game_over():
end = font.render("The end of your journey", 1, text_color)
window.blit(end, (window_width / 2 - 220, window_height / 2))
restart = font.render("Hit R to reset", 1, text_color)
window.blit(restart, (window_width / 2 - 120, window_height / 2 + 45))
pygame.display.update()
if __name__ == '__main__':
run()
pygame.quit()
I tried changing the draw function in the Player class, but still couldn't figure out how to do it correctly. I'm drawing an image of the spaceship on the screen/window, but I can't get it to move to the player rectangle.
I don't know what you've tried, but here's how to do this with a call to blit:
myimage = pygame.image.load("bar.png")
...
def draw(self, surface):
r = self.get_rect()
surface.blit(myimage, r)
The key point here is that you're giving blit the same coordinates that you were using to draw the rectangle. When I tried this, I got the correct/natural size of the image even though the r rectangle is of different dimensions. If that turns out to cause a problem, you could adjust the dimensions of the rectangle to be the same as the image. You also might want to adjust the coordinates of r such that the image is drawn centered on the location at which you wish to draw it.
The 'draw' family of functions are convenience functions that create Surface objects and then paint pixels on it that correspond to basic shapes (like circles, rectangles etc, filled or otherwise).
Instead, you need to create a Surface where the pixels have been initialised via an image. For this, you need the "image" family of functions (see https://www.pygame.org/docs/ref/image.html for image functions).
Other than that, everything in pygame is a surface, and you're manipulating and updating surfaces on the display, so your code should not change, whether your surfaces were initialised via 'draw' or 'image'.

One click activates multiple buttons if overlapping

Alright, so yes, I get that it is a lot of code I am about to display.
My problem: I am making a zombie shooter game where you are the main character on top of a building and you have to click on zombies as they come in waves. My current problem is whenever multiple zombies overlap on top of each other, I can kill both of them (or as many are overlapping) in one click because technically, all of their hitboxes are colliding.
If this is a bigger problem than sought out to be, I would like someone to just say that.
import pygame
import random
import time
pygame.init()
#Setting Variables
screenW = 1020
screenH = 630
x = 125
y = 164
width = 50
height = 50
velocity = 5
wave = 2
GOLD = (255, 215, 0)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 128, 0)
wallHealth = 0
zombieKilled = 0
class ZombieChars():
def __init__(self):
self.damage = 0
self.vel = 5
self.x_change = random.randrange(2,5)
self.y_change = 1
self.height = 120
self.width = 149
self.color = random.sample(range(250), 4)
self.image = pygame.Surface([self.width, self.height], pygame.HWSURFACE, 32)
self.rect = self.image.get_rect(topleft = (random.randrange(900, 1150), 330))
#pygame.draw.rect(self.image, (self.color), (self.x, self.y, self.width, self.height))
def draw(self):
window.blit(ZombieWalking, self.rect.topleft)
def update(self):
if self.rect.x >= 364:
self.rect.x -= self.x_change
else:
self.rect.x -= 0
def wallHP(self):
global wallHealth
if self.rect.x < 365:
self.damage += 1
if self.damage == 30:
self.damage = 0
wallHealth += 1
def death(self):
global zombieKilled
if event.type == pygame.MOUSEBUTTONDOWN:
gunShot.play()
mouse_pos = event.pos
if self.rect.collidepoint(mouse_pos):
self.rect.x = 5000
self.rect.x -= self.x_change
zombieHit.play()
zombieKilled += 1
print(zombieKilled)
def waveCounter(self):
global wave
print(wave)
if wave == zombieKilled / 2:
wave = 2
#FPS
clock = pygame.time.Clock()
clock.tick(60)
#Screen
window = pygame.display.set_mode((screenW,screenH))
pygame.display.set_caption(("Zombie Shooter"))
#Image Loading
bg = pygame.image.load("bg.jpg")
mainmenu = pygame.image.load("mainmenu.jpg")
ZombieWalking = pygame.image.load("Sprites/AAIdle.png")
#Sound Loading
gunShot = pygame.mixer.Sound('sounds/gunShot.wav')
zombieHit = pygame.mixer.Sound('sounds/zombieHit.wav')
gameMusic = pygame.mixer.music.load('sounds/gameMusic.mp3')
menuMusic = pygame.mixer.music.load('sounds/menuMusic.mp3')
zombies = ZombieChars()
my_list = []
for zombs in range(wave):
my_object = ZombieChars()
my_list.append(my_object)
def text_objects(text, font):
textSurface = font.render(text, True, BLACK)
return textSurface, textSurface.get_rect()
smallText = pygame.font.Font('freesansbold.ttf', 30)
tinyText = pygame.font.Font('freesansbold.ttf', 20)
TextSurf3, TextRect3 = text_objects("Wave: " + str(wave), smallText)
TextRect3.center = ((1020 / 2), (50))
#Main Loop
run = True
mainMenu = True
pygame.mixer.music.play()
global event
while mainMenu == True:
window.blit(mainmenu, (0,0))
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False #if x is pressed dont run game
mainMenu = False
keys = pygame.key.get_pressed()
if keys[pygame.K_a]:
mainMenu = False #if a is pressed run game
def wallHPBar():
pygame.draw.rect(window, GREEN, (20, 20, 100, 10))
if wallHealth == 0:
pass
if wallHealth == 1:
pygame.draw.rect(window, RED, (20, 20, 25, 10))
if wallHealth == 2:
pygame.draw.rect(window, RED, (20, 20, 50, 10))
if wallHealth == 3:
pygame.draw.rect(window, RED, (20, 20, 75, 10))
if wallHealth >= 4:
pygame.draw.rect(window, RED, (20, 20, 100, 10))
def overlapKill():
if zombieKilled == 1:
print("oh my goodness we going")
if zombieKilled == 2:
print("we 2 ")
while run:
pygame.mixer.music.stop()
window.blit(bg, (0, 0))
window.blit(TextSurf3, TextRect3)
wallHPBar()
pygame.time.delay(25)
for zombie in my_list:
zombie.draw()
zombie.update()
zombie.death()
zombie.wallHP()
zombie.waveCounter()
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
Thank you.
Remove the event handling from the method death and return a boolean value, that indicates if a zombie was killed:
class ZombieChars():
# [...]
def death(self):
global zombieKilled
mouse_pos = pygame.mouse.get_pos()
if self.rect.collidepoint(mouse_pos):
self.rect.x = 5000
self.rect.x -= self.x_change
zombieHit.play()
zombieKilled += 1
print(zombieKilled)
return True
return False
Do the pygame.MOUSEBUTTONDOWN event handling in the event loop and evaluate if a zombie was killed in a loop. break the loop when a zombie is killed. Thus only one zombie can be get killed on one klick:
while run:
# [...]
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
gunShot.play()
for zombie in (reversed):
if zombie.death():
break
for zombie in my_list:
zombie.draw()
zombie.update()
# zombie.death() <--- DELETE
zombie.wallHP()
zombie.waveCounter()
A Zombie object should not be dealing with user-input. Handle the click outside of the zombie, then the outside code gets to decide if the click is "used up".
class ZombieChars():
[ ... ]
def death( self, mouse_position ):
killed = False
global zombieKilled
if self.rect.collidepoint( mouse_position ):
self.rect.x = 5000
self.rect.x -= self.x_change
zombieHit.play()
zombieKilled += 1
print(zombieKilled)
killed = True
return killed
Then in your main loop, stop processing hits once the first is found:
### Main Loop
while not exiting:
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
exiting = True
elif ( event.type == pygame.MOUSEBUTTONDOWN ):
gunShot.play()
mouse_pos = event.pos
for zombie in my_list:
if ( zombie.death( mouse_pos ) ):
break # stop on first hit

Why are some events don't execute when called?

Python 3.
Hello. I made a game which starts off with a main menu and when 'd' is pressed, it will cut to the game screen.
Before I made this main menu, when I would hold space bar, the shapes would rumble. Now when I press 'd' to start the game, the objects are displayed, but holding space bar doesn't do anything, and neither does pressing escape or closing the game. It seems like the keyboard events / game events are not being called anymore once the 'd' is pressed.
Code:
import pygame
import random
import time
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
# Edit the intensity of the shake (Must be one number apart)
# Ex: a = -100, b = 101. A is negative, B is positive
a = -4
b = 5
up = 10
intensity = (a, b)
startGame = True
# Image Loading
pygame.init()
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("My Game")
done = False
clock = pygame.time.Clock()
class Rectangle():
def __init__(self):
self.x = random.randrange(0, 700)
self.y = random.randrange(0, 500)
self.height = random.randrange(20, 70)
self.width = random.randrange(20, 70)
self.x_change = random.randrange(-3, 3)
self.y_change = random.randrange(-3, 3)
self.color = random.sample(range(250), 4)
def draw(self):
pygame.draw.rect(screen, self.color, [self.x, self.y, self.width, self.height])
def move(self):
self.x += self.x_change
self.y += self.y_change
class Ellipse(Rectangle):
pass
def draw(self):
pygame.draw.ellipse(screen, self.color, [self.x, self.y, self.width, self.height])
def move(self):
self.x += self.x_change
self.y += self.y_change
def text_objects(text, font):
textSurface = font.render(text, True, BLACK)
return textSurface, textSurface.get_rect()
def game_intro():
global event
intro = True
keys = pygame.key.get_pressed()
while intro:
for event in pygame.event.get():
print(event)
if event.type == pygame.QUIT:
pygame.quit()
quit()
screen.fill(WHITE)
largeText = pygame.font.Font('freesansbold.ttf', 45)
smallText = pygame.font.Font('freesansbold.ttf', 30)
TextSurf, TextRect = text_objects("Welcome to Crazy Rumble.", largeText)
TextRect.center = ((700 / 2), (100 / 2))
TextSurff, TextRectt = text_objects("Press enter to start", smallText)
TextRectt.center = ((700 / 2), (900 / 2))
TextStart, TextRecttt = text_objects("Hold space to make the shapes shake!", smallText)
TextRecttt.center = ((700 / 2), (225 / 2))
screen.blit(TextSurf, TextRect)
screen.blit(TextSurff, TextRectt)
screen.blit(TextStart, TextRecttt)
pygame.display.update()
if event.type == pygame.KEYUP:
intro = False
startGame = True
global intro
my_list = []
for number in range(600):
my_object = Rectangle()
my_list.append(my_object)
for number in range(600):
my_object = Ellipse()
my_list.append(my_object)
# -------- Main Program Loop -----------
while not done:
game_intro()
game_intro = True
if event.type == pygame.KEYUP:
game_intro = False
keys = pygame.key.get_pressed()
# --- Main event loop
while game_intro == False:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(BLACK)
for rect in my_list:
rect.draw()
rect.move()
for rectElli in my_list:
rectElli.draw()
if keys[pygame.K_SPACE]:
rectElli.y_change = random.randrange(a, b)
rectElli.x_change = random.randrange(a, b)
rectElli.move()
if keys[pygame.K_UP]:
print(up)
print(intensity)
up += 1
if up % 10 == 0:
a -= 1
b -= -1
else:
a, b = -4, 5
pygame.display.flip()
clock.tick(60)
You're just setting keys once with
keys = pygame.key.get_pressed()
You need to put that call inside the loop, so it gets updated after every event.

Issue extending tail in Snake game Pygame

I'm writing a basic Snake game in Pygame, but the body of the snake is not extending after its eaten 4 pieces of food, nor does it extend after the first bite. I'm creating a new body object after each bite, and storing it in a list. x and y variables are used to store the position of the head prior to its movement, which in turn I use as the coordinates for the first segment of the snake's body. I'm then trying to iterate over this list, creating new objects with the x and y coordinates of the previous body segment to create the tail effect. Why is it stopping short?
import pygame
from pygame.locals import *
import random
import sys
pygame.init()
FPS = 30
fpsClock = pygame.time.Clock()
WIN_WIDTH = 680 #width of window
WIN_HEIGHT = 500 #height of window
DISPLAY = (WIN_WIDTH, WIN_HEIGHT) #variable for screen display
DEPTH = 32 #standard
FLAGS = 0 #standard
BLACK = (0, 0, 0) #black
RED = (255, 0, 0) #red
GOLD = (255, 215, 0)
IDK = (178, 154, 96)
screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
pygame.display.set_caption('Snake')
snake_parts = [1]
Score = 0
speed = 10
snakex = 15
snakey = 70
size = 20
Snakes = 1
# --- classes ---
class Snake(pygame.Rect):
def __init__(self, x, y, screen, size, colour):
pygame.Rect.__init__(self, x, y, size, 20)
self.screen = screen
self.colour = colour
self.x = x
self.y = y
def draw(self, screen):
pygame.draw.rect(self.screen, self.colour, self)
def coordinates(self):
return self.x, self.y
class Food(pygame.Rect):
def __init__(self, x, y, screen):
pygame.Rect.__init__(self, x, y, 20, 20)
self.screen = screen
def draw(self, screen):
pygame.draw.rect(self.screen, GOLD, self)
# --- functions ---
def get_food_pos(WIN_WIDTH, WIN_HEIGHT):
WIN_WIDTH = random.randint(1, WIN_WIDTH)
WIN_HEIGHT = random.randint(1, WIN_HEIGHT)
return WIN_WIDTH, WIN_HEIGHT
eaten = True
pressed_right = True
pressed_left = False
pressed_up = False
pressed_down = False
pygame.key.set_repeat(10,10)
while True:
screen.fill(BLACK)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN: # check for key presses
if event.key == pygame.K_LEFT: # left arrow turns left
pressed_left = True
pressed_right = False
pressed_up = False
pressed_down = False
elif event.key == pygame.K_RIGHT: # right arrow turns right
pressed_right = True
pressed_left = False
pressed_up = False
pressed_down = False
elif event.key == pygame.K_UP: # up arrow goes up
pressed_up = True
pressed_right = False
pressed_left = False
pressed_down = False
elif event.key == pygame.K_DOWN: # down arrow goes down
pressed_down = True
pressed_right = False
pressed_up = False
pressed_left = False
x = snakex
y = snakey
if pressed_left:
snakex -= speed
elif pressed_right:
snakex += speed
elif pressed_up:
snakey -= speed
elif pressed_down:
snakey += speed
snake_parts[0] = Snake(snakex, snakey, screen, int(size), IDK)
snake_parts[0].draw(screen)
if eaten:
foodx, foody = get_food_pos(WIN_WIDTH, WIN_HEIGHT)
eaten = False
my_food = Food(foodx, foody, screen)
my_food.draw(screen)
if snake_parts[0].colliderect(my_food):
eaten = True
screen.fill(BLACK)
a_snake = Snake(snakex, snakey, screen, int(size), RED)
snake_parts.append(a_snake)
if len(snake_parts) >= 1:
for i in range(1, len(snake_parts)-1):
tempx, tempy = snake_parts[i].coordinates()
snake_parts[i] = Snake(x, y, screen, int(size), RED)
snake_parts[i].draw(screen)
snake_parts[i+1] = Snake(tempx, tempy, screen, int(size), RED)
x, y = tempx, tempy
Figured it out, the issue was this line:
snake_parts[i+1] = Snake(tempx, tempy, screen, int(size), RED)
removed it and it's working fine.

Collision in the Class

I am writing a code for a game (school project).
I have a Class with different images for objects.
What I want is to create a condition for collision. For example, if the image if fire collides the image of earth then get a new image.
How can I do it ?
Thank you!
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((900,800))
pygame.display.set_caption("Tiny Alchemist")
clock = pygame.time.Clock()
FPS = 90
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
ALTWHITE = (240, 240, 240)
clear = False # Flag that shows if the user wants to clear the screen
class Element(pygame.Surface):
def __init__(self, image, xpos, ypos):
self.image = image
self.xpos = xpos
self.ypos = ypos
self.width = image.get_width()
self.height = image.get_height()
self.selected = False
self.visible = False
self.rect = pygame.Rect(xpos, ypos, image.get_width(), image.get_height())
def move(self, move):
self.xpos += move[0]
self.ypos += move[1]
self.rect = pygame.Rect(self.xpos, self.ypos, self.width, self.height)
class Recycle(pygame.Surface):
def __init__(self, xpos, ypos):
self.image = pygame.image.load("ElementIcon/recycle.png").convert_alpha()
self.image = pygame.transform.scale(self.image, (75, 75))
self.image.set_colorkey(BLACK)
self.xpos = xpos
self.ypos = ypos
self.rect = pygame.Rect(xpos, ypos, self.image.get_width(), self.image.get_height())
class PanelElements(pygame.Surface):
def __init__ (self, image, xpos, ypos):
self.image = image
self.xpos = xpos
self.ypos = ypos
self.rect = pygame.Rect(xpos, ypos, image.get_width(), image.get_height())
self.clicked = False
def init():
global ImageList
global Panel
global recycle
fire = pygame.image.load("ElementIcon/fire.png").convert_alpha()
fire = pygame.transform.scale(fire, (50, 69))
fire.set_colorkey(BLACK)
fire_mini = pygame.transform.scale(fire, (40,50))
fire_mini.set_colorkey(ALTWHITE)
earth = pygame.image.load("ElementIcon/earth.png").convert_alpha()
earth = pygame.transform.scale(earth, (50, 69))
earth.set_colorkey(BLACK)
earth_mini = pygame.transform.scale(earth, (40, 50))
earth_mini.set_colorkey(ALTWHITE)
water = pygame.image.load("ElementIcon/water.png").convert_alpha()
water = pygame.transform.scale(water, (50, 69))
water.set_colorkey(BLACK)
water_mini = pygame.transform.scale(water, (40, 50))
water_mini.set_colorkey(ALTWHITE)
wind = pygame.image.load("ElementIcon/wind.png").convert_alpha()
wind = pygame.transform.scale(wind, (50, 69))
wind.set_colorkey(BLACK)
wind_mini = pygame.transform.scale(wind, (40, 50))
wind_mini.set_colorkey(ALTWHITE)
energy = pygame.image.load("ElementIcon/energy.png").convert_alpha()
energy = pygame.transform.scale(energy, (50, 69))
energy.set_colorkey(BLACK)
energy_mini = pygame.transform.scale(energy, (40, 50))
energy_mini.set_colorkey(ALTWHITE)
recycle = Recycle(650, 718)
fire_mini_obj = PanelElements(fire_mini, 750, 10)
earth_mini_obj = PanelElements(earth_mini, 750, 60)
water_mini_obj = PanelElements(water_mini, 750, 110)
wind_mini_obj = PanelElements(wind_mini, 750, 160)
fire_obj = Element(fire, 362, 460)
fire_obj.visible = True
earth_obj = Element(earth, 300, 410)
earth_obj.visible = True
water_obj = Element(water, 365, 350)
water_obj.visible = True
wind_obj = Element(wind, 420, 409)
wind_obj.visible = True
Panel = [] #adding elements to the list
Panel.append(fire_mini_obj)
Panel.append(earth_mini_obj)
Panel.append(water_mini_obj)
Panel.append(wind_mini_obj)
ImageList =[] #adding elements to the list
ImageList.append(fire_obj)
ImageList.append(earth_obj)
ImageList.append(water_obj)
ImageList.append(wind_obj)
def run():
global done
done = False
while done == False:
check_events()
update()
clock.tick(60)
def check_events():
global done
global ImageList
global Panel
global recycle
global clear
mouse_pos = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
print("User quits the game :(")
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
done = True
print("Game stopped early by user :( ")
if event.type == pygame.MOUSEBUTTONDOWN:
for im in ImageList:
if im.rect.collidepoint(mouse_pos) and (im.visible == True):
im.selected = True
if recycle.rect.collidepoint(mouse_pos):
clear = True
for mini in Panel:
if mini.rect.collidepoint(mouse_pos):
mini.clicked = True
if event.type == pygame.MOUSEBUTTONUP:
for im in ImageList:
if im.rect.collidepoint(mouse_pos) and im.visible == True:
im.selected = False
if event.type == pygame.MOUSEMOTION:
for im in ImageList:
if im.rect.collidepoint(mouse_pos) and im.selected and (im.visible == True):
xmv = event.rel[0]
ymv = event.rel[1]
if event.buttons[0]:
if xmv < 0:
if im.xpos > 0:
im.move((xmv,0))
elif event.rel[0] > 0:
if im.xpos < screen.get_width():
im.move((xmv,0))
elif ymv < 0:
if im.ypos > 0:
im.move((0,ymv))
elif event.rel[1] > 0:
if im.ypos < screen.get_height():
im.move((0,ymv))
#pygame.display.update()
def update():
global ImageList
global Panel
global recycle
global clear
screen.fill(WHITE)
#Update the screen with drawings
for im in ImageList:
if im.visible == True:
screen.blit(im.image, (im.xpos, im.ypos))
pygame.draw.rect(screen, ALTWHITE, (740, 0, 160, 800), 0)
for mini in Panel:
screen.blit(mini.image, (mini.xpos, mini.ypos))
screen.blit(recycle.image, (recycle.xpos, recycle.ypos))
if (clear == True):
for im in ImageList:
im.visible = False
clear = False
for i in range(0,len(Panel)):
if Panel[i].clicked == True:
Panel[i].clicked = False
pygame.display.update()
if __name__=="__main__":
init()
run()
pygame.quit()
perhaps something like this:
earth = pygame.image.load("earth.png").convert()
earthRect = earth.get_rect()
fire = pygame.image.load("fire.png").convert()
fireRect = fire.get_rect()
if earth.colliderect(fire):
earth = pygame.image.load("thirdimage.png")
with the first four lines defining our images and the rect objects used to detect collision, the last two line detecting the collision and changing the image file

Categories