@amasad/

jumper

Pyxel

No description

fork
loading
Files
  • main.py
  • jump_game.pyxel

This Plugin Crashed!

Error: Error: must not create an existing file {"type":"CREATE_FILE","wid":"0.7152779045714159","path":"main.py","file":{"path":"main.py","content":{"asEncoding":{"base64":"IyBSdW4gdGhlIGFzc2V0IGVkaXRvciBieSB1bmNvbW1lbnRpbmcgdGhlIGZvbGxvd2luZzoKIyBmcm9tIHB5eGVsLmVkaXRvci5hcHAgaW1wb3J0IEFwcAojIEFwcCgianVtcF9nYW1lLnB5eGVsIikKCgpmcm9tIHJhbmRvbSBpbXBvcnQgcmFuZGludAoKaW1wb3J0IHB5eGVsCgpjbGFzcyBBcHA6CiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgcHl4ZWwuaW5pdCgxNjAsIDEyMCwgY2FwdGlvbj0iUHl4ZWwgSnVtcCIpCgogICAgICAgIHB5eGVsLmxvYWQoImp1bXBfZ2FtZS5weXhlbCIpCgogICAgICAgIHNlbGYuc2NvcmUgPSAwCiAgICAgICAgc2VsZi5wbGF5ZXJfeCA9IDcyCiAgICAgICAgc2VsZi5wbGF5ZXJfeSA9IC0xNgogICAgICAgIHNlbGYucGxheWVyX3Z5ID0gMAogICAgICAgIHNlbGYucGxheWVyX2lzX2FsaXZlID0gVHJ1ZQoKICAgICAgICBzZWxmLmZhcl9jbG91ZCA9IFsoLTEwLCA3NSksICg0MCwgNjUpLCAoOTAsIDYwKV0KICAgICAgICBzZWxmLm5lYXJfY2xvdWQgPSBbKDEwLCAyNSksICg3MCwgMzUpLCAoMTIwLCAxNSldCiAgICAgICAgc2VsZi5mbG9vciA9IFsoaSAqIDYwLCByYW5kaW50KDgsIDEwNCksIFRydWUpIGZvciBpIGluIHJhbmdlKDQpXQogICAgICAgIHNlbGYuZnJ1aXQgPSBbKGkgKiA2MCwgcmFuZGludCgwLCAxMDQpLCByYW5kaW50KDAsIDIpLCBUcnVlKSBmb3IgaSBpbiByYW5nZSg0KV0KCiAgICAgICAgcHl4ZWwucGxheW0oMCwgbG9vcD1UcnVlKQoKICAgICAgICBweXhlbC5ydW4oc2VsZi51cGRhdGUsIHNlbGYuZHJhdykKCiAgICBkZWYgdXBkYXRlKHNlbGYpOgogICAgICAgIGlmIHB5eGVsLmJ0bnAocHl4ZWwuS0VZX1EpOgogICAgICAgICAgICBweXhlbC5xdWl0KCkKCiAgICAgICAgc2VsZi51cGRhdGVfcGxheWVyKCkKCiAgICAgICAgZm9yIGksIHYgaW4gZW51bWVyYXRlKHNlbGYuZmxvb3IpOgogICAgICAgICAgICBzZWxmLmZsb29yW2ldID0gc2VsZi51cGRhdGVfZmxvb3IoKnYpCgogICAgICAgIGZvciBpLCB2IGluIGVudW1lcmF0ZShzZWxmLmZydWl0KToKICAgICAgICAgICAgc2VsZi5mcnVpdFtpXSA9IHNlbGYudXBkYXRlX2ZydWl0KCp2KQoKICAgIGRlZiB1cGRhdGVfcGxheWVyKHNlbGYpOgogICAgICAgIGlmIHB5eGVsLmJ0bihweXhlbC5LRVlfTEVGVCkgb3IgcHl4ZWwuYnRuKHB5eGVsLkdBTUVQQURfMV9MRUZUKToKICAgICAgICAgICAgc2VsZi5wbGF5ZXJfeCA9IG1heChzZWxmLnBsYXllcl94IC0gMiwgMCkKCiAgICAgICAgaWYgcHl4ZWwuYnRuKHB5eGVsLktFWV9SSUdIVCkgb3IgcHl4ZWwuYnRuKHB5eGVsLkdBTUVQQURfMV9SSUdIVCk6CiAgICAgICAgICAgIHNlbGYucGxheWVyX3ggPSBtaW4oc2VsZi5wbGF5ZXJfeCArIDIsIHB5eGVsLndpZHRoIC0gMTYpCgogICAgICAgIHNlbGYucGxheWVyX3kgKz0gc2VsZi5wbGF5ZXJfdnkKICAgICAgICBzZWxmLnBsYXllcl92eSA9IG1pbihzZWxmLnBsYXllcl92eSArIDEsIDgpCgogICAgICAgIGlmIHNlbGYucGxheWVyX3kgPiBweXhlbC5oZWlnaHQ6CiAgICAgICAgICAgIGlmIHNlbGYucGxheWVyX2lzX2FsaXZlOgogICAgICAgICAgICAgICAgc2VsZi5wbGF5ZXJfaXNfYWxpdmUgPSBGYWxzZQogICAgICAgICAgICAgICAgcHl4ZWwucGxheSgzLCA1KQoKICAgICAgICAgICAgaWYgc2VsZi5wbGF5ZXJfeSA+IDYwMDoKICAgICAgICAgICAgICAgIHNlbGYuc2NvcmUgPSAwCiAgICAgICAgICAgICAgICBzZWxmLnBsYXllcl94ID0gNzIKICAgICAgICAgICAgICAgIHNlbGYucGxheWVyX3kgPSAtMTYKICAgICAgICAgICAgICAgIHNlbGYucGxheWVyX3Z5ID0gMAogICAgICAgICAgICAgICAgc2VsZi5wbGF5ZXJfaXNfYWxpdmUgPSBUcnVlCgogICAgZGVmIHVwZGF0ZV9mbG9vcihzZWxmLCB4LCB5LCBpc19hY3RpdmUpOgogICAgICAgIGlmIGlzX2FjdGl2ZToKICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgc2VsZi5wbGF5ZXJfeCArIDE2ID49IHgKICAgICAgICAgICAgICAgIGFuZCBzZWxmLnBsYXllcl94IDw9IHggKyA0MAogICAgICAgICAgICAgICAgYW5kIHNlbGYucGxheWVyX3kgKyAxNiA+PSB5CiAgICAgICAgICAgICAgICBhbmQgc2VsZi5wbGF5ZXJfeSA8PSB5ICsgOAogICAgICAgICAgICAgICAgYW5kIHNlbGYucGxheWVyX3Z5ID4gMAogICAgICAgICAgICApOgogICAgICAgICAgICAgICAgaXNfYWN0aXZlID0gRmFsc2UKICAgICAgICAgICAgICAgIHNlbGYuc2NvcmUgKz0gMTAKICAgICAgICAgICAgICAgIHNlbGYucGxheWVyX3Z5ID0gLTEyCiAgICAgICAgICAgICAgICBweXhlbC5wbGF5KDMsIDMpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgeSArPSA2CgogICAgICAgIHggLT0gNAoKICAgICAgICBpZiB4IDwgLTQwOgogICAgICAgICAgICB4ICs9IDI0MAogICAgICAgICAgICB5ID0gcmFuZGludCg4LCAxMDQpCiAgICAgICAgICAgIGlzX2FjdGl2ZSA9IFRydWUKCiAgICAgICAgcmV0dXJuIHgsIHksIGlzX2FjdGl2ZQoKICAgIGRlZiB1cGRhdGVfZnJ1aXQoc2VsZiwgeCwgeSwga2luZCwgaXNfYWN0aXZlKToKICAgICAgICBpZiBpc19hY3RpdmUgYW5kIGFicyh4IC0gc2VsZi5wbGF5ZXJfeCkgPCAxMiBhbmQgYWJzKHkgLSBzZWxmLnBsYXllcl95KSA8IDEyOgogICAgICAgICAgICBpc19hY3RpdmUgPSBGYWxzZQogICAgICAgICAgICBzZWxmLnNjb3JlICs9IChraW5kICsgMSkgKiAxMDAKICAgICAgICAgICAgc2VsZi5wbGF5ZXJfdnkgPSBtaW4oc2VsZi5wbGF5ZXJfdnksIC04KQogICAgICAgICAgICBweXhlbC5wbGF5KDMsIDQpCgogICAgICAgIHggLT0gMgoKICAgICAgICBpZiB4IDwgLTQwOgogICAgICAgICAgICB4ICs9IDI0MAogICAgICAgICAgICB5ID0gcmFuZGludCgwLCAxMDQpCiAgICAgICAgICAgIGtpbmQgPSByYW5kaW50KDAsIDIpCiAgICAgICAgICAgIGlzX2FjdGl2ZSA9IFRydWUKCiAgICAgICAgcmV0dXJuICh4LCB5LCBraW5kLCBpc19hY3RpdmUpCgogICAgZGVmIGRyYXcoc2VsZik6CiAgICAgICAgcHl4ZWwuY2xzKDEyKQoKICAgICAgICAjIGRyYXcgc2sgeCAgIHkgIGkgIHUgIHYgLiB3IC4gIGgKICAgICAgICBweXhlbC5ibHQoMCwgODgsIDAsIDAsIDg4LCAxNjAsIDMyKQoKICAgICAgICAjIGRyYXcgbW91bnRhaW4KICAgICAgICBweXhlbC5ibHQoMCwgODgsIDAsIDAsIDY0LCAxNjAsIDI0LCAxMikKCiAgICAgICAgIyBkcmF3IGZvcmVzdAogICAgICAgIG9mZnNldCA9IHB5eGVsLmZyYW1lX2NvdW50ICUgMTYwCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoMik6CiAgICAgICAgICAgIHB5eGVsLmJsdChpICogMTYwIC0gb2Zmc2V0LCAxMDQsIDAsIDAsIDQ4LCAxNjAsIDE2LCAxMikKCiAgICAgICAgIyBkcmF3IGNsb3VkcwogICAgICAgIG9mZnNldCA9IChweXhlbC5mcmFtZV9jb3VudCAvLyAxNikgJSAxNjAKICAgICAgICBmb3IgaSBpbiByYW5nZSgyKToKICAgICAgICAgICAgZm9yIHgsIHkgaW4gc2VsZi5mYXJfY2xvdWQ6CiAgICAgICAgICAgICAgICBweXhlbC5ibHQoeCArIGkgKiAxNjAgLSBvZmZzZXQsIHksIDAsIDY0LCAzMiwgMzIsIDgsIDEyKQoKICAgICAgICBvZmZzZXQgPSAocHl4ZWwuZnJhbWVfY291bnQgLy8gOCkgJSAxNjAKICAgICAgICBmb3IgaSBpbiByYW5nZSgyKToKICAgICAgICAgICAgZm9yIHgsIHkgaW4gc2VsZi5uZWFyX2Nsb3VkOgogICAgICAgICAgICAgICAgcHl4ZWwuYmx0KHggKyBpICogMTYwIC0gb2Zmc2V0LCB5LCAwLCAwLCAzMiwgNTYsIDgsIDEyKQoKICAgICAgICAjIGRyYXcgZmxvb3JzCiAgICAgICAgZm9yIHgsIHksIGlzX2FjdGl2ZSBpbiBzZWxmLmZsb29yOgogICAgICAgICAgICBweXhlbC5ibHQoeCwgeSwgMCwgMCwgMTYsIDQwLCA4LCAxMikKCiAgICAgICAgIyBkcmF3IGZydWl0cwogICAgICAgIGZvciB4LCB5LCBraW5kLCBpc19hY3RpdmUgaW4gc2VsZi5mcnVpdDoKICAgICAgICAgICAgaWYgaXNfYWN0aXZlOgogICAgICAgICAgICAgICAgcHl4ZWwuYmx0KHgsIHksIDAsIDMyICsga2luZCAqIDE2LCAwLCAxNiwgMTYsIDEyKQoKICAgICAgICAjIGRyYXcgcGxheWVyCiAgICAgICAgcHl4ZWwuYmx0KAogICAgICAgICAgICBzZWxmLnBsYXllcl94LAogICAgICAgICAgICBzZWxmLnBsYXllcl95LAogICAgICAgICAgICAwLAogICAgICAgICAgICAxNiBpZiBzZWxmLnBsYXllcl92eSA+IDAgZWxzZSAwLAogICAgICAgICAgICAwLAogICAgICAgICAgICAxNiwKICAgICAgICAgICAgMTYsCiAgICAgICAgICAgIDEyLAogICAgICAgICkKCiAgICAgICAgIyBkcmF3IHNjb3JlCiAgICAgICAgcyA9ICJTQ09SRSB7Oj40fSIuZm9ybWF0KHNlbGYuc2NvcmUpCiAgICAgICAgcHl4ZWwudGV4dCg1LCA0LCBzLCAxKQogICAgICAgIHB5eGVsLnRleHQoNCwgNCwgcywgNykKCgpBcHAoKQ=="},"asBuffer":null},"loaded":true}}
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
# Run the asset editor by uncommenting the following:
# from pyxel.editor.app import App
# App("jump_game.pyxel")


