Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Error: Game too laggy!

A topic by spraypaintdev created Aug 05, 2024 Views: 133 Replies: 1
Viewing posts 1 to 3

Hi, I'm making a raycaster game on pygame, but it's too laggy! Here is the code for it, and let me know what i have to fix

import pygame as pg

import numpy as np

from numba import njit

def main():

    pg.init()

    screen = pg.display.set_mode((800, 600))

    running = True

    clock = pg.time.Clock()

    pg.mouse.set_visible(False)

    hres = 200  # horizontal resolution

    halfvres = 150  # vertical resolution/2

    mod = hres / 60  # scaling factor (60° fov)

    size = 50

    posx, posy, rot, maph, mapc, exitx, exity = gen_map(size)

    

    frame = np.zeros((hres, halfvres * 2, 3))

    sky = pg.image.load('skybox.png')

    sky = pg.surfarray.array3d(pg.transform.scale(sky, (360, halfvres * 2))) / 255

    floor = pg.surfarray.array3d(pg.image.load('grass.png')) / 255

    wall = pg.surfarray.array3d(pg.image.load('Wall.jpg')) / 255

    pg.event.set_grab(1)

    sprite = pg.image.load('Zombie1.png')

    sprite = pg.transform.scale(sprite, (500, 800))

    spsize = np.asarray(sprite.get_size())

    enemies = np.random.uniform(0, 50, (100, 4))

    while running:

        for event in pg.event.get():

            if event.type == pg.QUIT or (event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE):

                running = False

        frame = new_frame(posx, posy, rot, frame, sky, floor, hres, halfvres, mod, maph, size, wall, mapc, exitx, exity)

        surf = pg.surfarray.make_surface(frame * 255)

        surf = pg.transform.scale(surf, (800, 600))

        

        # Efficient enemy rendering

        render_enemies(screen, posx, posy, rot, enemies, sprite, spsize, halfvres, hres)

        fps = int(clock.get_fps())

        pg.display.set_caption(f"Abantonian Forces 3DRM - FPS: {fps}")

        screen.blit(surf, (0, 0))

        pg.display.update()

        posx, posy, rot = movement(posx, posy, rot, maph, clock.tick() / 500)

def movement(posx, posy, rot, maph, et):

    pressed_keys = pg.key.get_pressed()

    x, y, diag = posx, posy, rot

    p_mouse = pg.mouse.get_rel()

    rot = rot + np.clip(p_mouse[0] / 200, -0.2, 0.2)

    if pressed_keys[pg.K_UP] or pressed_keys[ord('w')]:

        x, y = x + et * np.cos(rot), y + et * np.sin(rot)

    elif pressed_keys[pg.K_DOWN] or pressed_keys[ord('s')]:

        x, y = x - et * np.cos(rot), y - et * np.sin(rot)

    if pressed_keys[pg.K_LEFT] or pressed_keys[ord('a')]:

        x, y = x + et * np.sin(rot), y - et * np.cos(rot)

    elif pressed_keys[pg.K_RIGHT] or pressed_keys[ord('d')]:

        x, y = x - et * np.sin(rot), y + et * np.cos(rot)

    if not maph[int(x - 0.2)][int(y)] and not maph[int(x + 0.2)][int(y)] and not maph[int(x)][int(y - 0.2)] and not maph[int(x)][int(y + 0.2)]:

        posx, posy = x, y

    elif not maph[int(posx - 0.2)][int(y)] and not maph[int(posx + 0.2)][int(y)] and not maph[int(posx)][int(y - 0.2)] and not maph[int(posx)][int(y + 0.2)]:

        posy = y

    elif not maph[int(x - 0.2)][int(posy)] and not maph[int(x + 0.2)][int(posy)] and not maph[int(x)][int(posy - 0.2)] and not maph[int(x)][int(posy + 0.2)]:

        posx = x

        

    return posx, posy, rot

def gen_map(size):

    mapc = np.random.uniform(0, 1, (size, size, 3)) 

    maph = np.random.choice([0] * 10 + [1], (size, size))

    maph[0, :], maph[size - 1, :], maph[:, 0], maph[:, size - 1] = 1, 1, 1, 1

    posx, posy, rot = 1.5, np.random.randint(1, size - 1) + 0.5, np.pi / 4

    x, y = int(posx), int(posy)

    maph[x][y] = 0

    count = 0

    while True:

        testx, testy = x, y

        if np.random.uniform() > 0.5:

            testx += np.random.choice([-1, 1])

        else:

            testy += np.random.choice([-1, 1])

        if 0 < testx < size - 1 and 0 < testy < size - 1:

            if maph[testx][testy] == 0 or count > 5:

                count = 0

                x, y = testx, testy

                maph[x][y] = 0

                if x == size - 2:

                    exitx, exity = x, y

                    break

            else:

                count += 1

    return posx, posy, rot, maph, mapc, exitx, exity

