pokemonmain.py

Created by maelg0000

Created on April 01, 2026

10.2 KB


from kandinsky import fill_rect, draw_string, color
from time import sleep
from ion import keydown, KEY_OK, KEY_ZERO, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT

# Constantes ecran
SW, SH = 320, 222
OFF = 10
C_WHITE = color(255, 255, 255)
C_BLACK = color(0, 0, 0)
C_GRAY = color(30, 30, 30)
ANIM_SPD = 0.04
W, H = SW - OFF * 2, 60
W_YN, H_YN = SW // 4, 60

# Constantes jeu
TILE = 16
CAM_X, CAM_Y = 152, 95
SPD = 4

# Couleurs tiles
C_GRASS = color(34, 139, 34)
C_PATH = color(194, 178, 128)
C_WATER = color(30, 144, 255)
C_TREE = color(0, 100, 0)
C_DOOR = color(101, 67, 33)
C_WALL = color(160, 82, 45)
C_FLOOR = color(180, 140, 100)
C_WALLIN = color(80, 60, 50)
C_ROOF = color(139, 60, 60)
C_PLAYER = color(255, 50, 50)
C_ALERT = color(255, 255, 0)

COL_PNJ = [
    color(255, 165, 0),
    color(150, 100, 200),
    color(100, 200, 150)
]

BORDER_COL = [C_TREE, C_WALLIN, C_WALLIN, C_WALLIN]

