Does Pygame Do 3D

Does PyGame do 3d?

No, Pygame is a wrapper for SDL, which is a 2D api. Pygame doesn't provide any 3D capability and probably never will.

3D libraries for Python include Panda3D and DirectPython, although they are probably quite complex to use, especially the latter.

3D Projection in pygame

There is no bug in this code. The points rotate around the top left (0, 0). Note, In 3D mode, p5.js uses a different coordinate system than pygame.

If you want to rotate the dots around the centre of the window, then define the points in range [-1, 1] (normalized device space:

points.append(np.matrix([ 0.5,  0.5, 1]))
points.append(np.matrix([ 0.5, -0.5, 1]))
points.append(np.matrix([-0.5, 0.5, 1]))
points.append(np.matrix([-0.5, -0.5, 1]))

Define a projection matrix from the range[-1, 1] to window space:

projectionMatrix = np.matrix([[height/2, 0, width/2],
[0, height/2, height/2]])

Specify a 3x3 rotation matrix:

rotation = np.array([[math.cos(angle), -math.sin(angle), 0],
[math.sin(angle), math.cos(angle), 0],
[0, 0, 1]])

First rotate the points, then project it to the window:

projected2d = projectionMatrix * rotation * point.reshape((3, 1))

Complete example:

Sample Image

import pygame
import numpy as np
import os
import math

WHITE = (255,255,255)
width, height = 400, 300
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()

points = []
angle = 0

points.append(np.matrix([ 0.5, 0.5, 1]))
points.append(np.matrix([ 0.5, -0.5, 1]))
points.append(np.matrix([-0.5, 0.5, 1]))
points.append(np.matrix([-0.5, -0.5, 1]))

projectionMatrix = np.matrix([[height/2, 0, width/2],
[0, height/2, height/2]])

while True:
clock.tick(30)
screen.fill((0,0,0))

rotation = np.matrix([[math.cos(angle), -math.sin(angle), 0],
[math.sin(angle), math.cos(angle), 0],
[0, 0, 1]])

for event in pygame.event.get():
if event.type == pygame.QUIT:
os._exit(1)

for point in points:
projected2d = projectionMatrix * rotation * point.reshape((3, 1))
pygame.draw.circle(screen, WHITE, (int(projected2d[0][0]), int(projected2d[1][0])), 5)

angle += 0.01
pygame.display.update()

Pygame 3D: How to and is it possible?

Pygame doesn't have the ability to do this natively. If you really want this, you'll need to brush up on your trigonometry to map lines from the 3D space to the 2D screen. At that point, you'll essentially be re-implementing a 3D engine.

Pygame and 3D stuff without external libraries

Pygame, by default, is a 2D game engine so there is no built-in support for 3D but you can implement your own 3D operations with extensive math. Take a look here.

Hello, someone knows how to make 3D games with Python?

Yes, you can absolutely make 3D games in Python.

For example, PyOpenGL (http://pyopengl.sourceforge.net/) is a wrapper around the OpenGL library that will allow you to develop 3D graphics.

Panda3D (http://www.panda3d.org/) is a framework made specifically for 3D games.

3d game with Python, starting from nothing

There's Pygame: A game framework for the Python language. If you need to know the basics for game development (engine, flow, ui, mathematics), this framework with all its examples will help you a lot. This won't take you by the hand and guide you step by step through game-development, but if you need a reference and a decent framework, than this is a good start.

There's also PyOpenGL: The official Python wrapper for OpenGL programming. Again with lots of programming examples in the field and tons of code snippets on how to use 3d models and the likes. Can be used together with PyGame.

But you should start by familiarizing yourself with some 3D basics. Look around at the GameDev.net site. Learn a thing or two about matrices (and perhaps quaternions). There are lots of beginners tutorials and references available to get you started.

edit: I almost forgot: there's also Panda3D with extensive scripting possibilities for Python. Maybe that'll offer a higher level of game development.

How to improve my simulation of 3d space in pygame?

In general perspective is achieved by Homogeneous coordinates. Your approach is close to that.

I recommend to operate Cartesian coordinates, where the 3 dimensions have the same scale.

Emulate a Perspective projection when you draw the points.

This means you've to calculate the w component of the Homogeneous coordinates dependent on the depth (z coordiante) of the point (e.g. w = p[2] * 30 / 5000) and to perform a "perspective divide" of the x, y and z components by the w component, before you draw the points. e.g:

Sample Image

#delta mov
ds=10
do=0.01

#Stars
points=[]
for i in range(1000):
n1 = random.randrange(-5000,5000)
n2 = random.randrange(-5000,5000)
n3 = random.randrange(-5000,5000)
points.append([n1,n2,n3])

while run:
pygame.time.delay(20)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run=False

################## keys
keys=pygame.key.get_pressed()

if keys[pygame.K_w]:
for p in points:
p[2]-=ds
if keys[pygame.K_s]:
for p in points:
p[2]+=ds

if keys[pygame.K_a] or keys[pygame.K_d]:
if keys[pygame.K_a]:
for p in points:
p[0], p[2] = np.cos(-do)*p[0]-np.sin(-do)*p[2], np.sin(-do)*p[0]+np.cos(-do)*p[2]
else:
for p in points:
p[0], p[2] = np.cos(do)*p[0]-np.sin(do)*p[2], np.sin(do)*p[0]+np.cos(do)*p[2]

###############################projection###################

screen.fill((0,0,0))
for p in points:
#this is to create new stars
if p[2]<=-5000 or p[2]>=5000:
p[0], p[1], p[2] = random.randrange(-5000,5000), random.randrange(-5000,5000), 5000
else:
#this is to ignore stars which are behind the ship
if p[2]<=0:
pass
else:
w = p[2] * 30 / 5000
pygame.draw.circle(screen,(255,255,0),(int(p[0]/w+center[0]),int(p[1]/w+center[1])),int(10/w))

pygame.display.update()

Furthermore, the rotation is not correct. When you do

p[0]=np.cos(-do)*p[0]-np.sin(-do)*p[2]
p[2]=np.sin(-do)*p[0]+np.cos(-do)*p[2]

the p[0] is changed in the first line, but the original value should be used in the 2nd line.

Do "tuple" assignment to solve the issue:

p[0], p[2] = np.cos(-do)*p[0]-np.sin(-do)*p[2], np.sin(-do)*p[0]+np.cos(-do)*p[2]


Related Topics



Leave a reply



Submit