Currently, I am loading all images at the start of the program. Is there a better solution for this? As some images may not be used at all throughout the entire game (I'm currently making a main menu).
Main.py
import pygame as pg
from Menu import Menu
pg.init()
"""Displays screen"""
winWidth = 1920
winHeight = 1080
size = (winWidth, winHeight)
win = pg.display.set_mode(size)
"""Load images"""
bg_img = pg.image.load('Pic/td-gui/PNG/menu/bg.png')
title_img = pg.image.load('transtitle.png')
settings_img = pg.image.load('Pic/td-gui/PNG/menu/button_settings.png')
play_img = pg.image.load('Pic/td-gui/PNG/menu/button_play.png')
reg_img = pg.image.load('Pic/td-gui/PNG/menu/button_registration.png')
quit_img = pg.image.load('Custom/Menu/Quit.png')
rope_img = pg.image.load('Pic/td-gui/PNG/menu/rope_small.png')
changeDiff_img = pg.image.load('Custom/Menu/Change_Difficulty.png')
score_img = pg.image.load('Custom/Menu/Scoreboard.png')
selectmap_img = pg.image.load('Custom/Menu/Select_map.png')
tutorial_img = pg.image.load('Custom/Menu/Tutorial.png')
"""Puts loaded images into the correct size"""
bg_img = pg.transform.scale(bg_img,(winWidth, winHeight))
title_img = pg.transform.scale(title_img, (750, 75))
play_img = pg.transform.scale(play_img, (250, 250))
rope_img = pg.transform.scale(rope_img, (27, 290))
clock = pg.time.Clock()
win.blit(bg_img, (0, 0))
mainMenu = True
settingsMenu = False
run = True
running = True
while run:
clock.tick(30)
pg.display.update()
for event in pg.event.get():
if event.type == pg.QUIT:
run = False
if not run:
pg.quit()
"""Places correct images in specified location"""
title = Menu(winWidth // 2 - 375, winHeight // 2 - 500, title_img)
if mainMenu:
reg_button = Menu(winWidth // 2 - 150, winHeight // 2 - 100, reg_img)
ropeR = Menu(winWidth // 2 - 100, 200, rope_img)
ropeL = Menu(winWidth // 2 + 70, 200, rope_img)
scoreboard_button = Menu(winWidth//2 - 330, winHeight//2 + 275, score_img)
play_button = Menu(winWidth // 2 - 125, winHeight // 2 - 375, play_img)
reg_button = Menu(winWidth // 2 - 161, winHeight // 2 - 100, reg_img)
quit_button = Menu(winWidth//2 + 30, winHeight//2 + 275, quit_img)
changeDiff_button = Menu(winWidth//2 - 330, winHeight//2 + 80, changeDiff_img)
selectmap_button = Menu(winWidth//2 + 30, winHeight//2 + 80, selectmap_img)
settings_button = Menu(winWidth - 200, winHeight - 200, settings_img)
"""Draws images in specified location and makes buttons if specified"""
title.draw_img(win)
if reg_button.draw_button(win):
print('Reg button clicked')
ropeL.draw_img(win)
ropeR.draw_img(win)
if scoreboard_button.draw_button(win):
print("options Clicked")
if play_button.draw_button(win):
print("Play Clicked")
if quit_button.draw_button(win):
pg.quit()
if changeDiff_button.draw_button(win):
print('Change Difficulty button pressed')
if selectmap_button.draw_button(win):
print('Select Map button preseed')
if settings_button.draw_button(win):
print('Settings button pressed')
mainMenu = False
settingsMenu = True
if settingsMenu:
win.blit(bg_img, (0, 0))
title.draw_img(win)
Menu.py
import pygame as pg
pg.init()
class Menu():
def __init__(self, x, y, img):
self.img = img
self.rect = self.img.get_rect()
self.rect.y = y
self.rect.x = x
self.clicked = False
def draw_button(self, win):
action = False
#get mouse position
pos = pg.mouse.get_pos()
#check mouseover and clicked conditions
if self.rect.collidepoint(pos):
if pg.mouse.get_pressed()[0] == 1 and not self.clicked:
action = True
self.clicked = True
if pg.mouse.get_pressed()[0] == 0:
action = False
#draw image
win.blit(self.img, (self.rect.x, self.rect.y))
return action
def draw_img(self, win):
win.blit(self.img, (self.rect.x, self.rect.y))
Say I'm making a music button, which is accessible through the settings button, I would currently load the music button image at the start of the program. Is there a way to make it so the music image would only be loaded once the settings button has been pressed?
To give a quick and simple overview of what you could do, here's an example. You define an abstract Scene class. Then, every "scene" in your game inherits from it. Each scene has a setup method that loads everything the scene needs (or might need).
import pygame
class Scene:
def __init__(self):
""" Create all attributes """
def setup(self):
""" Load everything in and initialize attributes """
def handle_events(self, events):
""" Handle the events for this scene """
def update(self, dt):
""" Run logic """
def render(self, screen):
""" Draw to the screen """
class Menu(Scene):
def __init__(self):
""" Create all attributes """
self.image1 = None
self.image2 = None
# ... and so on ...
def setup(self):
""" Load everything in and initialize attributes """
self.image1 = pygame.image.load("my_image1.png")
self.image2 = pygame.image.load("my_image2.png")
# ... and so on ...
def handle_events(self, events):
""" Handle the events for this scene """
def update(self, dt):
""" Run logic """
def render(self, screen):
""" Draw to the screen """
screen.blit(self.image1, (0, 0))
# ... and so on ...
class Game(Scene):
def __init__(self):
""" Create all attributes """
self.player = None
self.enemies = None
# ... and so on ...
def setup(self):
""" Load everything in and initialize attributes """
self.player = Player(position=(100, 100), image=pygame.image.load("player.png"))
self.enemies = [
Enemy(position=(200, 400), pygame.image.load("enemy1.png")),
Enemy(position=(200, 500), pygame.image.load("enemy2.png")),
]
# ... and so on ...
def handle_events(self, events):
""" Handle the events for this scene """
for event in events:
if event.type == pygame.KEY_DOWN:
print('PAM!')
def update(self, dt):
""" Run logic """
self.player.update(dt)
for enemy in self.enemies:
enemy.update()
def render(self, screen):
""" Draw to the screen """
screen.blit(self.player.image, self.player.position)
for enemy in self.enemies:
screen.blit(enemy.image, enemy.position)
# ... and so on ...
Here's roughly how a game loop would look like.
def main():
screen = pygame.display.set_mode((1024, 1024))
clock = pygame.time.Clock()
running = True
scene = Menu()
scene.setup()
while running:
dt = clock.tick(60)
events = list(pygame.event.get())
scene.handle_events(events)
scene.update(dt)
scene.render(screen)
# Have some way of determining when to switch scene.
if should_switch_to_game:
scene = Game()
scene.setup()
elif should_switch_to_menu:
scene = Menu()
scene.setup()
# ... and so on ...
This is a basic starting point, but there are other ways to handle the situation, like having an asset manager that dynamically load and unload assets based on usage. However, these are quite complicated and will make development and debugging much harder. It's always best to keep things simple when you can. If you can load all images at the beginning of the program, then I'd suggest doing so.
Also, remember that there's nothing that's "best" or "optimized" as all you're doing is tradeoffs. If you're trying to optimize for memory, then you're often making your program slower. If you're optimizing for speed, then you're often making your program use more memory.
If you are loading things just when you need them, you're going to have a loading time switching between different views in your menu. This is often not something you want as the user expects it to be fast. Switching from the game to the menu, it's more forgiving to have a couple of extra ms. But if you feel you want to go the other way then different views in the menu could be considered different scenes.
In general, no it's not a problem to load images that are never used, as long as the images are small. It's better to load them all at once so that the interface never has to wait for loading.
However, if you have a very large amount of images or your images are very big, it might be worth loading some images only when you need them. You could do something like this when you start your music field:
def start_music_menu():
global music_icon # Sorry about the global
if music_icon is None:
music_icon = pygame.image.load('...')
In this case your interface will freeze while loading the extra image. You can also use threading or asyncio to keep your interface responsive while a image is loading.
Properly use OOP concept make separate class for various loading image and then use them accordingly .
Related
im not sure why im getting errors, as it was working perfectly fine before i started to add a button to my game. Ultimately my goal is to create a game menu with the options to start game which then moves onto the next screen, the level platform, and quit, which ultimately will close the window. Bonus, if i can get help on this, im thinking about also creating a sign up and login page, i already have one set up using tkinter but im not sure how to access the stored information using pygames, so it saves game progress from username and password. Also, what website do you guys use to get free images for your games? I can't draw that well and am having trouble finding images that match what im trying to accomplish.
# imports
import pygame, sys
import pygame.freetype
from pygame.sprite import Sprite
from pygame.rect import Rect
# colors
green = (0, 255, 0)
black = (0, 0, 0)
# buttons
def create_text(text, font_size, text_color, bg_color):
font = pygame.freetype.Sysfont("Courioer", font_size, bold=True)
surface, _ = font.render(text=text, fgcolor=text_color, bgcolor = bg_color)
return surface.convert_alpha()
class UIElement(Sprite):
def __init__(self, center_position, text, font_size, bg_color, text_color):
super().__init__()
self.mouse_over = False
default_image = create_text(text, font_size, text_color, bg_text)
highlighted_image = create_text(text, font_size * 1.2, text_color, bg_text)
self.images = [default_image, highlighted_image]
self.rects = [
default_image.get_rect(center = center_position),
highlighted_image.get_rect(center = center_position)]
super().__init__()
#property
def image(self):
return self.image[1] if self.mouse_over else self.image[0]
#property
def rect(self):
return self.rects[1] if self.mouse_over else self.rects[0]
def update(self, mouse_pos):
if self.rect.collidepoint(mouse_pos):
self.mouse_over = True
else:
self.mouse_over = False
def draw(self, surface):
surface.blit(self.image, self.rect)
# Title
pygame.display.set_caption("Zombrio")
icon = pygame.image.load("zombie.png")
pygame.display.set_icon(icon)
# character
survivorImg = pygame.image.load("frankenstein.png")
survivorx = 1
survivory = 400
def player():
screen.blit(survivorImg, (survivorx, survivory))
def main():
pygame.init()
# screen
screen = pygame.display.set_mode((800, 800))
clock = pygame.time.Clock()
uielement = UIElement(
center_position = (400, 400),
font_size = 30,
bg_color = black,
text_color = green,
text = "Start"
)
# Game Loop
while True:
screen.fill(black) # not defined error, only occurred after creating buttons
for event in pygame.event.get(): # video system not initialized
if event.type == pygame.QUIT: # indent error
pygame.quit()
sys.exit()
uielement.update(pygame.mouse.get_pos()) # says uielement is not defined
uielement.draw(screen)
pygame.display.flip()
player()
pygame.display.update()
clock.tick(120)
main()
pygame.quit()
So """Text""" is a string literal. You can use it for multi-line strings.
https://developers.google.com/edu/python/strings#:~:text=String%20literals%20inside%20triple%20quotes,go%20to%20represent%20computed%20values.
You can also use it to create a docstring.
The way you are using it here does not look correct. If you want to print those statements, then trying print("""Text""") on the next line.
If you want to use it as a comment on a line of code, then follow it with the "#"
For more examples of using tripple quotes, see here: https://www.geeksforgeeks.org/triple-quotes-in-python/
I am new to python and wanted to create a game to test some knowledge. Please bare with my mistakes. I would also really appreciate an example written out if possible so I can wrap my head around the concept.
I couldn't figure out how to post the entire code without formatting nightmares so I put it in github sorry if this is against terms!
I removed most of the dialogue because it was very very long.
Some background about the same:
It was written as a text-based only game first, then I heard about pygame wanted to figure out how to put the game into the window. So first I created all of the code, which ran perfectly fine even with sound effects / music, but then after trying to figure out pygame's game loop, I can't figure out how to change the background image.
I have 5 scenes that I want 5 images for, that change when I change the scene with user input. Even now, the music changes, but the background images don't change after blitting the first one in the 'naming' scene. I don't really understand how the pygame loop works in conjunction with the game engine I have currently. I know it's looping through the pygame loop as I tested it with printing things, but when trying to add images or saying if scene == naming: blit image, it doesn't work. I also tried putting the images into each of the scenes. I also tried putting the images into a class called background with all 5 scenes and images to each. Can't figure it out.
Any help would be greatly appreciated!
-M
Here is an example of how to use scenes. This is not the only way of doing it, but i though it would be easy to use/understand. I also noticed in your code that you used input(). which is annoying if your using a window, so i also added a button and a textbox input that kinda works.
import pygame as pg
pg.init() # initialize the pg
win = pg.display.set_mode((1080, 720)) # create the game window
pg.display.set_caption("Puppy Love")
white = (255,255,255)
black = (0,0,0)
clock = pg.time.Clock()
fps = 60
class Scene:
def __init__(self):
self.sceneNum = 1
def Scene_1(self):
win.fill(white)
if next_scene_button.draw(): #if clicked button
self.sceneNum += 1
name_Box.Draw()
#anything else you want to draw
def Scene_2(self):
win.fill((0,0,255))
if next_scene_button.draw():
self.sceneNum = 1
#...
def Draw_Scene(self):
if self.sceneNum == 1:
self.Scene_1()
elif self.sceneNum == 2:
self.Scene_2()
class Button:
def __init__(self,x,y,w,h,text):
self.x = x
self.y = y
self.w = w
self.h = h
self.text = text
self.font = pg.font.Font(pg.font.match_font("Calibri"),20)
def draw(self):
button_clicked = False
col = (150,150,150)
if mouse_pos[0] > self.x and mouse_pos[0] < self.x + self.w:
if mouse_pos[1] > self.y and mouse_pos[1] < self.y + self.h:
col = (200,200,200)
if click:
button_clicked = True
pg.draw.rect(win,col,(self.x,self.y,self.w,self.h))
obj = self.font.render(self.text,True, black)
win.blit(obj,(self.x + (self.w-obj.get_width())//2,self.y + (self.h-obj.get_height())//2)) #center the text
return button_clicked #return if the button was clicked or not
class TextBox:
def __init__(self,x = 0, y = 0, w = 0, h = 0, text = "", background = False, font_size = 30, font = "Calibri", text_colour = (0,0,0)):
self.x = x
self.y = y
self.w = w
self.h = h
self.text_colour = text_colour
self.text = text
self.background = background
self.font = pg.font.Font(pg.font.match_font(font),font_size)
def Add_char(self,key):
if key == 8:
self.text = self.text[:-1]
else:
char = pg.key.name(key)
self.text += char
def Draw(self):
if self.background:
pg.draw.rect(win, self.background, (self.x,self.y,self.w,self.h))
obj = self.font.render(self.text,True,self.text_colour)
win.blit(obj,(self.x,self.y))
def Get_pos(self):
return (self.x,self.y)
name_Box = TextBox(x=100, y=200, w=150, h=40, background=(200,200,200))
Scenes = Scene()
next_scene_button = Button(400,400,100,50,"next scene")
click = False
mouse_pos = [0,0]
running = True
while running:
clock.tick(fps)
Scenes.Draw_Scene()
mouse_pos = pg.mouse.get_pos()
click = False
pg.display.update() #no diference between .flip() and .update()
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
running = False
if event.type == pg.MOUSEBUTTONDOWN:
click = True
if event.type == pg.KEYDOWN:
if Scenes.sceneNum == 1:
name_Box.Add_char(event.key)
The main thing to take away from this is to only use one pygame.display.flip(). Hopefully you can use this to improve your program
I'm trying to make a simple application with pyglet. My main problem so far is that I can't seem to blit an image with alpha - all of the transparent pixels are converted into black pixels. I'm not sure whether the problem is with the loading of the image or the blitting. Here is a very basic overview of how I'm trying to render the image:
import pyglet
import pyglet.clock
window = pyglet.window.Window()
window.config.alpha_size = 8
#fancy text
text = pyglet.resource.image("text.png")
#background image
bg = pyglet.resource.image("bg.png")
bg.blit(0, 0)
text.blit(100, 100)
pyglet.app.run()
Any help is appreciated. Thanks in advance.
You most likely just need to enable GL ALPHA blends.
from pyglet.gl import *
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
But first of all, your code is not able to run.
Mostly because you don't declare a window.event function to handle the on_draw where you normally render things.
Secondly, you never clear your window (which will cause a mess).
Here's a minimal working example of your code:
import pyglet
import pyglet.clock
window = pyglet.window.Window()
window.config.alpha_size = 8
#fancy text
text = pyglet.resource.image("text.png")
#background image
bg = pyglet.resource.image("bg.png")
#window.event
def on_draw():
window.clear()
bg.blit(0, 0)
text.blit(100, 100)
pyglet.app.run()
Now this generates this:
And here's a working example of how you use the GL_BLEND feature:
import pyglet
import pyglet.clock
from pyglet.gl import *
window = pyglet.window.Window()
window.config.alpha_size = 8
#fancy text
text = pyglet.resource.image("text.png")
#background image
bg = pyglet.resource.image("bg.png")
#window.event
def on_draw():
window.clear()
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
bg.blit(0, 0)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
text.blit(100, 100)
pyglet.app.run()
This yields a result like so:
However, this code will quickly become messy.
So there's two things you can do. You can first, put your images into sprite objects. Secondly, make this a bit more object oriented.
First, we'll use sprites.
self.fancy_background = pyglet.sprite.Sprite(pyglet.image.load('bg.png'))
self.fancy_background.draw() # not blit!
Sprites automatically uses transparency, which makes your life (and code) a lot easier.
Secondly, we'll put these into a batch.
Batches are made to bunch A LOT of sprites so you can call .draw() on the batch, and all sprites in that batch gets insta-rendered.
self.background = pyglet.graphics.Batch()
self.fancy_background = pyglet.sprite.Sprite(pyglet.image.load('bg.png'), batch=self.background)
self.background.draw() # background, not fancy_background! And also not blit!!
Last and most certainly not least.
We'll put this into a class so we can do cool stuff later on.
import pyglet
import pyglet.clock
from pyglet.gl import *
key = pyglet.window.key
class main(pyglet.window.Window):
def __init__ (self, width=800, height=600, fps=False, *args, **kwargs):
super(main, self).__init__(width, height, *args, **kwargs)
self.x, self.y = 0, 0
self.background = pyglet.graphics.Batch()
self.texts = pyglet.graphics.Batch()
self.fancy_background = pyglet.sprite.Sprite(pyglet.image.load('bg.png'), batch=self.background)
self.fancy_text = pyglet.sprite.Sprite(pyglet.image.load('text.png'), batch=self.texts)
self.mouse_x = 0
self.mouse_y = 0
self.alive = 1
def on_draw(self):
self.render()
def on_close(self):
self.alive = 0
def on_mouse_motion(self, x, y, dx, dy):
self.mouse_x = x
self.mouse_y = y
def on_mouse_press(self, x, y, button, modifiers):
if button == 1: # Left click
pass
def on_key_press(self, symbol, modifiers):
if symbol == key.ESCAPE: # [ESC]
self.alive = 0
def render(self):
self.clear()
self.background.draw()
self.texts.draw()
self.flip()
def run(self):
while self.alive == 1:
self.render()
# -----------> This is key <----------
# This is what replaces pyglet.app.run()
# but is required for the GUI to not freeze
#
event = self.dispatch_events()
if __name__ == '__main__':
x = main()
x.run()
BAM.
This code will enable you to create custom functions and custom "player objects" later on for instance. Also you can do collision detection easier and the code just looks a lot more structured (I threw in a little bonus features such as keyboard and mouse events).
Note tho, that the position of the sprites will default to x=0, y=0 as shown in the last picture. You can set the position with x=100 either on the variable/handle or when creating the sprite.
couple of days ago, I made a code that plays a video in pygame window.
Code works just fine, just as I originally intended. However, when I print debug statement to see its fps, it's somewhere around 30fps. If I were to increase fps, what should I do?
Here is the code I used.
import sys
from color import *
import pyglet
pygame.init()
running = True
gameDisplay= pygame.display.set_mode((800,600))
window = pyglet.window.Window(visible=False)
background_vid = pyglet.media.Player()
background_vid.queue(pyglet.media.load(".\\music_folder\\music_vid/servant_of_evil_converted.mp4"))
background_vid.play()
def hellow():
print "hellow bloody world"
def on_draw():
#We have to convert the Pyglet media player's image to a Pygame surface
rawimage = background_vid.get_texture().get_image_data()
print "rawimage "+str(rawimage)
pixels = rawimage.get_data('RGBA', rawimage.width *8)
video = pygame.image.frombuffer(pixels, (rawimage.width*2,rawimage.height), 'RGBA')
#Blit the image to the screen
gameDisplay.blit(video, (0, 0))
circle_x=300
while True:
pyglet.clock.tick()
on_draw()
print "fps: "+str(pyglet.clock.get_fps())
for event in pygame.event.get():
if(event.type == pygame.QUIT):
sys.exit()
pygame.quit()
pygame.draw.rect(gameDisplay, red, (circle_x, 300, 300, 300), 5)
circle_x+=1
pygame.display.update()
So what #pydude said is not completely wrong.
However, in order to actually messure FPS I'd put a custom counter in the on_draw function, that will give better accuracy.
Further more, the only real problem with your code is that you don't insert vsync=False into your Window() decorator.
I've reworked your code to make it a little bit more modular, I've also removed potential bottle-necks and added my own custom FPS counter (via GL and not console), here - have a go and see if it works better for you.
(Note: Pressing Escape will exit the application)
import sys
from color import *
import pyglet
from pyglet.gl import *
from time import time # Used for FPS calc
key = pyglet.window.key
class main(pyglet.window.Window):
def __init__ (self):
super(main, self).__init__(800, 800, fullscreen = False, vsync = True)
self.running = True
self.background_vid = pyglet.media.Player()
self.background_vid.queue(pyglet.media.load(".\\music_folder\\music_vid/servant_of_evil_converted.mp4"))
self.background_vid.play()
self.fps_counter = 0
self.last_fps = time()
self.fps_text = pyglet.text.Label(str(self.fps_counter), font_size=12, x=10, y=10)
def on_key_press(self, symbol, modifiers):
if symbol == key.ESCAPE: # [ESC]
self.running = False
def on_draw(self):
self.render()
#We have to convert the Pyglet media player's image to a Pygame surface
def render(self):
self.clear()
rawimage = background_vid.get_texture().get_image_data()
pixels = rawimage.get_data('RGBA', rawimage.width *8)
video = pygame.image.frombuffer(pixels, (rawimage.width*2,rawimage.height), 'RGBA')
#Blit the image to the screen
self.blit(video, (0, 0))
# And flip the GL buffer
self.fps_counter += 1
if time() - self.last_fps > 1:
self.fps_text.text = str(self.fps_counter)
self.fps_counter = 0
self.last_fps = time()
self.fps_text.draw()
self.flip()
def run(self):
while self.running is True:
self.render()
# -----------> This is key <----------
# This is what replaces pyglet.app.run()
# but is required for the GUI to not freeze
#
event = self.dispatch_events()
if event and event.type == pygame.QUIT:
self.running = False
x = main()
x.run()
Try toggling vsync = True to vsync = False and watch the difference in the FPS counter.
With python, printing is very slow. Try just printing every once and a while.
Example:(requires import random):
if random.random()>0.09:print "fps: "+str(pyglet.clock.get_fps())
I'm trying to make a basic (Mario style) game but my sprite(plumber) doesn't appear, it could be hidden behind background? i'm not exactly sure, i am not getting any errors either.
import pygame
import sys
import itertools
import pygame
from pygame.sprite import Sprite
cloud_background = pygame.image.load('clouds.bmp')
brick_tile = pygame.image.load('brick_tile.png')
pink = (255, 64, 64)
w = 640
h = 480
screen = pygame.display.set_mode((w, h))
running = 1
def setup_background():
screen.fill((pink))
screen.blit(cloud_background,(0,0))
brick_width, brick_height = brick_tile.get_width(), brick_tile.get_height()
for x,y in itertools.product(range(0,640,brick_width),
range(390,480,brick_height)):
# print(x,y)
screen.blit(brick_tile, (x, y))
pygame.display.flip()
while running:
setup_background()
event = pygame.event.poll()
if event.type == pygame.QUIT: sys.exit()
class plumber(sprite):
def __init__(
self, screen, img_filename, init_position,
init_direction, speed):
Sprite.__init__(self)
self.screen = screen
self.speed = speed
self.base_image = pygame.image.load(Mario_sideways_sprite_2xL.png).convert_alpha()
self.image = self.base_image
self.pos = 50,50
First problem found is that you must modify
pygame.image.load(Mario_sideways_sprite_2xL.png)
with something like.
pygame.image.load("Mario_sideways_sprite_2xL.png")
Besides this, the code has many problems that impedes it to work. For example,
you do not instantiate your plumber class.
class plumber(sprite) should be plumber(Sprite) (still better Plumber(Sprite))
You need something like:
myplumber = Plumber()
allsprites = pygame.sprite.RenderPlain((myplumber, ....))
clock = pygame.time.Clock()
You could see here the main parts of a simple program like yours.