I can't get a very simple pygame script to work:
import pygame
class MainWindow(object):
def __init__(self):
pygame.init()
pygame.display.set_caption('Game')
pygame.mouse.set_visible(True)
# pygame.mouse.set_visible(False) # this doesn't work either!
screen = pygame.display.set_mode((640,480), 0, 32)
pygame.mixer.init()
while True:
print pygame.mouse.get_pos()
pygame.mixer.quit()
pygame.quit()
MainWindow()
This just outputs (0,0) as I move the mouse around the window:
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
Can anyone check this?
Edit - fixed code:
import pygame
class MainWindow(object):
def __init__(self):
pygame.init()
pygame.display.set_caption('Game')
pygame.mouse.set_visible(True)
# pygame.mouse.set_visible(False) # this doesn't work either!
screen = pygame.display.set_mode((640,480), 0, 32)
pygame.mixer.init()
while True:
for event in pygame.event.get():
if event.type == pygame.MOUSEMOTION:
print pygame.mouse.get_pos()
pygame.mixer.quit()
pygame.quit()
MainWindow()
Pygame will constantly dispatch events while it's running. These need to be handled in some way or pygame will hang and not do anything. Simplest way to fix it is by adding this to your main loop:
...
while True:
for event in pygame.event.get():
pass
print pygame.mouse.get_pos()
...
I never used this before, but I found that
Pygame: Mouse Specific Axis Detection
You need to wait until an event happens. I assume this empties the stack and allows you to get the data later on.
for event in pygame.event.get()
Related
I'm currently trying to follow the Introduction to Pygame tutorial and I'm stuck on one step where the speaker makes the surface. His surface is bright red while my surface isn't visible at all.
Here's the code:
import pygame
from sys import exit
pygame.init()
screen = pygame.display.set_mode((800, 400))
pygame.display.set_caption('Runner')
clock = pygame.time.Clock()
test_surface = pygame.Surface((100, 200))
test_surface.fill('Red')
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
screen.blit(test_surface, (0, 0))
pygame.display.update()
clock.tick(60)
I've already tried starting from the very beginning, my code and the steps I make are identical to his. I've also tried deleting python and pygame. I've installed Python version that the speaker has (3.9), but nothing helps.
It is a matter of indentation. You have draw the scene and update the display in the application loop:
import pygame
from sys import exit
pygame.init()
screen = pygame.display.set_mode((800, 400))
pygame.display.set_caption('Runner')
clock = pygame.time.Clock()
test_surface = pygame.Surface((100, 200))
test_surface.fill('Red')
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
# INDENTATION
#<------|
screen.blit(test_surface, (0, 0))
pygame.display.update()
clock.tick(60)
I'm relatively new to programming, and even newer to pygame. As a high school IT project, I've decided to create a simple rage platformer game in pygame with a goal to improve my Python skills. I've just started the code after watching a few Clear Code videos (lots of inspiration from him). My main issue I'm running into, regardless of any other bad programming practices or mistakes elsewhere, is that when I blit the surfaces player_surf and background_surf onto the screen, only the bottom one appears when I run the code. I orginally thought it was something wrong with the transparency of the images I was importing, but that wasn't the issue after I fixed that. Then, I thought it might be bliting it off the screen, but if I do them seperately, they work. As I'm extrememly new, I'm not sure what went wrong. I would appreciate any advice.
import pygame
from sys import exit
class GameState():
def __init__(self):
self.state = "cutscene"
def cutscene(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
screen.blit(background_surf, (0, 0))
def main_game(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
screen.blit(player_surf, (screen_x / 2, screen_y / 2))
screen.blit(background_surf, (0, 0))
black = pygame.Color(0, 0, 0)
white = pygame.Color(255, 255, 255)
pygame.init()
screen_x = 800
screen_y = 400
screen = pygame.display.set_mode((screen_x, screen_y))
pygame.display.set_caption("Game")
fps = pygame.time.Clock()
game_state = GameState()
# Background
background_surf = pygame.image.load("Game/Background.png").convert()
background_surf = pygame.transform.smoothscale(background_surf, (screen_x, screen_y))
# Player
player_surf = pygame.image.load("Game/Red_Square.png").convert_alpha()
player_rect = player_surf.get_rect(center=(screen_x / 2, screen_y / 2))
while True:
game_state.main_game()
# game_state.cutscene()
pygame.display.update()
fps.tick(60)
You need to draw the background, then the player otherwise the player will be hidden:
def main_game(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
# draw
screen.blit(background_surf, (0, 0))
screen.blit(player_surf, (screen_x // 2, screen_y // 2))
I've written my code and whenever I run it, I expect for it to open up the screen with the background but instead nothing happens at all. I don't know where I went wrong or what I did wrong.
My code:
import os.path
import sys
import pygame
from settings import Settings
class Slingshot_Adventures:
def __init__(self):
"""Initialize the game, and create game resources."""
pygame.init()
self.screen = pygame.display.set_mode((1280, 720))
pygame.display.set_caption('Slingshot Adventures')
self.bg_color = (0, 0, 0)
bg = pygame.image.load_basic(os.path.join('Final/bg.bmp'))
def run_game(self):
while True:
# Watch for keyboard and mouse events.
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# Redraw the screen during each pass through the loop.
self.screen.fill(self.bg_color)
# Make the most recently drawn screen visible.
pygame.display.flip()
if __name__ == '__main__':
# Make a game instance, and run the game.
ai = Slingshot_Adventures()
ai.run_game
You have set the local variable bg in the constructor of the class Slingshot_Adventures, but you did not set the attribute self.bg:
bg = pygame.image.load_basic(os.path.join('Final/bg.bmp'))
self.bg = pygame.image.load_basic(os.path.join('Final/bg.bmp'))
class Slingshot_Adventures:
def __init__(self):
"""Initialize the game, and create game resources."""
pygame.init()
self.screen = pygame.display.set_mode((1280, 720))
pygame.display.set_caption('Slingshot Adventures')
self.bg_color = (0, 0, 0)
#put your path to the image here
self.image = pygame.image.load(r"path/to/your/image.png")
def run_game(self):
while True:
# Watch for keyboard and mouse events.
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# Redraw the screen during each pass through the loop.
self.screen.fill(self.bg_color)
self.screen.blit(self.image, (0, 0))
# Make the most recently drawn screen visible.
pygame.display.flip()
if __name__ == '__main__':
# Make a game instance, and run the game.
ai = Slingshot_Adventures()
ai.run_game()
Here's the code. I have both images correctly named in the same folder, so thats not the issue. Both the runner.png and the rectangle for the button don't show, but the background does.
class gamewindow():
def __init__(self):
pygame.init()
self.game = pygame.display.set_mode((1300, 768))
background = pygame.image.load('temporarybackground.jpg')
self.green = (1,255,1)
self.buttonstart = pygame.draw.rect(self.game, self.green,(100,100, 20, 20))
self.runner = pygame.image.load('runner.png')
from sys import exit
while True:
self.game.fill((0,0,0))
self.game.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
pygame.display.flip()
JasonHarper's comment is correct. You're not drawing the button or runner in the loop. When you redraw the background, the other objects are erased.
Corrected code:
class gamewindow():
def __init__(self):
pygame.init()
self.game = pygame.display.set_mode((1300, 768))
background = pygame.image.load('temporarybackground.jpg')
self.green = (1,255,1)
self.runner = pygame.image.load('runner.png')
from sys import exit
while True:
self.game.fill((0,0,0)) # clear screen
self.game.blit(background, (0, 0)) # draw background
self.game.blit(self.runner, (50, 0)) # draw runner
pygame.draw.rect(self.game, self.green,(100,100, 20, 20)) # draw button
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
pygame.display.flip()
You also have your game code in a class constructor, which seems odd. It may be better to put your game in a standard function.
I'm trying to build a simple version of an aim trainer using pygame and have decided to change the original mouse pointer to a crosshair (an image). When testing if the image has been blitted on the mouse rect I noticed that the image is significantly lagging behind the position of the mouse.
I have tried to tamper with the FPS of the game by setting the clock.tick() to different integers. Tried loading the images in a different part of the code. However nothing seems to change the lag.
import pygame
pygame.init()
from win32api import GetSystemMetrics ## screen size getter so that theres no need to use coordinates, can be run on multiple resolutions
screen_width = GetSystemMetrics(0) ## get screen width and hieght
screen_hieght = GetSystemMetrics(1)
class GameWindow():
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
pygame.display.toggle_fullscreen()
caption = pygame.display.set_caption("Alex's FPS Trainer")
main_screen_font = pygame.font.SysFont('consolas', 100)
main_screen_background = pygame.image.load("fps_background.jpg") ## loading images
xhair_image = pygame.image.load("crosshair.png")
def __init__(self):
self.background = pygame.transform.scale(GameWindow.main_screen_background, (screen_width, screen_hieght))
self.title = self.main_screen_font.render("Alex's FPS Aim Trainer", 1, (245, 66, 66))
self.run()
def blit(self):
self.screen.blit(self.background, (0, 0))
self.screen.blit(self.title, (screen_width/2 - screen_width/3.5, screen_hieght/5))
self.screen.blit(GameWindow.xhair_image, (pygame.mouse.get_pos()[0] - 13.5,pygame.mouse.get_pos()[1] - 13.5)) ## centres mouse
def createButton(self):
pass
def run(self):
run = True
while run:
pygame.time.Clock().tick(120)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE: ## temporary quit key
run = False
if event.type == pygame.MOUSEBUTTONDOWN: ## detect clicks
print("Mouse pressed")
self.blit()
pygame.display.update()
pygame.quit()
GameWindow = GameWindow()
I was hoping that the image would follow the mouse without lag since it is important for the crosshair in an aim trainer to follow the mouse well.
The easiest solution is to change the mouse cursor by win32api.SetCursor():
win32api.SetCursor(cursor)
A cursor can be loaded by win32gui.LoadImage() from a .cur file:
cursor = win32gui.LoadImage(0, "cursor.cur", win32con.IMAGE_CURSOR,
0, 0, win32con.LR_LOADFROMFILE)
or from an .ico file.
cursor = win32gui.LoadImage(0, path + "cursor.ico", win32con.IMAGE_ICON,
0, 0, win32con.LR_LOADFROMFILE)
See also Cursors and LoadImage.
To avoid flickering it is important to make the "pygame" cursor invisible by pygame.mouse.set_visible()
pygame.mouse.set_visible(False)
Set the cursor immediately before pygame.display.update() respectively pygame.display.flip(), to make it "visible" and to give pygame no chance to "hide" it.
win32api.SetCursor(cursor)
pygame.display.update()
See the example application:
import pygame
import win32api, win32gui, win32con
pygame.init()
screen = pygame.display.set_mode((640, 480))
cursor = win32gui.LoadImage(0, path + "cursor.ico", win32con.IMAGE_ICON,
0, 0, win32con.LR_LOADFROMFILE)
pygame.mouse.set_visible(False)
run = True
while run:
pygame.time.Clock().tick(120)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
win32api.SetCursor(cursor)
pygame.display.update()
pygame.quit()