@njit()

def new_frame(posx, posy, rot, frame, sky, floor, hres, halfvres, mod, maph, size, wall, mapc, exitx, exity):

    for i in range(hres):

        rot_i = rot + np.deg2rad(i / mod - 30)

        sin, cos, cos2 = np.sin(rot_i), np.cos(rot_i), np.cos(np.deg2rad(i / mod - 30))

        frame[i][:] = sky[int(np.rad2deg(rot_i) % 359)][:]

        x, y = posx, posy

        while maph[int(x) % (size - 1)][int(y) % (size - 1)] == 0:

            x, y = x + 0.01 * cos, y + 0.01 * sin

        n = abs((x - posx) / cos)    

        h = int(halfvres / (n * cos2 + 0.001))

        xx = int(x * 3 % 1 * 99)        

        if x % 1 < 0.02 or x % 1 > 0.98:

            xx = int(y * 3 % 1 * 99)

        yy = np.linspace(0, 3, h * 2) * 99 % 99

        shade = 0.3 + 0.7 * (h / halfvres)

        if shade > 1:

            shade = 1

            

        ash = 0 

        if maph[int(x - 0.33) % (size - 1)][int(y - 0.33) % (size - 1)]:

            ash = 1

            

        if maph[int(x - 0.01) % (size - 1)][int(y - 0.01) % (size - 1)]:

            shade, ash = shade * 0.5, 0

        c = mapc[int(x) % (size - 1)][int(y) % (size - 1)]

        for k in range(h * 2):

            if 0 <= halfvres - h + k < 2 * halfvres:

                if ash and 1 - k / (2 * h) < 1 - xx / 99:

                    c, ash = 0.5 * c, 0

                if not (int(x) == exitx and int(y) == exity):

                    frame[i][halfvres - h + k] = wall[xx][int(yy[k])]

                if halfvres + 3 * h - k < halfvres * 2:

                    if not (int(x) == exitx and int(y) == exity):

                        frame[i][halfvres + 3 * h - k] = wall[xx][int(yy[k])]

                

        for j in range(halfvres - h):

            n = (halfvres / (halfvres - j)) / cos2

            x, y = posx + cos * n, posy + sin * n

            xx, yy = int(x * 2 % 1 * 99), int(y * 2 % 1 * 99)

            shade = 0.2 + 0.8 * (1 - j / halfvres)

            if maph[int(x - 0.33) % (size - 1)][int(y - 0.33) % (size - 1)]:

                shade *= 0.5

            elif ((maph[int(x - 0.33) % (size - 1)][int(y) % (size - 1)] and y % 1 > x % 1) or

                  (maph[int(x) % (size - 1)][int(y - 0.33) % (size - 1)] and x % 1 > y % 1)):

                shade *= 0.5

            if int(x) == exitx and int(y) == exity and (x % 1 - 0.5) ** 2 + (y % 1 - 0.5) ** 2 < 0.2:

                continue

            frame[i][halfvres * 2 - j - 1] = shade * (floor[xx][yy] + frame[i][halfvres * 2 - j - 1]) / 2

            if int(x) == exitx and int(y) == exity and (x % 1 - 0.5) ** 2 + (y % 1 - 0.5) ** 2 < 0.2:

                ee = j / (10 * halfvres)

                frame[i][j:2 * halfvres - j] = (ee * np.ones(3) + frame[i][j:2 * halfvres - j]) / (1 + ee)

    return frame

def render_enemies(screen, posx, posy, rot, enemies, sprite, spsize, halfvres, hres):

    for en in range(len(enemies)):

        enx, eny = enemies[en][0], enemies[en][1]

        angle = np.arctan((eny - posy) / (enx - posx))

        if abs((posx + np.cos(angle)) - enx) > abs(posx - enx):

            angle = (angle - np.pi) % (2 * np.pi)

        anglediff = (rot - angle) % (2 * np.pi)

        if anglediff > 11 * np.pi / 6 or anglediff < np.pi / 6:

            dist = np.sqrt((posx - enx) ** 2 + (posy - eny) ** 2)

            enemies[en][2], enemies[en][3] = anglediff, 1 / dist

        else:

            enemies[en][3] = 999

    enemies = enemies[enemies[:, 3].argsort()]

    for en in range(len(enemies)): 

        if enemies[en][3] > 10:

            break

        cos2 = enemies[en][2]

        scaling = min(enemies[en][3], 2) / cos2

        vert = 300 + 300 * scaling - scaling * spsize[1] / 2

        hor = 400 - 800 * np.sin(enemies[en][2]) - scaling * spsize[0] / 2

        spsurf = pg.transform.scale(sprite, (int(scaling * spsize[0]), int(s

Moderator moved this topic to General Development
Moderator

(moved to the right category)