from random import randint

import pyxel

class App:
    def __init__(self):
        pyxel.init(160, 120, caption="Pyxel Jump")

        pyxel.load("jump_game.pyxel")

        self.score = 0
        self.player_x = 72
        self.player_y = -16
        self.player_vy = 0
        self.player_is_alive = True

        self.far_cloud = [(-10, 75), (40, 65), (90, 60)]
        self.near_cloud = [(10, 25), (70, 35), (120, 15)]
        self.floor = [(i * 60, randint(8, 104), True) for i in range(4)]
        self.fruit = [(i * 60, randint(0, 104), randint(0, 2), True) for i in range(4)]

        pyxel.playm(0, loop=True)

        pyxel.run(self.update, self.draw)

    def update(self):
        if pyxel.btnp(pyxel.KEY_Q):
            pyxel.quit()

        self.update_player()

        for i, v in enumerate(self.floor):
            self.floor[i] = self.update_floor(*v)

        for i, v in enumerate(self.fruit):
            self.fruit[i] = self.update_fruit(*v)

    def update_player(self):
        if pyxel.btn(pyxel.KEY_LEFT) or pyxel.btn(pyxel.GAMEPAD_1_LEFT):
            self.player_x = max(self.player_x - 2, 0)

        if pyxel.btn(pyxel.KEY_RIGHT) or pyxel.btn(pyxel.GAMEPAD_1_RIGHT):
            self.player_x = min(self.player_x + 2, pyxel.width - 16)

        self.player_y += self.player_vy
        self.player_vy = min(self.player_vy + 1, 8)

        if self.player_y > pyxel.height:
            if self.player_is_alive:
                self.player_is_alive = False
                pyxel.play(3, 5)

            if self.player_y > 600:
                self.score = 0
                self.player_x = 72
                self.player_y = -16
                self.player_vy = 0
                self.player_is_alive = True

    def update_floor(self, x, y, is_active):
        if is_active:
            if (
                self.player_x + 16 >= x
                and self.player_x <= x + 40
                and self.player_y + 16 >= y
                and self.player_y <= y + 8
                and self.player_vy > 0
            ):
                is_active = False
                self.score += 10
                self.player_vy = -12
                pyxel.play(3, 3)
        else:
            y += 6

        x -= 4

        if x < -40:
            x += 240
            y = randint(8, 104)
            is_active = True

        return x, y, is_active

    def update_fruit(self, x, y, kind, is_active):
        if is_active and abs(x - self.player_x) < 12 and abs(y - self.player_y) < 12:
            is_active = False
            self.score += (kind + 1) * 100
            self.player_vy = min(self.player_vy, -8)
            pyxel.play(3, 4)

        x -= 2

        if x < -40:
            x += 240
            y = randint(0, 104)
            kind = randint(0, 2)
            is_active = True

        return (x, y, kind, is_active)

    def draw(self):
        pyxel.cls(12)

        # draw sk x   y  i  u  v . w .  h
        pyxel.blt(0, 88, 0, 0, 88, 160, 32)

        # draw mountain
        pyxel.blt(0, 88, 0, 0, 64, 160, 24, 12)

        # draw forest
        offset = pyxel.frame_count % 160
        for i in range(2):
            pyxel.blt(i * 160 - offset, 104, 0, 0, 48, 160, 16, 12)

        # draw clouds
        offset = (pyxel.frame_count // 16) % 160
        for i in range(2):
            for x, y in self.far_cloud:
                pyxel.blt(x + i * 160 - offset, y, 0, 64, 32, 32, 8, 12)

        offset = (pyxel.frame_count // 8) % 160
        for i in range(2):
            for x, y in self.near_cloud:
                pyxel.blt(x + i * 160 - offset, y, 0, 0, 32, 56, 8, 12)

        # draw floors
        for x, y, is_active in self.floor:
            pyxel.blt(x, y, 0, 0, 16, 40, 8, 12)

        # draw fruits
        for x, y, kind, is_active in self.fruit:
            if is_active:
                pyxel.blt(x, y, 0, 32 + kind * 16, 0, 16, 16, 12)

        # draw player
        pyxel.blt(
            self.player_x,
            self.player_y,
            0,
            16 if self.player_vy > 0 else 0,
            0,
            16,
            16,
            12,
        )

        # draw score
        s = "SCORE {:>4}".format(self.score)
        pyxel.text(5, 4, s, 1)
        pyxel.text(4, 4, s, 7)


App()