鱼C论坛

 找回密码
 立即注册
查看: 1149|回复: 6

[已解决]pygame天体运动模拟问题

[复制链接]
发表于 2023-7-26 22:32:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 歌者文明清理员 于 2023-7-26 23:11 编辑

目前已经放弃 SCALE

怎么会,居然把 pygame 写成了 pycharm

目前问题是不能将天体和轨道合并在同一个点上

cjjJasonchen 的回答:https://fishc.com.cn/forum.php?m ... 284&pid=6297452
当用鼠标滚轮滑动的时候行星会变大或者变小,这时,他们的中心点会发生变化,
而此时,轨迹的生成位置还是在行星原本大小时的center,

所以看上去轨道就不和行星在一起了


我有点没懂,这么说不应该是轨道的曲线很诡异吗,再说我这个现象不是滚轮,是拖动时发生的
目前的想法:https://fishc.com.cn/forum.php?m ... 284&pid=6298215
那可以不可以让StarSprite和轨迹都先放到另外一个surface上,对另外一个surface处理后再放回screen?
这样也有一个问题,就是轨迹的粗细不固定


但这个肯定不可行,首先这个 Surface 会超出屏幕
screen.blit(surf, rel)

因为 surf 也得有大小,不能无限大,所以就会出现过一会儿就黑屏的情况

求救,不然 Star Motion Simulate 将止步于此……

code.zip (128.5 KB, 下载次数: 1)
最佳答案
2023-7-26 22:35:45
本帖最后由 hellomyprogram 于 2023-7-27 11:12 编辑

对于这种大型程序,你可以将代码拆分成不同板块来分别储存。

大功告成!以下是结果(代码部分):
import itertools
import os
import pygame
import pyini
import tkinter as tk
import tkinter.filedialog as fd
from time import sleep
from threading import Thread

pygame.init()
pygame.key.set_repeat(1000, 50)

G = 6

# why do you need to create another object?
class StarObject:
    def __init__(self, x, y, vx, vy, mass):
        self.x = x
        self.y = y
        self.vx = vx  # v means speed
        self.vy = vy
        self.mass = mass

    @property
    def info(self):
        return self.x, self.y, self.vx, self.vy, self.mass

class StarSprite(pygame.sprite.Sprite):
    def __init__(self, name, star, radius, color):
        # pygame.sprite.Sprite.__init__(self)
        super().__init__()
        self.name = name
        self.star = star  # this is a StarObject
        self.radius = radius
        self.color = color
        self.trail = []
        self.image = pygame.Surface((radius * 2, radius * 2)).convert_alpha()
        self.image.fill((0, 0, 0, 0))
        pygame.draw.circle(self.image, color, (radius, radius), radius, 0)
        self.rect = self.image.get_rect()
        self.flush()

    def flush(self):
        self.rect.center = self.star.x, self.star.y
        self.trail.append(self.rect.center)

    def __repr__(self):
        return self.name

    __str__ = __repr__

class Message(pygame.sprite.Sprite):
    def __init__(self, text, pos):
        pygame.sprite.Sprite.__init__(self)
        self._text = text
        self.flush(pos)

    @property
    def text(self):
        return self._text

    @text.setter
    def text(self, text):
        pos = self.rect.topright
        self._text = text
        self.flush(pos)

    def flush(self, pos):
        self.image = font.render(self._text, False, (255, 255, 255))
        self.image = pygame.transform.scale_by(self.image, 1 / SCALE)
        self.rect = self.image.get_rect()
        self.rect.topright = pos

def get_distance(sprite1, sprite2):
    x1, y1 = sprite1.star.x, sprite1.star.y
    x2, y2 = sprite2.star.x, sprite2.star.y
    dx = x2 - x1
    dy = y2 - y1
    return (dx ** 2 + dy ** 2) ** 0.5

def disappear_message(delay=5, interval=0.09):
    sleep(delay)
    while message.text:
        try:
            message.text = message.text[:-1]
        except pygame.error:
            return
        sleep(interval)

