Sprites don't blit onto surface PyGame - python

I'm making chess in pygame, but the pieces don't blit onto the surface for them. How could I fix this?
import pygame
pygame.init()
size = (600,600)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("chess")
clock = pygame.time.Clock()
chessboard = pygame.image.load("chess_board.png")
whitepawn = pygame.image.load("whitepawn.png")
blackpawn = pygame.image.load("blackpawn.png")
class pawn(pygame.sprite.Sprite):
def __init__(self,colour,x,y):
self.x = x
self.y = y
moved = False
self.colour = colour
pygame.sprite.Sprite.__init__(self)
self.im = pygame.surface.Surface((75,75))
def showpiece(self):
if self.colour == "white":
pygame.Surface.blit(self.im,whitepawn,(self.x,self.y))
elif self.colour == "black":
pygame.Surface.blit(self.im,blackpawn,(self.x,self.y))
num1 = 0
pawns = []
for i in range (8):
pawns.append(pawn("black",0+num1,75))
pawns.append(pawn("white",0+num1,450))
num1 += 75
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
screen.blit(chessboard,[0,0])
for n in range (len(pawns)):
pawns[n].showpiece()
pygame.display.flip()
clock.tick(60)
Also what is the point in clock.tick? I know it controls fps, but why does that need limiting?

You have to blit the Sprites on the display Surface (screen):
class pawn(pygame.sprite.Sprite):
# [...]
def showpiece(self):
if self.colour == "white":
screen.blit(whitepawn, (self.x,self.y))
elif self.colour == "black":
ecreen.blit(blackpawn, (self.x,self.y))
I suggest to use pygame.Rect to store the positions of the pieces:
import pygame
pygame.init()
size = (600,600)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("chess")
clock = pygame.time.Clock()
chessboard = pygame.image.load("chess_board.png")
whitepawn = pygame.image.load("whitepawn.png")
blackpawn = pygame.image.load("blackpawn.png")
class pawn(pygame.sprite.Sprite):
def __init__(self, colour, image, x, y):
pygame.sprite.Sprite.__init__(self)
self.colour = colour
self.image = image
self.rect = self.image.get_rect(topleft = (x, y))
def showpiece(self, surf):
surf.blit(self.image, self.rect)
pawns = []
for i in range(8):
pawns.append(pawn("black", blackpawn, i*75, 75))
pawns.append(pawn("white", whitepawn, i*75, 450))
run = True
while run :
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
screen.blit(chessboard, (0, 0))
for p in pawns:
p.showpiece(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()

Related

i want to change the location of my sprite when i click.... who to do that?

from numpy import place
import pygame, sys ,random as ran
start = True
ref_x = ran.randint(18,387)
ref_y = ran.randint(18,387)
class Player(pygame.sprite.Sprite):
def __init__(self, pos_x, pos_y):
super().__init__()
self.attack_animation = False
self.sprites_1 = []
self.sprites_1.append(pygame.image.load('.\crossHair.png'))
self.sprites_1.append(pygame.image.load('.\crossHair_2.png'))
self.sprites_1.append(pygame.image.load('.\crossHair_3.png'))
self.sprites_1.append(pygame.image.load('.\crossHair_4.png'))
self.sprites_1.append(pygame.image.load('.\crossHair_5.png'))
self.sprites_1.append(pygame.image.load('.\FIRE.png'))
self.current_sprite = 0
self.image = self.sprites_1[self.current_sprite]
self.image.set_colorkey('white')
for items in self.sprites_1:
items.set_colorkey('white')
self.rect = self.image.get_rect()
self.rect.topleft = [pos_x,pos_y]
def attack(self):
self.attack_animation = True
self.image.set_colorkey('white')
if mouse[0]+24 >= ref_x and ref_x+4 >= mouse[0] and mouse[1]+24 >= ref_y and ref_y+13 >= mouse[1]:
get_shot()
else :
print(ref_x,'here')
def update(self,speed):
self.image.set_colorkey('white')
mouse = pygame.mouse.get_pos()
if self.attack_animation == True:
self.current_sprite += speed
if int(self.current_sprite) >= len(self.sprites_1):
self.current_sprite = 0
self.attack_animation = False
print(mouse)
print('shot')
self.image = self.sprites_1[int(self.current_sprite)]
# self.image = self.sprites_1[int(self.current_sprite)]
self.rect = mouse
class enemy(pygame.sprite.Sprite):
def __init__(self, pos_x, pos_y):
super().__init__()
self.image = pygame.image.load('sp_1.png')
self.rect = self.image.get_rect()
self.rect.center = [pos_x, pos_y]
self.image.set_colorkey((255,255,255))
# General setup
pygame.init()
pygame.mouse.set_visible(0)
clock = pygame.time.Clock()
# Game Screen
screen_width = 400
screen_height = 400
mouse = pygame.mouse.get_pos()
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption("Sprite Animation")
# Creating the sprites and groups
moving_sprites = pygame.sprite.Group()
crosshair = Player(mouse[0],mouse[1])
enemy_x = ref_x
enemy_y = ref_y
print(enemy_x,enemy_y)
enemy_ = enemy(enemy_x,enemy_y)
moving_sprites.add(enemy_,crosshair)
def get_shot():
moving_sprites.remove(enemy_)
moving_sprites.add(enemy_)
moving_sprites.remove(crosshair)
moving_sprites.add(crosshair)
pygame.display.flip()
while True:
# Player.set_pos(*pygame.mouse.get_pos())
globals()['mouse'] = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if pygame.mouse.get_pressed()[0]:
crosshair.attack()
# enemy.checkCollision(enemy,crosshair,enemy_)
# enemy.attack()
# pygame.sprite.spritecollide(Player,enemy,True)
screen.fill((120,220,150))
#this is causing the problem
# get_hit = pygame.sprite.spritecollide(Player,enemy,True)
# Drawing
screen.set_colorkey('white')
moving_sprites.draw(screen)
moving_sprites.update(0.06)
pygame.display.flip()
clock.tick(120)
on function get_shot i want to create my sp_1 at a new place i already tried to change the rect but it didn't work so what can I do to make it work and tell me it get_shot is the best method or not or do i have to create another sprite to make it work also i am a beggener to pygame so tr y to make it easy as possible ...
kill the enemy and spawn a new enemy in a new random position:
enemy_ = enemy(ref_x, ref_y)
moving_sprites.add(enemy_, crosshair)
def get_shot():
global enemy_, ref_x, ref_y
enemy_.kill()
ref_x = ran.randint(18,387)
ref_y = ran.randint(18,387)
enemy_ = enemy(ref_x, ref_y)
moving_sprites.add(enemy_)

Pygame - creating a rotating projectile arount the center [duplicate]

This code is mostly just the generic start up of a pygame window but I'm trying to make it so the object moves (the planet object I've made) in the orbit around the sun object I've made for the coordinates I've given it. I know the x and y values are updating but I don't understand why the object doesn't move.
#import the library
import pygame
import math
#classes
class button:
def _init_ (self,screen, colour, x, y, width,height, letter):
self.screen = screen
self.colour = colour
self.x = x
self.y = y
self.width = width
self.height = height
self.letter = letter
self.radius = radius
def draw(self):
pygame.draw.rect(self.screen, self.colour,(self.x,self.y, self.width, self.height))
if self.letter!= '+' and self.letter!= '-':
font = pygame.font.SysFont('agencyfb',15,True,False)
else:
font = pygame.font.SysFont('agencyfb',25,True,False)
text = font.render(self.letter, True, black)
text_rect = text.get_rect(center=(self.x+self.width/2,self.y+self.height/2))
screen.blit(text, text_rect)
class orbit:
def __init__(self,screen,colour,x,y,radius,width):
self.screen = screen
self.colour = colour
self.x = x
self.y = y
self.width = width
self.radius = radius
def draw_circle(self):
pygame.draw.circle(self.screen,self.colour,(self.x,self.y),self.radius,self.width)
#define colours
##Sun = pygame.draw.circle(screen,Sun,[1000,450],100,0)
Black = (0,0,0)
White = (255,255,255)
Green = (0,255,0)
Red = (255,0,0)
Blue = (0,0,255)
Sun = (255,69,0)
Sun = []
Planet = []
#initialise the engine
pygame.init()
#Opening a window
size = (1920,1080)
screen = pygame.display.set_mode(size)
#set window title
pygame.display.set_caption("Orbit Simulator")
#loop unti the user clicks the close button
done = False
#
x=1000
y=450
Sun.append(orbit(screen,Red,1000,450,100,0))
Planet.append(orbit(screen,White,x,y,50,0))
#
#used to manage how fast the screen updates
clock = pygame.time.Clock()
#------ Main program Loop ------
while not done:
#--- Main event loop
for event in pygame.event.get(): #user did something
if event.type == pygame.QUIT: #if user clicked close
done = True #flag that we are done and exit the loop
#------ Game logic should go here ------
#------ Drawing code should go here -------
#first, clear the screen to white. Don't put other drawing commands above this or they will be erased with this command.
screen.fill(Black)
for i in Sun:
i.draw_circle()
for i in Planet:
r=150
angle=0
count = 0
while angle <= 360:
angle_radians = math.radians(angle)
x = int(math.cos(angle_radians)*r)
y = int(math.sin(angle_radians)*r)
angle +=1
count +=1
print(count)
x+=1000
y+=450
pygame.draw.circle(screen,White,[x,y],10,0)
print("Position [",x,",",y,"]")
#update the screen
pygame.display.flip()
#------ Limit to 60 frames per second ------
clock.tick(60)
#------ When the loop ends, quit ------
pygame.quit()
You can make an object rotate around another by using trigonometry or vectors. With vectors you just have to rotate a vector which defines the offset from the rotation center each frame and add it to the position vector (self.pos which is the rotation center) to get the desired self.rect.center coordinates of the orbiting object.
import pygame as pg
from pygame.math import Vector2
class Planet(pg.sprite.Sprite):
def __init__(self, pos, *groups):
super().__init__(*groups)
self.image = pg.Surface((40, 40), pg.SRCALPHA)
pg.draw.circle(self.image, pg.Color('dodgerblue'), (20, 20), 20)
self.rect = self.image.get_rect(center=pos)
self.pos = Vector2(pos)
self.offset = Vector2(200, 0)
self.angle = 0
def update(self):
self.angle -= 2
# Add the rotated offset vector to the pos vector to get the rect.center.
self.rect.center = self.pos + self.offset.rotate(self.angle)
def main():
pg.init()
screen = pg.display.set_mode((640, 480))
screen_rect = screen.get_rect()
clock = pg.time.Clock()
all_sprites = pg.sprite.Group()
planet = Planet(screen_rect.center, all_sprites)
yellow = pg.Color('yellow')
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
return
all_sprites.update()
screen.fill((30, 30, 30))
pg.draw.circle(screen, yellow, screen_rect.center, 60)
all_sprites.draw(screen)
pg.display.flip()
clock.tick(60)
if __name__ == '__main__':
main()
pg.quit()

