pygame does not receive scroll event after re-init - pygame

I'm making a game for school project, and there's scrolling stuffs in my game. I need to reinit pygame to make sure every is reset. But somehow, scrolling stops working after reinit pygame.
I made a simple script to test if that really was the case, and it was.
import pygame
def main():
while True:
pygame.init()
screen = pygame.display.set_mode([1280, 720])
pygame.display.set_caption("PYGAME DOES NOT RECEIVE SCROLL EVENT AFTER RE-INIT?")
frame = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
print("left click")
elif event.button == 4:
print("scroll up")
elif event.button == 5:
print("scroll down")
if event.type == pygame.QUIT:
running = False
frame.tick(30)
pygame.quit()
if __name__ == "__main__":
main()
It gets left click event but not the scrolling ones.
Is there any way to fix this?

don't use pygame.MOUSEBUTTONDOWN for scroll.
I have found another way for you to map scrollling using pygame.MOUSEWHEEL.
Here is the revised code:
import pygame
def main():
while True:
pygame.init()
screen = pygame.display.set_mode([1280, 720])
pygame.display.set_caption("PYGAME DOES NOT RECEIVE SCROLL EVENT AFTER RE-INIT?")
frame = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
print("left click")
if event.button == 3:
print("right click")
if event.type == pygame.MOUSEWHEEL:
if event.y == 1:
print("scroll up")
if event.y == -1:
print("scroll down")
if event.type == pygame.QUIT:
running = False
frame.tick(60)
pygame.quit()
if __name__ == "__main__":
main()
btw, happy new year and good luck mate~

Related

Why does the pygame window become unresponsive?

In a 'Pygame loop', I'm trying to ask for user input but when I run the program, the pygame window becomes unresponsive if I hover my mouse over it or click anywhere. Does anyone know what's going wrong?
import pygame
win = pygame.display.set_mode((600, 600))
win.fill((240, 240, 240)) #white
pygame.display.update()
#Game loop
quit = False
while quit == False:
for e in pygame.event.get():
if e.type == pygame.QUIT:
exit()
u_input = input("Enter 'q' to quit or 'n' to fill the window with navy: ")
if u_input == 'q':
quit = True
elif u_input == 'n':
win.fill((60, 55, 100)) #navy
pygame.display.update()
Unresponsive pygame window image
The IDE I'm using is Visual Studio Code
Unfortunately, this is just a nature of pygame. When you ask for an input, the program stops and waits for the user to input something, preventing the pygame.diplay.flip() from occuring.
There is two ways I can think of to fix this. Using, threads, one for powershell (terminal) and one for pygame should work, however I'm not familiar with that at all, so you would need to research for yourself.
A different solution is to listen for user input instead of using terminal prompts
#Game loop
quit = False
while quit == False:
for e in pygame.event.get():
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_q:
quit = True
if e.key == pygame.K_n:
win.fill((60, 55, 100)) #navy
pygame.display.update()

How to stop cursor lag in Pygame?