def move(t):
    global sprites
    sprites_to_delete = set()
    for sprite1, sprite2 in itertools.combinations(sprites, 2):  # this is way faster
        star1 = sprite1.star
        star2 = sprite2.star
        if star1 is star2:
            continue
        x1, y1, vx1, vy1, m1 = star1.info
        x2, y2, _, _, m2 = star2.info
        ax1, ay1 = 0, 0
        dx = x2 - x1
        dy = y2 - y1
        r = get_distance(sprite1, sprite2)
        if is_collide(sprite1, sprite2):
            heavier = sprite1 if star1.mass > star2.mass else sprite2
            lighter = sprite2 if heavier is sprite1 else sprite1
            sprites_to_delete.add(lighter)
            heavier.star.vx += lighter.star.vx
            heavier.star.vy += lighter.star.vy
            message.text = language["star"]["collide"] % (heavier, lighter)
            Thread(target=disappear_message).start()
        f = G * m1 * m2 / (r ** 2)
        accel = f / m1
        ax1 += accel * (dx / r)
        ay1 += accel * (dy / r)
        x, y = (
            x1 + vx1 * t + 0.5 * ax1 * (t ** 2),
            y1 + vy1 * t + 0.5 * ay1 * (t ** 2)
        )
        tempx, tempy = star1.x, star1.y
        star1.x, star1.y = x, y
        star1.vx = (x - tempx) / t
        star1.vy = (y - tempy) / t
        sprite1.flush()
    sprites -= sprites_to_delete  # delete everything in sprites_to_delete

def is_collide(sprite1, sprite2):
    r1, r2 = sprite1.radius, sprite2.radius
    return r1 + r2 > get_distance(sprite1, sprite2)

def zoom(direction, each=0.01):
    global scale
    if direction > 0:
        scale += each
    elif direction < 0:
        scale -= each
    message.text = language["game"]["zoom"] % scale
    Thread(target=disappear_message).start()

def change_view(move_x, move_y):
    rel[0] += move_x
    rel[1] += move_y
    message.text = language["game"]["rel"] % str(tuple(rel))

with open("config/config.ini", "r", encoding="utf-8") as f:
    config = pyini.ConfigParser(f.read())

with open(f"config/language_{config['language']['default']}.ini", "r", encoding="utf-8") as f:
    language = pyini.ConfigParser(f.read())

SCALE = int(config["window"]["screen_zoom"]) / 100  # what's this? is it different from "scale"?

clock = pygame.time.Clock()
drag = False
rel = [0, 0]  # do you mean "the world origin on the screen"
scale = 1
paused = False

size = width, height = (1000 / SCALE, 1000 / SCALE)
screen = pygame.display.set_mode(size)
screen_original = pygame.Surface(size)

movement = 10

pygame.display.set_icon(pygame.image.load(config["window"]["icon"]))
pygame.display.set_caption("Pygame Star Motion Simulate")

with open(f"simulation/{config['simulation']['file']}.simulation", "r", encoding="utf-8") as f:
    sprites = eval(f.read())  # you can use sets rather than lists

font = pygame.font.SysFont("Microsoft YaHei UI", 20)
message = Message("", (width - 10, 10))

running = True
while running:
    screen.fill((0, 0, 0))
    clock.tick(30)
    if not paused:
        move(2)
    for sprite, trail in map(lambda each_sprite: (each_sprite, each_sprite.trail), sprites):
        if len(trail) < 2:
            continue
        trail = list(map(lambda point: ((point[0] + rel[0]) * scale, (point[1] + rel[1]) * scale), trail))
        pygame.draw.lines(screen, sprite.color, False, trail, 2)
    for sprite in sprites:
        image = sprite.image
        image = pygame.transform.scale(image, (sprite.radius * 2 * scale,) * 2)
        screen.blit(image, ((sprite.rect.topleft[0] + rel[0]) * scale, (sprite.rect.topleft[1] + rel[1]) * scale))
    try:
        screen.blit(message.image, message.rect)
    except pygame.error:
        pass
    pygame.display.flip()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                drag = True
        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                drag = False
            elif event.button == 4:
                zoom(1)
            else:
                zoom(-1)
        elif event.type == pygame.MOUSEMOTION:
            if drag:
                change_view(*event.rel)
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                paused = not paused
            elif event.mod & pygame.KMOD_CTRL and event.key == pygame.K_s:
                root = tk.Tk()
                root.withdraw()
                filepath = fd.asksaveasfilename(
                    initialdir=os.path.dirname(__file__),
                    defaultextension=".png",
                    filetypes=((language["game"]["picture"] % "PNG", "*.png"), )
                )
                if filepath:
                    pygame.image.save(screen, filepath)
                root.destroy()
            elif event.key in (pygame.K_LEFT, pygame.K_a, pygame.K_KP_4):
                change_view(movement, 0)
            elif event.key in (pygame.K_RIGHT, pygame.K_d, pygame.K_KP_6):
                change_view(-movement, 0)
            elif event.key in (pygame.K_UP, pygame.K_w, pygame.K_KP_8):
                change_view(0, movement)
            elif event.key in (pygame.K_DOWN, pygame.K_s, pygame.K_KP_2):
                change_view(0, -movement)
            elif event.key in (pygame.K_EQUALS, pygame.K_KP_PLUS):
                zoom(1)
            elif event.key in (pygame.K_MINUS, pygame.K_KP_MINUS):
                zoom(-1)
