Eyes for a robot in python with Pygame

Viewed 222

I have a robot eye code made in pygame that works perfectly, it is the following:

import pygame
from itertools import cycle
import tkinter as tk
import random
import sqlite3
import time

root = tk.Tk()
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()

class Expression(pygame.sprite.Sprite):
    def __init__(self, data):
        super().__init__()
        self.image = pygame.Surface((len(data[0]), len(data)))
        x = y = 0
        for row in data:
            for col in row:
                if col == "O":
                    self.image.set_at((x, y), pygame.Color('dodgerblue'))
                x += 1
            y += 1
            x = 0
        self.image = pygame.transform.scale(self.image, (screen_width, screen_height))
        self.rect = self.image.get_rect()

REGULAR = Expression([
"                     ",
"                     ",
"    OOOO     OOOO    ",
"   OOOOOO   OOOOOO   ",
"   OOOOOO   OOOOOO   ",
"    OOOO     OOOO    ",
"                     ",
"                     ",
])

QUESTION = Expression([
"                     ",
"                     ",
"     OOOO             ",
"    OOOOOO    OOOO    ",
"    OOOOOO   OOOOOO   ",
"     OOOO     OOOO    ",
"                     ",
"                     ",
])

SAD = Expression([
"                     ",
"                     ",
"                     ",
"                     ",
"   OOOOOO   OOOOOO   ",
"                     ",
"                     ",
"                     ",
])

def read_data(data, table):
    con = sqlite3.connect("settings.db")
    cur = con.cursor()
    read_data.row = cur.execute(f"SELECT {data} FROM {table}").fetchall()[0][0]

def main():
    pygame.init()
    screen = pygame.display.set_mode((0,0), pygame.NOFRAME)
    timer = pygame.time.Clock()

    read_data("data", "eyes")
    eyes = read_data.row
    print(eyes)

    if eyes == 0:
        #pestañar = cycle([REGULAR, SAD, REGULAR, REGULAR, REGULAR, REGULAR, REGULAR, REGULAR, REGULAR, REGULAR, REGULAR])
        expressions = cycle([SAD, SAD])
        # expressions = random.choice([pestañar, pestañar1])

    elif eyes == 1:
        expressions = cycle([REGULAR, SAD, SAD, SAD, SAD, SAD, REGULAR, REGULAR, REGULAR, REGULAR, REGULAR])
        #pestañar1 = cycle([SAD, SAD])
        #expressions = random.choice([pestañar, pestañar1])
    
    current = next(expressions)
    pygame.time.set_timer(pygame.USEREVENT, 500)
    root.destroy()
    
    while True:
        for e in pygame.event.get():
            if e.type == pygame.QUIT: 
                return
            if e.type == pygame.MOUSEBUTTONUP: 
                return
            if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
                return
            if e.type == pygame.USEREVENT:
                current = next(expressions)

        screen.fill((30, 30, 30))
        screen.blit(current.image, current.rect)
        timer.tick(60)
        pygame.display.update()

if __name__ == "__main__":
    main()

The robot's eyes look like this: https://i.stack.imgur.com/UeLpH.gif

My problem is that I want to change the "expressions" with the conditional "eyes". The conditional is outside the While and when it enters the loop it does not recognize the outside values.

The conditional cannot go inside the While because it glitches, it is seen that it changes very fast.

The original code is from this page: https://stackoverflow.com/a/52950553/17475108

UPDATE When I enter the expressions in the while, it fails:

while True:
    if eyes == 0:
            expressions = cycle([SAD, SAD])

    elif eyes == 1:
            expressions = cycle([REGULAR, SAD, SAD, SAD, SAD, SAD, REGULAR, REGULAR, REGULAR, REGULAR, REGULAR])

    current = next(expressions)
    pygame.time.set_timer(pygame.USEREVENT, 500)
1 Answers

Maybe set timer.tick(60) to timer.tick(1) or 0.1, since 60 is the framerate and every time you cycle it takes one frame.

Related