summaryrefslogtreecommitdiff
path: root/snakegame/viewers/pyglet.py
blob: f1a5f883da0e58ad49fa9bb470b85a498e1743b4 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
from __future__ import absolute_import

import pyglet.resource
pyglet.resource.path.append('@snakegame')
pyglet.resource.reindex()

from pyglet import gl

from snakegame import common
from snakegame.utils import scale_aspect

class Viewer(pyglet.window.Window):
    EDGE_COLOR = (255, 255, 255, 255)
    EDGE_WIDTH = 2

    def __init__(self, engine, caption='SnakeGame Window', resizable=True, **kwargs):
        super(Viewer, self).__init__(
            caption=caption,
            resizable=resizable,
            **kwargs
        )

        self.engine = engine
        self.engine_iter = iter(engine)

        gl.glEnable(gl.GL_BLEND)
        gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)

        pyglet.clock.schedule_interval(lambda t: self.update_snakes(), 1/30.0)

        self.board = None
        self.columns = None
        self.rows = None

    def update_snakes(self, *args):
        self.board = next(self.engine_iter, None)
        if self.board is None:
            pyglet.app.exit()
            return

        columns, rows = common.get_size(self.board)
        if columns != self.columns or rows != self.rows:
            self.columns = columns
            self.rows = rows
            self.on_resize(self.width, self.height)

    def on_resize(self, width, height):
        super(Viewer, self).on_resize(width, height)

        if self.board is None:
            return

        # make board surface
        self.board_width, self.board_height = scale_aspect(
            (self.columns, self.rows), (self.width, self.height)
        )

        # load sprites
        xscale = float(self.board_width) / self.columns
        yscale = float(self.board_height) / self.rows

        self.images = {
                common.APPLE : 'images/apple.png',
                common.ICE_CREAM : 'images/icecream.png',
                common.SHRINK_POTION : 'images/shrinkpotion.png'
        }

        for item, location in self.images.items():
            image = pyglet.resource.image(location)
            image.size = scale_aspect(
                (image.width, image.height),
                (xscale, yscale)
            )
            self.images[item] = image

        self.eyes = pyglet.resource.image('images/eyes.png')
        self.eyes.size = scale_aspect(
            (self.eyes.width, self.eyes.height),
            (xscale, yscale)
        )

    def on_draw(self):
        self.clear()

        if self.board is None:
            return

        xscale = float(self.board_width) / self.columns
        yscale = float(self.board_height) / self.rows

        # Draw grid.
        for y, row in enumerate(self.board):
            for x, cell in enumerate(row):
                left = int(x * xscale)
                top = self.height - int(y * yscale)
                right = int((x + 1) * xscale)
                bottom = self.height - int((y + 1) * yscale)
                r = (left, top, right, top, right, bottom, left, bottom)

                # Draw a square.
                gl.glLineWidth(self.EDGE_WIDTH)
                pyglet.graphics.draw(4, gl.GL_LINE_LOOP,
                                     ('v2f', r),
                                     ('c4B', self.EDGE_COLOR * 4))

                # Draw the things on the square.
                if cell in self.images:
                    image = self.images[cell]
                    w, h = image.size
                    image.blit(left + (xscale - w) / 2.0, top - h, width=w, height=h)

                elif common.is_snake(cell):
                    bot = self.engine.bots[cell.lower()]
                    colour = bot[1] + (255,)
                    gl.glPolygonMode(gl.GL_FRONT, gl.GL_FILL)
                    pyglet.graphics.draw(4, gl.GL_POLYGON,
                                         ('v2f', r),
                                         ('c4B', colour * 4),
                    )

                    if common.is_snake_head(cell):
                        w, h = self.eyes.size
                        self.eyes.blit(left, top - h, width=w, height=h)

    def run(self):
        pyglet.app.run()