pygame.quit()
存储部分要把.simulation的文件中的方括号改为大括号。以下是完整文件:
code (fixed).zip (128.92 KB, 下载次数: 2)
其实,问题出在这一行(第188行)上:
screen.blit(image, sprite.rect)
这样并没有改变星球的显示位置,只改变了大小,将这一行改为这样:
screen.blit(image, ((sprite.rect.topleft[0] + rel[0]) * scale, (sprite.rect.topleft[1] + rel[1]) * scale))


无关紧要的问题:
  • 你可以将StarObject与StarSprite整合在一起,分开来似乎没有什么用;
  • 你在进行缩小判断的时候只用了else语句,这样会匹配其他按键(例如鼠标中键和鼠标右键),你可以试试;
  • 把大写的SCALE改为SCREEN_SIZE_SCALE语义会明确一点;
  • 你可以将两个循环通过itertools.combination整合到一起(又不需要第三方库),一次性计算两个星球之间的关系,比用两个循环要快;
  • set(集合)自带差集、并集和交集算法,可以使用set加快运行速度,减少代码量;
  • 对于加速度、速度以及力这些矢量,你可以创建一个向量(Vector)对象来存储并更改他们,加强可读性;
  • 你可以定时清理trail(星球轨迹),否则内存占用会一直增加,直到爆栈。
  • 像你这样的文件,可以使用git作为版本管理工具(不想开源可以不用github),在每一个版本附上这个版本的说明,如果出了什么bug,可以回退版本查看问题出在哪里。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-7-26 22:33:03 | 显示全部楼层
根据你提供的信息,你的问题是在pycharm中进行天体运动模拟时,无法将天体和轨道合并在同一个点上。

根据你提到的想法,将StarSprite和轨迹都放到另一个surface上,然后对该surface进行处理后再放回screen。但是这个方法是不可行的,因为这个surface的大小是有限的,可能会超出屏幕范围,导致黑屏的情况。

根据cjjJasonchen的回答,当用鼠标滚轮滑动时,行星的大小会改变,这时行星的中心点会发生变化,而轨道的生成位置仍然是在行星原本大小时的中心点上,所以看上去轨道和行星不在一起。

根据你的描述,这个现象是在拖动时发生的,而不是滚轮滑动。对于这个问题,我需要查看你的代码来进行更详细的分析和解答。请提供你的代码文件(code.zip)以便我可以帮助你解决问题。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-26 22:33:12 | 显示全部楼层
很抱歉,由于我无法打开或访问链接中的内容,我无法准确理解你提到的问题和现象。但是,我可以为你提供一些关于天体运动模拟问题的一般性建议。

对于将天体和轨道合并在同一个点上的问题,你的想法是将StarSprite和轨迹放到另一个surface上进行处理,然后再放回screen。这个想法是可行的,可以使用一个临时的surface来进行处理,但需要注意处理后的surface大小不能超出屏幕。

关于轨迹的粗细不固定的问题,你可以尝试使用适当的绘图函数或技巧来实现轨迹的可变粗细。例如,你可以使用带有透明度的画笔,在每个时间步骤中根据行星的位置绘制轨迹,并根据距离行星中心的距离来调整透明度或线条的粗细,以达到变化的效果。

