Related
so i wrote this game from a pygame intro tutorial, added menus and all to modify it. whenever i run the game on my MBP 17, it runs extremely slow. i googled it, and tried all solutions, to no avail. also, typing in my event.unicode works extremely horribly, i have to press the same key more than once for it to register. any help is appreciated.
import sys
import pygame
import random
import math
import mysql.connector as mysql
import pygame_textinput
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption('Die Alien Die')
#database requirements
msql = mysql.connect(user='root', password='7014403396', database='gamer')
cursor = msql.cursor()
#background
background = pygame.image.load('back.png').convert()
pygame.mixer.music.load('y2mate.com - Star Wars_ Sith Battle Theme Music_XS4_5xlA3Ls_320kbps.mp3')
pygame.mixer.music.play(-1)
clock = pygame.time.Clock()
#millenium falcom
playerimg = pygame.image.load('mfc.png')
playerX = 350
playerY = 480
dx = 0
dy = 0
#alien die
alienimg = []
alienX =[]
alienY =[]
adx = []
ady = []
no_of_aliens = 8
for i in range(no_of_aliens):
alienimg.append(pygame.image.load('spaceship.png'))
alienX.append(random.randint(0,735))
alienY.append(random.randint(50,250))
adx.append(0.3)
ady.append(random.randint(20,43))
#bullets
bulletimg = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 480
bdx = 0
bdy = 1
visibility = False
score = 0
font=pygame.font.Font('freesansbold.ttf',32)
font2 = pygame.font.Font('freesansbold.ttf',25)
font3 = pygame.font.Font('freesansbold.ttf',22)
# Game Over
over_font = pygame.font.Font('freesansbold.ttf', 64)
click = False
def EnterUser():
texty = ''
global click
while True:
screen.fill((255, 255, 255))
textinput = pygame_textinput.TextInput()
events = pygame.event.get()
textinput.update(events)
screen.blit(textinput.get_surface(), (50, 150))
buttong = pygame.Rect(50, 330, 200, 50)
mx, my = pygame.mouse.get_pos()
pygame.draw.rect(screen, (255, 0, 0), buttong)
draw_text('enter username', font, (0, 0, 0), screen, 20, 20)
draw_text("Press Enter", font2, (0, 0, 0), screen, 50, 200)
draw_text("If you leave username blank", font2, (0, 0, 0), screen, 50, 250)
draw_text("your score wont register", font2, (0, 0, 0), screen, 50, 280)
text_surface = font.render(texty, True, (0,0,0))
screen.blit(text_surface, (50, 150))
draw_text('Lets Go', font2, (0, 0, 0), screen, 52, 340)
if buttong.collidepoint((mx, my)):
if click:
main_menu()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
texty += event.unicode
if event.key == pygame.K_BACKSPACE:
texty = texty[:-1]
if event.key == pygame.K_ESCAPE:
pygame.quit()
if event.type == pygame.K_RETURN:
main_menu()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
click = True
pygame.display.update()
def draw_text(text, font, color, surface, x, y):
textobj = font.render(text, 1, color)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
surface.blit(textobj, textrect)
def player(x, y):
screen.blit(playerimg, (x, y))
def alien(x,y,i):
screen.blit(alienimg[i],(x,y))
def shoot(x,y):
global visibility
visibility = True
screen.blit(bulletimg,(x+25,y+10))
def collide(bulletX,bulletY,alienX,alienY):
distance = math.sqrt(math.pow(alienX-bulletX,2)+math.pow(alienY-bulletY,2))
if distance < 27:
return True
else:
return False
def showscore(x,y):
sscore=font.render('Score: '+str(score),True,(141,27,31))
screen.blit(sscore,(x,y))
def game_over_text():
over_text = over_font.render("GAME OVER", True, (255, 255, 255))
screen.blit(over_text, (200, 250))
fscore = score
save_score()
def save_score():
t = "INSERT INTO alien VALUES('{}', '{}')".format(texty, str(score))
#val = (texty, str(score))
cursor.execute(t)
msql.commit()
#def show_high():
def main_menu():
while True:
screen.fill((0, 0, 0))
draw_text('Main Menu', font, (255, 255, 255), screen, 20, 20)
mx, my = pygame.mouse.get_pos()
button_1 = pygame.Rect(50, 100, 200, 50)
button_2 = pygame.Rect(50, 200, 200, 50)
if button_1.collidepoint((mx, my)):
if click:
game()
if button_2.collidepoint((mx, my)):
if click:
options()
pygame.draw.rect(screen, (255, 0, 0), button_1)
pygame.draw.rect(screen, (255, 0, 0), button_2)
draw_text('Alien Destroyer', font2, (0,0,0), screen, 52, 110)
draw_text('Show high scores', font3, (0,0,0), screen, 52, 206)
draw_text('for Alien Destroyer', font3, (0,0,0), screen, 52, 230)
click = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
click = True
pygame.display.update()
# game loop
def game():
global dx
global dy
global adx
global ady
global bdx
global bdy
global playerY
global playerX
global alienX
global alienY
global bulletY
global bulletX
global visibility
global score
running = True
while running:
clock.tick(60)
screen.fill((0, 0, 0))
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
dx = -1
if event.key == pygame.K_RIGHT:
dx = 1
if event.key == pygame.K_SPACE:
pygame.mixer.music.load('laser.wav')
pygame.mixer.music.play()
bulletX = playerX
shoot(bulletX, bulletY)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
dx = 0
playerX += dx
if playerX <= 0:
playerX = 0
elif playerX >= 736:
playerX = 736
for i in range(no_of_aliens):
if alienY[i] > 440:
for j in range(no_of_aliens):
alienY[j] = 2000
game_over_text()
break
alienX[i] += adx[i]
if alienX[i] <= 0:
adx[i] = 0.3
alienY[i] += ady[i]
elif alienX[i] >= 736:
adx[i] = -0.3
alienY[i] += ady[i]
death = collide(bulletX, bulletY, alienX[i], alienY[i])
if death:
pygame.mixer.music.load('explosion.wav')
pygame.mixer.music.play()
bulletY = 480
visibility = False
score += 1
alienX[i] = random.randint(0, 735)
alienY[i] = random.randint(30, 130)
alien(alienX[i], alienY[i], i)
if bulletY <= 0:
bulletY = 480
visibility = False
if visibility is True:
shoot(bulletX, bulletY)
bulletY -= bdy
showscore(10, 10)
player(playerX, playerY)
pygame.display.update()
EnterUser()
The problem is that you are calling pygame.event.get() multiple times (Lines: 89, 174, 208). This causes different events queues to disagree and causes problems. There is an easy fix.
In you main application loop, call pygame.event.get() once.
def game:
while running:
#omitted code
events = pygame.event.get()
for event in events:
#...
Then, you can pass events variable to other functions as an argument.
Everything seems fine but my computer found that i have invalid syntax and it marks colon(:).
code:
if keys[pygame.K_RIGHT] and man.x < 500 - man.width: # <- here he marks this colon
man.x = man.x + man.vel
man.right = True
man.left = False
man.standing = False
Full code:
import pygame
pygame.init()
cl = pygame.time.Clock()
lefty = [pygame.image.load('Game/L1.png'),pygame.image.load('Game/L2.png'),pygame.image.load('Game/L3.png'),pygame.image.load('Game/L4.png'),pygame.image.load('Game\L5.png'),pygame.image.load('Game/L6.png'),pygame.image.load('Game/L7.png'),pygame.image.load('Game/L8.png'),pygame.image.load('Game/L9.png')]
righty = [pygame.image.load('Game/R1.png'),pygame.image.load('Game/R2.png'),pygame.image.load('Game/R3.png'),pygame.image.load('Game/R4.png'),pygame.image.load('Game/R5.png'),pygame.image.load('Game/R6.png'),pygame.image.load('Game/R7.png'),pygame.image.load('Game/R8.png'),pygame.image.load('Game/R9.png')]
gr = pygame.image.load('Game/bg.jpg')
st = pygame.image.load('Game/standing.png')
win = pygame.display.set_mode((500,480))
name = pygame.display.set_caption("photo game")
class player(object):
def __init__(self, x, y, width, height):
self.jumpCount = 10
self.jump=False
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 5
self.left = False
self.right = False
self.walkCount= 0
self.standing = True
def draw(self,win):
if self.walkCount+1>=27:
self.walkCount=0
if not(self.standing):
if self.left:
win.blit(lefty[self.walkCount//3],(self.x,self.y))
self.walkCount +=1
elif self.right:
win.blit(righty[self.walkCount//3],(self.x,self.y))
self.walkCount +=1
else:
if self.right:
win.blit(righty[0], (self.x, self.y))
else:
win.blit(lefty[0], (self.x, self.y))
class projectiles(object):
def __init__(self,x,y,radius,color,facing):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.facing = facing
self.vel = 8 * facing
def draw(win, self):
pygame.draw.radius(win, self.color, (self.x, self.y), self.radius, self.facing)
def redrawchar():
win.blit(gr,(0,0))
man.draw(win)
for bullet in bullets:
bullet.draw(win)
pygame.display.update()
man = player(50, 420, 62, 62)
while True:
cl.tick(27)
bullets = []
for events in pygame.event.get():
if events.type == pygame.QUIT:
break
for bullet in bullets:
if bullet.x < 500 and bullet.x > 0:bullet.x += bullet.vel
else: bullets.pop(bullets.index(bullet))
for events in pygame.event.get():
if events.type == pygame.QUIT:
break
keys = pygame.key.get_pressed()
if keys[pygame.K_c]:
if man.right:
facing=1
else:
facing = -1
if len(bullets) < 5:
bullets.append(projectiles((round(man.x + man.weight //2)), (round(man.y + man.height //2)), 6, (0,0,0), facing)
if keys[pygame.K_RIGHT] and man.x < 500 - man.width: #here is that error
man.x = man.x + man.vel
man.right = True
man.left = False
man.standing = False
elif keys[pygame.K_LEFT] and man.x > man.vel-5-5:
man.x-=man.vel
man.left = True
man.right = False
man.standing = False
else:
man.standing = True
man.walkCount=0
if not(man.jump):
if keys[pygame.K_SPACE]:
man.jump = True
man.right = False
man.left = False
man.walkCount=0
else:
if man.jumpCount>=-10:
man.y -= (man.jumpCount*abs(man.jumpCount)) *0.5
man.jumpCount -=1
else:
man.jumpCount = 10
man.jump = False
redrawchar()
pygame.quit()
I tryed to put 500 - man.width in brackets like (500 - man.width): but it's not working.
Can someone please help.
I am working in py 3.7 and everything is ok and seems to be right. However why does my computer not like that colon(:) for some reason?
Does anyone have any ideas why?
The syntax error is not caused by the line:
if keys[pygame.K_RIGHT] and man.x < 500 - man.width:
This line is syntactically correct. It is the line before that line, which causes the error:
if len(bullets) < 5:
bullets.append(projectiles((round(man.x + man.weight //2)), (round(man.y + man.height //2)), 6, (0,0,0), facing)
At the end of the call to bullets.append is missing the closing bracket ). This causes the syntax error in the next line, because the subsequent tokens are unexpected.
I want to create a pygame window that doesn't have a frame and that moves when the user clicks on it and moves the mouse.
I tried this script but when I click on the windows, '0' is printed but not '1'
Something is wrong in my script.
# coding : utf-8
import pygame
from pygame.locals import *
from random import randint
from os import environ
from math import sqrt
pygame.init()
max_fps = 250
clock = pygame.time.Clock()
window_size_x, window_size_x = 720, 360
infos = pygame.display.Info()
environ['SDL_VIDEO_WINDOW_POS'] = str(int(infos.current_w / 2)) + ',' + str(int(infos.current_h / 2)) # center the window
screen = pygame.display.set_mode((window_size_x, window_size_x), pygame.NOFRAME)
def move_window(): # move the windows when custom bar is hold
window_x, window_y = eval(environ['SDL_VIDEO_WINDOW_POS'])
mouse_x, mouse_y = pygame.mouse.get_pos()
dist_x , dist_y = mouse_x - window_x, mouse_y - window_y # calculate the distance between mouse and window origin
for event in pygame.event.get():
if event.type != MOUSEBUTTONUP: # while bar is hold
print('1')
mouse_x, mouse_y = pygame.mouse.get_pos()
environ['SDL_VIDEO_WINDOW_POS'] = str(mouse_x - dist_x) + ',' + str(mouse_x - dist_x)
screen = pygame.display.set_mode((window_size_x, window_size_x), pygame.NOFRAME) # rebuild window
def main():
run = True
while run :
screen.fill((255, 255, 255))
pygame.display.update()
clock.tick(60) # build frame with 60 frame per second limitation
for event in pygame.event.get():
if event.type == MOUSEBUTTONDOWN:
print('0')
move_window()
if __name__ == '__main__':
main()
Write a function, which moves the window from dependent on a previous mouse position (start_x, start_y) and a mouse position (new_x, new_y)
def move_window(start_x, start_y, new_x, new_y):
global window_size_x, window_size_y
window_x, window_y = eval(environ['SDL_VIDEO_WINDOW_POS'])
dist_x, dist_y = new_x - start_x, new_y - start_y
environ['SDL_VIDEO_WINDOW_POS'] = str(window_x + dist_x) + ',' + str(window_y + dist_y)
# Windows HACK
window_size_x += 1 if window_size_x % 2 == 0 else -1
screen = pygame.display.set_mode((window_size_x, window_size_y), pygame.NOFRAME)
In this function is a very important line:
window_size_x += 1 if window_size_x % 2 == 0 else -1
this line changes the width of the window from alternately by +1 and -1. On Windows systems there seems to be a bug, which ignores the new position parameter, if the size of the window didn't change.
This "hack" is a workaround, which slightly change the size of the window whenever the position is changed.
A different approach, with no flickering, may look as follows. Note, though, that this version is significantly slower:
def move_window(start_x, start_y, new_x, new_y):
global window_size_x, window_size_y
buffer_screen = pygame.Surface((window_size_x, window_size_y))
buffer_screen.blit(pygame.display.get_surface(), pygame.display.get_surface().get_rect())
window_x, window_y = eval(environ['SDL_VIDEO_WINDOW_POS'])
dist_x, dist_y = new_x - start_x, new_y - start_y
environ['SDL_VIDEO_WINDOW_POS'] = str(window_x + dist_x) + ',' + str(window_y + dist_y)
window_size_x += 1 if window_size_x % 2 == 0 else -1
screen = pygame.display.set_mode((window_size_x, window_size_y), pygame.NOFRAME)
screen.blit(buffer_screen, buffer_screen.get_rect())
pygame.display.flip()
Change the position on MOUSEMOTION and MOUSEBUTTONUP:
def main():
run = True
pressed = False
start_pos = (0,0)
while run :
# [...]
for event in pygame.event.get():
if event.type == MOUSEBUTTONDOWN:
pressed = True
start_pos = pygame.mouse.get_pos()
elif event.type == MOUSEMOTION:
if pressed:
new_pos = pygame.mouse.get_pos()
move_window(*start_pos, *new_pos)
pygame.event.clear(pygame.MOUSEBUTTONUP)
elif event.type == MOUSEBUTTONUP:
pressed = False
new_pos = pygame.mouse.get_pos()
move_window(*start_pos, *new_pos)
Full example program:
# coding : utf-8
import pygame
from pygame.locals import *
from os import environ
pygame.init()
clock = pygame.time.Clock()
window_size_x, window_size_y = 720, 360
infos = pygame.display.Info()
environ['SDL_VIDEO_WINDOW_POS'] = str(int(infos.current_w/2)) + ',' + str(int(infos.current_h/2))
screen = pygame.display.set_mode((window_size_x, window_size_x), pygame.NOFRAME)
def move_window(start_x, start_y, new_x, new_y):
global window_size_x, window_size_y
window_x, window_y = eval(environ['SDL_VIDEO_WINDOW_POS'])
dist_x, dist_y = new_x - start_x, new_y - start_y
environ['SDL_VIDEO_WINDOW_POS'] = str(window_x + dist_x) + ',' + str(window_y + dist_y)
window_size_x += 1 if window_size_x % 2 == 0 else -1
screen = pygame.display.set_mode((window_size_x, window_size_y), pygame.NOFRAME)
def main():
run = True
pressed = False
start_pos = (0,0)
while run :
screen.fill((255, 255, 255))
pygame.display.update()
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if event.type == MOUSEBUTTONDOWN:
pressed = True
start_pos = pygame.mouse.get_pos()
elif event.type == MOUSEMOTION:
if pressed:
new_pos = pygame.mouse.get_pos()
move_window(*start_pos, *new_pos)
pygame.event.clear(pygame.MOUSEBUTTONUP)
elif event.type == MOUSEBUTTONUP:
pressed = False
new_pos = pygame.mouse.get_pos()
move_window(*start_pos, *new_pos)
if __name__ == '__main__':
main()
This solution no longer works under Windows systems and with Pygame 2.0. The position of a window can, however, be changed with the WINAPI function MoveWindow:
import pygame
from ctypes import windll
pygame.init()
screen = pygame.display.set_mode((400, 400), pygame.NOFRAME)
clock = pygame.time.Clock()
def moveWin(new_x, new_y):
hwnd = pygame.display.get_wm_info()['window']
w, h = pygame.display.get_surface().get_size()
windll.user32.MoveWindow(hwnd, new_x, new_y, w, h, False)
window_pos = [100, 100]
moveWin(*window_pos)
run = True
while run :
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
elif event.type == pygame.MOUSEMOTION:
if pygame.mouse.get_pressed()[0]:
window_pos[0] += event.rel[0]
window_pos[1] += event.rel[1]
moveWin(*window_pos)
screen.fill((255, 255, 255))
pygame.display.update()
clock.tick(60)
This code use only one for event loop with MOUSEBUTTONDOWN to set moving = True, MOUSEBUTTONUP to set moving = False and MOUSEMOTION which changes window's position when moving is True.
After move I use pygame.event.clear(pygame.MOUSEBUTTONUP) to remove this type of events because new window was getting this even and it was stoping window.
import pygame
from os import environ
# --- constants --- (UPPER_CASE_NAMES)
WINDOW_WIDTH = 720
WINDOW_HEIGHT = 360
# --- main ---
def main():
pygame.init()
infos = pygame.display.Info()
environ['SDL_VIDEO_WINDOW_POS'] = '{},{}'.format(infos.current_w//2, infos.current_h//2) # center the window
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.NOFRAME)
moving = False
clock = pygame.time.Clock()
run = True
while run:
screen.fill((255, 255, 255))
pygame.display.update()
clock.tick(60) # build frame with 60 frame per second limitation
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if not moving:
print('MOUSEBUTTONDOWN')
moving = True
# remeber start distance
#window_x, window_y = eval(environ['SDL_VIDEO_WINDOW_POS'])
window_x, window_y = map(int, environ['SDL_VIDEO_WINDOW_POS'].split(','))
dist_x = event.pos[0] # mouse x
dist_y = event.pos[1] # mouse y
elif event.type == pygame.MOUSEBUTTONUP:
if moving:
print('MOUSEBUTTONUP')
moving = False
elif event.type == pygame.MOUSEMOTION:
if moving:
print('moving')
mouse_x, mouse_y = pygame.mouse.get_pos()
diff_x = dist_x - mouse_x
diff_y = dist_y - mouse_y
window_x -= diff_x
window_y -= diff_y
environ['SDL_VIDEO_WINDOW_POS'] = "{},{}".format(window_x, window_y)
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.NOFRAME) # rebuild window
pygame.event.clear(pygame.MOUSEBUTTONUP) # to remove MOUSEBUTTONUP event which stops moving window
if __name__ == '__main__':
main()
The code's not ready, but I was getting there.
I had to abandon it, but it might help someone save some time.
Press f for full-screen mode. The part that is not done,
supposed to be the window-mode resize part. You must have an in-depth
look at toogle_resize() function for that.
The resize it's taking full desktop resolution and compare it
to the space between clik (MOUSEBUTTONDOWN) and (MOUSEBUTTONUP).
Or at least that's how I wanted it to work. Good luck!
Also the code needs to be optimized, it is raw.
import pyautogui
import pygame
import sys
from pygame.locals import *
from pyinput.mouse import Controller
Mouse controller gets the position on desktop, but I had to run it once more inside the while loop to get the updated values.
mouse = Controller()
standard = current_mouse_position = mouse.position
pygame.init()
Silkscreen = False
blueGray = (73, 111, 135)
width, height = pyautogui.size()
w = width / 4
h = height / 4
ww = width - w
hh = height - h
wi = ww - 4
hi = hh - 4
Set the background and the flags
room = pygame.image.load('img.png')
full_flags = pygame.FULLSCREEN | pygame.SCALED |
pygame.NOFRAME
normal_flags = pygame.NOFRAME | pygame.RESIZABLE |
pygame.SCALED
def toggle_fullscreen(f):
if f:
return pygame.display.set_mode((ww, hh), full_flags)
# pygame.display.set_mode(size, normal_flags) # uncomment
this to see issue being fixed as a workaround
return pygame.display.set_mode((ww, hh), normal_flags)
def toggle_resize(click):
if click:
return pygame.display.set_mode((ww + movement, hh),
normal_flags) # Expands by resize_y
# Set up the drawing window
screen = pygame.display.set_mode((ww, hh), normal_flags)
def bg():
screen.blit(room, (0, 0))
def border():
pygame.draw.rect(screen, blueGray, (0, 0, ww, hh), 2) #
width = 3
clock = pygame.time.Clock()
# Run until the user asks to quit
running = True
while running:
current_mouse_position = mouse.position
# print(current_mouse_position[0])
bg()
mw, mh = pygame.mouse.get_pos() # 0 - 1439(window size)
In the next line, I checked if the mouse is on the window border. Apply only to the left, right border. You must create code for the top, bottom border. Left, right borders, 3 pixels range each side.
if mw <= 3 or (mw > wi and mw < ww):
active = True
moveOne = 0
# print("data", moveOne)
# print(type(moveOne))
moveTwo = 0
# event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
running = False
sys.exit()
# print(mw, mh)
If the user clicks, the standard variable at the beginning of the code it gets the mouse current position. You must run the active bool and check if it is True if you want to start resizing from the border of the window.
The code is very complicated and needs some optimization, but I bet you gonna get it right. Good luck!;)
if event.type == pygame.MOUSEBUTTONDOWN:
standard = current_mouse_position[0]
print(standard)
if event.type == pygame.MOUSEBUTTONUP:
moveTwo = current_mouse_position[0]
movement = standard - moveTwo
print("This is:", moveTwo)
toggle_resize(click=MOUSEBUTTONUP)
active = False
Full-screen handler from here down. Press f for full screen and back to window mode.
if event.type == pygame.KEYDOWN:
Silkscreen = not Silkscreen
if event.key == K_f:
screen = toggle_fullscreen(Silkscreen)
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
border()
# Flip the display
pygame.display.flip()
clock.tick(144) # framerate
# Done! Time to quit.
pygame.quit()'
Here is a version of #Rabbid76's answer for Pygame 2. Note that this example may break as the module _sdl2.video, used to set the window position, is experimental.
move_window.py
import pygame
from pygame._sdl2.video import Window
start_pos = pygame.Vector2(0, 0) #Initial mouse position
pressed = False #Flag that denotes when the mouse is being continuously pressed down
def move_window(window : Window, start_mouse_pos : pygame.Vector2, new_mouse_pos : pygame.Vector2) -> None:
"""Moves the window by the offset between start_mouse_pos and new_mouse_pos"""
screen = pygame.display.get_surface()
buffer_screen = pygame.Surface((window.size[0], window.size[1]))
buffer_screen.blit(screen, screen.get_rect())
window_pos_Vec2 = pygame.Vector2(window.position)
window.position = window_pos_Vec2 + new_mouse_pos - start_mouse_pos
screen.blit(buffer_screen, buffer_screen.get_rect())
pygame.display.flip()
def check_event(window : Window, event : pygame.event, move_area : pygame.Rect = pygame.Rect(-1, -1, 1, 1)) -> None:
"""Takes a window and event and updates the window position accordingly. \n
move_area can be used to set what area of the screen can be clicked in order to move the window. \n
move_area defaults to a dummy rect which is then internally changed to the full window."""
global start_pos, pressed
if move_area == pygame.Rect(-1, -1, 1, 1):
move_area = pygame.Rect((0, 0), window.size)
mouse_pos = pygame.Vector2(pygame.mouse.get_pos())
if move_area.collidepoint(mouse_pos):
if event.type == pygame.MOUSEBUTTONDOWN:
pressed = True
start_pos = mouse_pos
elif event.type == pygame.MOUSEMOTION and pressed:
move_window(window, start_pos, mouse_pos)
elif event.type == pygame.MOUSEBUTTONUP:
pressed = False
move_window(window, start_pos, mouse_pos)
else:
pressed = False
And in your main file:
import pygame
from pygame._sdl2.video import Window
screen = pygame.display.set_mode(...)
window = Window.from_display_module()
#...
while True:
for event in pygame.event.get():
#...
move_window.check_event(window, event)
I'm trying to make piano tiles in python using pygame. So, I've started with making an intro window but I'm unable to upload a background image1 in my into window. I actually want to display the name 'Piano tiles' and the background image whenever the player starts the game. Here's my code:
import pygame,os,random,time
from pygame.locals import *
wix=800
wiy=800
pygame.init()
white=(255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0,155,0)
clock = pygame.time.Clock()
smallfont = pygame.font.SysFont("comicsansms", 25)
medfont = pygame.font.SysFont("comicsansms", 50)
largefont = pygame.font.SysFont("comicsansms", 100)
gameDisplay=pygame.display.set_mode((wix,wiy))
bg = pygame.image.load("background.jpg")
pygame.display.set_caption("Piano Tiles")
def game_intro():
screen=pygame.display.set_mode((wix,wiy))
intro =True
while intro:
bg = pygame.image.load("background.jpg")
screen.blit(bg,(0,0))
gameDisplay.fill(white)
message_to_screen("PIANO TILES",black,-100,"large")
pygame.display.update()
clock.tick(8)
def text_objects(text,color,size):
if size == "small":
textSurface = smallfont.render(text, True, color)
elif size == "medium":
textSurface = medfont.render(text, True, color)
elif size == "large":
textSurface = largefont.render(text, True, color)
return textSurface, textSurface.get_rect()
def message_to_screen(msg,color, y_displace=0, size = "small"):
textSurf, textRect = text_objects(msg,color, size)
textRect.center = (wix/ 2), (wiy / 2)+y_displace
gameDisplay.blit(textSurf, textRect)
game_intro()
pygame.time.wait(4000)
pygame.quit()
quit()
You have to use fill(white) before you blit anything because it clear screen.
It could look like this
import pygame
# --- constants --- (UPPER_CASE names)
WIX = 800
WIY = 800
WHITE = (255,255,255)
BLACK = ( 0, 0, 0)
RED = (255, 0, 0)
GREEN = ( 0,155, 0)
FPS = 8
# --- functions --- (lower_case names)
def text_objects(text, color, size):
if size == "small":
text_font = small_font
elif size == "medium":
font = med_font
elif size == "large":
font = large_font
#fonts = {"small": small_font, "medium": med_font, "large": large_font}
#font = fonts[size]
text_surface = font.render(text, True, color)
text_rect = text_surface.get_rect()
return text_surface, text_rect
def message_to_screen(screen, msg, color, y_displace=0, size="small"):
text_surface, text_rect = text_objects(msg, color, size)
text_rect.center = screen.get_rect().center
text_rect.y += y_displace
screen.blit(text_surface, text_rect)
def game_intro(screen, text):
#bg = pygame.image.load("background.jpg")
screen.fill(WHITE) # use if background is smaller then screen
screen.blit(bg, (0,0))
message_to_screen(screen, text, BLACK, -100, "large")
message_to_screen(screen, text, BLACK, 0, "large")
message_to_screen(screen, text, BLACK, 100, "large")
pygame.display.update()
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False # exit program
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
return True # go to next stage
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
return True # go to next stage
clock.tick(FPS)
# --- main --- (lower_case names)
# - init -
pygame.init()
screen = pygame.display.set_mode((WIX, WIY))
#screen_rect = screen.get_rect()
pygame.display.set_caption("Piano Tiles")
# - resources -
bg = pygame.image.load("Obrazy/test.png")#"background.jpg")
small_font = pygame.font.SysFont("comicsansms", 25)
med_font = pygame.font.SysFont("comicsansms", 50)
large_font = pygame.font.SysFont("comicsansms", 100)
#fonts = {"small": small_font, "medium": med_font, "large": large_font}
# - stages -
go_next = game_intro(screen, "HELLO WORLD")
if go_next:
go_next = game_intro(screen, "PIANO TILES")
if go_next:
go_next = game_intro(screen, "BYE, BYE")
# - exit -
pygame.quit()
I'm a student and this game is one of my task. when the player win or loose, pressanykeytostart() doesn't work. however in the beginning it works. Also I get this error massage (Pygame Error: Video System not Initialized) every time I play.
How can I add a Pause function in my game?
###########################Set up the screen, background image and sound
import random,pygame,sys,math
pygame.init()
from pygame.locals import*
WIDTH = 600
HEIGHT = 600
TEXTCOLOR = (255, 255, 255)
Yellow = (255, 255, 0)
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Pacman')
pygame.mouse.set_visible(False)
background_image = pygame.image.load('leaves.jpg')
backgroundmusic = pygame.mixer.Sound('lost.wav')
backgroundmusic.play()
##################################################Set up the score font
font_name = pygame.font.match_font('arial')
def draw_text(surf, text, size, x, y):
font = pygame.font.Font(font_name, size)
text_surface = font.render(text, True, Yellow)
text_rect = text_surface.get_rect()
text_rect.midtop = (x, y)
surf.blit(text_surface, text_rect)
###################################################SET UP the images and Sound
pacman = pygame.sprite.Sprite()
ghost = pygame.sprite.Sprite()
eatingsound = pygame.mixer.Sound('pacman_eatfruit.wav')
pacman.image = pygame.image.load('pacman1.png')
pacman.rect = pacman.image.get_rect()
pacman_group = pygame.sprite.GroupSingle(pacman)
over_image = pygame.image.load('game.jpg')
deathsound = pygame.mixer.Sound('pacman_death.wav')
##################################################press a key to start
def terminate():
pygame.quit()
sys.exit()
def waitForPlayerToPressKey():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
return
def drawText(text, font, surface, x, y):
screen.blit(background_image, (0,0))
textobj = font.render(text, 1, TEXTCOLOR)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
screen.blit(textobj, textrect)
font = pygame.font.SysFont(None, 48)
drawText('Pacman Game', font, screen, (WIDTH / 3), (HEIGHT / 3))
drawText('Press a key to start.', font, screen, (WIDTH / 3) - 30, (HEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()
######################################Adding Ghost in different position with different speed
class Ghost(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('ghost.png')
self.rect = self.image.get_rect()
self.rect.x = random.randrange(WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
def update(self):
self.rect.y += self.speedy
if self.rect.top > HEIGHT + 10:
self.rect.x = random.randrange(WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
all_sprites = pygame.sprite.Group()
ghosts = pygame.sprite.Group()
for i in range(2):
g = Ghost()
all_sprites.add(g)
ghosts.add(g)
#################################################### Adding the Coins
TILE_SIZE = pacman.rect.width
NUM_TILES_WIDTH = WIDTH / TILE_SIZE
NUM_TILES_HEIGHT = HEIGHT / TILE_SIZE
candies = pygame.sprite.OrderedUpdates()
for i in range(50):
candy = pygame.sprite.Sprite()
candy.image = pygame.image.load('coin.png')
candy.rect = candy.image.get_rect()
candy.rect.left = random.uniform(0, NUM_TILES_WIDTH - 1) * TILE_SIZE
candy.rect.top = random.uniform(0, NUM_TILES_HEIGHT - 1) * TILE_SIZE
candies.add(candy)
###########################################Game Loop
score = 0
pause = False
gameOver = False
running = True
win = False
while running :
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
running = False
if event.type == pygame.QUIT:
running = False
###########################################Move the pacman
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
pacman.rect.top -= TILE_SIZE
elif event.key == pygame.K_DOWN:
pacman.rect.top += TILE_SIZE
elif event.key == pygame.K_RIGHT:
pacman.rect.right += TILE_SIZE
elif event.key == pygame.K_LEFT:
pacman.rect.right -= TILE_SIZE
##############################################Keep the pacman on the screen
if pacman.rect.left < 0:
pacman.rect.left = 0
elif pacman.rect.right > 600:
pacman.rect.right = 600
elif pacman.rect.top <= 0:
pacman.rect.top = 0
elif pacman.rect.bottom >= 600:
pacman.rect.bottom = 600
###############################################Able to use mouse
if event.type == MOUSEMOTION:
pacman.rect.move_ip(event.pos[0] - pacman.rect.centerx, event.pos[1] - pacman.rect.centery)
###############################################Adding coins randomly
if event.type == pygame.USEREVENT:
if win == False:
candy = pygame.sprite.Sprite()
candy.image = pygame.image.load('coin.png')
candy.rect = candy.image.get_rect()
candy.rect.left = random.uniform(0, NUM_TILES_WIDTH - 1) * TILE_SIZE
candy.rect.top = random.uniform(0, NUM_TILES_HEIGHT - 1) * TILE_SIZE
candies.add(candy)
################################################Collecting the coins and set the score
collides = pygame.sprite.groupcollide(pacman_group, candies, False, True)
if len(collides) > 0:
eatingsound.play()
score += 1
if len(candies) == 0:
win = True
screen.blit(background_image, (0,0))
#################################################Wining the game
if win:
drawText('You Win!', font, screen, (WIDTH / 3) - 30, (HEIGHT / 3) + 50)
pygame.display.update()
winingsound = pygame.mixer.Sound('applause3.wav')
winingsound.play()
backgroundmusic.stop()
waitForPlayerToPressKey()
##################################################################### Game Over screen
candies.draw(screen)
pacman_group.draw(screen)
all_sprites.draw(screen)
draw_text(screen, str(score), 18, WIDTH / 2, 10)
pygame.display.flip()
all_sprites.update()
hits = pygame.sprite.spritecollide(pacman, ghosts, False)
if hits:
gameOver = True
if gameOver == True:
drawText('Game Over!', font, screen, (WIDTH / 3) - 30, (HEIGHT / 3) + 50)
drawText('Press a key to start again.', font, screen, (WIDTH / 3) - 30, (HEIGHT / 3) + 50)
pygame.display.update()
deathsound.play()
backgroundmusic.stop()
waitForPlayerToPressKey()
#############################################Drwing everything on the screen
pygame.quit()
Try with pygame.time.wait(time)
Or Pygame.event.wait (). The first wait the amount of time in brakets, and the second wait until a new event received.