Which approach for making Cozmo's expressions

2019-08-17 18:57发布

I have this idea, in which I'd like to animate a pair of robot eyes, similar to Anki's Cozmo, but instead of displaying on a LED screen, I would like to run this in a python application, while still have a similar feel/effect (slight flickering, look pixelated). The problem here is that I have not a clue where to start. Must I have all the animation sprites for all the expressions (sad, happy, angry...) and transitions, then using tkinter or pygame. Or can I just draw directly from a set of configuration (e.g. array)? It would be great if you can suggest some approaches.

1条回答
啃猪蹄的小仙女
2楼-- · 2019-08-17 19:33

An easy way is to store the data in a simple string, and then create your surfaces from those strings. It does not need much memory while being easy to read and modify and it can live inside your code.

Of course there are a lot of different ways to do what you want, but I guess something simple like this would be a good start (you'll get the idea):

enter image description here

import pygame
from itertools import cycle

TILE_SIZE = 32
SCREEN_SIZE = pygame.Rect((0, 0, 21*TILE_SIZE, 8*TILE_SIZE))


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, (TILE_SIZE*len(data[0]), TILE_SIZE*len(data)))
        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 main():
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE.size)
    timer = pygame.time.Clock()
    expressions = cycle([REGULAR, QUESTION, REGULAR, QUESTION, SAD])
    current = next(expressions)
    pygame.time.set_timer(pygame.USEREVENT, 1000)

    while True:

        for e in pygame.event.get():
            if e.type == pygame.QUIT: 
                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()

Where to go from here:

  • Use a smaller tile size and bigger strings to get a better resolution.

  • Or create the images for your animation outside of your program (in a drawing tool) and use these of you want.

  • Create different lists of expressions that define different animations, and change the current animation for each "mood".

查看更多
登录 后发表回答