I have created a shooting game using Pygame in which one's cursor turns into a cross-hair and moves around shooting static images. However, the lag on the cross-hair is simply unbearable as the image is continually redrawn and a new background imposed over it every clock tick.
My code is as below:
import pygame, sys, random
class Crosshair(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load("ch.png").convert_alpha()
self.rect = self.image.get_rect()
self.gunshot = pygame.mixer.Sound("gs.wav")
def shoot(self):
self.gunshot.play()
pygame.sprite.spritecollide(crosshair, target_group, True)
def update(self):
self.rect.center = pygame.mouse.get_pos()
class Target(pygame.sprite.Sprite):
def __init__(self, pos_x, pos_y):
super().__init__()
self.image = pygame.image.load("al.png").convert_alpha()
self.rect = self.image.get_rect()
self.rect.center = [pos_x, pos_y]
pygame.init()
clock = pygame.time.Clock()
screen_width = 1920
screen_height = 1080
screen = pygame.display.set_mode((screen_width, screen_height))
background = pygame.image.load("hoc.png").convert_alpha()
pygame.mouse.set_visible(False)
crosshair = Crosshair()
crosshair_group = pygame.sprite.Group()
crosshair_group.add(crosshair)
target_group = pygame.sprite.Group()
for target in range(20):
new_target = Target(random.randrange(0, screen_width), random.randrange(0, screen_height))
target_group.add(new_target)
Running = True
while Running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
crosshair.shoot()
pygame.display.flip()
screen.blit(background, (0, 0))
target_group.draw(screen)
crosshair_group.draw(screen)
crosshair_group.update()
clock.tick(60)
Is there any way to make the cross-hair motion smoother? Most of the code is taken almost directly from a Youtube tutorial, but for some reason I am experiencing this problem when others are not.
It is a matter of indentation. You must update and draw the scene in the application loop rather than the event loop. The application loop is executed once per frame, but the event loop is only executed when an event occurse. Actually the call of clock.tick(60) slows down your application after each event instead of each frame:
while Running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
crosshair.shoot()
# INDENTATION
#<--|
pygame.display.flip()
screen.blit(background, (0, 0))
target_group.draw(screen)
crosshair_group.draw(screen)
crosshair_group.update()
clock.tick(60)

In pygame key read is delayed

import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif (event.type == pygame.KEYDOWN):
if (event.key == pygame.K_LEFT):
print('LEFT')
if (event.key == pygame.K_DOWN):
print('DOWN')
if (event.key == pygame.K_RIGHT):
print('RIGHT')
if (event.key == pygame.K_UP):
print('UP')
print('FRAME')
pygame.display.update()
clock.tick(1)
If you press arrow key just after 'FRAME' is printed, sometimes 'FRAME' is printed for second time before keypressed arrow is printed. Is as if pygame.event.get() is delayed. Example:
FRAME
FRAME
<---- UP pressed here
FRAME
UP
FRAME
FRAME
<---- UP pressed here
FRAME
UP
How could I correct this behaviour?
You are using clock.tick(1), so this is telling pygame that you want 1 fps. This will make everything slower, and pretty much pause your code for a tiny bit. Try changing the 1 to something like 60 or 30.

pygame window opens and instantly closes

So I have a file in the same folder as the file i'm coding right now and when the code runs in pycharm, if I press left arrow the other file is opened, but if I open the file using python straight from the file location it just opens and closes. Here is my code:
import pygame
import sys
import random
import subprocess
pygame.init()
GUI = pygame.display.set_mode((800,600))
pygame.display.set_caption("The incredible guessing game")
x = 284
y = 250
width = 68
length = 250
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run =False
if event.type == pygame.KEYDOWN:
command = "python AhjaiyGame.py"
subprocess.call(command)
pygame.draw.rect(GUI, (255,210,0), (x,y,length,width))
pygame.display.update()
pygame.quit()
Simply put, the program exists because it has completed running.
Python is tabulation based, and in the code you posted, the while loop is not actually doing anything.
You need to indent the code you need looped:
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run =False
if event.type == pygame.KEYDOWN:
command = "python AhjaiyGame.py"
subprocess.call(command)
pygame.draw.rect(GUI, (255,210,0), (x,y,length,width))
pygame.display.update()
pygame.quit()
Notice the tabulation.
In this example, pygame.quit() will only be called when run becomes False and the while loop completes.
import pygame
import sys
import random
import subprocess
pygame.init()
win = pygame.display.set_mode((500,500))
pygame.display.set_caption("The incredible guessing game")
x = 40
y = 30
width = 10
height = 20
vel=0.1
run = True
while run:
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
win.fill((0,0,0))
pygame.draw.rect(win, (255,0,0), (x,y,width,height))
pygame.display.update()
pygame.quit()

How to create a brush with pygame?

I'm trying to create a brush on pygame. It should draw rectangles while the left mouse button is down.
Below is what I tried:
while not game_exit:
if event.type == pygame.MOUSEBUTTONDOWN and pygame.mouse.get_pressed()[0]:
while pygame.mouse.get_pressed()[0]:
pygame.draw.rect(gameDisplay, red, [pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1], 10, 10])
But it is now working. Where is the problem?
If you need to draw rectangle when mouse button is pressed (and mouse is moving) then use
import pygame
RED = (255,0,0)
BLACK = (0,0,0)
gameDisplay = pygame.display.set_mode((600,400))
brush = None
game_exit = False
while not game_exit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_exit = True
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # left button pressed
brush = event.pos
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1: # left button released
brush = None
elif event.type == pygame.MOUSEMOTION:
if brush: # left button still pressed
brush = event.pos
# clear bufor
gameDisplay.fill(BLACK)
# draw brush in bufor
if brush:
pygame.draw.rect(gameDisplay, RED, [brush[0], brush[1], 10, 10])
# send bufor on the screen
pygame.display.flip()
Here is a stable loop that fills, flips and receives events:
while True:
for event in pregame.event.get():
if event.type == pregame.QUIT:
pregame.quit()
window.fill((0,0,0))
#####Render here
pygame.display.flip()
pygame.time.Clock().tick(30)
Hope it helps :D