В этой статье я покажу как сделать простейшую 3d шаблонную игру на python.
Нам нужны несколько файлов:
Это модуль, то есть какое-то дополнение к языку Python.С помощью pygame можно написать свою игру, иногда очень даже приличную.С помощью pygame написан шаблон для игры, о котором я вам сейчас рассказываю.Что-бы работать с pygame, нужно скачать его, то есть ввести в консоли: pip install pygame.
Основной файл.
import pygame
from settings import *
from player import Player
import math
from map import world_map
from ray_casting import ray_casting
pygame.init()
sc = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
player = Player()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
player.movement()
sc.fill(BLACK)
pygame.draw.rect(sc, BLUE, (0, 0, WIDTH, HALF_HEIGHT))
pygame.draw.rect(sc, DARKGRAY, (0, HALF_HEIGHT, WIDTH, HALF_HEIGHT))
ray_casting(sc, player.pos, player.angle)
pygame.display.flip()
clock.tick(FPS)
В этом файле мы указываем некоторые настройки(переменные), которые пригодятся нам в разных файлах, например какой-то цвет.
import math
# game settings
WIDTH = 1500
HEIGHT = 800
HALF_WIDTH = WIDTH // 2
HALF_HEIGHT = HEIGHT // 2
FPS = 60
TILE = 100
# ray casting settings
FOV = math.pi / 3
HALF_FOV = FOV / 2
NUM_RAYS = 120
MAX_DEPTH = 800
DELTA_ANGLE = FOV / NUM_RAYS
DIST = NUM_RAYS / (2 * math.tan(HALF_FOV))
PROJ_COEFF = 3 * DIST * TILE
SCALE = WIDTH // NUM_RAYS
# player settings
player_pos = (HALF_WIDTH, HALF_HEIGHT)
player_angle = 0
player_speed = 2
# colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (220, 0, 0)
GREEN = (0, 220, 0)
BLUE = (0, 0, 255)
DARKGRAY = (40, 40, 40)
PURPLE = (120, 0, 120)
В этом файле мы создаем карту в самом простом - текстовом формате.
from settings import *
text_map = [
'WWWWWWWWWWWW',
'W......W...W',
'W..WWW...W.W',
'W....W..WW.W',
'W..W....W..W',
'W..W...WWW.W',
'W....W.....W',
'WWWWWWWWWWWW'
]
world_map = set()
for j, row in enumerate(text_map):
for i, char in enumerate(row):
if char == 'W':
world_map.add((i * TILE, j * TILE))
В этом файле мы прописываем управление игроком.
from settings import *
import pygame
import math
class Player:
def __init__(self):
self.x, self.y = player_pos
self.angle = player_angle
@property
def pos(self):
return (self.x, self.y)
def movement(self):
sin_a = math.sin(self.angle)
cos_a = math.cos(self.angle)
keys = pygame.key.get_pressed()
if keys[pygame.K_w]:
self.x = player_speed * cos_a
self.y = player_speed * sin_a
if keys[pygame.K_s]:
self.x = -player_speed * cos_a
self.y = -player_speed * sin_a
if keys[pygame.K_a]:
self.x = player_speed * sin_a
self.y = -player_speed * cos_a
if keys[pygame.K_d]:
self.x = -player_speed * sin_a
self.y = player_speed * cos_a
if keys[pygame.K_LEFT]:
self.angle -= 0.02
if keys[pygame.K_RIGHT]:
self.angle = 0.02
Файл, где наша карта преобразовывается из 2d в 3d.
import pygame
from settings import *
from map import world_map
def ray_casting(sc, player_pos, player_angle):
cur_angle = player_angle - HALF_FOV
xo, yo = player_pos
for ray in range(NUM_RAYS):
sin_a = math.sin(cur_angle)
cos_a = math.cos(cur_angle)
for depth in range(MAX_DEPTH):
x = xo depth * cos_a
y = yo depth * sin_a
if (x // TILE * TILE, y // TILE * TILE) in world_map:
depth *= math.cos(player_angle - cur_angle)
proj_height = min(PROJ_COEFF / (depth 0.0001), HEIGHT)
c = 255 / (1 depth * depth * 0.0001)
color = (c // 2, c, c // 3)
pygame.draw.rect(sc, color, (ray * SCALE, HALF_HEIGHT - proj_height // 2, SCALE, proj_height))
break
cur_angle = DELTA_ANGLE
На этом все, сначала будет выдавать ошибку из-за того, что в таком формате сложно передать все пробелы, поэтому с ними надо будет чуть повозится.После "укрощения" пробелов можно запустить файл main.py и наслаждаться, пока что, не шедевром. Пишите в комментариях, если нужно продолжение.