image is bad with python in pygame - python

I have a program in python:
import sys, random, pygame
from pygame.locals import *
pygame.init()
# Preparing Pygame
size = width, height = 718, 502
screen = pygame.display.set_mode(size)
framerate = pygame.time.Clock()
pygame.display.set_caption('Flappy Cube')
#Peparing background
background_x = 0
background_y = 0
background = pygame.image.load("background.jpg")
#Preparing Cube
cube_x = 100
cube_y = 200
cube_unscaled = pygame.image.load("cube.png")
cube = pygame.transform.smoothscale(cube_unscaled, (64, 64))
#Preparing Tubes
tube_x = 750
tube_y= 300
tube_unscaled = pygame.image.load("tube.png")
tube = pygame.transform.smoothscale(tube_unscaled, (125, 500))
# The main game loop
def exit_game():
sys.exit()
while True:
#Background
screen.blit(background, (background_x,background_y))
background_x = background_x+254.5
screen.blit(cube,(cube_x, cube_y))
#Tube
tube_x = tube_x -.075
screen.blit(tube,(tube_x, tube_y))
# If exit
for event in pygame.event.get():
if event.type == pygame.QUIT: exit_game()
# If Space Key is presed
elif event.type == pygame.KEYDOWN and event.key == K_SPACE:
cube_y = cube_y-10
#If Clicked
elif pygame.mouse.get_pressed()[0]:
cube_y = cube_y-10
framerate.tick(60)
pygame.display.flip()
run_game()
I get this result: http://i.stack.imgur.com/MKYRM.png
I have to boost framerate.tick(60) to framerate.tick(700) it looks a glichy. when I program the gravity the multiple images won't look good.
how can i fix the images been drawn multiple times before the screen updates?

Try:
cube_unscaled = pygame.image.load("cube.png").convert_alpha()
You shouldn't need to boost your FPS in such way, 60 is a good value.
Also, I like better this order for your main loop: check events, draw, update, tick.
I don't think it makes a difference to your problem, but I think it easier to understand that way.
while True:
# If exit
for event in pygame.event.get():
if event.type == pygame.QUIT: exit_game()
# If Space Key is presed
elif event.type == pygame.KEYDOWN and event.key == K_SPACE:
cube_y = cube_y-10
#If Clicked
elif pygame.mouse.get_pressed()[0]:
cube_y = cube_y-10
#Background
screen.blit(background, (background_x,background_y))
background_x = background_x+254.5
screen.blit(cube,(cube_x, cube_y))
#Tube
tube_x = tube_x -.075
screen.blit(tube,(tube_x, tube_y))
pygame.display.flip()
framerate.tick(60)

I fixed it! I just needed to fill the screen with black before "bliting" it.

Related

How do I detect a click on an image thats being toggeled by another image

So i was messing around in computer science and starting actually getting some decent progress (for me) on a project that managed to last longer than 2 days.
I just want some help on what im doing wrong.
heres my code its like some fnaf spin off that im planning to add some watermelon enemy to. Im just confused on how to do this click detection
import pygame, random, time
import pygame_textinput
import prompts
pygame.init()
textinput = pygame_textinput.TextInputVisualizer()
font = pygame.font.SysFont("Comicsansms", 55)
display = pygame.display.set_mode((575, 375))
pygame.display.set_caption("Game")
clock = pygame.time.Clock()
pygame.key.set_repeat(200, 25)
room = pygame.image.load("assets/images/room.png")
dark = pygame.image.load("assets/images/dark.png")
light = pygame.image.load("assets/images/light.png")
mel = pygame.image.load("assets/images/waterelo.png")
tablet = pygame.image.load("assets/images/3.png")
cam1 = pygame.image.load("assets/images/winner1.png")
def wait(x):
time.sleep(x)
def insideimage(pos, rsurf):
refrect = rsurf.get_rect().move((100, 100))
pickedcol = display.get_at(pos)
return refrect.collidepoint(pos)
q = False
flash = False
while True:
display.fill((225, 225, 225))
display.blit(room, (0, 0))
events = pygame.event.get()
textinput.update(events)
for event in events:
if event.type == pygame.QUIT:
exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
flash = not flash
if event.key == pygame.K_SPACE:
q = not q
elif event.type == pygame.MOUSEBUTTONDOWN and q == True:
if cam1.rect.collidepoint(event.pos):
print("hi")
if q == True:
display.blit(tablet, (-75, -75))
display.blit(cam1, (450, 240))
elif flash == True:
display.blit(light, (70, 60))
else:
display.blit(dark, (80, 55))
pygame.display.update()
clock.tick(30)
##if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
See How do I detect collision in pygame?. A pygame.Surface has no rect attribute. Use get_rect() to get a rectangle with the size of the image and set the position with keyword arguments:
elif event.type == pygame.MOUSEBUTTONDOWN and q == True:
cam1_rect = cam1.get_rect(topleft = (450, 240))
if cam1_rect .collidepoint(event.pos):
print("hi")