MAP_EXT = [
[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3],
[3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
[3,0,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,0,0,0,0,3],
[3,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,3],
[3,0,5,4,5,0,0,0,0,0,0,0,0,0,0,0,0,5,4,5,0,0,0,0,3],
[3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,3],
[3,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,3],
[3,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
[3,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,2,0,0,3],
[3,0,3,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,2,2,0,3],
[3,0,3,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,2,0,0,3],
[3,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
[3,0,0,0,0,0,0,8,8,8,1,8,8,8,0,0,0,0,0,0,0,0,0,0,3],
[3,0,0,0,0,0,0,5,5,5,5,5,5,5,0,0,0,0,3,3,0,0,0,0,3],
[3,0,0,0,0,0,0,5,4,5,5,5,4,5,0,0,0,0,3,3,0,0,0,0,3],
[3,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3],
[3,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,3],
[3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],
[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]
]

MAP_H1 = [
[7,7,7,7,7,7,7],
[7,6,6,6,6,6,7],
[7,6,6,6,6,6,7],
[7,6,6,6,6,6,7],
[7,6,6,6,6,6,7],
[7,7,7,4,7,7,7]
]

MAP_H2 = [
[7,7,7,7,7,7,7],
[7,6,6,6,6,6,7],
[7,6,6,6,6,6,7],
[7,6,6,6,6,6,7],
[7,6,6,6,6,6,7],
[7,7,7,4,7,7,7]
]

MAP_H3 = [
[7,7,7,7,7,7,7,7,7],
[7,6,6,6,6,6,6,6,7],
[7,6,6,6,6,6,6,6,7],
[7,6,6,6,6,6,6,6,7],
[7,6,6,6,7,6,6,6,7],
[7,6,6,6,7,6,6,6,7],
[7,7,7,4,7,4,7,7,7]
]

MAPS = [MAP_EXT, MAP_H1, MAP_H2, MAP_H3]
MAP_SIZES = [(25, 19), (7, 6), (7, 6), (9, 7)]

cur_map = 0
px, py = 4 * TILE, 6 * TILE
last_px, last_py = px, py
borders_drawn = False

PNJS = [
    [0, 12, 6, 0, "Marcel"],
    [1, 3, 2, 1, "Marie"],
    [2, 3, 2, 2, "Jean"],
    [3, 2, 3, 0, "Pierre"],
    [3, 6, 3, 1, "Lucie"]
]

DIAL = {
    "Marcel": ["Salut dresseur !", "Va voir dans les maisons."],
    "Marie": ["Bienvenue chez moi !", "Fais comme chez toi."],
    "Jean": ["Yo mec !", "T'as vu la grande maison ?"],
    "Pierre": ["Salut !", "On est colocs avec Lucie."],
    "Lucie": ["Hey !", "Cette maison est grande !"]
}

PORTALS = [
    [0, 3, 4, 1, 3*TILE, 4*TILE],
    [1, 3, 5, 0, 3*TILE, 5*TILE],
    [0, 18, 4, 2, 3*TILE, 4*TILE],
    [2, 3, 5, 0, 18*TILE, 5*TILE],
    [0, 8, 14, 3, 3*TILE, 5*TILE],
    [0, 12, 14, 3, 5*TILE, 5*TILE],
    [3, 3, 6, 0, 8*TILE, 15*TILE],
    [3, 5, 6, 0, 12*TILE, 15*TILE]
]

SOLID = [2, 3, 5, 7, 8]

# === FONCTIONS UI ===

def fade_out():
    for i in range(6):
        fill_rect(0, 0, SW, SH, color(50-i*10, 50-i*10, 50-i*10))
        sleep(0.03)
    fill_rect(0, 0, SW, SH, C_BLACK)

def draw_spike(x, y, t="down"):
    if t == "down":
        for i in range(5):
            fill_rect(x + i, y + i * 2, 10 - i * 2, 2, C_BLACK)
    elif t == "r":
        for i in range(6):
            fill_rect(x + i * 2, y + i, 2, 10 - i * 2, C_BLACK)

def draw_box(t="dialogue"):
    if t == "dialogue":
        bx, by, bw, bh = OFF, SH - H - OFF, W, H
    else:
        bx = SW - OFF - W_YN
        by = SH - OFF * 2 - H - H_YN
        bw, bh = W_YN, H_YN
    for i in range(4):
        c = i * 80
        fill_rect(bx + i * 2, by + i * 2, bw - i * 4, bh - i * 4, color(c, c, c))
    fill_rect(bx + 8, by + 8, bw - 16, bh - 16, C_WHITE)

def draw_yn_arrow(state):
    num = 23 if state == "down" else 0
    fill_rect(238, 90, 22, 40, C_WHITE)
    draw_spike(SW - OFF - W_YN + 15, SH - OFF * 2 - H - H_YN + 13 + num, "r")

def draw_next_arrow(y_off=0):
    fill_rect(SW - OFF * 4 + 3, SH - OFF * 3 - 6 + y_off, 10, 16, C_WHITE)
    draw_spike(SW - OFF * 4 + 3, SH - OFF * 3 - 3 + y_off)

def wait_next():
    while keydown(KEY_OK) or keydown(KEY_ZERO):
        sleep(0.05)
    lvl = [0, 1, 2, 3, 2, 1]
    while True:
        for i in lvl:
            draw_next_arrow(i)
            sleep(0.1)
            if keydown(KEY_OK) or keydown(KEY_ZERO):
                while keydown(KEY_OK) or keydown(KEY_ZERO):
                    sleep(0.05)
                return

def animatext(user, text, nxt=False):
    draw_box("dialogue")
    txt = user + ": " + text if user else text
    if len(txt) > 56:
        return
    t1, t2 = txt, ""
    if len(txt) > 28:
        cut = txt[:28].rfind(" ")
        if cut == -1:
            cut = 28
        t1 = txt[:cut]
        t2 = txt[cut:].strip()
    skip = False
    for i in range(len(t1) + 1):
        if keydown(KEY_OK) or keydown(KEY_ZERO):
            skip = True
        if skip:
            draw_string(t1, OFF * 2, SH - H + 5)
            break
        draw_string(t1[:i], OFF * 2, SH - H + 5)
        sleep(ANIM_SPD)
    if t2:
        if not skip:
            for i in range(len(t2) + 1):
                if keydown(KEY_OK) or keydown(KEY_ZERO):
                    skip = True
                if skip:
                    draw_string(t2, OFF * 2, SH - H + 22)
                    break
                draw_string(t2[:i], OFF * 2, SH - H + 22)
                sleep(ANIM_SPD)
        else:
            draw_string(t2, OFF * 2, SH - H + 22)
    while keydown(KEY_OK) or keydown(KEY_ZERO):
        sleep(0.05)
    if nxt:
        draw_next_arrow()

# === FONCTIONS JEU ===

def tile_col(t):
    if t == 0: return C_GRASS
    if t == 1: return C_PATH
    if t == 2: return C_WATER
    if t == 3: return C_TREE
    if t == 4: return C_DOOR
    if t == 5: return C_WALL
    if t == 6: return C_FLOOR
    if t == 7: return C_WALLIN
    if t == 8: return C_ROOF
    return C_GRASS

def get_tile(x, y):
    m = MAPS[cur_map]
    mw, mh = MAP_SIZES[cur_map]
    tx, ty = x // TILE, y // TILE
    if tx < 0 or ty < 0 or tx >= mw or ty >= mh:
        return 7
    return m[ty][tx]

def draw_borders():
    mw, mh = MAP_SIZES[cur_map]
    bc = BORDER_COL[cur_map]
    
    ml = -px + CAM_X
    mt = -py + CAM_Y
    mr = mw * TILE - px + CAM_X
    mb = mh * TILE - py + CAM_Y
    
    if ml > 0:
        fill_rect(0, 0, ml, SH, bc)
    if mr < SW:
        fill_rect(mr, 0, SW - mr, SH, bc)
    if mt > 0:
        fill_rect(ml if ml > 0 else 0, 0, (mr if mr < SW else SW) - (ml if ml > 0 else 0), mt, bc)
    if mb < SH:
        fill_rect(ml if ml > 0 else 0, mb, (mr if mr < SW else SW) - (ml if ml > 0 else 0), SH - mb, bc)

def draw_map():
    m = MAPS[cur_map]
    mw, mh = MAP_SIZES[cur_map]
    
    for row in range(mh):
        for col in range(mw):
            scr_x = col * TILE - px + CAM_X
            scr_y = row * TILE - py + CAM_Y
            if -TILE < scr_x < SW and -TILE < scr_y < SH:
                fill_rect(scr_x, scr_y, TILE, TILE, tile_col(m[row][col]))

def draw_pnjs():
    for p in PNJS:
        if p[0] != cur_map:
            continue
        scr_x = p[1] * TILE - px + CAM_X
        scr_y = p[2] * TILE - py + CAM_Y
        if -TILE < scr_x < SW and -TILE < scr_y < SH:
            c = COL_PNJ[p[3]]
            fill_rect(scr_x + 2, scr_y + 2, 12, 12, c)
            fill_rect(scr_x + 4, scr_y + 4, 3, 3, C_BLACK)
            fill_rect(scr_x + 9, scr_y + 4, 3, 3, C_BLACK)
            dist = abs(px - p[1]*TILE) + abs(py - p[2]*TILE)
            if dist <= TILE * 2:
                fill_rect(scr_x + 5, scr_y - 12, 6, 10, C_ALERT)
                fill_rect(scr_x + 6, scr_y - 10, 4, 5, C_BLACK)
                fill_rect(scr_x + 6, scr_y - 4, 4, 2, C_BLACK)

def draw_player():
    fill_rect(CAM_X, CAM_Y, TILE, TILE, C_PLAYER)
    fill_rect(CAM_X + 3, CAM_Y + 3, 3, 3, C_WHITE)
    fill_rect(CAM_X + 10, CAM_Y + 3, 3, 3, C_WHITE)
    fill_rect(CAM_X + 4, CAM_Y + 10, 8, 2, C_WHITE)

def can_move(nx, ny):
    for ox in [2, TILE - 3]:
        for oy in [2, TILE - 3]:
            t = get_tile(nx + ox, ny + oy)
            if t in SOLID:
                return False
    for p in PNJS:
        if p[0] != cur_map:
            continue
        if abs(nx - p[1]*TILE) < TILE - 2 and abs(ny - p[2]*TILE) < TILE - 2:
            return False
    return True

def draw_all(with_borders=True):
    if with_borders:
        draw_borders()
    draw_map()
    draw_pnjs()
    draw_player()

def check_portal():
    global cur_map, px, py
    tx = (px + TILE // 2) // TILE
    ty = (py + TILE // 2) // TILE
    for p in PORTALS:
        if p[0] == cur_map and p[1] == tx and p[2] == ty:
            fade_out()
            cur_map = p[3]
            px, py = p[4], p[5]
            draw_all(True)
            sleep(0.1)
            return True
    return False

def talk_to_pnj():
    for p in PNJS:
        if p[0] != cur_map:
            continue
        dist = abs(px - p[1]*TILE) + abs(py - p[2]*TILE)
        if dist <= TILE * 2:
            nom = p[4]
            if nom in DIAL:
                for txt in DIAL[nom]:
                    animatext(nom, txt, True)
                    wait_next()
            draw_all(True)
            return True
    return False

def game():
    global px, py
    draw_all(True)
    while True:
        nx, ny = px, py
        if keydown(KEY_UP):
            ny -= SPD
        if keydown(KEY_DOWN):
            ny += SPD
        if keydown(KEY_LEFT):
            nx -= SPD
        if keydown(KEY_RIGHT):
            nx += SPD
        
        if nx != px or ny != py:
            if can_move(nx, ny):
                px, py = nx, ny
                draw_all(False)
                if check_portal():
                    continue
        
        if keydown(KEY_OK):
            talk_to_pnj()
            while keydown(KEY_OK):
                sleep(0.05)
        
        sleep(0.015)

# === LANCEMENT ===
fill_rect(0, 0, SW, SH, C_GRAY)
animatext("", "Bienvenue !", True)
wait_next()
animatext("", "Fleches = bouger", True)
wait_next()
animatext("", "OK = parler", True)
wait_next()
fade_out()
draw_all(True)
sleep(0.1)
game()

During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:

With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our cookies policy.