I'm currently working on a Space Ship Simulator project and I came across a problem. In my code I have an Arrow class and I create 4 arrow objects that are going to be buttons.
This is my code:
from pygame.locals import *
pygame.init()
SCR_WIDTH = 700
SCR_HEIGHT = 900
screen = pygame.display.set_mode((SCR_WIDTH, SCR_HEIGHT))
pygame.display.set_caption("Space Ship Simulator")
# image loads
bg_image = pygame.image.load("img/space_background.jpg")
bg_image = pygame.transform.scale(bg_image, (SCR_WIDTH, SCR_HEIGHT))
ss_board = pygame.image.load("img/spaceship_board.png")
class Arrow:
def __init__(self, degree, x, y):
self.degree = degree
self.active = 0
self.arrow_list = []
self.x = x
self.y = y
self.active = 0
self.released = True
# arrow color: R: 0, G: 234, B: 0
for x in range(2):
img = pygame.image.load(f"img/arrow_{x}.png")
self.arrow_list.append(img)
self.image = pygame.transform.rotate(self.arrow_list[self.active], self.degree)
self.width = self.image.get_width()
self.height = self.image.get_height()
self.rect = Rect((self.x, self.y), (self.width, self.height))
def draw(self):
# get mouse position
mouse_pos = pygame.mouse.get_pos()
# check mouseover and clicked conditions
if self.rect.collidepoint(mouse_pos):
if pygame.mouse.get_pressed()[0] == 1 and self.active == 0 and self.released:
self.active = 1
self.released = False
print('Active')
if pygame.mouse.get_pressed()[0] == 0:
self.released = True
if self.active and self.released:
if pygame.mouse.get_pressed()[0] == 1:
self.active = 0
print('Inactive')
self.released = False
# draw arrow on screen
self.image = pygame.transform.rotate(self.arrow_list[self.active], self.degree)
screen.blit(self.image, (self.x, self.y))
arrowRight = Arrow(0, 553, 700)
arrowLeft = Arrow(180, 425, 700)
arrowUp = Arrow(91, 440, 776)
arrowDown = Arrow(271, 557, 779)
run = True
while run:
# background
screen.blit(bg_image, (0, 0))
screen.blit(ss_board, (0, 200))
# draw arrows
arrowRight.draw()
arrowLeft.draw()
arrowUp.draw()
arrowDown.draw()
# event handlers
for event in pygame.event.get():
# quit game
if event.type == pygame.QUIT:
run = False
pygame.display.update()
pygame.quit()
I have two requirements for the buttons:
If I click a button that is active, it should be deactivated again. I already managed to implement this.
If I click a button that is not active, it should be activated, and every other active button should be deactivated.
How can I implement the second requirement? Right now, it is possible for all four buttons to be active at the same time.
You need to link the buttons. Create a list of the buttons and set the list of buttons to each button object:
class Arrow:
def __init__(self, degree, x, y):
self.linkedButtons = []
self.active = 0
# [...]
arrowList = [
Arrow(0, 553, 700)
Arrow(180, 425, 700)
Arrow(91, 440, 776)
Arrow(271, 557, 779)
]
for arrow in arrowList:
arrow.linkedButtons = arrowList
Deactivate all buttons before you activate a button:
class Arrow:
# [...]
def draw(self):
# get mouse position
mouse_pos = pygame.mouse.get_pos()
# check mouseover and clicked conditions
if self.rect.collidepoint(mouse_pos):
if pygame.mouse.get_pressed()[0] == 1 and self.active == 0 and self.released:
# deactivate all buttons
for button in self.linkedButtons:
button.active = 0
# activate this button
self.active = 1
self.released = False
print('Active')
# [...]
Draw the buttons in a loop:
run = True
while run:
# background
screen.blit(bg_image, (0, 0))
screen.blit(ss_board, (0, 200))
# draw arrows
for arrow in arrowList:
arrow.draw()
# event handlers
for event in pygame.event.get():
# quit game
if event.type == pygame.QUIT:
run = False
pygame.display.update()
pygame.quit()
i think you should make a list of array button like
arrow_list = [arrowRight,arrowLeft,arrowUp,arrowDown]
then in the game loop you can can function to do the rest of the work
def button_activation(arrow_list):
index = none
for i,arrow in enumerate(arrow_list):
if arrow.activate:
index = i
for i,arrow in enumerate(arrow_list):
if index != i:
arrow.activate = False
For some reason, my return isn't working. This is from a tutorial. When I download the file and edit it from there it works, but if I copy and paste it from the exact file it doesn't work. Sorry, I am a beginner - open to any suggestions
The is the tutorial I used:
https://www.youtube.com/watch?v=G8MYGDf_9ho
Code:
import pygame
import sys
pygame.init()
WinHeight = 600
WinWidth = 900
Window = pygame.display.set_mode((WinWidth,WinHeight))
#button class
class Button():
def __init__(self, x, y, image, scale):
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
self.clicked = False
def draw(self, surface):
action = False
#get mouse position
pos = pygame.mouse.get_pos()
#check mouseover and clicked conditions
if self.rect.collidepoint(pos):
if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
self.clicked = True
action = True
if pygame.mouse.get_pressed()[0] == 0:
self.clicked = False
#draw button on screen
surface.blit(self.image, (self.rect.x, self.rect.y))
return action
Good_ball_img = pygame.image.load("GoodBall.png")
Bad_ball_img = pygame.image.load("BadBall.png")
#Button instances
Good_ball = Button(100,100,Good_ball_img,2)
Bad_ball = Button(200,200,Bad_ball_img,3)
def drawwin():
Window.fill((202,241,208))
Good_ball.draw(Window)
Bad_ball.draw(Window)
pygame.display.update()
def Main():
run = True
while run:
if Good_ball.draw(Window):
print("green clicked")
if Bad_ball.draw(Window)=="t":
print("red clicked")
for event in pygame.event.get():
#quit game
if event.type == pygame.QUIT:
run = False
pygame.quit()
sys.exit()
drawwin()
checkpress()
if __name__ == "__main__":
Main()
Code works for me if I change order - first process all events later check mouse position.
Problema can be because PyGame updates values in pygame.mouse and pygame.key only if you run pygame.event.get() - so it may need pygame.event.get() or at least pygame.event.pump() before other functions.
for event in pygame.event.get():
#quit game
if event.type == pygame.QUIT:
run = False
pygame.quit()
sys.exit()
if Good_ball.draw(Window):
print("green clicked")
if Bad_ball.draw(Window):
print("red clicked")
EDIT:
In documentation for pygame.event there is
To get the state of various input devices, you can forego the event queue and
access the input devices directly with their appropriate modules: `pygame.mouse`,
`pygame.key` and `pygame.joystick`. If you use this method, remember
that pygame requires some form of communication with the system window manager
and other parts of the platform. To keep pygame in sync with the system,
you will need to call `pygame.event.pump()` to keep everything current.
Minimal working code - with surfaces instead images so everyone can simply copy and run it
import pygame
import sys
# --- constants --- # PEP8: `UPPER_CASE_NAMES`
WINDOW_WIDTH = 900
WINDOW_HEIGHT = 600
# --- classes --- # PEP8: `CamelCaseNames`
class Button():
def __init__(self, x, y, image, scale):
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
self.clicked = False
def check_click(self):
action = False
# get mouse
pos = pygame.mouse.get_pos()
left_button = pygame.mouse.get_pressed()[0]
# check mouseover and clicked conditions
if left_button:
if self.rect.collidepoint(pos) and not self.clicked:
self.clicked = True
action = True
else:
self.clicked = False
return action
def draw(self, surface):
# draw button on screen
surface.blit(self.image, self.rect)
# --- functions --- # PEP8: `lower_case_names`
def draw_window(window):
window.fill((202, 241, 208))
good_ball.draw(window)
bad_ball.draw(window)
pygame.display.update()
# --- main ---
pygame.init()
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
# button class
#good_ball_img = pygame.image.load("GoodBall.png")
good_ball_img = pygame.Surface((100, 50))
good_ball_img.fill((0, 255, 0))
#bad_ball_img = pygame.image.load("BadBall.png")
bad_ball_img = pygame.Surface((100, 50))
bad_ball_img.fill((255,0,0))
# Button instances
good_ball = Button(100, 100, good_ball_img, 2) #
bad_ball = Button(200, 200, bad_ball_img, 3)
run = True
while run:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
sys.exit()
# - checks and updates -
if good_ball.check_click():
print("green clicked")
if bad_ball.check_click():
print("red clicked")
#checkpress()
# - draws -
draw_window(window)
PEP 8 -- Style Guide for Python Code
I want to view my blit() however once i add the line self.screen_dim.fill([255, 255, 255])
pygame.display.update() it overlaps
def __init__(self):
self.width = 500
self.height = 500
self.screen_dim = pygame.display.set_mode((self.width, self.height))
self.mole = pygame.image.load("mole.png")
self.mole_hit = pygame.image.load("mole-hit.png")
I am confused on how to get my pygame screen the images within that function is working however it overlaps if i added a new background color
def start(self):
stat = True
num_display = 1
x_array = []
y_array = []
for i in self.mole_pos:
x_array.append(i[0])
y_array.append(i[1])
while stat:
Rand_Pos = random.randint(0, 8)
if num_display == 1:
self.screen_dim.blit(self.mole, (x_array[Rand_Pos], y_array[Rand_Pos]))
for Event in pygame.event.get():
if Event.type == pygame.QUIT:
stat = False
if self.mouse_clicked(mouse.get_pos(), self.mole_pos[Rand_Pos]):
num_display = 0
self.screen_dim.blit(self.mole_hit, (x_array[Rand_Pos], y_array[Rand_Pos]))
continue
pygame.display.flip()
This ahs nothing to to with class. It is just a matter of Indentation. You have to draw self.mole_hit in the application loop rather than the event loop:
def start(self):
# [...]
while stat:
# [...]
for Event in pygame.event.get():
if Event.type == pygame.QUIT:
stat = False
#<--| INDENTATION
if self.mouse_clicked(mouse.get_pos(), self.mole_pos[Rand_Pos]):
num_display = 0
self.screen_dim.blit(self.mole_hit, (x_array[Rand_Pos], y_array[Rand_Pos]))
pygame.display.flip()
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 am trying to animate a wizard walking to the left when holding down the left arrow key and walking to the right when holding down the right arrow key. The problem: I don't know how to assign a variable to the whole class.
Here is the error:
Traceback (most recent call last):
File "C:\Python27\Wizard Game\wizard game", line 18, in <module>
class player_standing_right(object):
File "C:\Python27\Wizard Game\wizard game", line 61, in player_standing_right
screen.blit(player_spr, player_rect)
NameError: name 'player_spr' is not defined
Here is my code:
import sys, pygame
pygame.init()
size = (640, 480)
screen = pygame.display.set_mode(size)
gamerunning = True
def load_image(name):
image = pygame.image.load(name)
return image
clock = pygame.time.Clock()
while gamerunning == True:
white = (255, 255, 255)
clock.tick(30)
screen.fill(white)
class player_standing_right(object):
def __init__(self):
self.player_spr = player_spr
player_spr = load_image("wizard right 0.bmp")
x = 0
player_right = [load_image("wizard right 0.bmp"), load_image("wizard right 1.bmp"), load_image("wizard right 0.bmp")]
player_left = [load_image("wizard left 0.bmp"), load_image("wizard left 1.bmp"), load_image("wizard left 0.bmp")]
def key_press(keypressed):
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == keypressed:
return True
def key_release(keyreleased):
for event in pygame.event.get():
if event.type == pygame.KEYUP:
if event.key == keyreleased:
return True
if key_press(pygame.K_LEFT):
player_spr = player_left[x]
while key_press(pygame.K_LEFT):
player_rect = player_rect.move(-1, 0)
x += 1
if x == len(player_left):
x = 0
player_spr = player_left[x]
if key_press(pygame.K_RIGHT):
player_spr = player_right[x]
while key_press(pygame.K_RIGHT):
player_rect = player_rect.move(1, 0)
x += 1
if x == len(player_right):
x = 0
player_spr = player_right[x]
screen.blit(player_spr, player_rect)
pygame.display.flip()
You assigned player_spr when key is left and right, but you didn't assign it on "idle" state. When you're starting game you're not pressing any key, thus sprite is not assigned. You did it before class definition. You can try to put it inside. Also I'm not an expert but I would define class outside the actual main loop.
#TRY USING THIS METHOD
class AnimationClass():
def __init__(self):
self.x = 0
self.y = 0
self.frame_count = 0
self.image_list = []
def update(self):
self.frame_count += 1
for num in range(1,5): # SET THE NUM OF FRAMES
image = pygame.image.load(f"YOURE IMAGE FILE{num}.png") # loading youre image file
self.image_list.append(image) # appending youre image file
window.blit(self.image_list[int(self.frame_count)],(self.x , self.y)) # rendering youre image
animation = AnimationClass()
Loop = True
while Loop == True:
for event in pygame.event.get():
if event.type == pg.QUIT:
Loop = False
animation.update() # CALLING THE UPDATE IN LOOP
pygame.display.update()