使用 Cocos2d 模拟 N 体问题
2010-08-09
最近学习了一下 Cocos2d,它是一个基于 Python 的用于创建 2D 游戏、演示以及其它图像/交互应用的框架。
这个框架总体来说,还是很简单清晰的。我用它把之前写的网页版的 N 体问题模拟重新实现了一遍。效果如下:
只模拟万有引力,没有做碰撞检测。代码比较简单:
# -*- coding: utf-8 -*-
#
# N 体问题模拟
# https://oldj.net/
#
import cocos
from cocos.director import director
from cocos.sprite import Sprite
from cocos.actions import *
from cocos import draw
import pyglet
import random
import os
import math
G = 0.001 # 万有引力常数
class Planet(Sprite):
def __init__(self, x, y, r):
super(Planet, self).__init__(
"0.png",
rotation = 90,
position = (x, y),
scale = r * 0.1,
)
self.r = r
self.m = math.pi * self.r * self.r
self.vx = 0
self.vy = 0
def beAttracted(self, planets):
for planet in planets:
if planet != self:
self.beAttractedBy(planet)
def beAttractedBy(self, planet):
distance = math.sqrt(pow(self.x - planet.x, 2) + pow(self.y - planet.y, 2))
f = G * self.m * planet.m / (distance + 0.0000001)
if self.x != planet.x:
a = math.atan((planet.y - self.y) / (planet.x - self.x))
vx = f * math.cos(a) / self.m
vy = f * math.sin(a) / self.m
if planet.x > self.x:
self.vx += vx
self.vy += vy
else:
self.vx -= vx
self.vy -= vy
else:
self.vy += f if self.y < planet.y else -f
def move(self):
self.x += self.vx
self.y += self.vy
class SpaceLayer(cocos.layer.Layer):
def __init__(self):
super(SpaceLayer, self).__init__()
# self.schedule(lambda x: 0)
self.mkPlanets(50)
self.schedule(self.timer)
def mkPlanets(self, n = 10):
self.planets = []
ri = random.randint
w, h = director.get_window_size()
for i in range(n):
planet = Planet(ri(0, w), ri(0, h), ri(1, 10))
self.planets.append(planet)
self.add(planet)
def timer(self, x):
self.attract()
def attract(self):
for planet in self.planets:
planet.beAttracted(self.planets)
for planet in self.planets:
planet.move()
if __name__ == "__main__":
director.init(
# resizable = True,
# width = 800,
# height = 600,
caption = u"N 体问题模拟",
)
space_layer = SpaceLayer()
main_scene = cocos.scene.Scene(space_layer)
director.run(main_scene)
其中需要一个图像文件,点击这儿可以下载完整的源文件。
发表评论:
电子邮件地址不会被公开。必填项已用 * 标注。
评论: