This question already has an answer here:
How can I add an image or icon to a button rectangle in Pygame?
(1 answer)
Closed 1 year ago.
How can I stick an image to a rectangle? I think it has something to do with the blit function. I want to blit the image onto the rectangle on line 50.
import pygame
import sys
pygame.init()
FPS = 60
start_smallfont = pygame.font.SysFont('Corbel', 45)
start_text = start_smallfont.render('Start', True, (255, 255, 255))
rect_smallfont = pygame.font.SysFont('Corbel', 33)
rect_text = rect_smallfont.render('You', True, (255, 255, 255))
x = 375
y = 335
vel = 0.1
startWIDTH, startHEIGHT = 170, 80
screenWIDTH, screenHEIGHT = 800, 720
WIN = pygame.display.set_mode((screenWIDTH, screenHEIGHT))
pygame.display.set_caption(":D")
def main():
clock = pygame.time.Clock()
run = True
while run:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
if event.type == pygame.MOUSEBUTTONDOWN:
if 800/2-85 <= mouse[0] <= 800/2-85+startWIDTH and 720/2-40 <= mouse[1] <= 720/2-40+startHEIGHT:
clock.tick(FPS)
run = False
while True:
global x, y
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
WIN.fill((0, 0, 0))
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > vel:
x -= vel
if keys[pygame.K_RIGHT] and x < screenWIDTH - 50 - vel:
x += vel
if keys[pygame.K_UP] and y > vel:
y -= vel
if keys[pygame.K_DOWN] and y < screenHEIGHT - 50 - vel:
y += vel
pygame.draw.rect(WIN, (255, 0, 0), (x, y, 50, 50))
pygame.display.update()
mouse = pygame.mouse.get_pos()
if 800/2-85 <= mouse[0] <= 800/2-85+startWIDTH and 720/2-40 <= mouse[1] <= 720/2-40+startHEIGHT:
pygame.draw.rect(WIN, (255, 91, 91), (800/2-85, 720/2-40, startWIDTH, startHEIGHT))
else:
pygame.draw.rect(WIN, (255, 0, 0), (800/2-85, 720/2-40, startWIDTH, startHEIGHT))
WIN.blit(start_text, (800/2-85+42,720/2-40+20))
pygame.display.update()
if __name__ == "__main__":
main()
Any basic tutorial like this one shows how to do it, so it's not clear what you're having trouble with, since you didn't specify what issues you're having. This should work in your code though:
# goes at the top of the script:
image_to_draw = pygame.image.load('something.png')
# to draw the image:
WIN.blit(image_to_draw, (x, y, 50, 50))
Related
Game Target is for android device.
When i add the buttons, they seem only to work one at a time, how can i make it so more button could work?
Here's the function:
def button_move(player_car):
pressed = pygame.mouse.get_pressed()
pos = pygame.mouse.get_pos()
moved = False
if pressed[0] == 1:
if 300 < pos[0] < 400 and 800 < pos[1] < 900:
player_car.move_forward()
moved = True
if 300 < pos[0] < 400 and 1100 < pos[1] < 1200:
player_car.move_backward()
moved = True
if 100 < pos[0] < 200 and 950 < pos[1] < 1050:
player_car.rotate(left=True)
if 500 < pos[0] < 600 and 950 < pos[1] < 1050:
player_car.rotate(right=True)
if not moved:
player_car.reduce_speed()
[...] they seem only to work one at a time [...]"
You only have one mouse. You have to use the "touch" events. Use the FINGERDOWN and FINGERUP event. Store the position of the finger into a dictionary when a FINGERDOWN event occurs and remove it on FINGERUP:
fingers = {}
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.FINGERDOWN:
x = event.x * window.get_height()
y = event.y * window.get_width()
fingers[event.finger_id] = x, y
if event.type == pygame.FINGERUP:
fingers.pop(event.finger_id, None)
# [...]
Use the positions to detect if a button is touched. Use pygame.Rect and pygame.Rect.collidepoint for the "touch" detection. e.g.:
rect = pygame.Rect(300, 800, 100, 100)
touched = False
for finger, pos in fingers.items():
if rect.collidepoint(pos):
touched = True
Minimal example:
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
buttons = [
pygame.Rect(25, 25, 100, 100),
pygame.Rect(175, 25, 100, 100),
pygame.Rect(25, 175, 100, 100),
pygame.Rect(175, 175, 100, 100)]
colors = [(64, 0, 0), (64, 64, 0), (0, 64, 0), (0, 0, 64)]
colorsH = [(255, 0, 0), (255, 255, 0), (0, 255, 0), (0, 0, 255)]
fingers = {}
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.FINGERDOWN:
x = event.x * window.get_height()
y = event.y * window.get_width()
fingers[event.finger_id] = x, y
if event.type == pygame.FINGERUP:
fingers.pop(event.finger_id, None)
highlight = []
for i, rect in enumerate(buttons):
touched = False
for finger, pos in fingers.items():
if rect.collidepoint(pos):
touched = True
highlight.append(touched)
# the same with list comprehensions
#highlight = [any(r.collidepoint(p) for _, p in fingers.items()) for _, r in enumerate(buttons)]
window.fill(0)
for rect, color, colorH, h in zip(buttons, colors, colorsH, highlight):
c = colorH if h else color
pygame.draw.rect(window, c, rect)
pygame.display.flip()
pygame.quit()
exit()
I am a newbie in Pygame (I use many libraries in python) There is a severe problem I face that is My pygame window is not responding I don't know why but this is happening every time I
run the code.
Here is the window
here is the code:
import pygame
pygame.init()
win = pygame.display.set_mode((500,500))
pygame.display.set_caption("First Game")
x = 50
y = 50
width = 20
height = 60
vel = 5
x1 = 100
y1 = 100
width1 = 20
height1 = 60
vel1 = 5
run = True
while run:
pygame.time.delay(100)
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > vel:
x -= vel
if keys[pygame.K_RIGHT] and x < 245 - vel - width:
x += vel
if keys[pygame.K_UP] and y > vel :
y -= vel
if keys[pygame.K_DOWN] and y < 500 - height - vel:
y += vel
win.fill((255,255,255)) # Fills the screen with black
pygame.draw.circle(win , (255,0,0), (x,y), width)
pygame.draw.circle(win , (255,0,0), (x1,y1), width)
pygame.draw.rect(win, (0,0,0), (245, 0, 20, 500))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
Could you just please help to deal wit this problem.
It's just a matter of Indentation. You have implemented an infinite loop, therefore the window does not respond. You need to draw the scene and handle the event in the application loop instead of after the application loop.
import pygame
pygame.init()
win = pygame.display.set_mode((500,500))
pygame.display.set_caption("First Game")
x = 50
y = 50
width = 20
height = 60
vel = 5
x1 = 100
y1 = 100
width1 = 20
height1 = 60
vel1 = 5
run = True
while run:
pygame.time.delay(100)
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > vel:
x -= vel
if keys[pygame.K_RIGHT] and x < 245 - vel - width:
x += vel
if keys[pygame.K_UP] and y > vel :
y -= vel
if keys[pygame.K_DOWN] and y < 500 - height - vel:
y += vel
# INDENTATION
#-->|
win.fill((255,255,255)) # Fills the screen with black
pygame.draw.circle(win , (255,0,0), (x,y), width)
pygame.draw.circle(win , (255,0,0), (x1,y1), width)
pygame.draw.rect(win, (0,0,0), (245, 0, 20, 500))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
Your issue is caused by the indentation of your script.
pygame.display.update() will update the screen, that should be inside the while run!
The 'Fills screen with black' can be done above the while, since you want that just once.
Same story for the for loop that will set run = False, the button and event's is something you want to check every iteration, so move it inside the while
import pygame
pygame.init()
win = pygame.display.set_mode((500,500))
pygame.display.set_caption("First Game")
x = 50
y = 50
width = 20
height = 60
vel = 5
x1 = 100
y1 = 100
width1 = 20
height1 = 60
vel1 = 5
run = True
win.fill((255,255,255)) # Fills the screen with black
pygame.draw.circle(win , (255,0,0), (x,y), width)
pygame.draw.circle(win , (255,0,0), (x1,y1), width)
pygame.draw.rect(win, (0,0,0), (245, 0, 20, 500))
while run:
# pygame.time.delay(100)
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > vel:
x -= vel
if keys[pygame.K_RIGHT] and x < 245 - vel - width:
x += vel
if keys[pygame.K_UP] and y > vel :
y -= vel
if keys[pygame.K_DOWN] and y < 500 - height - vel:
y += vel
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
I've tried to add gravity using the quadratic formula but didn't seem to work and I tried to turn it into a function and that still didn't seem to work. I tried using a class but I don't quite understand how they work so can someone help me add gravity to my platformer. I've tried many videos but didn't seem to help so any help would be much appreciated
import pygame
from pygame.locals import *
from pygame import mixer
from typing import Tuple
import pickle
from os import path
import time
import sys
import os
pygame.init()
white = 255,255,255
black = 0,0,0
green = 0, 255, 0
blue = 0,0,255
font = pygame.font.SysFont('Comic Sans MS', 50, 70)
screen_width = 650
screen_height = 800
screen = pygame.display.set_mode([screen_width,screen_height])
screen.fill((white))
pygame.display.set_caption("Darsh's Game")
pygame.display.update()
pygame.draw.rect(screen,white,(200,150,100,50))
running = 1
speed = 1
x = 25
y = 669
isJump = False
jumpCount = 10
left = False
right = True
def draw_text(text, font, text_col, x, y):
img = font.render(text, True, text_col)
screen.blit(img, (x, y))
def draw_rect():
rect1 = pygame.Rect(0, 0, 25, 800)
pygame.draw.rect(screen, black, rect1)
rect2 = pygame.Rect(625, 0, 25, 800)
pygame.draw.rect(screen, black, rect2)
rect3 = pygame.Rect(0, 775, 650, 25)
pygame.draw.rect(screen, green, rect3)
pygame.display.flip()
def direction(left, right):
if left == True:
screen.blit(mainleft_img, (x, y))
elif right == True:
screen.blit(mainright_img, (x, y))
draw_rect()
draw_text("George is dumb", font, green, 100, 400)
pygame.display.update()
mainright_img = pygame.image.load('newgameimg/mainright.png')
mainleft_img = pygame.image.load('newgameimg/mainleft.png')
screen.blit(mainright_img, (300, 400))
run = True
while run:
draw_text("George is dumb", font, green, 100, 400)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x > speed - 16:
x -= speed
left = True
right = False
draw_text("George is dumb", font, green, 100, 400)
pygame.display.update()
if keys[pygame.K_d] and x < screen_width - speed - 89:
x += speed
left = False
right = True
draw_text("George is dumb", font, green, 100, 400)
pygame.display.update()
if keys[pygame.K_ESCAPE]:
pygame.quit()
if not (isJump):
if keys[pygame.K_SPACE]: # jumping code
isJump = True
else:
if jumpCount >= -10:
time.sleep(0.02)
y -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False # jumping code
screen.fill(white)
direction(left, right)
draw_text("George is dumb", font, green, 100, 400)
draw_rect()
pygame.display.update()
You don't need the quadratic formula to get a simple gravity going; a simple gravity variable increasing every frame should do the trick.
...
gravity = 0
while run:
...
...
if keys[pygame.K_SPACE]:
gravity += 1
y -= gravity
...
Note that I don't speak your language; I mainly code in JavaScript, but I did try python once and I got the syntax down pretty quick. Hopefully this suits your needs, with a bit of tweaking of course.
Add a variable fall = 0. Increment the variable if the player does not jump (fall += 0.2). Change the y coordinate of the player through the variable fall in each frame. Get the bounding rectangle of the player with pygame.Surface.get_rect(). If the bottom of the rectangle reaches the floor then stop falling, and restricting the bottom of the rectangle on the floor. Set fall = 0 if the player starts to jump:
while run:
# [...]
if not (isJump):
fall += 0.2
y += fall
player_rect = mainleft_img.get_rect(topleft = (x, y))
if player_rect.bottom > 775:
player_rect.bottom = 775
y = player_rect.top
fall = 0
if keys[pygame.K_SPACE]: # jumping code
isJump = True
fall = 0
else:
# [...]
Multiple calls to pygame.display.update() or pygame.display.flip() cause flickering. Remove all calls to pygame.display.update() from your code, but call it once at the end of the application loop.
In addition, draw each object only once.
Do not delay, wait or sleep. Use pygame.time.Clock to control the frames per second and thus the game speed.
The method tick() of a pygame.time.Clock object, delays the game in that way, that every iteration of the loop consumes the same period of time. See pygame.time.Clock.tick():
This method should be called once per frame.
That means that the loop:
clock = pygame.time.Clock()
run = True
while run:
clock.tick(60)
runs 60 times per second.
See pygame.time.Clock.tick():
This method should be called once per frame. It will compute how many milliseconds have passed since the previous call.
Complete example:
import pygame
from pygame.locals import *
pygame.init()
white = 255,255,255
black = 0,0,0
green = 0, 255, 0
blue = 0,0,255
screen_width = 650
screen_height = 800
screen = pygame.display.set_mode([screen_width,screen_height])
pygame.display.set_caption("Darsh's Game")
font = pygame.font.SysFont('Comic Sans MS', 50, 70)
running = 6
speed = 2
fall = 0
x = 25
y = 669
isJump = False
jumpCount = 10
left = False
right = True
def draw_text(text, font, text_col, x, y):
img = font.render(text, True, text_col)
screen.blit(img, (x, y))
def draw_rect():
rect1 = pygame.Rect(0, 0, 25, 800)
pygame.draw.rect(screen, black, rect1)
rect2 = pygame.Rect(625, 0, 25, 800)
pygame.draw.rect(screen, black, rect2)
rect3 = pygame.Rect(0, 775, 650, 25)
pygame.draw.rect(screen, green, rect3)
def direction(left, right):
if left == True:
screen.blit(mainleft_img, (x, y))
elif right == True:
screen.blit(mainright_img, (x, y))
draw_text("George is dumb", font, green, 100, 400)
mainright_img = pygame.image.load('newgameimg/mainright.png')
mainleft_img = pygame.image.load('newgameimg/mainleft.png')
clock = pygame.time.Clock()
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x > speed - 16:
x -= speed
left = True
right = False
if keys[pygame.K_d] and x < screen_width - speed - 89:
x += speed
left = False
right = True
if keys[pygame.K_ESCAPE]:
pygame.quit()
if not (isJump):
fall += 0.2
y += fall
player_rect = mainleft_img.get_rect(topleft = (x, y))
if player_rect.bottom > 775:
player_rect.bottom = 775
y = player_rect.top
fall = 0
if keys[pygame.K_SPACE]: # jumping code
isJump = True
fall = 0
else:
if jumpCount >= -10:
y -= (jumpCount * abs(jumpCount)) * 0.5
jumpCount -= 1
else:
jumpCount = 10
isJump = False # jumping code
screen.fill(white)
draw_rect()
direction(left, right)
pygame.display.update()
I am starting with pygame and can't seem to figure out how to implement continuous movement. This is my current code:
import pygame
pygame.init()
window = pygame.display.set_mode(((500, 500)))
pygame.display.set_caption(("First Game"))
x = 50
y = 50
width = 40
height = 60
vel = 10
run = True
while run:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel
if keys[pygame.K_RIGHT]:
x += vel
if keys[pygame.K_UP]:
y -= vel
if keys[pygame.K_DOWN]:
y += vel
window.fill((0, 0, 0))
pygame.draw.rect(window, (200, 23, 255), (350, 350, width, height))
pygame.display.update()
pygame.quit()
As I have just started, I can't think of any possible solutions. Would be really nice of you if you can resolve this issue of mine. I know there is going to be some really stupid bug.
You need to draw the rectangle x, y instead of constant 350, 350:
pygame.draw.rect(window, (200, 23, 255), (350, 350, width, height))
pygame.draw.rect(window, (200, 23, 255), (x, y, width, height))
For a smooth movement you need to set vel to 1 and decrease the delay in the application loop.
Use pygame.time.Clock to control the frames per second and thus the game speed.
The method tick() of a pygame.time.Clock object, delays the game in that way, that every iteration of the loop consumes the same period of time. See pygame.time.Clock.tick():
import pygame
pygame.init()
window = pygame.display.set_mode(((500, 500)))
pygame.display.set_caption(("First Game"))
x, y = 50, 50
width, height = 40, 60
vel = 1
clock = pygame.time.Clock()
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= vel
if keys[pygame.K_RIGHT]:
x += vel
if keys[pygame.K_UP]:
y -= vel
if keys[pygame.K_DOWN]:
y += vel
window.fill((0, 0, 0))
pygame.draw.rect(window, (200, 23, 255), (x, y, width, height))
pygame.display.update()
pygame.quit()
Draw your rectangle at x and y coordinates as origin.
This question already has an answer here:
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Closed 2 years ago.
I'm just trying something with collisions and found the way to check one side of the rectangle with the other side.
I have the following problem:
If I move my game character (pink box) from the left against the object, my game character just moves through it:
If I come from the other side, everything works and my game character stops.
I mean to say that I need the same code for both sides but have to change the sides from if not player_rect.left == other_rect.right: to if not player_rect.right == other_rect.left:. But this does not work for one side.
import pygame
import sys
pygame.init()
clock = pygame.time.Clock()
window = pygame.display.set_mode([1200, 800])
pygame.display.set_caption("Collision Test")
x = 300
y = 300
width = 48
height = 96
velocity = 5
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
is_pressed = pygame.key.get_pressed()
player_rect = pygame.Rect(x, y, width, height)
other_rect = pygame.Rect(400, 300, 50, 50)
if is_pressed[pygame.K_d]:
if not player_rect.right == other_rect.left:
x += velocity
if is_pressed[pygame.K_a]:
if not player_rect.left == other_rect.right:
x -= velocity
window.fill((100, 150, 50))
pygame.draw.rect(window, (255, 50, 100), player_rect)
pygame.draw.rect(window, (255, 100, 50), other_rect)
pygame.display.update()
clock.tick(60)
Use collideRect().
Move the object and test if the rectangles are colliding. When a collision is detected, change the position of the object according to the moving direction:
is_pressed = pygame.key.get_pressed()
move_right = is_pressed[pygame.K_d]
move_left = is_pressed[pygame.K_a]
if move_right:
x += velocity
if move_left:
x -= velocity
player_rect = pygame.Rect(x, y, width, height)
other_rect = pygame.Rect(400, 300, 50, 50)
if player_rect.colliderect(other_rect):
if move_right:
player_rect.right = other_rect.left
x = player_rect.left
if move_left:
player_rect.left = other_rect.right
x = player_rect.left
For a smooth movement you've to do evaluate pygame.key.get_pressed() in the application loop rather than the event loop.
See also What all things happens inside pygame when I press a key? When to use pygame.event==KEYDOWN.
import pygame
import sys
pygame.init()
clock = pygame.time.Clock()
window = pygame.display.set_mode([1200, 800])
pygame.display.set_caption("Collision Test")
x = 300
y = 300
width = 48
height = 96
velocity = 5
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
is_pressed = pygame.key.get_pressed()
move_right = is_pressed[pygame.K_d]
move_left = is_pressed[pygame.K_a]
if move_right:
x += velocity
if move_left:
x -= velocity
player_rect = pygame.Rect(x, y, width, height)
other_rect = pygame.Rect(400, 300, 50, 50)
if player_rect.colliderect(other_rect):
if move_right:
player_rect.right = other_rect.left
x = player_rect.left
if move_left:
player_rect.left = other_rect.right
x = player_rect.left
window.fill((100, 150, 50))
pygame.draw.rect(window, (255, 50, 100), player_rect)
pygame.draw.rect(window, (255, 100, 50), other_rect)
pygame.display.update()
clock.tick(60)