Why is my pygame program laggy even with a great pc and other code works fine

Code to run the simple game.
All it does is move a circle just to test the fps
But when you run it, it takes awhile for it to start and than stutters
import pygame
pygame.init()
screen = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
playerX = 250 # Player X
playerY = 250 # Player Y
playerColor = (10, 10, 100)
class Player:
def __init__(self, x, y, color):
self.x = x
self.y = y
self.color = color
def show(self):
pygame.draw.circle(screen, self.color, (self.x, self.y), 10)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
playerX += 5
player = Player(playerX, playerY, playerColor)
screen.fill((60, 30, 10))
player.show()
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
It is a matter of Indentation. You need to update the position of the player and draw the scene in the application loop rather than the event loop.
Create the instance of the Player before the application loop:
import pygame
pygame.init()
screen = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
class Player:
def __init__(self, x, y, color):
self.x = x
self.y = y
self.color = color
def show(self):
pygame.draw.circle(screen, self.color, (self.x, self.y), 10)
playerX = 250 # Player X
playerY = 250 # Player Y
playerColor = (10, 10, 100)
player = Player(playerX, playerY, playerColor)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#<--| INDENTATION
player.x += 5
screen.fill((60, 30, 10))
player.show()
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()

Im trying to make a movable rectangle. When you run this code it displays the pygame window but nothing else. Any ideas? [duplicate]