关于行星大小变化导致轨道生成位置的问题,你可以在每次行星大小发生变化时,同时更新轨道的生成位置。根据新的行星大小,重新计算轨道生成位置,确保轨道与行星始终保持一致。

总之,天体运动模拟问题涉及到多个方面的计算和图形处理,需要综合考虑各个因素来进行解决。如果你能提供更具体的代码或问题描述,我将能够给出更详细和准确的帮助。希望这些提示对你有所帮助,如果还有其他问题,请随时提问。
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-26 22:33:13 | 显示全部楼层
问题描述

根据你的描述,你在使用PyCharm进行天体运动模拟时遇到了问题。目前无法将天体和轨道合并在同一个点上。你考虑过将StarSprite和轨迹都放在一个新的surface上,然后对该surface进行处理后再放回主屏幕。但是这样会导致surface超出屏幕大小,并最终导致黑屏现象。此外,你提到鼠标滚轮滑动时行星的大小变化会影响到轨道的生成位置。

解决方案

1. 合并天体和轨道显示: 为了将天体和轨道合并在同一个点上,你可以将天体和轨道的绘制操作都放在同一个循环中,并将它们都绘制在同一个surface上,然后将该surface绘制到屏幕上。这样可以保证天体和轨道在视觉上的一致性。

2. 轨道粗细处理: 如果你希望轨道的粗细有所不同,可以使用Pygame的pygame.draw.lines()函数绘制轨道,该函数可以指定线条的宽度。你可以根据行星的大小或其他条件来动态调整轨道的粗细。如果你不希望轨道的粗细固定,可以在每次绘制轨道时计算轨道的粗细值,并将其作为参数传递给绘制函数。

3. 行星大小变化对轨道位置的影响: 当行星的大小发生变化时,它的中心点也会随之发生变化。这可能导致轨道生成位置与行星当前位置不一致。为了解决这个问题,你需要确保轨道的生成位置始终与行星的中心点保持一致。你可以根据行星的当前位置和大小重新计算轨道的生成位置,以确保它们始终在一起。

希望以上解决方案能够对你的问题有所帮助。如果你还有其他问题,请随时提问。

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-26 22:35:24 | 显示全部楼层
isdkz 发表于 2023-7-26 22:33
根据你提供的信息,你的问题是在pycharm中进行天体运动模拟时,无法将天体和轨道合并在同一个点上。

根 ...

为何不下载 code.zip 去问 GPT?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-26 22:35:45 | 显示全部楼层    本楼为最佳答案   
本帖最后由 hellomyprogram 于 2023-7-27 11:12 编辑

对于这种大型程序,你可以将代码拆分成不同板块来分别储存。

大功告成!以下是结果(代码部分):
import itertools
import os
import pygame
import pyini
import tkinter as tk
import tkinter.filedialog as fd
from time import sleep
from threading import Thread

pygame.init()
pygame.key.set_repeat(1000, 50)

G = 6

# why do you need to create another object?
class StarObject:
    def __init__(self, x, y, vx, vy, mass):
        self.x = x
        self.y = y
        self.vx = vx  # v means speed
        self.vy = vy
        self.mass = mass

    @property
    def info(self):
        return self.x, self.y, self.vx, self.vy, self.mass

class StarSprite(pygame.sprite.Sprite):
    def __init__(self, name, star, radius, color):
        # pygame.sprite.Sprite.__init__(self)
        super().__init__()
        self.name = name
        self.star = star  # this is a StarObject
        self.radius = radius
        self.color = color
        self.trail = []
        self.image = pygame.Surface((radius * 2, radius * 2)).convert_alpha()
        self.image.fill((0, 0, 0, 0))
        pygame.draw.circle(self.image, color, (radius, radius), radius, 0)
        self.rect = self.image.get_rect()
        self.flush()

    def flush(self):
        self.rect.center = self.star.x, self.star.y
        self.trail.append(self.rect.center)

    def __repr__(self):
        return self.name

    __str__ = __repr__

