pygame | ๐๐ฎ pygame is a Free and Open Source python | Game Engine library
kandi X-RAY | pygame Summary
Support
Quality
Security
License
Reuse
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample Here
pygame Key Features
pygame Examples and Code Snippets
#!/usr/bin/env python """ pygame.examples.glcube Draw a cube on the screen. Amazing. Every frame we orbit the camera around a small amount creating the illusion of a spinning object. First we setup some points of a multicolored cube. Then we then go through a semi-unoptimized loop to draw the cube points onto the screen. OpenGL does all the hard work for us. :] Keyboard Controls ----------------- * ESCAPE key to quit * f key to toggle fullscreen. """ import math import ctypes import pygame as pg try: import OpenGL.GL as GL import OpenGL.GLU as GLU except ImportError: print("pyopengl missing. The GLCUBE example requires: pyopengl numpy") raise SystemExit try: from numpy import array, dot, eye, zeros, float32, uint32 except ImportError: print("numpy missing. The GLCUBE example requires: pyopengl numpy") raise SystemExit # do we want to use the 'modern' OpenGL API or the old one? # This example shows you how to do both. USE_MODERN_GL = True # Some simple data for a colored cube here we have the 3D point position # and color for each corner. A list of indices describes each face, and a # list of indices describes each edge. CUBE_POINTS = ( (0.5, -0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, 0.5, -0.5), (-0.5, -0.5, -0.5), (0.5, -0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, -0.5, 0.5), (-0.5, 0.5, 0.5), ) # colors are 0-1 floating values CUBE_COLORS = ( (1, 0, 0), (1, 1, 0), (0, 1, 0), (0, 0, 0), (1, 0, 1), (1, 1, 1), (0, 0, 1), (0, 1, 1), ) CUBE_QUAD_VERTS = ( (0, 1, 2, 3), (3, 2, 7, 6), (6, 7, 5, 4), (4, 5, 1, 0), (1, 5, 7, 2), (4, 0, 3, 6), ) CUBE_EDGES = ( (0, 1), (0, 3), (0, 4), (2, 1), (2, 3), (2, 7), (6, 3), (6, 4), (6, 7), (5, 1), (5, 4), (5, 7), ) def translate(matrix, x=0.0, y=0.0, z=0.0): """ Translate (move) a matrix in the x, y and z axes. :param matrix: Matrix to translate. :param x: direction and magnitude to translate in x axis. Defaults to 0. :param y: direction and magnitude to translate in y axis. Defaults to 0. :param z: direction and magnitude to translate in z axis. Defaults to 0. :return: The translated matrix. """ translation_matrix = array( [ [1.0, 0.0, 0.0, x], [0.0, 1.0, 0.0, y], [0.0, 0.0, 1.0, z], [0.0, 0.0, 0.0, 1.0], ], dtype=matrix.dtype, ).T matrix[...] = dot(matrix, translation_matrix) return matrix def frustum(left, right, bottom, top, znear, zfar): """ Build a perspective matrix from the clipping planes, or camera 'frustrum' volume. :param left: left position of the near clipping plane. :param right: right position of the near clipping plane. :param bottom: bottom position of the near clipping plane. :param top: top position of the near clipping plane. :param znear: z depth of the near clipping plane. :param zfar: z depth of the far clipping plane. :return: A perspective matrix. """ perspective_matrix = zeros((4, 4), dtype=float32) perspective_matrix[0, 0] = +2.0 * znear / (right - left) perspective_matrix[2, 0] = (right + left) / (right - left) perspective_matrix[1, 1] = +2.0 * znear / (top - bottom) perspective_matrix[3, 1] = (top + bottom) / (top - bottom) perspective_matrix[2, 2] = -(zfar + znear) / (zfar - znear) perspective_matrix[3, 2] = -2.0 * znear * zfar / (zfar - znear) perspective_matrix[2, 3] = -1.0 return perspective_matrix def perspective(fovy, aspect, znear, zfar): """ Build a perspective matrix from field of view, aspect ratio and depth planes. :param fovy: the field of view angle in the y axis. :param aspect: aspect ratio of our view port. :param znear: z depth of the near clipping plane. :param zfar: z depth of the far clipping plane. :return: A perspective matrix. """ h = math.tan(fovy / 360.0 * math.pi) * znear w = h * aspect return frustum(-w, w, -h, h, znear, zfar) def rotate(matrix, angle, x, y, z): """ Rotate a matrix around an axis. :param matrix: The matrix to rotate. :param angle: The angle to rotate by. :param x: x of axis to rotate around. :param y: y of axis to rotate around. :param z: z of axis to rotate around. :return: The rotated matrix """ angle = math.pi * angle / 180 c, s = math.cos(angle), math.sin(angle) n = math.sqrt(x * x + y * y + z * z) x, y, z = x / n, y / n, z / n cx, cy, cz = (1 - c) * x, (1 - c) * y, (1 - c) * z rotation_matrix = array( [ [cx * x + c, cy * x - z * s, cz * x + y * s, 0], [cx * y + z * s, cy * y + c, cz * y - x * s, 0], [cx * z - y * s, cy * z + x * s, cz * z + c, 0], [0, 0, 0, 1], ], dtype=matrix.dtype, ).T matrix[...] = dot(matrix, rotation_matrix) return matrix class Rotation: """ Data class that stores rotation angles in three axes. """ def __init__(self): self.theta = 20 self.phi = 40 self.psi = 25 def drawcube_old(): """ Draw the cube using the old open GL methods pre 3.2 core context. """ allpoints = list(zip(CUBE_POINTS, CUBE_COLORS)) GL.glBegin(GL.GL_QUADS) for face in CUBE_QUAD_VERTS: for vert in face: pos, color = allpoints[vert] GL.glColor3fv(color) GL.glVertex3fv(pos) GL.glEnd() GL.glColor3f(1.0, 1.0, 1.0) GL.glBegin(GL.GL_LINES) for line in CUBE_EDGES: for vert in line: pos, color = allpoints[vert] GL.glVertex3fv(pos) GL.glEnd() def init_gl_stuff_old(): """ Initialise open GL, prior to core context 3.2 """ GL.glEnable(GL.GL_DEPTH_TEST) # use our zbuffer # setup the camera GL.glMatrixMode(GL.GL_PROJECTION) GL.glLoadIdentity() GLU.gluPerspective(45.0, 640 / 480.0, 0.1, 100.0) # setup lens GL.glTranslatef(0.0, 0.0, -3.0) # move back GL.glRotatef(25, 1, 0, 0) # orbit higher def init_gl_modern(display_size): """ Initialise open GL in the 'modern' open GL style for open GL versions greater than 3.1. :param display_size: Size of the window/viewport. """ # Create shaders # -------------------------------------- vertex_code = """ #version 150 uniform mat4 model; uniform mat4 view; uniform mat4 projection; uniform vec4 colour_mul; uniform vec4 colour_add; in vec4 vertex_colour; // vertex colour in in vec3 vertex_position; out vec4 vertex_color_out; // vertex colour out void main() { vertex_color_out = (colour_mul * vertex_colour) + colour_add; gl_Position = projection * view * model * vec4(vertex_position, 1.0); } """ fragment_code = """ #version 150 in vec4 vertex_color_out; // vertex colour from vertex shader out vec4 fragColor; void main() { fragColor = vertex_color_out; } """ program = GL.glCreateProgram() vertex = GL.glCreateShader(GL.GL_VERTEX_SHADER) fragment = GL.glCreateShader(GL.GL_FRAGMENT_SHADER) GL.glShaderSource(vertex, vertex_code) GL.glCompileShader(vertex) # this logs issues the shader compiler finds. log = GL.glGetShaderInfoLog(vertex) if isinstance(log, bytes): log = log.decode() for line in log.split("\n"): print(line) GL.glAttachShader(program, vertex) GL.glShaderSource(fragment, fragment_code) GL.glCompileShader(fragment) # this logs issues the shader compiler finds. log = GL.glGetShaderInfoLog(fragment) if isinstance(log, bytes): log = log.decode() for line in log.split("\n"): print(line) GL.glAttachShader(program, fragment) GL.glValidateProgram(program) GL.glLinkProgram(program) GL.glDetachShader(program, vertex) GL.glDetachShader(program, fragment) GL.glUseProgram(program) # Create vertex buffers and shader constants # ------------------------------------------ # Cube Data vertices = zeros( 8, [("vertex_position", float32, 3), ("vertex_colour", float32, 4)] ) vertices["vertex_position"] = [ [1, 1, 1], [-1, 1, 1], [-1, -1, 1], [1, -1, 1], [1, -1, -1], [1, 1, -1], [-1, 1, -1], [-1, -1, -1], ] vertices["vertex_colour"] = [ [0, 1, 1, 1], [0, 0, 1, 1], [0, 0, 0, 1], [0, 1, 0, 1], [1, 1, 0, 1], [1, 1, 1, 1], [1, 0, 1, 1], [1, 0, 0, 1], ] filled_cube_indices = array( [ 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 1, 1, 6, 7, 1, 7, 2, 7, 4, 3, 7, 3, 2, 4, 7, 6, 4, 6, 5, ], dtype=uint32, ) outline_cube_indices = array( [0, 1, 1, 2, 2, 3, 3, 0, 4, 7, 7, 6, 6, 5, 5, 4, 0, 5, 1, 6, 2, 7, 3, 4], dtype=uint32, ) shader_data = {"buffer": {}, "constants": {}} GL.glBindVertexArray(GL.glGenVertexArrays(1)) # Have to do this first shader_data["buffer"]["vertices"] = GL.glGenBuffers(1) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, shader_data["buffer"]["vertices"]) GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL.GL_DYNAMIC_DRAW) stride = vertices.strides[0] offset = ctypes.c_void_p(0) loc = GL.glGetAttribLocation(program, "vertex_position") GL.glEnableVertexAttribArray(loc) GL.glVertexAttribPointer(loc, 3, GL.GL_FLOAT, False, stride, offset) offset = ctypes.c_void_p(vertices.dtype["vertex_position"].itemsize) loc = GL.glGetAttribLocation(program, "vertex_colour") GL.glEnableVertexAttribArray(loc) GL.glVertexAttribPointer(loc, 4, GL.GL_FLOAT, False, stride, offset) shader_data["buffer"]["filled"] = GL.glGenBuffers(1) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, shader_data["buffer"]["filled"]) GL.glBufferData( GL.GL_ELEMENT_ARRAY_BUFFER, filled_cube_indices.nbytes, filled_cube_indices, GL.GL_STATIC_DRAW, ) shader_data["buffer"]["outline"] = GL.glGenBuffers(1) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, shader_data["buffer"]["outline"]) GL.glBufferData( GL.GL_ELEMENT_ARRAY_BUFFER, outline_cube_indices.nbytes, outline_cube_indices, GL.GL_STATIC_DRAW, ) shader_data["constants"]["model"] = GL.glGetUniformLocation(program, "model") GL.glUniformMatrix4fv(shader_data["constants"]["model"], 1, False, eye(4)) shader_data["constants"]["view"] = GL.glGetUniformLocation(program, "view") view = translate(eye(4), z=-6) GL.glUniformMatrix4fv(shader_data["constants"]["view"], 1, False, view) shader_data["constants"]["projection"] = GL.glGetUniformLocation( program, "projection" ) GL.glUniformMatrix4fv(shader_data["constants"]["projection"], 1, False, eye(4)) # This colour is multiplied with the base vertex colour in producing # the final output shader_data["constants"]["colour_mul"] = GL.glGetUniformLocation( program, "colour_mul" ) GL.glUniform4f(shader_data["constants"]["colour_mul"], 1, 1, 1, 1) # This colour is added on to the base vertex colour in producing # the final output shader_data["constants"]["colour_add"] = GL.glGetUniformLocation( program, "colour_add" ) GL.glUniform4f(shader_data["constants"]["colour_add"], 0, 0, 0, 0) # Set GL drawing data # ------------------- GL.glClearColor(0, 0, 0, 0) GL.glPolygonOffset(1, 1) GL.glEnable(GL.GL_LINE_SMOOTH) GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA) GL.glDepthFunc(GL.GL_LESS) GL.glHint(GL.GL_LINE_SMOOTH_HINT, GL.GL_NICEST) GL.glLineWidth(1.0) projection = perspective(45.0, display_size[0] / float(display_size[1]), 2.0, 100.0) GL.glUniformMatrix4fv(shader_data["constants"]["projection"], 1, False, projection) return shader_data, filled_cube_indices, outline_cube_indices def draw_cube_modern(shader_data, filled_cube_indices, outline_cube_indices, rotation): """ Draw a cube in the 'modern' Open GL style, for post 3.1 versions of open GL. :param shader_data: compile vertex & pixel shader data for drawing a cube. :param filled_cube_indices: the indices to draw the 'filled' cube. :param outline_cube_indices: the indices to draw the 'outline' cube. :param rotation: the current rotations to apply. """ GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) # Filled cube GL.glDisable(GL.GL_BLEND) GL.glEnable(GL.GL_DEPTH_TEST) GL.glEnable(GL.GL_POLYGON_OFFSET_FILL) GL.glUniform4f(shader_data["constants"]["colour_mul"], 1, 1, 1, 1) GL.glUniform4f(shader_data["constants"]["colour_add"], 0, 0, 0, 0.0) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, shader_data["buffer"]["filled"]) GL.glDrawElements( GL.GL_TRIANGLES, len(filled_cube_indices), GL.GL_UNSIGNED_INT, None ) # Outlined cube GL.glDisable(GL.GL_POLYGON_OFFSET_FILL) GL.glEnable(GL.GL_BLEND) GL.glUniform4f(shader_data["constants"]["colour_mul"], 0, 0, 0, 0.0) GL.glUniform4f(shader_data["constants"]["colour_add"], 1, 1, 1, 1.0) GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, shader_data["buffer"]["outline"]) GL.glDrawElements(GL.GL_LINES, len(outline_cube_indices), GL.GL_UNSIGNED_INT, None) # Rotate cube # rotation.theta += 1.0 # degrees rotation.phi += 1.0 # degrees # rotation.psi += 1.0 # degrees model = eye(4, dtype=float32) # rotate(model, rotation.theta, 0, 0, 1) rotate(model, rotation.phi, 0, 1, 0) rotate(model, rotation.psi, 1, 0, 0) GL.glUniformMatrix4fv(shader_data["constants"]["model"], 1, False, model) def main(): """run the demo""" # initialize pygame and setup an opengl display pg.init() gl_version = (3, 0) # GL Version number (Major, Minor) if USE_MODERN_GL: gl_version = (3, 2) # GL Version number (Major, Minor) # By setting these attributes we can choose which Open GL Profile # to use, profiles greater than 3.2 use a different rendering path pg.display.gl_set_attribute(pg.GL_CONTEXT_MAJOR_VERSION, gl_version[0]) pg.display.gl_set_attribute(pg.GL_CONTEXT_MINOR_VERSION, gl_version[1]) pg.display.gl_set_attribute( pg.GL_CONTEXT_PROFILE_MASK, pg.GL_CONTEXT_PROFILE_CORE ) fullscreen = False # start in windowed mode display_size = (640, 480) pg.display.set_mode(display_size, pg.OPENGL | pg.DOUBLEBUF | pg.RESIZABLE) if USE_MODERN_GL: gpu, f_indices, o_indices = init_gl_modern(display_size) rotation = Rotation() else: init_gl_stuff_old() going = True while going: # check for quit'n events events = pg.event.get() for event in events: if event.type == pg.QUIT or ( event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE ): going = False elif event.type == pg.KEYDOWN and event.key == pg.K_f: if not fullscreen: print("Changing to FULLSCREEN") pg.display.set_mode( (640, 480), pg.OPENGL | pg.DOUBLEBUF | pg.FULLSCREEN ) else: print("Changing to windowed mode") pg.display.set_mode((640, 480), pg.OPENGL | pg.DOUBLEBUF) fullscreen = not fullscreen if gl_version[0] >= 4 or (gl_version[0] == 3 and gl_version[1] >= 2): gpu, f_indices, o_indices = init_gl_modern(display_size) rotation = Rotation() else: init_gl_stuff_old() if USE_MODERN_GL: draw_cube_modern(gpu, f_indices, o_indices, rotation) else: # clear screen and move camera GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) # orbit camera around by 1 degree GL.glRotatef(1, 0, 1, 0) drawcube_old() pg.display.flip() pg.time.wait(10) pg.quit() if __name__ == "__main__": main()
#!/usr/bin/env python """ pygame.examples.midi midi input, and a separate example of midi output. By default it runs the output example. python -m pygame.examples.midi --output python -m pygame.examples.midi --input python -m pygame.examples.midi --input """ import sys import os import pygame as pg import pygame.midi # black and white piano keys use b/w color values directly BACKGROUNDCOLOR = "slategray" def print_device_info(): pygame.midi.init() _print_device_info() pygame.midi.quit() def _print_device_info(): for i in range(pygame.midi.get_count()): r = pygame.midi.get_device_info(i) (interf, name, input, output, opened) = r in_out = "" if input: in_out = "(input)" if output: in_out = "(output)" print( "%2i: interface :%s:, name :%s:, opened :%s: %s" % (i, interf, name, opened, in_out) ) def input_main(device_id=None): pg.init() pygame.midi.init() _print_device_info() if device_id is None: input_id = pygame.midi.get_default_input_id() else: input_id = device_id print(f"using input_id :{input_id}:") i = pygame.midi.Input(input_id) pg.display.set_mode((1, 1)) going = True while going: events = pygame.event.get() for e in events: if e.type in [pg.QUIT]: going = False if e.type in [pg.KEYDOWN]: going = False if e.type in [pygame.midi.MIDIIN]: print(e) if i.poll(): midi_events = i.read(10) # convert them into pygame events. midi_evs = pygame.midi.midis2events(midi_events, i.device_id) for m_e in midi_evs: pygame.event.post(m_e) del i pygame.midi.quit() def output_main(device_id=None): """Execute a musical keyboard example for the Church Organ instrument This is a piano keyboard example, with a two octave keyboard, starting at note F3. Left mouse down over a key starts a note, left up stops it. The notes are also mapped to the computer keyboard keys, assuming an American English PC keyboard (sorry everyone else, but I don't know if I can map to absolute key position instead of value.) The white keys are on the second row, TAB to BACKSLASH, starting with note F3. The black keys map to the top row, '1' to BACKSPACE, starting with F#3. 'r' is middle C. Close the window or press ESCAPE to quit the program. Key velocity (note amplitude) varies vertically on the keyboard image, with minimum velocity at the top of a key and maximum velocity at bottom. Default Midi output, no device_id given, is to the default output device for the computer. """ # A note to new pygamers: # # All the midi module stuff is in this function. It is unnecessary to # understand how the keyboard display works to appreciate how midi # messages are sent. # The keyboard is drawn by a Keyboard instance. This instance maps Midi # notes to musical keyboard keys. A regions surface maps window position # to (Midi note, velocity) pairs. A key_mapping dictionary does the same # for computer keyboard keys. Midi sound is controlled with direct method # calls to a pygame.midi.Output instance. # # Things to consider when using pygame.midi: # # 1) Initialize the midi module with a to pygame.midi.init(). # 2) Create a midi.Output instance for the desired output device port. # 3) Select instruments with set_instrument() method calls. # 4) Play notes with note_on() and note_off() method calls. # 5) Call pygame.midi.Quit() when finished. Though the midi module tries # to ensure that midi is properly shut down, it is best to do it # explicitly. A try/finally statement is the safest way to do this. # # GRAND_PIANO = 0 CHURCH_ORGAN = 19 instrument = CHURCH_ORGAN # instrument = GRAND_PIANO start_note = 53 # F3 (white key note), start_note != 0 n_notes = 24 # Two octaves (14 white keys) key_mapping = make_key_mapping( [ pg.K_TAB, pg.K_1, pg.K_q, pg.K_2, pg.K_w, pg.K_3, pg.K_e, pg.K_r, pg.K_5, pg.K_t, pg.K_6, pg.K_y, pg.K_u, pg.K_8, pg.K_i, pg.K_9, pg.K_o, pg.K_0, pg.K_p, pg.K_LEFTBRACKET, pg.K_EQUALS, pg.K_RIGHTBRACKET, pg.K_BACKSPACE, pg.K_BACKSLASH, ], start_note, ) pg.init() pygame.midi.init() _print_device_info() if device_id is None: port = pygame.midi.get_default_output_id() else: port = device_id print(f"using output_id :{port}:") midi_out = pygame.midi.Output(port, 0) try: midi_out.set_instrument(instrument) keyboard = Keyboard(start_note, n_notes) screen = pg.display.set_mode(keyboard.rect.size) screen.fill(BACKGROUNDCOLOR) pg.display.flip() background = pg.Surface(screen.get_size()) background.fill(BACKGROUNDCOLOR) dirty_rects = [] keyboard.draw(screen, background, dirty_rects) pg.display.update(dirty_rects) regions = pg.Surface(screen.get_size()) # initial color (0,0,0) keyboard.map_regions(regions) pg.event.set_blocked(pg.MOUSEMOTION) mouse_note = 0 on_notes = set() while True: e = pg.event.wait() if e.type == pg.MOUSEBUTTONDOWN: mouse_note, velocity, __, __ = regions.get_at(e.pos) if mouse_note and mouse_note not in on_notes: keyboard.key_down(mouse_note) midi_out.note_on(mouse_note, velocity) on_notes.add(mouse_note) else: mouse_note = 0 elif e.type == pg.MOUSEBUTTONUP: if mouse_note: midi_out.note_off(mouse_note) keyboard.key_up(mouse_note) on_notes.remove(mouse_note) mouse_note = 0 elif e.type == pg.QUIT: break elif e.type == pg.KEYDOWN: if e.key == pg.K_ESCAPE: break try: note, velocity = key_mapping[e.key] except KeyError: pass else: if note not in on_notes: keyboard.key_down(note) midi_out.note_on(note, velocity) on_notes.add(note) elif e.type == pg.KEYUP: try: note, __ = key_mapping[e.key] except KeyError: pass else: if note in on_notes and note != mouse_note: keyboard.key_up(note) midi_out.note_off(note, 0) on_notes.remove(note) dirty_rects = [] keyboard.draw(screen, background, dirty_rects) pg.display.update(dirty_rects) finally: del midi_out pygame.midi.quit() def make_key_mapping(keys, start_note): """Return a dictionary of (note, velocity) by computer keyboard key code""" mapping = {} for i, key in enumerate(keys): mapping[key] = (start_note + i, 127) return mapping class NullKey: """A dummy key that ignores events passed to it by other keys A NullKey instance is the left key instance used by default for the left most keyboard key. """ def _right_white_down(self): pass def _right_white_up(self): pass def _right_black_down(self): pass def _right_black_up(self): pass null_key = NullKey() def key_class(updates, image_strip, image_rects, is_white_key=True): """Return a keyboard key widget class Arguments: updates - a set into which a key instance adds itself if it needs redrawing. image_strip - The surface containing the images of all key states. image_rects - A list of Rects giving the regions within image_strip that are relevant to this key class. is_white_key (default True) - Set false if this is a black key. This function automates the creation of a key widget class for the three basic key types. A key has two basic states, up or down ( depressed). Corresponding up and down images are drawn for each of these two states. But to give the illusion of depth, a key may have shadows cast upon it by the adjacent keys to its right. These shadows change depending on the up/down state of the key and its neighbors. So a key may support multiple images and states depending on the shadows. A key type is determined by the length of image_rects and the value of is_white. """ # Naming convention: Variables used by the Key class as part of a # closure start with 'c_'. # State logic and shadows: # # A key may cast a shadow upon the key to its left. A black key casts a # shadow on an adjacent white key. The shadow changes depending of whether # the black or white key is depressed. A white key casts a shadow on the # white key to its left if it is up and the left key is down. Therefore # a keys state, and image it will draw, is determined entirely by its # itself and the key immediately adjacent to it on the right. A white key # is always assumed to have an adjacent white key. # # There can be up to eight key states, representing all permutations # of the three fundamental states of self up/down, adjacent white # right up/down, adjacent black up/down. # down_state_none = 0 down_state_self = 1 down_state_white = down_state_self << 1 down_state_self_white = down_state_self | down_state_white down_state_black = down_state_white << 1 down_state_self_black = down_state_self | down_state_black down_state_white_black = down_state_white | down_state_black down_state_all = down_state_self | down_state_white_black # Some values used in the class. # c_down_state_initial = down_state_none c_down_state_rect_initial = image_rects[0] c_updates = updates c_image_strip = image_strip c_width, c_height = image_rects[0].size # A key propagates its up/down state change to the adjacent white key on # the left by calling the adjacent key's _right_black_down or # _right_white_down method. # if is_white_key: key_color = "white" else: key_color = "black" c_notify_down_method = f"_right_{key_color}_down" c_notify_up_method = f"_right_{key_color}_up" # Images: # # A black key only needs two images, for the up and down states. Its # appearance is unaffected by the adjacent keys to its right, which cast no # shadows upon it. # # A white key with a no adjacent black to its right only needs three # images, for self up, self down, and both self and adjacent white down. # # A white key with both a black and white key to its right needs six # images: self up, self up and adjacent black down, self down, self and # adjacent white down, self and adjacent black down, and all three down. # # Each 'c_event' dictionary maps the current key state to a new key state, # along with corresponding image, for the related event. If no redrawing # is required for the state change then the image rect is simply None. # c_event_down = {down_state_none: (down_state_self, image_rects[1])} c_event_up = {down_state_self: (down_state_none, image_rects[0])} c_event_right_white_down = { down_state_none: (down_state_none, None), down_state_self: (down_state_self, None), } c_event_right_white_up = c_event_right_white_down.copy() c_event_right_black_down = c_event_right_white_down.copy() c_event_right_black_up = c_event_right_white_down.copy() if len(image_rects) > 2: c_event_down[down_state_white] = (down_state_self_white, image_rects[2]) c_event_up[down_state_self_white] = (down_state_white, image_rects[0]) c_event_right_white_down[down_state_none] = (down_state_white, None) c_event_right_white_down[down_state_self] = ( down_state_self_white, image_rects[2], ) c_event_right_white_up[down_state_white] = (down_state_none, None) c_event_right_white_up[down_state_self_white] = ( down_state_self, image_rects[1], ) c_event_right_black_down[down_state_white] = (down_state_white, None) c_event_right_black_down[down_state_self_white] = (down_state_self_white, None) c_event_right_black_up[down_state_white] = (down_state_white, None) c_event_right_black_up[down_state_self_white] = (down_state_self_white, None) if len(image_rects) > 3: c_event_down[down_state_black] = (down_state_self_black, image_rects[4]) c_event_down[down_state_white_black] = (down_state_all, image_rects[5]) c_event_up[down_state_self_black] = (down_state_black, image_rects[3]) c_event_up[down_state_all] = (down_state_white_black, image_rects[3]) c_event_right_white_down[down_state_black] = (down_state_white_black, None) c_event_right_white_down[down_state_self_black] = ( down_state_all, image_rects[5], ) c_event_right_white_up[down_state_white_black] = (down_state_black, None) c_event_right_white_up[down_state_all] = (down_state_self_black, image_rects[4]) c_event_right_black_down[down_state_none] = (down_state_black, image_rects[3]) c_event_right_black_down[down_state_self] = ( down_state_self_black, image_rects[4], ) c_event_right_black_down[down_state_white] = ( down_state_white_black, image_rects[3], ) c_event_right_black_down[down_state_self_white] = ( down_state_all, image_rects[5], ) c_event_right_black_up[down_state_black] = (down_state_none, image_rects[0]) c_event_right_black_up[down_state_self_black] = ( down_state_self, image_rects[1], ) c_event_right_black_up[down_state_white_black] = ( down_state_white, image_rects[0], ) c_event_right_black_up[down_state_all] = (down_state_self_white, image_rects[2]) class Key: """A key widget, maintains key state and draws the key's image Constructor arguments: ident - A unique key identifier. Any immutable type suitable as a key. posn - The location of the key on the display surface. key_left - Optional, the adjacent white key to the left. Changes in up and down state are propagated to that key. A key has an associated position and state. Related to state is the image drawn. State changes are managed with method calls, one method per event type. The up and down event methods are public. Other internal methods are for passing on state changes to the key_left key instance. """ is_white = is_white_key def __init__(self, ident, posn, key_left=None): """Return a new Key instance The initial state is up, with all adjacent keys to the right also up. """ if key_left is None: key_left = null_key rect = pg.Rect(posn[0], posn[1], c_width, c_height) self.rect = rect self._state = c_down_state_initial self._source_rect = c_down_state_rect_initial self._ident = ident self._hash = hash(ident) self._notify_down = getattr(key_left, c_notify_down_method) self._notify_up = getattr(key_left, c_notify_up_method) self._key_left = key_left self._background_rect = pg.Rect(rect.left, rect.bottom - 10, c_width, 10) c_updates.add(self) def down(self): """Signal that this key has been depressed (is down)""" self._state, source_rect = c_event_down[self._state] if source_rect is not None: self._source_rect = source_rect c_updates.add(self) self._notify_down() def up(self): """Signal that this key has been released (is up)""" self._state, source_rect = c_event_up[self._state] if source_rect is not None: self._source_rect = source_rect c_updates.add(self) self._notify_up() def _right_white_down(self): """Signal that the adjacent white key has been depressed This method is for internal propagation of events between key instances. """ self._state, source_rect = c_event_right_white_down[self._state] if source_rect is not None: self._source_rect = source_rect c_updates.add(self) def _right_white_up(self): """Signal that the adjacent white key has been released This method is for internal propagation of events between key instances. """ self._state, source_rect = c_event_right_white_up[self._state] if source_rect is not None: self._source_rect = source_rect c_updates.add(self) def _right_black_down(self): """Signal that the adjacent black key has been depressed This method is for internal propagation of events between key instances. """ self._state, source_rect = c_event_right_black_down[self._state] if source_rect is not None: self._source_rect = source_rect c_updates.add(self) def _right_black_up(self): """Signal that the adjacent black key has been released This method is for internal propagation of events between key instances. """ self._state, source_rect = c_event_right_black_up[self._state] if source_rect is not None: self._source_rect = source_rect c_updates.add(self) def __eq__(self, other): """True if same identifiers""" return self._ident == other._ident def __hash__(self): """Return the immutable hash value""" return self._hash def __str__(self): """Return the key's identifier and position as a string""" return "" % (self._ident, self.rect.top, self.rect.left) def draw(self, surf, background, dirty_rects): """Redraw the key on the surface surf The background is redrawn. The altered region is added to the dirty_rects list. """ surf.blit(background, self._background_rect, self._background_rect) surf.blit(c_image_strip, self.rect, self._source_rect) dirty_rects.append(self.rect) return Key def key_images(): """Return a keyboard keys image strip and a mapping of image locations The return tuple is a surface and a dictionary of rects mapped to key type. This function encapsulates the constants relevant to the keyboard image file. There are five key types. One is the black key. The other four white keys are determined by the proximity of the black keys. The plain white key has no black key adjacent to it. A white-left and white-right key has a black key to the left or right of it respectively. A white-center key has a black key on both sides. A key may have up to six related images depending on the state of adjacent keys to its right. """ my_dir = os.path.split(os.path.abspath(__file__))[0] strip_file = os.path.join(my_dir, "data", "midikeys.png") white_key_width = 42 white_key_height = 160 black_key_width = 22 black_key_height = 94 strip = pg.image.load(strip_file) names = [ "black none", "black self", "white none", "white self", "white self-white", "white-left none", "white-left self", "white-left black", "white-left self-black", "white-left self-white", "white-left all", "white-center none", "white-center self", "white-center black", "white-center self-black", "white-center self-white", "white-center all", "white-right none", "white-right self", "white-right self-white", ] rects = {} for i in range(2): rects[names[i]] = pg.Rect( i * white_key_width, 0, black_key_width, black_key_height ) for i in range(2, len(names)): rects[names[i]] = pg.Rect( i * white_key_width, 0, white_key_width, white_key_height ) return strip, rects class Keyboard: """Musical keyboard widget Constructor arguments: start_note: midi note value of the starting note on the keyboard. n_notes: number of notes (keys) on the keyboard. A Keyboard instance draws the musical keyboard and maintains the state of all the keyboard keys. Individual keys can be in a down (depressed) or up (released) state. """ _image_strip, _rects = key_images() white_key_width, white_key_height = _rects["white none"].size black_key_width, black_key_height = _rects["black none"].size _updates = set() # There are five key classes, representing key shape: # black key (BlackKey), plain white key (WhiteKey), white key to the left # of a black key (WhiteKeyLeft), white key between two black keys # (WhiteKeyCenter), and white key to the right of a black key # (WhiteKeyRight). BlackKey = key_class( _updates, _image_strip, [_rects["black none"], _rects["black self"]], False ) WhiteKey = key_class( _updates, _image_strip, [_rects["white none"], _rects["white self"], _rects["white self-white"]], ) WhiteKeyLeft = key_class( _updates, _image_strip, [ _rects["white-left none"], _rects["white-left self"], _rects["white-left self-white"], _rects["white-left black"], _rects["white-left self-black"], _rects["white-left all"], ], ) WhiteKeyCenter = key_class( _updates, _image_strip, [ _rects["white-center none"], _rects["white-center self"], _rects["white-center self-white"], _rects["white-center black"], _rects["white-center self-black"], _rects["white-center all"], ], ) WhiteKeyRight = key_class( _updates, _image_strip, [ _rects["white-right none"], _rects["white-right self"], _rects["white-right self-white"], ], ) def __init__(self, start_note, n_notes): """Return a new Keyboard instance with n_note keys""" self._start_note = start_note self._end_note = start_note + n_notes - 1 self._add_keys() def _add_keys(self): """Populate the keyboard with key instances Set the _keys and rect attributes. """ # Keys are entered in a list, where index is Midi note. Since there are # only 128 possible Midi notes the list length is manageable. Unassigned # note positions should never be accessed, so are set None to ensure # the bug is quickly detected. # key_map = [None] * 128 start_note = self._start_note end_note = self._end_note black_offset = self.black_key_width // 2 prev_white_key = None x = y = 0 if is_white_key(start_note): is_prev_white = True else: x += black_offset is_prev_white = False for note in range(start_note, end_note + 1): ident = note # For now notes uniquely identify keyboard keys. if is_white_key(note): if is_prev_white: if note == end_note or is_white_key(note + 1): key = self.WhiteKey(ident, (x, y), prev_white_key) else: key = self.WhiteKeyLeft(ident, (x, y), prev_white_key) else: if note == end_note or is_white_key(note + 1): key = self.WhiteKeyRight(ident, (x, y), prev_white_key) else: key = self.WhiteKeyCenter(ident, (x, y), prev_white_key) is_prev_white = True x += self.white_key_width prev_white_key = key else: key = self.BlackKey(ident, (x - black_offset, y), prev_white_key) is_prev_white = False key_map[note] = key self._keys = key_map kb_width = key_map[self._end_note].rect.right kb_height = self.white_key_height self.rect = pg.Rect(0, 0, kb_width, kb_height) def map_regions(self, regions): """Draw the key regions onto surface regions. Regions must have at least 3 byte pixels. Each pixel of the keyboard rectangle is set to the color (note, velocity, 0). The regions surface must be at least as large as (0, 0, self.rect.left, self.rect.bottom) """ # First draw the white key regions. Then add the overlapping # black key regions. # cutoff = self.black_key_height black_keys = [] for note in range(self._start_note, self._end_note + 1): key = self._keys[note] if key.is_white: fill_region(regions, note, key.rect, cutoff) else: black_keys.append((note, key)) for note, key in black_keys: fill_region(regions, note, key.rect, cutoff) def draw(self, surf, background, dirty_rects): """Redraw all altered keyboard keys""" changed_keys = self._updates while changed_keys: changed_keys.pop().draw(surf, background, dirty_rects) def key_down(self, note): """Signal a key down event for note""" self._keys[note].down() def key_up(self, note): """Signal a key up event for note""" self._keys[note].up() def fill_region(regions, note, rect, cutoff): """Fill the region defined by rect with a (note, velocity, 0) color The velocity varies from a small value at the top of the region to 127 at the bottom. The vertical region 0 to cutoff is split into three parts, with velocities 42, 84 and 127. Everything below cutoff has velocity 127. """ x, y, width, height = rect if cutoff is None: cutoff = height delta_height = cutoff // 3 regions.fill((note, 42, 0), (x, y, width, delta_height)) regions.fill((note, 84, 0), (x, y + delta_height, width, delta_height)) regions.fill( (note, 127, 0), (x, y + 2 * delta_height, width, height - 2 * delta_height) ) def is_white_key(note): """True if note is represented by a white key""" key_pattern = [ True, False, True, True, False, True, False, True, True, False, True, False, ] return key_pattern[(note - 21) % len(key_pattern)] def usage(): print("--input [device_id] : Midi message logger") print("--output [device_id] : Midi piano keyboard") print("--list : list available midi devices") def main(mode="output", device_id=None): """Run a Midi example Arguments: mode - if 'output' run a midi keyboard output example 'input' run a midi event logger input example 'list' list available midi devices (default 'output') device_id - midi device number; if None then use the default midi input or output device for the system """ if mode == "input": input_main(device_id) elif mode == "output": output_main(device_id) elif mode == "list": print_device_info() else: raise ValueError(f"Unknown mode option '{mode}'") if __name__ == "__main__": try: device_id = int(sys.argv[-1]) except ValueError: device_id = None if "--input" in sys.argv or "-i" in sys.argv: input_main(device_id) elif "--output" in sys.argv or "-o" in sys.argv: output_main(device_id) elif "--list" in sys.argv or "-l" in sys.argv: print_device_info() else: usage() pg.quit()
#!/usr/bin/env python """ pygame.examples.cursors Click a button and the cursor will change. This example will show you: *The different types of cursors that exist *How to create a cursor *How to set a cursor *How to make a simple button """ import pygame as pg import os # Create a system cursor system_cursor1 = pg.SYSTEM_CURSOR_CROSSHAIR system_cursor2 = pg.SYSTEM_CURSOR_HAND system_cursor3 = pg.SYSTEM_CURSOR_IBEAM # Create a color cursor surf = pg.Surface((40, 40)) surf.fill((120, 50, 50)) color_cursor = pg.cursors.Cursor((20, 20), surf) # Create a color cursor with an image surface main_dir = os.path.split(os.path.abspath(__file__))[0] image_name = os.path.join(main_dir, "data", "cursor.png") image = pg.image.load(image_name) image_cursor = pg.cursors.Cursor( (image.get_width() // 2, image.get_height() // 2), image ) # Create a bitmap cursor from simple strings # sized 24x24 thickarrow_strings = ( "XX ", "XXX ", "XXXX ", "XX.XX ", "XX..XX ", "XX...XX ", "XX....XX ", "XX.....XX ", "XX......XX ", "XX.......XX ", "XX........XX ", "XX........XXX ", "XX......XXXXX ", "XX.XXX..XX ", "XXXX XX..XX ", "XX XX..XX ", " XX..XX ", " XX..XX ", " XX..XX ", " XXXX ", " XX ", " ", " ", " ", ) bitmap_cursor1 = pg.cursors.Cursor( (24, 24), (0, 0), *pg.cursors.compile(thickarrow_strings, black="X", white=".", xor="o"), ) # Create a bitmap cursor from premade simple strings bitmap_cursor2 = pg.cursors.diamond # Calculate if mouse position is inside circle def check_circle(mouse_pos_x, mouse_pos_y, center_x, center_y, radius): return (mouse_pos_x - center_x) ** 2 + (mouse_pos_y - center_y) ** 2 < radius**2 def main(): pg.init() pg.display.set_caption("Cursors Example") pg.font.init() font = pg.font.Font(None, 30) font1 = pg.font.Font(None, 24) bg = pg.display.set_mode((500, 400)) bg.fill((183, 201, 226)) # Initialize circles radius1 = 40 radius2 = 40 radius3 = 40 radius4 = 40 radius5 = 40 radius6 = 40 radius7 = 40 pos_x1 = 82 pos_x2 = 138 pos_x3 = 194 pos_x4 = 250 pos_x5 = 306 pos_x6 = 362 pos_x7 = 418 pos_y1 = 140 pos_y2 = 220 pos_y3 = 140 pos_y4 = 220 pos_y5 = 140 pos_y6 = 220 pos_y7 = 140 circle1 = pg.draw.circle(bg, (255, 255, 255), (pos_x1, pos_y1), radius1) circle2 = pg.draw.circle(bg, (255, 255, 255), (pos_x2, pos_y2), radius2) circle3 = pg.draw.circle(bg, (255, 255, 255), (pos_x3, pos_y3), radius3) circle4 = pg.draw.circle(bg, (255, 255, 255), (pos_x4, pos_y4), radius4) circle5 = pg.draw.circle(bg, (255, 255, 255), (pos_x5, pos_y5), radius5) circle6 = pg.draw.circle(bg, (255, 255, 255), (pos_x6, pos_y6), radius6) circle7 = pg.draw.circle(bg, (255, 255, 255), (pos_x7, pos_y7), radius7) # Initialize button button_text = font1.render("Click here to change cursor", True, (0, 0, 0)) button = pg.draw.rect( bg, (180, 180, 180), (139, 300, button_text.get_width() + 5, button_text.get_height() + 50), ) button_text_rect = button_text.get_rect(center=button.center) bg.blit(button_text, button_text_rect) pg.display.update() cursors = [ system_cursor1, color_cursor, system_cursor2, image_cursor, system_cursor3, bitmap_cursor1, bitmap_cursor2, ] index = 0 pg.mouse.set_cursor(cursors[index]) pressed = False clock = pg.time.Clock() while True: clock.tick(50) mouse_x, mouse_y = pg.mouse.get_pos() # Check if mouse is inside a circle to change its color if check_circle(mouse_x, mouse_y, circle1.centerx, circle1.centery, radius1): circle1 = pg.draw.circle(bg, (255, 0, 0), (pos_x1, pos_y1), radius1) else: circle1 = pg.draw.circle(bg, (255, 255, 255), (pos_x1, pos_y1), radius1) if check_circle(mouse_x, mouse_y, circle2.centerx, circle2.centery, radius2): circle2 = pg.draw.circle(bg, (255, 127, 0), (pos_x2, pos_y2), radius2) else: circle2 = pg.draw.circle(bg, (255, 255, 255), (pos_x2, pos_y2), radius2) if check_circle(mouse_x, mouse_y, circle3.centerx, circle3.centery, radius3): circle3 = pg.draw.circle(bg, (255, 255, 0), (pos_x3, pos_y3), radius3) else: circle3 = pg.draw.circle(bg, (255, 255, 255), (pos_x3, pos_y3), radius3) if check_circle(mouse_x, mouse_y, circle4.centerx, circle4.centery, radius3): circle4 = pg.draw.circle(bg, (0, 255, 0), (pos_x4, pos_y4), radius4) else: circle4 = pg.draw.circle(bg, (255, 255, 255), (pos_x4, pos_y4), radius4) if check_circle(mouse_x, mouse_y, circle5.centerx, circle5.centery, radius4): circle5 = pg.draw.circle(bg, (0, 0, 255), (pos_x5, pos_y5), radius5) else: circle5 = pg.draw.circle(bg, (255, 255, 255), (pos_x5, pos_y5), radius5) if check_circle(mouse_x, mouse_y, circle6.centerx, circle6.centery, radius6): circle6 = pg.draw.circle(bg, (75, 0, 130), (pos_x6, pos_y6), radius6) else: circle6 = pg.draw.circle(bg, (255, 255, 255), (pos_x6, pos_y6), radius6) if check_circle(mouse_x, mouse_y, circle7.centerx, circle7.centery, radius7): circle7 = pg.draw.circle(bg, (148, 0, 211), (pos_x7, pos_y7), radius7) else: circle7 = pg.draw.circle(bg, (255, 255, 255), (pos_x7, pos_y7), radius7) bg.fill((183, 201, 226), (0, 15, bg.get_width(), 50)) text1 = font.render( (f"This is a {pg.mouse.get_cursor().type} cursor"), True, (0, 0, 0) ) text_rect1 = text1.get_rect(center=(bg.get_width() / 2, 40)) bg.blit(text1, text_rect1) button = pg.draw.rect( bg, (100, 149, 240), (139, 300, button_text.get_width() + 5, button_text.get_height() + 50), ) bg.blit(button_text, button_text_rect) # Check if button was clicked and change cursor if button.collidepoint(mouse_x, mouse_y): button = pg.draw.rect( bg, (60, 100, 255), ( 139, 300, button_text.get_width() + 5, button_text.get_height() + 50, ), ) bg.blit(button_text, button_text_rect) if pg.mouse.get_pressed()[0] == 1 and pressed == False: button = pg.draw.rect( bg, (0, 0, 139), ( 139, 300, button_text.get_width() + 5, button_text.get_height() + 50, ), ) bg.blit(button_text, button_text_rect) index += 1 index %= len(cursors) pg.mouse.set_cursor(cursors[index]) pg.display.update() pg.time.delay(40) if pg.mouse.get_pressed()[0] == 1: pressed = True elif pg.mouse.get_pressed()[0] == 0: pressed = False for event in pg.event.get(): if event.type == pg.QUIT: pg.quit() raise SystemExit pg.display.update() if __name__ == "__main__": main()
import pathlib
print(pathlib.Path(__file__))
print(pathlib.Path(__file__).parent)
print(pathlib.Path(__file__).parent / 'Grahics' / 'apple.png')
path_to_image= pathlib.Path(__file__).parent / 'Grahics' / 'apple.png'
apple = pygame.image.load(path_to_image).convert_alpha()
apple = pygame.image.load(str(path_to_image)).convert_alpha()
rect = pygame.Rect(block.x+scx, block.y+scy, 10, 10)
rect.inflate_ip(zoom, zoom)
pygame.draw.rect(screen, block.color, rect)
def main():
p.init()
screen = p.display.set_mode((WIDTH, HEIGHT))
clock = p.time.Clock()
screen.fill(p.Color("white"))
gs = engine.State()
loadImages()
running = True
while running:
for e in p.event.get():
if e.type == p.QUIT:
running = False
# INDENTATION
#-->|
visualise(screen, gs)
clock.tick(MAX_FPS)
p.display.flip()
mylist = [[Thing()] * 1000] * 800
mylist = [[Thing()] * 2] * 2
mylist[0][0].x = 42
print(mylist[0][1], mylist[1][0], mylist[1][1]) # 42 42 42
mylist = [[Thing() for _ in range(1000)] for _ in range(800)]
def create_list(rows, cols):
return [[Thing(col, row) for row in range(rows)] for col in range(cols)]
def change_list(to_change):
for ncol, col in enumerate(to_change):
for nrow, thing in enumerate(col):
thing.x = ncol
thing.y = nrow
thing.sound = 'Meow'
class AlienShooting():
def __init__(self, w=640, h=640):
self.spaceship_main = pygame.sprite.Sprite()
self.spaceship_main.image = pygame.image.load('spacecraft_1.png').convert_alpha()
self.spaceship_main.rect = self.spaceship_main.image.get_rect(center = (140, 140))
self.spaceship_main.mask = pygame.mask.from_surface(self.spaceship_main.image)
self.alien_spacecraft1 = pygame.sprite.Sprite()
self.alien_spacecraft1.image = pygame.image.load('spacecraft_alien.png').convert_alpha()
self.alien_spacecraft1.rect = self.alien_spacecraft1.image.get_rect(center = (160, 160))
self.alien_spacecraft1.mask = pygame.mask.from_surface(self.alien_spacecraft1.image)
def _is_collision(self):
if pygame.sprite.collide_mask(self.spaceship_main, self.alien_spacecraft1):
return True
return False
enemy(enemyX[i], enemyY[i], i)
Trending Discussions on pygame
Trending Discussions on pygame
QUESTION
I'm trying to put buttons in a surface*(screen)* and want to include them in just one class. This is the code:
larguraTela, alturaTela = (640, 480)
tela = pygame.display.set_mode((larguraTela, alturaTela))
verde = (38, 117, 1)
# Rect(left, top, width, height)
#botaoMenu = pygame.Rect(20, 415, 150, 45)
#setaEsquerda = pygame.Rect(10, 280, 45, 45)
#setaDireita = pygame.Rect(580, 280, 45, 45)
#pygame.draw.rect(tela, verde, botaoMenu)
#pygame.draw.rect(tela, verde, setaDireita)
#pygame.draw.rect(tela, verde, setaEsquerda)
class Button:
def __init__(self, left, top, width, height):
self.button = pygame.Rect(left, top, width, height)
def draw(self, screen, color, botao):
self.rect = pygame.draw.rect(screen, color, botao)
buttonMenu = Button(20, 415, 150 ,45)
buttonMenu.draw(tela, verde, buttonMenu)
The error is:
Traceback (most recent call last):
File "/home/rafael/ibi/Rafael/Cรณdigo organizado/menu_equipe_otimizado.py", line 31, in
buttonMenu.draw(tela, verde, buttonMenu)
File "/home/rafael/ibi/Rafael/Cรณdigo organizado/menu_equipe_otimizado.py", line 28, in draw
self.rect = pygame.draw.rect(self, screen, color, botao)
TypeError: argument 1 must be pygame.Surface, not Button
ANSWER
Answered 2021-Jun-15 at 19:22You don't need the button
attribute at all. Pass the color and the rectangle to the constructor of the class. Save the color and rectangle in an attribute and use the attributes to draw the button:
class Button:
def __init__(self, color, rect):
self.color = color
self.rect = rect
def draw(self, screen):
pygame.draw.rect(screen, self.color, self.rect)
botao = pygame.Rect(20, 415, 150, 45)
buttonMenu = Button(verde, botao)
buttonMenu.draw(tela)
Alternatively, you can pass the position and size of the rectangle to the constructor:
class Button:
def __init__(self, color, left, top, width, height):
self.color = color
self.rect = pygame.Rect(left, top, width, height)
def draw(self, screen):
pygame.draw.rect(screen, self.color, self.rect)
buttonMenu = Button(verde, 20, 415, 150, 45)
buttonMenu.draw(tela)
QUESTION
Here is my underdeveloped pygame ping-pong game, but my sprites(player&opponent) ain't moving, on giving a keyboard input. And when I quit the program, it yells an error pygame.error: video system not initialized
. My pygame is the latest 1.9.6 version with all the files up-to-daee. However, I am certain that pygame.display
is generating this error, but I even tried pygame.display.init()
and that too didn't worked :(
import pygame
# Initialization
pygame.init()
# Screen, Caption and Icon
width = 800
height = 600
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('PyGame')
icon = pygame.image.load('ping-pong.png')
pygame.display.set_icon(icon)
# Create Rects
player = pygame.Rect((5, 230), (10, 120))
opponent = pygame.Rect((785, 230), (10, 120))
# Game Variables
playerY_change = 0
opponentY_change = 0
game_over = False
while not game_over:
# Coloring the Screen
screen.fill((27, 35, 43))
# Draw Rects
pygame.draw.rect(screen, (255,255,255), player)
pygame.draw.rect(screen, (255,255,255), opponent)
# Managing Events
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
pygame.quit()
if event.type == pygame.KEYUP:
if event.type == pygame.K_UP:
opponentY_change -= 3
if event.type == pygame.K_DOWN:
opponentY_change += 3
if event.type == pygame.K_w:
playerY_change -= 3
if event.type == pygame.K_s:
playerY_change += 3
if event.type == pygame.KEYDOWN:
if (event.type == pygame.K_UP) or (event.type == pygame.K_DOWN):
opponentY_change = 0
if (event.type == pygame.K_w) or (event.type == pygame.K_s):
playerY_change = 0
# Moving my sprites
player.y += playerY_change
opponent.y += opponentY_change
# Updating the screen on every iter of loop
pygame.display.update()
ANSWER
Answered 2021-Jun-15 at 14:57Here, you have two different problems :
First the movement is not working because to differentiate the keys, you use event.type
to compare where it should be event.key
. Try with for example :
if event.key == pygame.K_UP:
opponentY_change -= 3
The other problem is that when the game is over, you use pygame.quit()
but later on the loop, you use pygame.display.update()
. You should put the display update at the beginning of the loop.
QUESTION
I am trying to make a popup for messages such as "Action completed" and I want a button on it to close the popup (A simple OK which quits only the popup). It also sometimes moves behind the window which is annoying. I have some code for the button but it has an issue with the geometry of the shape since the shape isn't exactly defined as it is variable through the size of font and text length.
import tkinter as tk
from tkinter import *
import pygame
import sys
def Text(Text_input, Font, Background, Foreground):
my_window = tk.Tk()
my_window.title(Text_input)
my_window.geometry()
help_label = tk.Label(my_window, font = Font, bg=Background, fg=Foreground, text = Text_input)
help_label.grid(row=0, column=0)
button = tk.Button(my_window, text="QUIT", fg="red", command=quit)
button.pack(side=tk.BOTTOM)
my_window.mainloop()
Text("Hello", "calibri 80", "white", "black")
ANSWER
Answered 2021-Jun-15 at 11:50From my own experience wanting to achieve this, I wrote a simple tkinter code export_success.py
as follows:
from tkinter import *
from tkinter import ttk
import sqlite3
from tkinter.ttk import *
root = Tk()
root.geometry('280x100')
root.title("Export Status")
root.config(bg="")
style = ttk.Style()
label_0 = Label(root, text="Export Successful", width=20, background="white", foreground="grey15", font=("Arial, bold", 15)).place(x=50, y=23)
exit1 = Button(root, text='Exit', style='C.TButton', width=11, command=root.destroy).place(x=100, y=60)
root.mainloop()
I then just insert this code os.system('python export_success.py')
at the end of my tkinker window that I'm working on.
In this case I'm exporting my information and wanted to know when it is successful.
I am not saying this is best practice and there might be other ways, I just found it to work out for me.
QUESTION
I have a sound that I wish to play.
My code;
[...]
if var_camera_flip == 1:
if var_camera != 4:
pygame.mixer.Channel(2).play(pygame.mixer.Sound(r'audio\camera\camera motor.mp3'), -1)
else:
pygame.mixer.Channel(2).stop()
else:
pygame.mixer.Channel(2).stop()
[...]
This code is in a subroutine that I call. What happens is that it restarts the sound each time it runs. What I want is that is the sound to continue playing until it is told not to.
ANSWER
Answered 2021-Jun-15 at 04:42Do not stop
a sound, but pause
it with pygame.mixer.Channel.pause
:
pygame.mixer.Channel(2).pause()
Once a sound is paused it can be continued with pygame.mixer.unpause
:
pygame.mixer.Channel(2).unpause()
QUESTION
i found this unfinished file in my files and now i need to finish it, only problem is idk really how do i detect collision with the bullet and the player thing and/or the bullet and the enemy thing, when the bullets collide with the enemy it still dies, i just don't remember how.
here's the code ig help thanks
import pygame, os, random,sys
pygame.init()
FPS=60
SCREEN = pygame.display.set_mode((400,500))
pygame.display.set_caption('caption')
x=50
y=450
vel = 3
width = 20
height = 20
class Player(pygame.sprite.Sprite):
def __init__(self,x,y,width,height):
super().__init__()
self.x = x
self.y = y
self.vel = 4
self.image = pygame.Surface((width, height))
self.image.fill((0,0,0))
self.rect = self.image.get_rect(topleft = (x, y))
class B(pygame.sprite.Sprite):
def __init__(self,x,y,radius, color):
super().__init__()
self.x = x
self.y = y
self.color = color
self.radius = radius
self.vel = vel
self.image = pygame.Surface((self.radius * 2, self.radius * 2), pygame.SRCALPHA)
pygame.draw.circle(self.image, self.color, (self.radius, self.radius), self.radius)
self.rect = self.image.get_rect(center = (self.x, self.y))
class Enemy(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((20,20))
self.image.fill((255, 0, 0))
y = random.randrange (0, 480)
x = 400
self.rect = self.image.get_rect(topleft = (x, y))
self.speed = random.randrange(1,2)
player = Player(x, y, width, height)
enemies = pygame.sprite.Group()
bullets = pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
all_sprites.add(player)
score = 0
# main loop
running = True
clock = pygame.time.Clock()
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and len(bullets) < 8:
bullet = B(player.rect.centerx, player.rect.centery, 2, (0,0,0))
bullets.add(bullet)
all_sprites.add(bullet)
if len(enemies) < 2:
e = Enemy()
enemies.add(e)
all_sprites.add(e)
for bullet in bullets:
if bullet.rect.right < 500:
bullet.rect.x += bullet.vel
else:
bullet.kill()
for enemy in enemies:
if enemy.rect.right > 0:
enemy.rect.x -= enemy.speed
else:
enemy.kill()
print ("L")
pygame.quit()
sys.exit()
pygame.sprite.groupcollide(bullets, enemies, True, True)
keys = pygame.key.get_pressed()
if keys[pygame.K_UP] and player.rect.top > player.vel:
player.rect.y -= player.vel
if keys[pygame.K_DOWN] and player.rect.bottom < 500 - player.vel:
player.rect.y += player.vel
SCREEN.fill((190, 232, 220))
all_sprites.draw(SCREEN)
pygame.display.update()
pygame.quit()
ANSWER
Answered 2021-Jun-15 at 02:18Collision detection depends on your needs.
- Bounding boxes are simple and can detect if the x, y edges of each object are not within one another. This is fine for fast moving games and things where you don't necessarily require point precision.
- Distance vectors are also simple and perfect solution for circle collisions. They calculate the difference in distance between two objects according to a radius prescribed with the hypotenuse of distX^2 + distY^2.
- Compound bounding objects are harder to calculate, especially for concave areas on objects of arbitrary shape. There are too many notable and novel approaches to collision detection beyond these to remark on here.
They're also increasingly complex depending on things like variability (if they're deformable objects, if they have particle seams, etc and 2d vs 3d object collision can be vastly different worlds as well. There are tons of articles, but I'll post one with implementation here
QUESTION
I am making a clock in my game. After roughly 60 seconds it changes to the next number. I use the subroutine below to change the clock image when it needs to. My problem is that the images flickers when displayed, and I don't want that.
My code;
def display_night_clock():
global var_clock
global var_6_am
if var_hide == False:
if var_6_am == False:
if var_clock == 1:
screen.blit(image_12_am, (1266, 0))
pygame.display.update()
if var_clock == 2:
screen.blit(image_1_am, (1266, 0))
pygame.display.update()
if var_clock == 3:
screen.blit(image_2_am, (1266, 0))
pygame.display.update()
if var_clock == 4:
screen.blit(image_3_am, (1266, 0))
pygame.display.update()
if var_clock == 5:
screen.blit(image_4_am, (1266, 0))
pygame.display.update()
if var_clock == 6:
screen.blit(image_5_am, (1266, 0))
pygame.display.update()
if var_clock == 7:
screen.blit(image_7_am, (1266, 0))
pygame.display.update()
var_6_am = True
var_clock = 1
I just call this subroutine in my main loop. I have used this method of displaying images before in my program in my other subroutines, and those images don't flicker. But for some reason these images flicker.
ANSWER
Answered 2021-Jun-15 at 04:33The problem is caused by multiple calls to pygame.display.update()
. An update of the display at the end of the application loop is sufficient. Multiple calls to pygame.display.update()
or pygame.display.flip()
cause flickering.
Remove all calls to pygame.display.update()
from your code, but call it once at the end of the application loop:
while running:
# [...]
pygame.display.update()
QUESTION
I did some research and found this: Setting a fixed FPS in Pygame, Python 3 and this: pygame clock.tick() vs framerate in game main loop. It is similar to what I am asking.
So the clock.tick(FPS)
caps the program to run at that FPS
. The reason you do this is so you can control the FPS
of the program and it makes it easier for time stuff like waits.
But how can I unlimited FPS
and still control my FPS
for time stuff like waits? From my understanding, this is not possible, due to the fact that clock.tick(FPS)
caps the FPS
and while not adding it in means unlimited FPS
but you not being able to control the FPS
.
So it seems to be a question of weather to cap you FPS
for control or have your program run as fast as possible, but without control.
In conclusion, what I am asking is four questions;
- Pros and cons of capping your
FPS
- Pros and cons of not capping your
FPS
and going on with the naturalFPS
of your program - Is it possible to have unlimited
FPS
and still control myFPS
for time stuff like waits? - If so, how?
ANSWER
Answered 2021-Jun-14 at 21:42You have to calculate the movement per frame depending on the frame rate.
pygame.time.Clock.tick
returns the number of milliseconds since the last call. When you call it in the application loop, this is the number of milliseconds that have passed since the last frame. When you call it without a parameter (framerate=0
), the FPS are unlimited.
Define the distance in pixels that the player should move per second (move_per_second
). Then compute the distance per frame in the application loop:
move_per_second = 500 # 500 is just an example and means 500 pixels/second
run = True
clock = pygame.time.Clock()
while run:
ms_frame = clock.tick() # get the milliseconds passed since the last frame
move_per_frame = move_per_second * ms_frame / 1000
# [...]
However, with this approach, you are wasting CPU time and you won't see a noticeable difference. The downside is that you don't have a constant frame rate and you have to calculate all animations and movements depending on the time that has passed in the last frame.
QUESTION
So in response to my question (How to continuously move an image smoothly in Pygame?) I was told to set my framerate in order to do my animation. But no matter where I place it, clock.tick(60)
does nothing. I do clock = pygame.time.Clock()
BTW. So how do I do this? I have researched and found this (pygame clock.tick() vs framerate in game main loop) but I don't really understand this.
My main game function;
def main_game():
global var_escape
global var_start_game
global var_menu_screen
global var_camera
global var_bounce
global var_x
global var_x_timer
global var_door
global var_light
global camera_flip
var_start_game = False
var_escape = False
var_menu_screen = 0
var_bounce = 0
var_x = 0
var_camera = 1
var_x_timer = 0
var_light = 0
var_door = 0
var_camera_flip = 0
pygame.mixer.init()
pygame.mixer.music.load(r'audio\Menu_Music.mp3')
pygame.mixer.music.play(-1)
pygame.mixer.music.set_volume(1.0)
while True:
if var_menu_screen == 0:
menu_screen()
if var_menu_screen == 1:
options_screen()
if var_menu_screen == 2:
new_game_boyz()
if var_menu_screen == 3:
pygame.quit()
sys.quit()
if var_menu_screen == 4:
credits_screen()
if var_start_game == True:
break
var_start_game = False
start_game()
image_door_6_off = pygame.image.load(r'textures\door\light off\frame_6_off.png')
image_door_button_off = pygame.image.load(r'textures\door button\door_button_off.png')
image_light_button_off = pygame.image.load(r'textures\light button\light_button_off.png')
image_door_6_off_size = image_door_6_off.get_rect().size
centered_image_door_6_off = [(display_size[0] - image_door_6_off_size[0])/2, (display_size[1] - image_door_6_off_size[1])/2]
screen.blit(image_door_6_off, centered_image_door_6_off)
screen.blit(image_door_button_off, (0, 0))
screen.blit(image_light_button_off, (1113, 0))
pygame.display.update()
while var_escape == False:
#This is my main game loop in the function
#This is where I would like to set the framerate
mouse_down = False
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
quit_popup()
elif event.type == MOUSEBUTTONDOWN:
mouse_down = True
light(mouse_down)
door(mouse_down)
camera_flip()
#Just so I can get a smoother animation for this function below
cameras() #<--- This function here
#Just so I can get a smoother animation for this function above
camera_buttons(mouse_down)
This is my main game loop;
while True:
#Calls the function
main_game()
The main game loop will not set the framerate because the main_game function has a loop inside it. This is only in a loop because when I want to restart the function I can. I just added this in to show how the function is run.
ANSWER
Answered 2021-Jun-14 at 04:28Use pygame.time.Clock
to control the frames per second and thus the game speed.
The method tick()
of a pygame.time.Clock
object, delays the game in that way, that every iteration of the loop consumes the same period of time. See pygame.time.Clock.tick()
:
This method should be called once per frame.
e.g.:
def main_game():
# [...]
FPS = 60
clock = pygame.time.Clock()
while var_escape == False:
clock.tick(60)
# [...]
QUESTION
i hope you can help, because I'm running out of knowledge. My Problem: i want to change a variable to a new value:
def Schwierigkeit1():
x = 1
return x
print(x)
therefore i call this function in my Button function:
def button(msg, x, y, w, h, ic, ac, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(gameDisplay, ac, (x, y, w, h))
if click[0] == 1 and action != None:
if (action == Schwierigkeit1):
schwierigkeitComputer = Schwierigkeit1()
print("Gegner auf Schwierigkeit: %d" % schwierigkeitComputer)
When i debug this, it shows me a good looking code and it seems to work. BUT: This button call is set in a loop to build a starting screen for my game. Whenever the program comes back to this while-loop, the value of this variable gets resetted to the "Global" value.
schwierigkeitComputer = 0
def game_intro():
while intro:
pygame.display.set_caption('Spieleinstellungen')
clock = pygame.time.Clock()
intro = True
pygame.init()
gameDisplay.fill(white)
for event in pygame.event.get():
# print(event)
if event.type == pygame.QUIT:
pygame.quit()
quit()
button("1", 100, (ZEILEN + 230), 100, 50, white, LIGHTBLUE, Schwierigkeit1)
Did I mess anything up or do i not understand how a button with pygame works?
Thank you for your help.
ANSWER
Answered 2021-Jun-13 at 09:02If you want to change a variabel in global namespace within a function, you need to use the global
statement:
def button(msg, x, y, w, h, ic, ac, action=None):
global schwierigkeitComputer # <--- this is missing
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
pygame.draw.rect(gameDisplay, ac, (x, y, w, h))
if click[0] == 1 and action != None:
if (action == Schwierigkeit1):
schwierigkeitComputer = Schwierigkeit1()
print("Gegner auf Schwierigkeit: %d" % schwierigkeitComputer)
QUESTION
I just want to play a simple MP3 file on Linux directly from the Python code.
I've looked at this and this question and tried the following libraries but all of them failed: audioplayer
, Ipython.display.Audio
, pydub
, pygame.mixer
, ossaudiodev
, soundfile
.
Errors that I saw often were:
ModuleNotFoundError: No module named 'gi'
- Errors with
ffmpeg
ANSWER
Answered 2021-Jun-11 at 11:03pyglet
is the only solution I found that can play MP3 on Linux:
import pyglet
sound = pyglet.media.load("/home/max/Desktop/sound.mp3")
sound.play()
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install pygame
Support
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesExplore Kits - Develop, implement, customize Projects, Custom Functions and Applications with kandi kitsโ
Save this library and start creating your kit
Share this Page