This question already has an answer here:
Python only running while loop once
(1 answer)
Closed 2 years ago.
This is my code for my game. I am trying to display a rectangle i can move with wasd or arrow keys. But when I run it the window is just black and that's it. No rectangle.
import pygame
class window:
def __init__(self, height, width):
self.height = height
self.width = width
window.height = 800
window.width = 600
class Player(object):
def __init__(self):
self.rect = pygame.rect.Rect((64, 54, 16, 16))
def handle_keys(self):
key = pygame.key.get_pressed()
dist = 1
if key[pygame.K_LEFT]:
self.rect.move_ip(-1, 0)
def draw(self, surface):
# Im guessing this is where the problem is
screen.fill(255, 255, 255)
pygame.draw.rect(screen, (0, 0, 128), self.rect)
#making thi window
def makeWindow():
pygame.init()
screen = pygame.display.set_mode((window.height, window.width))
# pygame loop
def loop():
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if __name__ == "__main__":
makeWindow()
player = Player()
loop()
To move the player with wasd, you have to evaluate the state of the keys in Player.handle_keys and to change the position of self.rect:
class Player(object):
# [...]
def handle_keys(self):
key = pygame.key.get_pressed()
dist = 1
if key[pygame.K_a]:
self.rect.move_ip(-1, 0)
if key[pygame.K_d]:
self.rect.move_ip(1, 0)
if key[pygame.K_w]:
self.rect.move_ip(0, -1)
if key[pygame.K_s]:
self.rect.move_ip(0, 1)
The argument to pygame.Surface.fill() has to be a tuple with 3 or 4 arguments:
screen.fill(255, 255, 255)
screen.fill((255, 255, 255))
screen has to be a variable in global namespace. Use the global statement:
def makeWindow():
global screen
pygame.init()
screen = pygame.display.set_mode((window.height, window.width))
In the main main application loop has to:
handle the events by either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by either pygame.display.update() or pygame.display.flip()
def loop():
running = True
while running:
# handle events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# update position of player
player.handle_keys()
# clear display
screen.fill((255, 255, 255))
# draw scene
player.draw(screen)
# update display
pygame.display.flip()
See the complete example code:
import pygame
class window:
def __init__(self, height, width):
self.height = height
self.width = width
window.height = 800
window.width = 600
class Player(object):
def __init__(self):
self.rect = pygame.rect.Rect((64, 54, 16, 16))
def handle_keys(self):
key = pygame.key.get_pressed()
dist = 1
if key[pygame.K_a]:
self.rect.move_ip(-1, 0)
if key[pygame.K_d]:
self.rect.move_ip(1, 0)
if key[pygame.K_w]:
self.rect.move_ip(0, -1)
if key[pygame.K_s]:
self.rect.move_ip(0, 1)
def draw(self, surface):
# Im guessing this is where the problem is
pygame.draw.rect(surface, (0, 0, 128), self.rect)
#making thi window
def makeWindow():
global screen
pygame.init()
screen = pygame.display.set_mode((window.height, window.width))
# pygame loop
def loop():
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((255, 255, 255))
player.handle_keys()
player.draw(screen)
pygame.display.flip()
if __name__ == "__main__":
makeWindow()
player = Player()
loop()

How to get car on top of the racetrack

