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:
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:
#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
How to Make Program Go Back to the Top of the Code Instead of Closing
What's the Deal with Python 3.4, Unicode, Different Languages and Windows
List on Python Appending Always the Same Value
Cartesian Product of Two Lists in Python
Execute Multiple Commands in Paramiko So That Commands Are Affected by Their Predecessors
Making the Background Move Sideways in Pygame
Using Django Time/Date Widgets in Custom Form
Applying Function with Multiple Arguments to Create a New Pandas Column
Multiple Modeladmins/Views for Same Model in Django Admin
How to Make a Scatter Plot Colored by Density in Matplotlib
What Are the Differences Between JSON and Simplejson Python Modules
Pandas: Merge (Join) Two Data Frames on Multiple Columns