python pygame window wont close "not responding"

I am trying to make a python window for my game from my laptop in pygame... however when I try to close the window I get an error message saying "not responding" im not sure why that if I thought i had done everything right.... the code is below any help is needed.
Thanks!
import pygame
from sys import exit
pygame.init()
screen = pygame.display.set_mode((800,400))
clock = pygame.time.Clock()
sky_surface = pygame.image.load("bg_desert.png").convert()
snail_surface = pygame.image.load("snailWalk1.png").convert_alpha()
player_surf = pygame.image.load("p1_walk01.png")
snail_x_pos = 600
while True:
pygame.time.set_timer(snail_x_pos, 100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
print("hello")
snail_x_pos -=4
if snail_x_pos < -100: snail_x_pos = 800
screen.blit(sky_surface,(0,0))
screen.blit(snail_surface,(snail_x_pos,350))
screen.blit(player_surf,(80, 200))
pygame.display.update()
clock.tick(60)
All problem makes
pygame.time.set_timer(snail_x_pos, 100)
which you run inside loop.
If I remove it then it closes without problem.
Every set_timer creates new timer which sends event every 100ms (again and again). If you run it in loop then you create hundreds timers.
You should run it only once - before loop - and it will repeatly send event which you can get in for-loop.
Problem is also that you use it in wrong way - you use snail position but it should user_id and time in milliseconds.
my_event_id = pygame.USEREVENT + 1
pygame.time.set_timer(my_event_id, 500) # 500ms = 0.5s
and later you can use it to move snail
elif event.type == my_event_id:
print('0.5 second')
snail_x_pos -= 4
Here my version with other changes.
I use Surfaces instead images so everyone can simply copy and run it.
I also use pygame.Rect to keep position and size - it has useful values (ie. .center to get/set center position) and functions (ie. to detect colisions). I use .left and .right to move snake to right side of window when it leaves window on left side.
import pygame
pygame.init()
screen = pygame.display.set_mode((800,400))
sky_surface = pygame.Surface((800, 100))
sky_surface.fill((0,0,255))
sky_surface_rect = sky_surface.get_rect()
snail_surface = pygame.Surface((100, 10))
snail_surface.fill((0,255,0))
snail_surface_rect = snail_surface.get_rect()
snail_surface_rect.x = 600
snail_surface_rect.y = 350
player_surf = pygame.Surface((10, 50))
player_surf.fill((255,0,0))
player_surf_rect = player_surf.get_rect()
player_surf_rect.x = 80
player_surf_rect.y = 200
clock = pygame.time.Clock()
my_event_id = pygame.USEREVENT + 1
pygame.time.set_timer(my_event_id, 500) # 500ms = 0.1s
while True:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
print("hello")
elif event.type == my_event_id:
print('0.5 second')
# move snake
snail_surface_rect.x -= 4
# use this event to slow down player
pressed = pygame.key.get_pressed()
if pressed[pygame.K_LEFT]:
player_surf_rect.x -= 4
elif pressed[pygame.K_RIGHT]:
player_surf_rect.x += 4
# - updates -
if snail_surface_rect.right < 0:
snail_surface_rect.left = 800
# - draw -
screen.fill((0,0,0)) # clear screen
screen.blit(sky_surface, sky_surface_rect)
screen.blit(snail_surface, snail_surface_rect)
screen.blit(player_surf, player_surf_rect)
pygame.display.update()
clock.tick(60)

After playing my game once, if i select it again from the main menu it instantly cuts to the game over screen (pygame)

Basically whenever i select my game from the main menu it will play, but then if i go back to the main menu and select it again, it just shows the game over screen, and wont play again.
In the code below its about the zy_mainloop() part of the main_menu that doesnt run after the first time. I'd really appreciate some help with this
def main_menu():
WIDTH = 1280
HEIGHT = 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
main_menu = True
while main_menu:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
WIDTH = 480
HEIGHT = 600
pygame.display.set_mode((WIDTH, HEIGHT))
g.new()
g.show_go_screen()
main_menu = False
if event.key == pygame.K_2:
zy_mainloop()
main_menu = False
screen.blit(mainmenu_img, mainmenu_rect)
pygame.display.flip()
def start_screen():
WIDTH = 1280
HEIGHT = 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
start_screen = True
while start_screen:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
main_menu()
start_screen = False
screen.blit(startscreen_img, startscreen_rect)
pygame.display.flip()
def game_over_noscore():
WIDTH = 1280
HEIGHT = 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen.blit(gameovernoscore_img, noscore_rect)
pygame.display.flip()
gameover_screen = True
while gameover_screen:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_x:
main_menu()
gameover_screen = False
def zy_mainloop():
WIDTH = 480
HEIGHT = 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
zy_running = True
while zy_running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
zy_running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and zyplayer.shotsfired <= 1:
zyplayer.shoot()
# Update
zy_all_sprites.update()
# Hit Check
hits = pygame.sprite.groupcollide(zy_bullets, zy_enemybullets, True, True, pygame.sprite.collide_circle)
for hit in hits:
m = zyEnemyBullet()
zy_all_sprites.add(m)
zy_enemybullets.add(m)
zyplayer.shotsfired -= 1
hits = pygame.sprite.spritecollide(zyplayer, zy_enemybullets, True, pygame.sprite.collide_circle)
for hit in hits:
zyplayer.lives -= 1
m = zyEnemyBullet()
zy_all_sprites.add(m)
zy_enemybullets.add(m)
hits = pygame.sprite.groupcollide(zy_bullets, zy_enemies, True, False, pygame.sprite.collide_circle)
for hit in hits:
zy_enemy.enemylives -= 1
zyplayer.shotsfired -= 1
hits = pygame.sprite.spritecollide(zyplayer, zy_enemies, False, pygame.sprite.collide_circle)
for hit in hits:
zyplayer.lives -= 3
# Win / Lose condition
if zyplayer.lives == 0:
game_over_noscore()
if zy_enemy.enemylives == 0:
game_over_noscore()
# Draw
zy_drawgame()
I had not seem code doing multiple windows, depending on the pygame.QUIT event, and then calling pygame.display.set_mode again before.
Maybe the "QUIT" event is persisting across function calls?
I'd suggest you to prefix each pygame.display.set_mode call in there with a pygame.event.get() - that would flush pending events, and ensure no events from a previous screen are on queue.
Looking back at your code - how does calling game_over_noscore() makes your program exit the mainloop? Or it does not, and only keeps displaying things until the player closes the window?

Image Loading by keystrokes in Python with pygame

Im trying to make a simple image gallery which loads images with keystrokes using pygame in python, and this is how far i got
import pygame
pygame.init()
width=1366;
height=768
screen = pygame.display.set_mode((width, height ), pygame.NOFRAME)
pygame.display.set_caption('Katso')
penguin = pygame.image.load("download.png").convert()
mickey = pygame.image.load("mickey.jpg").convert()
x = 0; # x coordnate of image
y = 0; # y coordinate of image
*keys = pygame.event.get()
for event in keys:
if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
screen.blit(mickey,(x,y)); pygame.display.update()
if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
screen.blit(penguin,(x,y)); pygame.display.update()*
running = True
while (running): # loop listening for end of game
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#loop over, quit pygame
pygame.quit()
i expect to press the arrow keys to load certain images
the screen opens but no image gets loaded
Program never wait for keypress so you have to check keys inside while loop.
import pygame
# --- constants --- (UPPER_CASE)
WIDTH = 1366
HEIGHT = 768
# --- main ---
# - init -
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT), pygame.NOFRAME)
pygame.display.set_caption('Katso')
# - objects -
penguin = pygame.image.load("download.png").convert()
mickey = pygame.image.load("mickey.jpg").convert()
x = 0 # x coordnate of image
y = 0 # y coordinate of image
# - mainloop -
running = True
while running: # loop listening for end of game
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
#screen.fill( (0, 0, 0) )
screen.blit(mickey,(x,y))
pygame.display.update()
elif event.key == pygame.K_RIGHT:
#screen.fill( (0, 0, 0) )
screen.blit(penguin,(x,y))
pygame.display.update()
# - end -
pygame.quit()