class Message(pygame.sprite.Sprite):
    def __init__(self, text, pos):
        pygame.sprite.Sprite.__init__(self)
        self._text = text
        self.flush(pos)

    @property
    def text(self):
        return self._text

    @text.setter
    def text(self, text):
        pos = self.rect.topright
        self._text = text
        self.flush(pos)

    def flush(self, pos):
        self.image = font.render(self._text, False, (255, 255, 255))
        self.image = pygame.transform.scale_by(self.image, 1 / SCALE)
        self.rect = self.image.get_rect()
        self.rect.topright = pos

def get_distance(sprite1, sprite2):
    x1, y1 = sprite1.star.x, sprite1.star.y
    x2, y2 = sprite2.star.x, sprite2.star.y
    dx = x2 - x1
    dy = y2 - y1
    return (dx ** 2 + dy ** 2) ** 0.5

def disappear_message(delay=5, interval=0.09):
    sleep(delay)
    while message.text:
        try:
            message.text = message.text[:-1]
        except pygame.error:
            return
        sleep(interval)

def move(t):
    global sprites
    sprites_to_delete = set()
    for sprite1, sprite2 in itertools.combinations(sprites, 2):  # this is way faster
        star1 = sprite1.star
        star2 = sprite2.star
        if star1 is star2:
            continue
        x1, y1, vx1, vy1, m1 = star1.info
        x2, y2, _, _, m2 = star2.info
        ax1, ay1 = 0, 0
        dx = x2 - x1
        dy = y2 - y1
        r = get_distance(sprite1, sprite2)
        if is_collide(sprite1, sprite2):
            heavier = sprite1 if star1.mass > star2.mass else sprite2
            lighter = sprite2 if heavier is sprite1 else sprite1
            sprites_to_delete.add(lighter)
            heavier.star.vx += lighter.star.vx
            heavier.star.vy += lighter.star.vy
            message.text = language["star"]["collide"] % (heavier, lighter)
            Thread(target=disappear_message).start()
        f = G * m1 * m2 / (r ** 2)
        accel = f / m1
        ax1 += accel * (dx / r)
        ay1 += accel * (dy / r)
        x, y = (
            x1 + vx1 * t + 0.5 * ax1 * (t ** 2),
            y1 + vy1 * t + 0.5 * ay1 * (t ** 2)
        )
        tempx, tempy = star1.x, star1.y
        star1.x, star1.y = x, y
        star1.vx = (x - tempx) / t
        star1.vy = (y - tempy) / t
        sprite1.flush()
    sprites -= sprites_to_delete  # delete everything in sprites_to_delete

def is_collide(sprite1, sprite2):
    r1, r2 = sprite1.radius, sprite2.radius
    return r1 + r2 > get_distance(sprite1, sprite2)

def zoom(direction, each=0.01):
    global scale
    if direction > 0:
        scale += each
    elif direction < 0:
        scale -= each
    message.text = language["game"]["zoom"] % scale
    Thread(target=disappear_message).start()

def change_view(move_x, move_y):
    rel[0] += move_x
    rel[1] += move_y
    message.text = language["game"]["rel"] % str(tuple(rel))

with open("config/config.ini", "r", encoding="utf-8") as f:
    config = pyini.ConfigParser(f.read())

with open(f"config/language_{config['language']['default']}.ini", "r", encoding="utf-8") as f:
    language = pyini.ConfigParser(f.read())

SCALE = int(config["window"]["screen_zoom"]) / 100  # what's this? is it different from "scale"?

clock = pygame.time.Clock()
drag = False
rel = [0, 0]  # do you mean "the world origin on the screen"
scale = 1
paused = False

size = width, height = (1000 / SCALE, 1000 / SCALE)
screen = pygame.display.set_mode(size)
screen_original = pygame.Surface(size)

movement = 10

pygame.display.set_icon(pygame.image.load(config["window"]["icon"]))
pygame.display.set_caption("Pygame Star Motion Simulate")

with open(f"simulation/{config['simulation']['file']}.simulation", "r", encoding="utf-8") as f:
    sprites = eval(f.read())  # you can use sets rather than lists

font = pygame.font.SysFont("Microsoft YaHei UI", 20)
message = Message("", (width - 10, 10))