i am working on a top down racing game, and currently i am trying to get the car to go on top of the racetrack. There are 2 cars, one is the computer's car (not finished) and the other is the user controlled car, however when i run the programme the user's car is behind the track, but still moves normally. I have tried a few different things, but the user's car never seems to get on top of the track. So i am mainly asking how to get the user's car on top of the track.
Thank you
import math
import random
from tkinter import *
import pygame
class Buttons:
#window
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.quitButton = Button(frame, text="Race!", fg="red", command=frame.quit)
self.quitButton.pack(side=LEFT)
root = Tk()
b = Buttons(root)
root.mainloop()
pygame.mixer.pre_init(44100,16,2,4096)
pygame.init()
screen = pygame.display.set_mode((1280, 800))
rect = screen.get_rect()
clock = pygame.time.Clock()
#music
pygame.mixer.music.load("Noteblock.mp3")
pygame.mixer.music.set_volume(0.5)
pygame.mixer.music.play(-1)
WHITE = pygame.Color('white')
# Load images globally and reuse them in your program.
# Also use the `.convert()` or `.convert_alpha()` methods after
# loading the images to improve the performance.
VEHICLE1 = pygame.Surface((40, 70), pygame.SRCALPHA)
VEHICLE1.fill((130, 180, 20))
#blitting car onto 'rectangle car'
VEHICLE1 = pygame.image.load("YellowLambo.png")
screen.blit(VEHICLE1,(0,0))
pygame.display.update()
VEHICLE2 = pygame.Surface((40, 70), pygame.SRCALPHA)
VEHICLE2.fill((200, 120, 20))
#blitting computer's car
VEHICLE2 = pygame.image.load("RedLambo.png")
screen.blit(VEHICLE2,(0,0))
pygame.display.update()
BACKGROUND = pygame.Surface((1280, 800))
BACKGROUND.fill((127, 69, 2))
BACKGROUND = pygame.image.load("track1.png").convert()
screen.blit(BACKGROUND,(0,0))
pygame.display.update()
class Entity(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
class VehicleSprite(Entity):
MAX_FORWARD_SPEED = 10
MAX_REVERSE_SPEED = 2
ACCELERATION = 0.05
TURN_SPEED = 0.000000000001
def __init__(self, image, position):
Entity.__init__(self)
self.src_image = image
self.image = image
self.rect = self.image.get_rect(center=position)
self.position = pygame.math.Vector2(position)
self.velocity = pygame.math.Vector2(0, 0)
self.speed = self.direction = 0
self.k_left = self.k_right = self.k_down = self.k_up = 0
def update(self, time):
# SIMULATION
self.speed += self.k_up + self.k_down
# To clamp the speed.
self.speed = max(-self.MAX_REVERSE_SPEED,
min(self.speed, self.MAX_FORWARD_SPEED))
# Degrees sprite is facing (direction)
self.direction += (self.k_right + self.k_left)
rad = math.radians(self.direction)
self.velocity.x = -self.speed*math.sin(rad)
self.velocity.y = -self.speed*math.cos(rad)
self.position += self.velocity
self.image = pygame.transform.rotate(self.src_image, self.direction)
self.rect = self.image.get_rect(center=self.position)
class Background(pygame.sprite.Sprite):
def __init__(self, image, location):
pygame.sprite.Sprite.__init__(self)
self.image = image
self.rect = self.image.get_rect(topleft=location)
def game_loop():
bike = VehicleSprite(VEHICLE1, rect.center)
pygame.sprite.LayeredUpdates.move_to_front
ball = VehicleSprite(VEHICLE2, rect.center)
bike_group = pygame.sprite.Group(bike)
ball_group = pygame.sprite.Group(ball)
all_sprites = pygame.sprite.Group(bike_group, ball_group)
background = Background(BACKGROUND, [0, 0])
camera = pygame.math.Vector2(0, 0)
done = False
while not done:
time = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
# Bike Input (Player 1)
if event.key == pygame.K_d:
bike.k_right = -5
elif event.key == pygame.K_a:
bike.k_left = 5
elif event.key == pygame.K_w:
bike.k_up = 2
elif event.key == pygame.K_s:
bike.k_down = -2
elif event.key == pygame.K_ESCAPE:
done = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_d:
bike.k_right = 0
elif event.key == pygame.K_a:
bike.k_left = 0
elif event.key == pygame.K_w:
bike.k_up = 0
elif event.key == pygame.K_s:
bike.k_down = 0
camera -= bike.velocity
#screen.blit(background.image, background.rect)
all_sprites.update(time)
screen.fill(WHITE)
for sprite in all_sprites:
screen.blit(background.image, background.rect.topleft+camera)
screen.blit(sprite.image, sprite.rect.topleft+camera)
pygame.display.flip()
game_loop()
pygame.quit()
The problem lies in the for loop in which you blit the sprite images:
for sprite in all_sprites:
screen.blit(background.image, background.rect.topleft+camera)
screen.blit(sprite.image, sprite.rect.topleft+camera)
Here you blit the background and one of the sprites, then you blit the background again and the next sprite. So the background will be blit above the previous sprites in each iteration of the for loop.
Just blit the background once before the loop and then the sprites:
screen.fill(WHITE)
screen.blit(background.image, background.rect.topleft+camera)
for sprite in all_sprites:
screen.blit(sprite.image, sprite.rect.topleft+camera)
I think you should blit the racetrack before the cars.
BACKGROUND = pygame.Surface((1280, 800))
BACKGROUND.fill((127, 69, 2))
BACKGROUND = pygame.image.load("track1.png").convert()
screen.blit(BACKGROUND,(0,0))
put this before you blit the cars.

Categories

Resources