pyopengl 重力小球

该博客介绍了如何利用PyOpenGL在Python中创建一个重力小球的模拟程序。程序需要两个特定的纹理文件,并且用户可以通过点击窗口来重新生成小球的位置。
摘要由CSDN通过智能技术生成
#! /usr/bin/env python
# -*- coding: utf8 -*-
"""Port of NeHe Lesson 26 by Ivan Izuver <izuver@users.sourceforge.net>"""
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
# from Image import *
from PIL.Image import *
import sys,gc
import random


ESCAPE = '\033'

# Number of the glut window.
window = 0

LightAmb=(0.7,0.7,0.7)  #Окружающий свет
LightDif=(1.0,1.0,0.0)  #Рассеянный свет
LightPos=(4.0,4.0,6.0,1.0) #Позиция источника освещения
#q=GLUquadricObj()
xrot=yrot=0.0 #Вращение по Х Y

xrotspeed=yrotspeed=0.0 #Скорость вращения по X Y
zoom=-3.0 #Глубина сцены в экране
height=0.5 #Высота мяча над полом
textures = {}

goblelength=2
ballr=0.05
x=0
y=0
z=0

vx=0.01
vy=0.01
vz=0.01

ax=0
ay=0
ag=-0.0098#重力加速度
az=0
time=0

def LoadTextures(fname):
	if textures.get( fname ) is not None:
		return textures.get( fname )
	texture = textures[fname] = glGenTextures(1)
	image = open(fname)
	
	ix = image.size[0]
	iy = image.size[1]
	image = image.tobytes("raw", "RGBX", 0, -1)
	
	# Create Texture    
	glBindTexture(GL_TEXTURE_2D, texture)   # 2d texture (x and y size)
	
	glPixelStorei(GL_UNPACK_ALIGNMENT,1)
	glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
	return texture

# A general OpenGL initialization function.  Sets all of the initial parameters. 
def InitGL(Width, Height):                # We call this right after our OpenGL window is created.
	glClearColor(0.2, 0.5, 1.0, 1.0)    # This Will Clear The Background Color To Black
	glClearDepth(1.0)                    # Enables Clearing Of The Depth Buffer
	glClearStencil(0)
	glDepthFunc(GL_LEQUAL)                # The Type Of Depth Test To Do
	glEnable(GL_DEPTH_TEST)           
要实现二维平面的小球碰撞,可以使用 PyOpenGL 和 PyGame 库。以下是一个简单的示例代码: ```python import pygame from pygame.locals import * from OpenGL.GL import * from OpenGL.GLU import * vertices = ( (1, -1), (1, 1), (-1, 1), (-1, -1) ) edges = ( (0, 1), (1, 2), (2, 3), (3, 0) ) balls = [ {'pos': [0, 0], 'vel': [0.02, 0.03], 'color': (1, 0, 0)}, {'pos': [-0.8, 0.5], 'vel': [0.03, -0.02], 'color': (0, 1, 0)}, {'pos': [0.5, -0.8], 'vel': [-0.01, 0.05], 'color': (0, 0, 1)} ] def draw_ball(pos, color): glPushMatrix() glTranslatef(pos[0], pos[1], 0) glColor3f(*color) glBegin(GL_QUADS) for vertex in vertices: glVertex2f(*vertex) glEnd() glPopMatrix() def check_ball_collision(ball1, ball2): dx = ball1['pos'][0] - ball2['pos'][0] dy = ball1['pos'][1] - ball2['pos'][1] distance = (dx ** 2 + dy ** 2) ** 0.5 if distance < 0.2: ball1['vel'], ball2['vel'] = ball2['vel'], ball1['vel'] def update_balls(): for ball in balls: ball['pos'][0] += ball['vel'][0] ball['pos'][1] += ball['vel'][1] if ball['pos'][0] > 1 or ball['pos'][0] < -1: ball['vel'][0] *= -1 if ball['pos'][1] > 1 or ball['pos'][1] < -1: ball['vel'][1] *= -1 for i in range(len(balls)): for j in range(i + 1, len(balls)): check_ball_collision(balls[i], balls[j]) def main(): pygame.init() display = (800, 600) pygame.display.set_mode(display, DOUBLEBUF | OPENGL) gluOrtho2D(-1, 1, -1, 1) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() glClear(GL_COLOR_BUFFER_BIT) update_balls() for ball in balls: draw_ball(ball['pos'], ball['color']) pygame.display.flip() if __name__ == '__main__': main() ``` 在这个示例中,我们定义了一个小球列表,每个小球有位置、速度和颜色属性。在主循环中,我们更新小球的位置,并检查它们之间是否有碰撞。如果两个小球之间的距离小于一定值(在这里设为 0.2),则交换它们的速度向量。 通过 PyOpenGL 库,我们可以在窗口中绘制小球。在 draw_ball 函数中,我们使用 glTranslate 函数将小球移动到正确的位置,然后使用 glBegin 和 glEnd 函数绘制一个正方形,使其看起来像是一个圆形。 最后,我们使用 PyGame 库来创建窗口和处理事件。在主循环中,我们清除屏幕并更新和绘制小球。pygame.display.flip() 函数将绘制的内容刷新到屏幕上。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值