Pygame fast food menu skeleton. Am I over thining it?.

  • (2 Pages)
  • +
  • 1
  • 2

16 Replies - 654 Views - Last Post: Yesterday, 03:28 PM Rate Topic: -----

#1 albert003  Icon User is offline

  • D.I.C Regular

Reputation: 14
  • View blog
  • Posts: 366
  • Joined: 15-December 14

Pygame fast food menu skeleton. Am I over thining it?.

Posted 05 November 2017 - 07:29 PM

Got hired to do a menu for a business and I wanted to use pygame to animate the menu. My idea is to use two separate programs for this code. The first will be a function where the user can modify the items and prices using dictionaries (I haven't gotten there yet. Ive been working on the menu). Then the second program will show the animation using pygame. They want to put it in a Rasberrypi and I figure I could make it into an executable file. The menu to change the items, prices and pictures I will work on after I get this pygame menu working.

Now they want six items on their menu and have it displayed on a large 30" TV above the server. My thinking is to use a class to make it work. I've drawn it with various flow charts and I can't decide whether to use a single class for all of the food items or a class for each item. Would someone tell me if I'm on the right track?. I know how to do the program using functions, but as far as I can tell, it will be three functions for each item and I think using oop will be easier. This is the program so far.


import pygame,random
from time import sleep
 
# Initialize the game engine
pygame.init()
 

black = (0, 0, 0)
white = (255, 255, 255)
blue = (0, 0, 255)
green = (0, 255, 0)
red = (255, 0, 0)
darkslateblue = (72, 61, 139)

size = (1900, 1000)#x y
screen = pygame.display.set_mode(size)
 
pygame.display.set_caption("snack menu")

def barname():
    font = pygame.font.SysFont('Calibri', 200, True, False)
    text = font.render("TRIFECTA EXPRESS", True,white)
    screen.blit(text,[140,0])

class Menu(object):# items in the menu
    def __init__(self): #load pics for menu in constructor
        self.loadburgerpics=(pygame.image.load("broiled1.jpg"),
                         pygame.image.load("broiled2.jpg"),
                         pygame.image.load("broiled3.jpg"),
                         bpygame.image.load("broiled4.jpg"))
        self.bbqsandwhich=(pygame.image.load("wings1.jpg"),
                         pygame.image.load("wings2.jpg"),
                         pygame.image.load("wings3.jpg"),
                         bpygame.image.load("wings4.jpg"))
        self.loadchickenwings=(pygame.image.load("wings1.jpg"),
                         pygame.image.load("wings2.jpg"),
                         pygame.image.load("wings3.jpg"),
                         bpygame.image.load("wings4.jpg"))
        self.soupdujour=(pygame.image.load("soup1.jpg"),
                         pygame.image.load("soup2.jpg"),
                         pygame.image.load("soup3.jpg"),
                         bpygame.image.load("soup4.jpg"))
        self.loadpizzapics=(pygame.image.load("pizza1.jpg"),
                         pygame.image.load("pizza2.jpg"),
                         pygame.image.load("pizza3.jpg"),
                         bpygame.image.load("pizza4.jpg"))
        self.cookies=(pygame.image.load("cookies1.jpg"),
                         pygame.image.load("cookies2.jpg"),
                         pygame.image.load("cookies3.jpg"),
                         bpygame.image.load("cookies4.jpg"))

    def burgertext(self):#text and prices for the burger
        font = pygame.font.SysFont('Calibri', 200, True, False)
        text = font.render("BROILED BURGER", True,white)
        screen.blit(text,[50,50])
        
    def burgerpics(self): #loads pics into a loop,transforms,scales and organises the pics
        pass

    def randomburgerpics(self): #randomlly changes pics of the burger
        return random.choice(pix)

    def bbqsandtext(self):
        pass

    def bbqsandpics(self):
        pass

    def randombbqpics(self):
        pass

    def cwingstext(self):#chicken wings
        pass

    def cwingspics(self):
        pass

    def randomwingspics(self):
        pass

    def souptext(self):
        pass

    def souppics(self):
        pass

    def randomsouppics(self):
        pass

    def pizzatext(self):
        pass

    def pizzapics(self):
        pass

    def randompizzapics(self):
        pass

    def cookiestext(self):
        pass

    def cookiespics(self):
        pass

    def randomcookiesqpics(self):
        pass
    
done = False
clock = pygame.time.Clock()

def Burger():# burger object made
    pass

def Bbq():# bbq object made
    pass

def Chickwings():#chicken wings object made
    pass

def Soup():#soup object made
    pass

def Pizza():#pizza object made
    pass

def Cookies():#cookies object made
    pass
# Loop as long as done == False
while not done:
 
    for event in pygame.event.get():  # User did something
        if event.type == pygame.QUIT:  # If user clicked close
            done = True  # Flag that we are done so we exit this loop
 

    screen.fill(darkslateblue)
    Burger()
    Bbq()
    Chickwings()
    Soup()
    Pizza()
    Cookies()
    pygame.display.update()


    clock.tick(60)
 
# Be IDLE friendly
pygame.quit()



Is This A Good Question/Topic? 0
  • +

Replies To: Pygame fast food menu skeleton. Am I over thining it?.

#2 jon.kiparsky  Icon User is online

  • Chinga la migra
  • member icon


Reputation: 10681
  • View blog
  • Posts: 18,290
  • Joined: 19-March 11

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 05 November 2017 - 08:50 PM

A bit of code cleanup to start with. Get the literals out of main flow - eventually, you'd like them to not be in the code at all but for the moment you can declare them as constants similar to what you're doing with the colors:

BURGER_PICS = (
    "broiled1.jpg",
    "broiled2.jpg",
    "broiled3.jpg",
    "broiled4.jpg"
)


etc

and
IMAGE_SETS = (
    BURGER_PICS, 
    BBQ_PICS,
    CHICKEN_WING_PICS,
    # etc
 )

Then your init can be reduced to a nested loop over the images in the image sets.
(eventually, you might want to come up with a way that the user can change this menu without you having to change the code - let that sit in the back of your mind, don't worry about it now, something will come to you)

Then I see a lonely function called burgertext. This looks like it belongs as part of the Burger class. Similarly, the randomburgerpics also looks like it's something that pertains to the Burger class. And since you have similarly named functions for similar-looking classes, I'm betting that you can collect a lot of functionality up into a MenuItem class and dispense with the separate classes for each menu item.
Now you'd have a half-dozen instances of MenuItem, each of which knows about its image set, its text, etc - all of the things that vary with a menu item - and a few things which probably live in the MenuItem class itself, like the font face and size.
If you collect those instances into a list, you can then iterate over them and your while loop looks like:

while not done:
    # check for done-ness
    screen.fill(BACKGROUND_COLOR)
    for item in menu_items:
        item.display(screen)
        pygame.display.update()
    clock.tick(60)



Obviously, that's sort of a quick sketch of where I'd go with that, but maybe it'll give you something to play with.
Was This Post Helpful? 1
  • +
  • -

#3 DK3250  Icon User is online

  • Pythonian
  • member icon

Reputation: 318
  • View blog
  • Posts: 1,048
  • Joined: 27-December 13

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 06 November 2017 - 01:56 AM

Just a small thing; you have this in the code:
for event in pygame.event.get():  # User did something
    if event.type == pygame.QUIT:  # If user clicked close
This makes it possible for the user to terminate the program by a mouse click.
However, you probably want this functionality available only to the administrator, not the user.
I suggest a termination code triggered by a keyboard input, not a mouse click in the user interphase.
Was This Post Helpful? 1
  • +
  • -

#4 albert003  Icon User is offline

  • D.I.C Regular

Reputation: 14
  • View blog
  • Posts: 366
  • Joined: 15-December 14

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 06 November 2017 - 09:44 PM

I'm stuck and I haven't been able to make any progress because I'm focusing on this one part. I don't know if I'm over thinking it or not. I can't seem to get this part to work and I keep getting this error message.
burger = pygame.image.load("broiled.jpg")
error: Couldn't open broiled.jpg

BURGER_PICS = (
"broiled1.jpg",
"broiled2.jpg",
"broiled3.jpg",
"broiled4.jpg"
)

I've tried different ways to make what you suggested work. I looked online for answers and on youtube. I've tried to make BURGER_PICS into an open list then load and append each picture. I'm out of ideas. Would you please elaborate more or what you meant or give me a link so I can see examples of what you mean?.
Was This Post Helpful? 0
  • +
  • -

#5 jon.kiparsky  Icon User is online

  • Chinga la migra
  • member icon


Reputation: 10681
  • View blog
  • Posts: 18,290
  • Joined: 19-March 11

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 06 November 2017 - 09:49 PM

Sounds like there's a problem with the path to the file.
Was This Post Helpful? 0
  • +
  • -

#6 DK3250  Icon User is online

  • Pythonian
  • member icon

Reputation: 318
  • View blog
  • Posts: 1,048
  • Joined: 27-December 13

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 07 November 2017 - 12:53 AM

The file you try to open must be placed in the same directory as the python file (or the full path to the jpg-file must be given).
The file name is case sensitive, make sure that you use exactly the same file name in your code including capital and non-capital letters.

In post #1 the names was "broiledx.jpg" where x is a number - in post #4 you only refer to "broiled.jpg" without number.
Did you change this on purpose?
Was This Post Helpful? 0
  • +
  • -

#7 albert003  Icon User is offline

  • D.I.C Regular

Reputation: 14
  • View blog
  • Posts: 366
  • Joined: 15-December 14

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 07 November 2017 - 11:57 AM

I just realised that this morning after I took another look at my program. I admit I was frustrated and tired for staring and working on it all day. I missed that little detail. I figured it out after a good nights sleep.

############burger pics
b1 = pygame.image.load("b1.jpg")
b2 = pygame.image.load("b2.jpg")
b3 = pygame.image.load("b3.jpg")
b4 = pygame.image.load("b4.jpg")
BURGER_PICS = [
b1,b2,b3,b4]
#############pizza pics
p1 = pygame.image.load("p1.jpg")
p2 = pyagme.image.load("p2.jpg")
p3 = pygame.image.load("p3.jpg")
p4 = pygame.image.load("p4.jpg")
PIZZA_PICS = [
p1,p2,p3,p4]
Was This Post Helpful? 0
  • +
  • -

#8 Radius Nightly  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 88
  • Joined: 07-May 15

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 08 November 2017 - 03:38 AM

When you start doing more then you have to, at the point when you start complicating too much, just remember this: KISS

Im not into this language, but my opinion is not to waste lines. It reminds me when i was writing alphabet, each character in new line, into new variable, later i learn it can be written in a single line, and then it was not so transparent with lets say 10-20 filenames in single line or so, because it become too long, so i continue to find a better ways.
You can probably make a single variable with table that will contain all filenames, for example instead of bg1.jpg, bg2.jpg, bg3.jpg as backgrounds (based on filename or folder), you can probably make quick index search and load on all of them (whole folder if its like group or bg#.jpg where # are number, can make it as loading while starting if there is too much things), and you can shift between them with repeat/while/loop-a-like until all things are shown (like 4 things found, no more then 4 things will loop/show) based on counts (like first loop is 1, it means bg1, second loop is 2, means bg2...), if you can make a function to do a whole process when you call it and give it some information (so he knows what to do), alongside with function complexity, each time you need it, it will cost you 1 line of code, longer code - more saves, better viewing, less work later due to changes or when adding features. Just my opinion.

This post has been edited by Radius Nightly: 08 November 2017 - 03:47 AM

Was This Post Helpful? 0
  • +
  • -

#9 jon.kiparsky  Icon User is online

  • Chinga la migra
  • member icon


Reputation: 10681
  • View blog
  • Posts: 18,290
  • Joined: 19-March 11

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 08 November 2017 - 07:09 AM

View PostRadius Nightly, on 08 November 2017 - 05:38 AM, said:

You can probably make a single variable with table that will contain all filenames, for example instead of bg1.jpg, bg2.jpg, bg3.jpg as backgrounds (based on filename or folder), you can probably make quick index search and load on all of them (whole folder if its like group or bg#.jpg where # are number, can make it as loading while starting if there is too much things), and you can shift between them with repeat/while/loop-a-like until all things are shown (like 4 things found, no more then 4 things will loop/show) based on counts (like first loop is 1, it means bg1, second loop is 2, means bg2...), if you can make a function to do a whole process when you call it and give it some information (so he knows what to do), alongside with function complexity, each time you need it, it will cost you 1 line of code, longer code - more saves, better viewing, less work later due to changes or when adding features. Just my opinion.


Yes, like I said there will be room for improvement on the file loading. However, I was not thinking of something this complex. As a short-term solution, you might come up with something where each menu type would have a pathname leading to directory of images as one of its fields. Then you could simply load the images as part of the init step for each menu item.

In the long run you'd like to have a goal of making this configurable by the user, so that the menu items are not fixed in the code, and part of that would be allowing the user to specify all of the details of each menu item they're showing. For that problem, the Simplest Solution That Might Possibly Work, in my view, is a config file, which would have an entry for each menu item, and each entry would have a line for each data point that needs to be set for that item. This would mean devising and parsing a little DSL, but that's not very hard.
Was This Post Helpful? 0
  • +
  • -

#10 DK3250  Icon User is online

  • Pythonian
  • member icon

Reputation: 318
  • View blog
  • Posts: 1,048
  • Joined: 27-December 13

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 08 November 2017 - 02:56 PM

In my book DSL = Digital Subscriber Line; a technique for broadband access on a normal telephone line. But in post #9 it seems to have another meaning....?
Was This Post Helpful? 0
  • +
  • -

#11 jon.kiparsky  Icon User is online

  • Chinga la migra
  • member icon


Reputation: 10681
  • View blog
  • Posts: 18,290
  • Joined: 19-March 11

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 08 November 2017 - 08:33 PM

Domain-specific language.
Was This Post Helpful? 0
  • +
  • -

#12 albert003  Icon User is offline

  • D.I.C Regular

Reputation: 14
  • View blog
  • Posts: 366
  • Joined: 15-December 14

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 12 November 2017 - 06:21 PM

So I'm building the program using your suggestions. But I'm building it piece by piece so I can troubleshoot problems as they happen. I'm starting with the title of the bar, the random changing of the burger pictures, the word "BROILED BURGER" and the price. Can't figure out why I can't get anything to appear on the screen. I get the purple back ground but nothing else. I thought the problem was with the pictures so I removed everything and just left the instance of the method Barname (Which displays the bars name) and I still get a blank purple screen. I've tried everything I could think of and I still can't get anything to appear on the screen.
Any hints or suggestions are welcome.

import pygame,random

# Initialize the game engine
pygame.init()
 

black = (0, 0, 0)
white = (255, 255, 255)
blue = (0, 0, 255)
green = (0, 255, 0)
red = (255, 0, 0)
darkslateblue = (72, 61, 139)

size = (1900, 900)#x y
screen = pygame.display.set_mode(size)
 
pygame.display.set_caption("snack menu")

############burger pics

b1 = pygame.image.load("b1.jpg")
b2 = pygame.image.load("b2.jpg")
b3 = pygame.image.load("b3.jpg")
b4 = pygame.image.load("b4.jpg")
BURGER_PICS = [b1,b2,b3,b4]
#############pizza pics
p1 = pygame.image.load("p1.jpg")
p2 = pygame.image.load("p2.jpg")
p3 = pygame.image.load("p3.jpg")
p4 = pygame.image.load("p4.jpg")
PIZZA_PICS = [p1,p2,p3,p4]

IMAGE_SETS = (
    BURGER_PICS,
    PIZZA_PICS)
def barname():
    font = pygame.font.SysFont('Calibri', 200, True, False)
    text = font.render("TRIFECTA EXPRESS", True,white)
    screen.blit(text,[140,0])

class Main(object):
    def __init__(self):
        self.BURGER_PICS = [b1,b2,b3,b4]
        #self.PIZZA_PICS = [p1,p2,p3,p4]
        self.Bran = random.choice(BURGER_PICS)
        #self.Pran = random.choice(PIZZA_PICS)
        
    def Barname(self):
        font = pygame.font.SysFont('Calibri', 200, True, False)
        text = font.render("TRIFECTA EXPRESS", True,white)
        screen.blit(text,[140,0])
        
    def BurgerPics(self):
        bpix = []
        for i in range(1,4):
            filename = "b"+str(i)+".jpg"
            BURGER_PICS = pygame.image.load(filename)
            pix.append(pygame.transform.scale(BURGER_PICS,[230,230]))
            bpix = self.BurgerPics()
        return bpix

    def DisplayBpics(self):#displays burger pics
        return random.choice(bpix)
        screen.blit(self.BurgerPics(),[0,100])
        
    def Burgertext(self):#displays burgers name and price
        font = pygame.font.SysFont('Calibri', 200, True, False)
        text = font.render("BROILED BURGER", True,white)
        screen.blit(text,[140,200])
        
done = False
clock = pygame.time.Clock()
mains = []
while not done:
 
    for event in pygame.event.get():  
        if event.type == pygame.QUIT:  
            done = True  
 

    screen.fill(darkslateblue)

    for Main in mains:
        Main.Barname()
        Main.DisplayBpics()

    pygame.display.update()
    clock.tick(60)


pygame.quit()



Was This Post Helpful? 0
  • +
  • -

#13 DK3250  Icon User is online

  • Pythonian
  • member icon

Reputation: 318
  • View blog
  • Posts: 1,048
  • Joined: 27-December 13

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 13 November 2017 - 12:53 AM

Read line 83 again, and then check line 73....
Was This Post Helpful? 1
  • +
  • -

#14 albert003  Icon User is offline

  • D.I.C Regular

Reputation: 14
  • View blog
  • Posts: 366
  • Joined: 15-December 14

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 13 November 2017 - 02:18 PM

Ah man, I can't believe I missed that detail. Ok, I have a new question I would like to ask you. When I run the program it says the following error.

TypeError: unbound method DisplayBpics() must be called with Main instance as first argument (got nothing instead)

This is what I have so far. If you could please give me a hint.
import pygame,random

# Initialize the game engine
pygame.init()
 

black = (0, 0, 0)
white = (255, 255, 255)
blue = (0, 0, 255)
green = (0, 255, 0)
red = (255, 0, 0)
darkslateblue = (72, 61, 139)

size = (1900, 900)#x y
screen = pygame.display.set_mode(size)
 
pygame.display.set_caption("snack menu")

############burger pics

b1 = pygame.image.load("b1.jpg")
b2 = pygame.image.load("b2.jpg")
b3 = pygame.image.load("b3.jpg")
b4 = pygame.image.load("b4.jpg")
BURGER_PICS = [b1,b2,b3,b4]
#############pizza pics
p1 = pygame.image.load("p1.jpg")
p2 = pygame.image.load("p2.jpg")
p3 = pygame.image.load("p3.jpg")
p4 = pygame.image.load("p4.jpg")
PIZZA_PICS = [p1,p2,p3,p4]

IMAGE_SETS = (
    BURGER_PICS,
    PIZZA_PICS)

class Main(object):
    def __init__(self):
        self.BURGER_PICS = [b1,b2,b3,b4]
        #self.PIZZA_PICS = [p1,p2,p3,p4]
        self.Bran = random.choice(BURGER_PICS)
        #self.Pran = random.choice(PIZZA_PICS)
        
    def Barname(self):
        font = pygame.font.SysFont('Calibri', 200, True, False)
        text = font.render("TRIFECTA EXPRESS", True,white)
        screen.blit(text,[140,0])
        
    def BurgerPics(self):
        bpix = []
        for i in range(1,4):
            filename = "b"+str(i)+".jpg"
            BURGER_PICS = pygame.image.load(filename)
            bpix.append(pygame.transform.scale(BURGER_PICS,[230,230]))
            
        return bpix

    def DisplayBpics(self):#displays burger pics
        Bran = random.choice(bpix)
        screen.blit(self.BurgerPics(),[0,100])
        
    def Burgertext(self):#displays burgers name and price
        font = pygame.font.SysFont('Calibri', 100, True, False)
        text = font.render("BROILED BURGER", True,white)
        screen.blit(text,[180,200])

    def Burgerprice(self):
        font = pygame.font.SysFont('Calibri', 100, True, False)
        text = font.render("$7.00", True,white)
        screen.blit(text,[1200,200])
        
done = False
clock = pygame.time.Clock()
mains = []
bpix = BURGER_PICS
while not done:
 
    for event in pygame.event.get():  
        if event.type == pygame.QUIT:  
            done = True  
 

    screen.fill(darkslateblue)

    mains.append(Main())
    for main in mains:
        Main.DisplayBpics()
        main.Barname()
        main.Burgertext()
        main.Burgerprice()
        

    pygame.display.update()
    
    clock.tick(60)


pygame.quit()



Was This Post Helpful? 0
  • +
  • -

#15 DK3250  Icon User is online

  • Pythonian
  • member icon

Reputation: 318
  • View blog
  • Posts: 1,048
  • Joined: 27-December 13

Re: Pygame fast food menu skeleton. Am I over thining it?.

Posted 13 November 2017 - 03:16 PM

With a class like 'Main()' you would normally make one (single) instance:
main = Main()

Later you can invoke the class methods like this:
main.Barname()
Note: <instance>.<method>

The error is due to the capital first 'M' in line 87; the syntax becomes <class name>.<method>

More problematic is the adding of new instances of Main() in line 85; that list will soon grow long... - drop this and only make one instance before the while loop.
Also, drop the for loop in line 86 - if you have only one instance of Main(), there is no need for a loop.

I hope this will push you forward.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2