running = True
while running:
    screen.fill((0, 0, 0))
    clock.tick(30)
    if not paused:
        move(2)
    for sprite, trail in map(lambda each_sprite: (each_sprite, each_sprite.trail), sprites):
        if len(trail) < 2:
            continue
        trail = list(map(lambda point: ((point[0] + rel[0]) * scale, (point[1] + rel[1]) * scale), trail))
        pygame.draw.lines(screen, sprite.color, False, trail, 2)
    for sprite in sprites:
        image = sprite.image
        image = pygame.transform.scale(image, (sprite.radius * 2 * scale,) * 2)
        screen.blit(image, ((sprite.rect.topleft[0] + rel[0]) * scale, (sprite.rect.topleft[1] + rel[1]) * scale))
    try:
        screen.blit(message.image, message.rect)
    except pygame.error:
        pass
    pygame.display.flip()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                drag = True
        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                drag = False
            elif event.button == 4:
                zoom(1)
            else:
                zoom(-1)
        elif event.type == pygame.MOUSEMOTION:
            if drag:
                change_view(*event.rel)
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                paused = not paused
            elif event.mod & pygame.KMOD_CTRL and event.key == pygame.K_s:
                root = tk.Tk()
                root.withdraw()
                filepath = fd.asksaveasfilename(
                    initialdir=os.path.dirname(__file__),
                    defaultextension=".png",
                    filetypes=((language["game"]["picture"] % "PNG", "*.png"), )
                )
                if filepath:
                    pygame.image.save(screen, filepath)
                root.destroy()
            elif event.key in (pygame.K_LEFT, pygame.K_a, pygame.K_KP_4):
                change_view(movement, 0)
            elif event.key in (pygame.K_RIGHT, pygame.K_d, pygame.K_KP_6):
                change_view(-movement, 0)
            elif event.key in (pygame.K_UP, pygame.K_w, pygame.K_KP_8):
                change_view(0, movement)
            elif event.key in (pygame.K_DOWN, pygame.K_s, pygame.K_KP_2):
                change_view(0, -movement)
            elif event.key in (pygame.K_EQUALS, pygame.K_KP_PLUS):
                zoom(1)
            elif event.key in (pygame.K_MINUS, pygame.K_KP_MINUS):
                zoom(-1)
pygame.quit()
存储部分要把.simulation的文件中的方括号改为大括号。以下是完整文件:
code (fixed).zip (128.92 KB, 下载次数: 2)
其实,问题出在这一行(第188行)上:
screen.blit(image, sprite.rect)
这样并没有改变星球的显示位置,只改变了大小,将这一行改为这样:
screen.blit(image, ((sprite.rect.topleft[0] + rel[0]) * scale, (sprite.rect.topleft[1] + rel[1]) * scale))


无关紧要的问题:
  • 你可以将StarObject与StarSprite整合在一起,分开来似乎没有什么用;
  • 你在进行缩小判断的时候只用了else语句,这样会匹配其他按键(例如鼠标中键和鼠标右键),你可以试试;
  • 把大写的SCALE改为SCREEN_SIZE_SCALE语义会明确一点;
  • 你可以将两个循环通过itertools.combination整合到一起(又不需要第三方库),一次性计算两个星球之间的关系,比用两个循环要快;
  • set(集合)自带差集、并集和交集算法,可以使用set加快运行速度,减少代码量;
  • 对于加速度、速度以及力这些矢量,你可以创建一个向量(Vector)对象来存储并更改他们,加强可读性;
  • 你可以定时清理trail(星球轨迹),否则内存占用会一直增加,直到爆栈。
  • 像你这样的文件,可以使用git作为版本管理工具(不想开源可以不用github),在每一个版本附上这个版本的说明,如果出了什么bug,可以回退版本查看问题出在哪里。

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
歌者文明清理员 + 5 + 5 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-26 22:38:16 | 显示全部楼层
hellomyprogram 发表于 2023-7-26 22:35
你可以试试用一个列表存储天体的位置,并使用pygame.draw.lines()方法将天体的位置信息画到屏幕上,你可能 ...


我的代码中为了让用户移动视角定义了 rel 变量,表示偏移量
然后 scale 是缩放比例(小数,类似 0.9 这种)
常量 SCALE 用来方便一些屏幕缩放不一样的用户,比如 125%,就让整个游戏的 x y width ehight都除以 SCALE

就是这些搞着搞着就搞糊涂了,还不写注释
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-22 07:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表