~facundo/enjuewemela/trunk

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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# This code is part of the 'enjuewemela' game
# License: GPLv3
# Main author: Facundo Batista
# Code, bug tracker, etc:
#   https://launchpad.net/enjuewemela/
#
"""Gems for the game."""

from __future__ import division

import os
import random

import cocos
from cocos.particle_systems import Galaxy
from cocos.particle import Color

import config


class _Gem(cocos.sprite.Sprite):
    """Gem wrapper around a sprite."""
    def __init__(self, filename, pos_id, explosive=False):
        cocos.sprite.Sprite.__init__(self, filename)
        # piece name is the file name without the .png
        self.name = filename[:-4]
        self.pos_id = pos_id
        self.is_explosive = explosive
        self.is_magic = False

    def get_explosive(self):
        """Return an explosive version of self."""
        if self.name[:4] == 'expl':
            fname = '%s.png' % self.name
        else:
            fname = 'expl-%s.png' % self.name
        g = _Gem(fname, self.pos_id, explosive=True)
        g.scale = self.scale
        return g

    def __str__(self):
        return self.name

    def __repr__(self):
        return "<Gem %s at %d>" % (self.name, id(self))


class _Magic(Galaxy):
    """Magic ball."""
    def __init__(self):
        Galaxy.__init__(self)
        self.size = 20
        self.live = 10.0
        self.speed = 30
        self.radial_accel = -100
        self.tangential_accel = 30
        self.total_particles = 60
        self.start_color = Color(.7, .7, 1, 1)
        self.end_color = Color(1, 0, 0, .7)

        self.name = 'magic'
        self.pos_id = 13
        self.is_magic = True
        self.is_explosive = False

    def __str__(self):
        return self.name

    def __repr__(self):
        return "<Gem %s at %d>" % (self.name, id(self))

    def _set_scale(self, scale):
        """Set the scale."""
        self._scale = scale * 5

    def _get_scale(self):
        """Get the scale."""
        return self._scale / 5

    scale = property(_get_scale, _set_scale)

    def _set_opacity(self, value):
        """Set the opacity."""
        self.active = bool(value)

    opacity = property(fset=_set_opacity)


class Gems(object):
    """A gem representation."""

    def __init__(self):
        # load all the gems
        jewels_path = os.path.join(config.BASEDIR, "jewels")
        jewels = [x for x in os.listdir(jewels_path)
                  if not x.startswith('expl') and not x.startswith('crazy')]
        self.pngs = sorted(x for x in jewels if x.endswith('.png'))
        if len(self.pngs) != 7:
            raise ValueError("The gems (png files) in the 'gems' directory "
                             "must be 7! (found %d)" % len(self.pngs))

        __, max_both = self._get_gems_size()

        # calculate the resize factor
        self.resize_factor = config.PIECE_SIZE / max_both

        # are we crazy? see the setter below for how these are used
        self._crazy_mode = False
        self._crazy_style = None
        self._crazy_fixed = None

    def _get_crazy(self):
        """Stupid getter for crazy mode."""
        return self._crazy_mode

    def _set_crazy(self, crazy):
        """Setter for craziness that also calculates other values."""
        if not crazy:
            self._crazy_mode = False
            self._crazy_style = None
            self._crazy_fixed = None
            return

        # go crazy!
        self._crazy_mode = True

        # style! 0 is 'all colors the same', 1 is 'all shapes the same'
        self._crazy_style = random.randint(0, 1)

        # which is the fixed value for the "sameness" in colors or shapes
        self._crazy_fixed = random.randint(0, 6)

    crazy = property(_get_crazy, _set_crazy)

    def _get_gems_size(self):
        """Return the gems and the max size in both axis."""
        # convert pngs into sprites
        all_gems = [cocos.sprite.Sprite(x) for x in self.pngs]

        # get the maximum height or width of all of them
        max_w = max(x.width for x in all_gems)
        max_h = max(x.height for x in all_gems)
        max_both = max(max_w, max_h)
        return all_gems, max_both

    def get_all(self, size=None):
        """Get all the gems, resized if indicated."""
        all_gems, max_both = self._get_gems_size()

        if size is not None:
            # resize the sprites accordingly
            resize_factor = size / max_both
            for gem in all_gems:
                gem.scale = resize_factor
        return all_gems

    def get_magic_ball(self):
        """Return a magic ball gem."""
        sp = _Magic()
        sp.scale = self.resize_factor
        return sp

    def by_name(self, name):
        """Return a gem by name."""
        if name == 'magic':
            return self.get_magic_ball()
        sp = _Gem(name + '.png', None)
        sp.scale = self.resize_factor
        return sp

    def __getitem__(self, pos):
        if self._crazy_mode:
            if self._crazy_style:
                # all shapes the same
                gempath = 'crazy-c%02d-s%02d.png' % (pos, self._crazy_fixed)
            else:
                # all colors the same
                gempath = 'crazy-c%02d-s%02d.png' % (self._crazy_fixed, pos)
            sp = _Gem(gempath, pos)

        else:
            sp = _Gem(self.pngs[pos], pos)

        sp.scale = self.resize_factor
        return sp


gems = Gems()