Pygame point image towards mouse

I am trying to get this image 'spaceship' to point towards my mouse on screen, proving to be quite difficult so I would appreciate any help :O Also, would appreciate it if you could help with moving an image towards the cursor, i'm guessing that would be quite similar to rotating towards it..
Heres my code:
import sys, pygame, math;
from pygame.locals import *;
spaceship = ('spaceship.png')
mouse_c = ('crosshair.png')
backg = ('background.jpg')
pygame.init()
screen = pygame.display.set_mode((800, 600))
bk = pygame.image.load(backg).convert_alpha()
mousec = pygame.image.load(mouse_c).convert_alpha()
space_ship = pygame.image.load(spaceship).convert_alpha()
clock = pygame.time.Clock()
pygame.mouse.set_visible(False)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == MOUSEBUTTONDOWN and event.button == 1:
print("test1")
elif event.type == MOUSEBUTTONDOWN and event.button == 3:
print("test3")
screen.blit(bk, (0, 0))
pos = pygame.mouse.get_pos()
screen.blit(mousec, (pos))
screen.blit(space_ship, (400, 300)) #I need space_ship to rotate towards my cursor
pygame.display.update()
Here:
import sys, pygame, math;
from pygame.locals import *;
spaceship = ('spaceship.png')
mouse_c = ('crosshair.png')
backg = ('background.jpg')
pygame.init()
screen = pygame.display.set_mode((800, 600))
bk = pygame.image.load(backg).convert_alpha()
mousec = pygame.image.load(mouse_c).convert_alpha()
space_ship = pygame.image.load(spaceship).convert_alpha()
clock = pygame.time.Clock()
pygame.mouse.set_visible(False)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == MOUSEBUTTONDOWN and event.button == 1:
print("test1")
elif event.type == MOUSEBUTTONDOWN and event.button == 3:
print("test3")
screen.blit(bk, (0, 0))
pos = pygame.mouse.get_pos()
screen.blit(mousec, (pos))
angle = 360-math.atan2(pos[1]-300,pos[0]-400)*180/math.pi
rotimage = pygame.transform.rotate(space_ship,angle)
rect = rotimage.get_rect(center=(400,300))
screen.blit(rotimage,rect) #I need space_ship to rotate towards my cursor
pygame.display.update()
First get the angle between the space ship and the mouse, then rotate the image and set the center of the image so the image doesn't move around while rotating.

Categories