dino.py

Created by 4223

Created on September 15, 2025

5.45 KB

dino


# Type your text here# Dino Run voor NumWorks
# Plaats dit script in de Python-app van je NumWorks rekenmachine en run het.
# Controls: OK of UP om te springen (KEY_OK of KEY_UP)

from kandinsky import fill_rect, draw_string
from ion import keydown, KEY_UP, KEY_OK
from time import monotonic, sleep
from random import randrange, choice

# Schermgrootte (gebruikbare grafische hoogte is 222 px op NumWorks Python).
SCREEN_W = 320
SCREEN_H = 222

# Kleuren
WHITE = (255,255,255)
BLACK = (0,0,0)
GREEN = (83, 141, 78)
BROWN = (120, 72, 0)

# Grond
GROUND_Y = 170  # y-positie van de grondlijn (pixels)

# Dino (speler)
DINO_X = 30
DINO_W = 20
DINO_H = 20

# Fysica
GRAVITY = 0.9
JUMP_V = -10

# Obstakel instellingen
OBSTACLE_MIN_GAP = 80
OBSTACLE_MAX_GAP = 170
OBSTACLE_SPEED_START = 3
OBSTACLE_SPEED_INCREASE = 0.001  # snelheidstoename per frame

# Timing
FRAME_TIME = 0.03  # ongeveer 30 ms per frame

# Helper functies

def cls():
    # Wis hele tekenveld (gebruik de volledige bruikbare schermhoogte)
    fill_rect(0, 0, SCREEN_W, SCREEN_H, WHITE)


def draw_ground():
    # eenvoudige grond: dikke lijn
    fill_rect(0, GROUND_Y, SCREEN_W, SCREEN_H - GROUND_Y, GREEN)
    # dunne lijn als rand
    fill_rect(0, GROUND_Y-1, SCREEN_W, 1, BROWN)


class Dino:
    def __init__(self):
        self.x = DINO_X
        self.y = GROUND_Y - DINO_H
        self.w = DINO_W
        self.h = DINO_H
        self.vy = 0
        self.on_ground = True

    def jump(self):
        if self.on_ground:
            self.vy = JUMP_V
            self.on_ground = False

    def update(self):
        # toepassen van zwaartekracht
        self.vy += GRAVITY
        self.y += self.vy
        if self.y >= GROUND_Y - self.h:
            self.y = GROUND_Y - self.h
            self.vy = 0
            self.on_ground = True

    def draw(self):
        # simpel blok als dino; je kunt hier pixel-art tekenen
        fill_rect(int(self.x), int(self.y), self.w, self.h, BLACK)
        # oog
        fill_rect(int(self.x + self.w - 6), int(self.y + 4), 3, 3, WHITE)

    def bbox(self):
        return (int(self.x), int(self.y), int(self.w), int(self.h))


class Obstacle:
    def __init__(self, x, speed):
        self.x = x
        self.speed = speed
        self.w = choice([8, 12, 16, 20])
        self.h = choice([18, 26, 34])
        # Sit on ground
        self.y = GROUND_Y - self.h

    def update(self):
        self.x -= self.speed

    def draw(self):
        fill_rect(int(self.x), int(self.y), int(self.w), int(self.h), BROWN)

    def offscreen(self):
        return self.x + self.w < 0

    def bbox(self):
        return (int(self.x), int(self.y), int(self.w), int(self.h))


def collides(a, b):
    ax, ay, aw, ah = a
    bx, by, bw, bh = b
    return not (ax+aw <= bx or bx+bw <= ax or ay+ah <= by or by+bh <= ay)


def draw_text_centered(text, y):
    # eenvoudige tekstcentrering, NumWorks draw_string gebruikt linkerbovenhoek
    # approximatie: elk karakter ~6 px breed bij default font; pas zonodig aan
    x = max(0, (SCREEN_W - len(text)*6)//2)
    draw_string(text, x, y, BLACK)


def game_loop():
    dino = Dino()
    obstacles = []
    last_obstacle_x = SCREEN_W
    speed = OBSTACLE_SPEED_START
    score = 0
    start_time = monotonic()

    running = True
    last_frame = monotonic()
    while running:
        now = monotonic()
        dt = now - last_frame
        last_frame = now

        # input
        if keydown(KEY_UP) or keydown(KEY_OK):
            dino.jump()
            # korte blocking op knopgewaarwording is niet strikt nodig

        # update
        dino.update()
        for ob in obstacles:
            ob.update()
        # verwijder offscreen obstakels
        obstacles = [ob for ob in obstacles if not ob.offscreen()]

        # spawn nieuwe obstakels indien nodig
        if not obstacles:
            gap = randrange(OBSTACLE_MIN_GAP, OBSTACLE_MAX_GAP)
            obstacles.append(Obstacle(SCREEN_W + gap, speed))
        else:
            last = obstacles[-1]
            if last.x < SCREEN_W - randrange(OBSTACLE_MIN_GAP, OBSTACLE_MAX_GAP):
                obstacles.append(Obstacle(SCREEN_W, speed))

        # verhoog snelheid heel geleidelijk
        speed += OBSTACLE_SPEED_INCREASE
        for ob in obstacles:
            ob.speed = speed

        # collision
        for ob in obstacles:
            if collides(dino.bbox(), ob.bbox()):
                running = False

        # score op tijdsbasis
        score = int((monotonic() - start_time) * 10)

        # draw
        cls()
        draw_ground()
        dino.draw()
        for ob in obstacles:
            ob.draw()

        # score en instructie
        draw_string('Score: {}'.format(score), 4, 4, BLACK)
        draw_string('OK / UP = spring', 4, 14, BLACK)

        # frame limiter
        sleep(FRAME_TIME)

    # game over scherm
    cls()
    draw_ground()
    draw_string('Game Over', 110, 80, BLACK)
    draw_string('Score: {}'.format(score), 110, 100, BLACK)
    draw_string('Druk OK om opnieuw te starten', 40, 140, BLACK)
    # wacht op OK
    while not keydown(KEY_OK):
        sleep(0.05)


# Hoofdmenu / start
while True:
    cls()
    draw_ground()
    draw_string('Dino Run (NumWorks)', 40, 40, BLACK)
    draw_string('Druk OK of UP om te starten', 20, 70, BLACK)
    draw_string('Gebruik EXE/OK of pijltje omhoog om te springen', 6, 120, BLACK)
    # wacht op OK of UP
    while not (keydown(KEY_OK) or keydown(KEY_UP)):
        sleep(0.05)
    # korte debounce
    while keydown(KEY_OK) or keydown(KEY_UP):
        sleep(0.01)
    game_loop()

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.