Compare commits

...

3 Commits

Author SHA1 Message Date
2ee3b96a45 rua 2022-07-08 22:20:54 +08:00
5042f490da rue 2022-07-07 21:22:20 +08:00
9fb2f717ea 正在做c扩展
readme

清理一些无用文件

rename folder

awa

awa

load textures!

删掉了一些没用的东西

hmmm

好耶!

看起来少,实际上多

awa

update

1.0!

rue

ah!

同步libs更新

Update __init__.py

merge!
2022-07-07 21:22:20 +08:00
131 changed files with 1856 additions and 3276 deletions

3
.gitignore vendored
View File

@ -149,5 +149,4 @@ dmypy.json
other things/
.git-/
try/cprint/cmake-build-debug
try/c/cmake-build-debug
*cmake-build-debug

48
DR.py
View File

@ -4,9 +4,9 @@ mail: 3695888@qq.com
"""
import os
import sys
import time
import cProfile
import traceback
import threading
import multiprocessing
# TODO 默认位置配置文件
# TODO 可自定义工作路径
@ -30,40 +30,30 @@ if __name__ == '__main__':
print(f'{os.getcwd()=}')
print(f'{os.path.abspath(__file__)=}')
print(f'{os.path.realpath(__file__)=}')
print(f'{os.path.split(os.path.split(os.path.realpath(__file__))[0])=}')
# 输出一遍大部分文件位置相关信息 以后可能会加到logs里
file_path = os.path.split(os.path.realpath(__file__))[0]
os.chdir(file_path) # 将运行路径切换到文件位置 防止bug
sys.path.append(f'{file_path}/Difficult_Rocket') # 添加local path
sys.path.append(f'{file_path}/libs') # 添加 libs path
print(sys.path) # 输出路径
print(hi) # hi
os.chdir(file_path)
sys.path.append(f'{file_path}/Difficult_Rocket')
sys.path.append(f'{file_path}/libs')
print(sys.path)
print(hi)
DEBUGGING = False
from SRtool.api.Exp import *
DEBUGGING = False # 是否在 DEBUG
from Difficult_Rocket.exception import TestError
from Difficult_Rocket.crash import crash
try:
start_time = time.perf_counter_ns() # 记录启动时间
import pyglet # 导入pyglet
from SRtool.crash import crash
from SRtool import main
from Difficult_Rocket import main
game = main.Game()
game.start()
from libs.pyglet.gl import glClearColor # 调整背景颜色
glClearColor(0.5, 0.5, 0.5, 0)
game = main.Game() # 实例化一个游戏
print(time.perf_counter_ns() - start_time) # 输出一下启动用时
cprofile = False # 是否使用cprofile
if cprofile:
cProfile.run('game.start()', sort='calls') # 使用 cprofile 启动
else:
game.start() # 直接启动
if DEBUGGING:
raise TestError('debugging') # debug 嘛试试crash
except Exception as exp: # 出毛病了
print(error_format['error.happen']) #
raise TestError('debugging')
except Exception as exp:
from SRtool.translate import tr
print(error_format['error.happen'])
error = traceback.format_exc()
name = type(exp).__name__
if name in error_format:

View File

@ -1,40 +0,0 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
from libs.MCDR.version import Version
game_version = Version("0.6.2")
__version__ = game_version
DR_options = {
'InputBox_use_TextEntry': False,
'playing': False
}
_DR_options_type = {
'InputBox_use_TextEntry': bool,
'playing': bool
}
if DR_options['playing']:
from .api import new_thread
def think_it(something):
return something
@new_thread('think')
def think(some_thing_to_think):
gotcha = think_it(some_thing_to_think)
return gotcha

View File

@ -1,298 +0,0 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
# system function
import os
import time
import logging
import traceback
from decimal import Decimal
# Difficult_Rocket function
from Difficult_Rocket.command import line, tree
from Difficult_Rocket.utils import new_thread
from Difficult_Rocket.utils.translate import tr
from Difficult_Rocket.guis.widgets import InputBox
# from Difficult_Rocket.client.screen import DRScreen
from Difficult_Rocket.utils import tools, translate
from Difficult_Rocket.client.fps.fps_log import FpsLogger
from Difficult_Rocket.exception.command import CommandError
from libs import pyglet
from libs.pyglet.window import Window
from libs.pyglet.window import key, mouse
from libs import toml
class Client:
def __init__(self, net_mode='local'):
start_time = time.time_ns()
# logging
self.logger = logging.getLogger('client')
# config
self.config = tools.load_file('./configs/main.toml')
# value
self.process_id = 'Client'
self.process_name = 'Client process'
self.process_pid = os.getpid()
self.net_mode = net_mode
self.caption = tools.name_handler(self.config['window']['caption'], {'version': self.config['runtime']['version']})
self.window = ClientWindow(net_mode=self.net_mode,
width=int(self.config['window']['width']),
height=int(self.config['window']['height']),
fullscreen=tools.format_bool(self.config['window']['full_screen']),
caption=self.caption,
resizable=tools.format_bool(self.config['window']['resizable']),
visible=tools.format_bool(self.config['window']['visible']))
self.logger.info(tr.lang('client', 'setup.done'))
end_time = time.time_ns()
self.use_time = end_time - start_time
self.logger.info(tr.lang('client', 'setup.use_time').format(Decimal(self.use_time) / 1000000000))
self.logger.debug(tr.lang('client', 'setup.use_time_ns').format(self.use_time))
def start(self):
self.window.start_game() # 游戏启动
# TODO 写一下服务端启动相关,还是需要服务端啊
def pyglet_load_fonts_folder(folder) -> None:
file_folder_list = os.listdir(folder)
for obj in file_folder_list:
if os.path.isfile(os.path.join(folder, obj)):
if obj[-4:] == '.ttf':
pyglet.font.add_file(os.path.join(folder, obj))
else:
pyglet_load_fonts_folder(os.path.join(folder, obj))
class ClientWindow(Window):
def __init__(self, net_mode='local', *args, **kwargs):
start_time = time.time_ns()
super().__init__(*args, **kwargs)
"""
:param dev_list: 共享内存
:param dev_dic: 共享内存
:param logger: logger
:param net_mode: 网络模式 # local / ip
"""
# logging
self.logger = logging.getLogger('client')
# value
self.net_mode = net_mode
self.run_input = False
# configs
pyglet.resource.path = ['/textures/']
pyglet.resource.reindex()
self.set_icon(pyglet.image.load('./textures/icon.png'))
self.main_config = tools.load_file('./configs/main.toml')
self.game_config = tools.load_file('./configs/game.config')
# FPS
self.FPS = Decimal(int(self.main_config['runtime']['fps']))
self.SPF = Decimal('1') / self.FPS
self.fps_log = FpsLogger(stable_fps=int(self.FPS))
# batch
self.part_batch = pyglet.graphics.Batch()
self.label_batch = pyglet.graphics.Batch()
# frame
self.frame = pyglet.gui.Frame(self, order=20)
self.M_frame = pyglet.gui.MovableFrame(self, modifier=key.LCTRL)
# self.DRscreen = DRScreen(self)
# setup
self.setup()
# 命令显示
self.command_group = pyglet.graphics.Group(0)
self.command_tree = tree.CommandTree(tree.DR_command)
self.input_box = InputBox(x=50, y=30, width=300, height=20,
batch=self.label_batch) # 实例化
self.push_handlers(self.input_box)
self.input_box.enabled = True
# fps显示
self.fps_label = pyglet.text.Label(x=10, y=self.height - 10,
width=self.width - 20, height=20,
anchor_x='left', anchor_y='top',
font_name=translate.微软等宽无线, font_size=20,
multiline=True,
batch=self.label_batch, group=self.command_group)
# 设置刷新率
pyglet.clock.schedule_interval(self.draw_update, float(self.SPF))
# 完成设置后的信息输出
self.logger.info(tr.lang('window', 'setup.done'))
self.logger.info(tr.lang('window', 'os.pid_is').format(os.getpid(), os.getppid()))
end_time = time.time_ns()
self.use_time = end_time - start_time
self.logger.info(tr.lang('window', 'setup.use_time').format(Decimal(self.use_time) / 1000000000))
self.logger.debug(tr.lang('window', 'setup.use_time_ns').format(self.use_time))
self.count = 0
def setup(self):
self.load_fonts()
def load_fonts(self):
fonts_folder_path = self.main_config['runtime']['fonts_folder']
# 加载字体路径
# 淦,还写了个递归来处理
pyglet_load_fonts_folder(fonts_folder_path)
# @new_thread('window load_editor')
def load_editor(self):
pass
def start_game(self) -> None:
self.run_input = True
self.read_input()
pyglet.app.event_loop.run(1 / self.main_config['runtime']['fps'])
@new_thread('window read_input', daemon=True)
def read_input(self):
self.logger.debug('read_input start')
while self.run_input:
get = input()
if get in ('', ' ', '\n', '\r'):
continue
if get == 'stop':
self.run_input = False
try:
self.on_command(line.CommandText(get))
except CommandError:
self.logger.error(traceback.format_exc())
self.logger.debug('read_input end')
@new_thread('window save_info')
def save_info(self):
self.logger.info('save_info start')
config_file = tools.load_file('./configs/main.toml')
config_file['window']['width'] = self.width
config_file['window']['height'] = self.height
toml.dump(config_file, open('./configs/main.toml', 'w'))
self.logger.info('save_info end')
"""
draws and some event
"""
def draw_update(self, tick: float):
# self.count += 1
# if self.count >= 100:
# try:
# self.count = 0
# self.logger.debug(tick)
# self.logger.debug('update! {} {}'.format(tick, pyglet.clock.get_frequency()))
# except ZeroDivisionError:
# pass
decimal_tick = Decimal(str(tick)[:10])
self.FPS_update(decimal_tick)
def FPS_update(self, tick: Decimal):
now_FPS = pyglet.clock.get_frequency()
self.fps_log.update_tick(now_FPS, tick)
self.fps_label.text = f'FPS: {self.fps_log.fps: >5.1f}({self.fps_log.middle_fps: >5.1f})[{now_FPS: >.7f}]\n {self.fps_log.max_fps: >7.1f} {self.fps_log.min_fps:>5.1f}'
def on_draw(self, *dt):
# self.logger.debug('on_draw call dt: {}'.format(dt))
self.clear()
self.draw_batch()
def on_resize(self, width: int, height: int):
super().on_resize(width, height)
self.fps_label.y = height - 10
def on_refresh(self, dt):
...
def draw_batch(self):
self.part_batch.draw()
self.label_batch.draw()
"""
command line event
"""
def on_command(self, command: line.CommandText):
self.logger.info(tr.lang('window', 'command.text').format(command))
if command.match('stop'):
self.dispatch_event('on_exit')
# platform_event_loop.stop()
self.dispatch_event('on_close', 'command') # source = command
elif command.match('fps'):
if command.match('log'):
self.logger.debug(self.fps_log.fps_list)
elif command.match('max'):
self.logger.info(self.fps_log.max_fps)
self.command.push_line(self.fps_log.max_fps, block_line=True)
elif command.match('min'):
self.logger.info(self.fps_log.min_fps)
self.command.push_line(self.fps_log.min_fps, block_line=True)
elif command.match('default'):
self.set_size(int(self.main_config['window_default']['width']), int(self.main_config['window_default']['height']))
self.command_tree.parse(command.plain_command)
def on_message(self, message: line.CommandLine.text):
self.logger.info(tr.lang('window', 'message.text').format(message))
"""
keyboard and mouse input
"""
def activate(self):
super().activate()
def on_mouse_motion(self, x, y, dx, dy) -> None:
pass
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers) -> None:
pass
def on_mouse_press(self, x, y, button, modifiers) -> None:
self.logger.debug(tr.lang('window', 'mouse.press').format([x, y], tr.lang('window', 'mouse.{}'.format(mouse.buttons_string(button)))))
def on_mouse_release(self, x, y, button, modifiers) -> None:
self.logger.debug(tr.lang('window', 'mouse.release').format([x, y], tr.lang('window', 'mouse.{}'.format(mouse.buttons_string(button)))))
def on_key_press(self, symbol, modifiers) -> None:
if symbol == key.ESCAPE and not (modifiers & ~(key.MOD_NUMLOCK |
key.MOD_CAPSLOCK |
key.MOD_SCROLLLOCK)):
self.dispatch_event('on_close')
self.logger.debug(tr.lang('window', 'key.press').format(key.symbol_string(symbol), key.modifiers_string(modifiers)))
def on_key_release(self, symbol, modifiers) -> None:
self.logger.debug(tr.lang('window', 'key.release').format(key.symbol_string(symbol), key.modifiers_string(modifiers)))
def on_text(self, text):
if text == '\r':
self.logger.debug(tr.lang('window', 'text.new_line'))
else:
self.logger.debug(tr.lang('window', 'text.input').format(text))
if text == 't':
self.input_box.enabled = True
def on_text_motion(self, motion):
motion_string = key.motion_string(motion)
self.logger.debug(tr.lang('window', 'text.motion').format(motion_string))
def on_text_motion_select(self, motion):
motion_string = key.motion_string(motion)
self.logger.debug(tr.lang('window', 'text.motion_select').format(motion_string))
def on_close(self, source: str = 'window') -> None:
self.logger.info(tr.lang('window', 'game.stop_get').format(tr.lang('window', f'game.{source}_stop')))
self.logger.info(tr.lang('window', 'game.stop'))
self.fps_log.check_list = False
if self.run_input:
self.run_input = False
self.save_info()
super().on_close()
self.logger.info(tr.lang('window', 'game.end'))

View File

@ -1,68 +0,0 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
from Difficult_Rocket import game_version
from Difficult_Rocket.command import line
COMMAND = 'command'
SUB_COMMAND = 'sub_command'
INFO = 'info'
RUN = 'run'
DR_command = {
'name': 'DR-root',
'version': game_version,
INFO: 'DR的自带命令解析树',
COMMAND: {
INFO: '这里是DR的根命令节点',
RUN: None,
SUB_COMMAND: {
'stop': {
INFO: '退出游戏',
RUN: None
},
'fps': {
INFO: 'FPS相关命令',
RUN: None,
SUB_COMMAND: {
'log': {
INFO: '输出FPS信息',
RUN: None
},
'min': {
INFO: '输出一段时间内最小fps',
RUN: None
},
'max': {
INFO: '输出一段时间内最大FPS',
RUN: None
}
}
},
'default': {
INFO: '重置一些设置'
}
}
}
}
# TODO 给爷做了他
class CommandTree:
def __init__(self, command_tree_dict):
self.command_tree_dict = command_tree_dict
def parse(self, command: [line.CommandText, str]):
pass

View File

@ -1,19 +0,0 @@
#=
html:
- Julia version: 1.7.2
- Author: shenjack
- Date: 2022-04-26
=#
using PyCall
include("../../utils/translate.jl")
struct default_style
font_name::String
font_size::UInt8
bold::Bool
italic::Bool
end
default_style = default_style(fonts.HOS)

View File

@ -1,334 +0,0 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
import re
from utils import translate
default_style = {
'font_name': 'Times New Roman',
'font_size': 12,
'bold': False,
'italic': False
}
class SingleTextStyle:
"""
单个字符的字体样式
"""
def __init__(self,
font_name: str = '',
font_size: int = 12,
bold: bool = False,
italic: bool = False,
color: str = 'white',
text_tag: list = None,
show: bool = True,
prefix: str = '',
suffix: str = '',
text: str = ''):
self.font_name = font_name
self.font_size = font_size
self.bold = bold
self.italic = italic
self.color = color
self.prefix = prefix
self.suffix = suffix
if not text_tag:
self._tag = []
else:
self._tag = text_tag
self.show = show
self.text = text
@property
def tag(self) -> list:
return self._tag
@tag.setter
def tag(self, value: list):
assert type(value) == list, 'SingleTextStyle.tag must be list'
for tag in value:
if tag not in self._tag:
self._tag.append(tag)
self._tag.sort()
"""
对运算操作的支持
"""
def __add__(self, other: 'SingleTextStyle') -> 'SingleTextStyle':
"""
叠加两个字体样式 优先使用 other 的样式
:param other: 叠加的字体样式
:return: 叠加后的字体样式
"""
assert type(other) == SingleTextStyle, f'SingleTextStyle + other\n other must be the same type, not a {type(other)}'
return SingleTextStyle(
font_name=other.font_name or self.font_name,
font_size=other.font_size or self.font_size,
bold=other.bold or self.bold,
italic=other.italic or self.italic,
color=other.color or self.color,
text_tag=other.tag + self.tag,
show=other.show or self.show,
prefix=other.prefix + self.prefix,
suffix=other.suffix + self.suffix,
text=self.text
)
def __iadd__(self, other: 'SingleTextStyle') -> 'SingleTextStyle':
"""
叠加两个字体样式 优先使用 other 的样式
:param other: 叠加的字体样式
:return: 叠加后的字体样式
"""
assert type(other) == SingleTextStyle, f'SingleTextStyle += other\n other must be the same type, not a {type(other)}'
self.font_name = other.font_name or self.font_name
self.font_size = other.font_size or self.font_size
self.bold = other.bold or self.bold
self.italic = other.italic or self.italic
self.color = other.color or self.color
self.tag += other.tag
self.show = other.show or self.show
self.prefix += other.prefix
self.suffix += other.suffix
self.text = self.text
return self
"""
对各种判定的支持
"""
def have_tag(self, other: 'SingleTextStyle') -> bool:
"""
比较两个字体样式tag是否相同
:param other: 叠加的字体样式
:return: 是否相同
"""
assert type(other) == SingleTextStyle
return other.tag in self.tag
def same_font(self, other: 'SingleTextStyle') -> bool:
"""
比较两个字体样式的字体属性是否相同
:param other: 叠加的字体样式
:return: 是否相同
"""
assert type(other) == SingleTextStyle
return (self.font_name == other.font_name and
self.font_size == other.font_size and
self.color == other.color and
self.show == other.show)
def same_bold(self, other: 'SingleTextStyle') -> bool:
"""
比较两个字体样式的加粗属性是否相同
:param other: 叠加的字体样式
:return: 是否相同
"""
assert type(other) == SingleTextStyle
return self.bold == other.bold
def same_italic(self, other: 'SingleTextStyle') -> bool:
"""
比较两个字体样式的斜体属性是否相同
:param other: 叠加的字体样式
:return: 是否相同
"""
assert type(other) == SingleTextStyle
return self.italic == other.italic
"""
自动输出一些属性的支持
"""
def HTML_font(self, suffix: bool = False) -> str:
"""
输出字体样式的HTML字符
:return: HTML 格式字符
"""
if suffix:
return font_HTML_end
text = f'<font face="{self.font_name}" color={self.color}'
if self.font_size != default_style['font_size']:
text += f' real_size={self.font_size}'
text += '>'
return text
def HTML_bold(self, suffix: bool = False) -> str:
"""
输出字体粗体的HTML字符
:return: HTML 格式字符
"""
if self.bold:
if suffix:
return bold_HTML_end
return '<b>'
else:
return ''
def HTML_italic(self, suffix: bool = False) -> str:
"""
输出字体斜体的HTML字符
:return: HTML 格式字符
"""
if self.italic:
if suffix:
return italic_HTML_end
return '<i>'
else:
return ''
def HTML(self, suffix: bool = False) -> str:
"""
输出字体样式的HTML字符
:return: HTML 格式字符
"""
if not suffix:
return self.HTML_bold() + self.HTML_italic() + self.HTML_font()
else:
return font_HTML_end + (bold_HTML_end if self.bold else '') + (italic_HTML_end if self.italic else '')
# [\u4e00-\u9fa5] 中文字符
default_fonts_config = [
{
'match': re.compile(r'.'), # 匹配的字符 匹配选项是re.compile()
'shown': re.compile(r'.'), # 匹配到的字符中显示的部分 匹配选项是re.compile()
'style': SingleTextStyle(font_name=translate.鸿蒙简体, font_size=15, bold=False, italic=False, show=True, color='white'),
},
{
'match': re.compile(r'[a-zA-Z0-9]'),
'shown': re.compile(r'[a-zA-Z0-9]'),
'style': SingleTextStyle(font_name=translate.微软等宽, font_size=15)
},
# Markdown 语法规则匹配
{
# Markdown 粗体语法规则匹配
'match': re.compile(r'\*\*(.*?(?<!\s))\*\*'),
'shown': re.compile(r'(?<=\*\*)(.*?(?<!\s))(?=\*\*)'),
'tag': {
# 为 match 匹配到的字符添加标签
'match': re.compile(r'\*\*'),
'style': SingleTextStyle(text_tag=['bold'])
},
'style': SingleTextStyle(bold=True)
},
{
# Markdown 斜体语法规则匹配
'match': re.compile(r'\*(.*?(?<!\s))\*'),
'shown': re.compile(r'(?<=\*)(.*?(?<!\s))(?=\*)'),
'ignore': {
# 如果匹配到的字符含有 tag 就忽略本次解析
'match': re.compile(r'\*'),
'tag': SingleTextStyle(text_tag=['italic'])
},
'style': SingleTextStyle(italic=True)
},
{
# Markdown 链接规则匹配
# 注意:这里的匹配模式是非贪婪的,即匹配到的结果必须是完整的
# 即:链接名称不能是空格等空白字符开头,链接名称不能是空格等空白字符结尾
# 匹配的内容:[abc](def)
# 显示的内容abc
'match': re.compile(r'\[(.*?(?<!\s))\]\((.*?(?<!\s))\)'),
'shown': re.compile(r'(?<=\[)(.*?(?<!\s))(?=\]\((.*?(?<!\s))\))'),
'style': SingleTextStyle(bold=True)
}
]
font_HTML_end = '</font>'
bold_HTML = '<b>'
bold_HTML_end = '</b>'
italic_HTML = '<i>'
italic_HTML_end = '</i>'
def decode_text2HTML(text: str,
configs=None,
show_style: bool = False) -> str:
if text == '':
return ''
if configs is None:
configs = default_fonts_config
style_list = [SingleTextStyle(text=text[x]) for x in range(0, len(text))]
# 根据输入的配置对每一个字符进行样式设定
for config in configs:
# 根据 配置"文件"
match_texts = config['match'].finditer(text) # 使用 config.match 匹配
for match_text in match_texts: # 每一个匹配到的匹配项
text_match = match_text.group() # 缓存一下匹配到的字符,用于匹配显示的字符
shown_texts = config['shown'].finditer(text_match) # 使用 config.shown 匹配
match_start, match_end = match_text.span()
if 'ignore' in config: # 如果样式选项包含忽略某些字符的tag
ignore_texts = config['ignore']['match'].finditer(text_match) # 根据选项匹配可能忽略的字符
ignore = False # 忽略先为False
for ignore_text in ignore_texts: # 每一个可能忽略的字符
if ignore: # 为了方便退出
break
for ignore_index in range(match_start + ignore_text.span()[0], match_start + ignore_text.span()[1]): # 对每一个可能的字符进行检测
if style_list[ignore_index].have_tag(config['ignore']['tag']): # 如果确实包含要忽略的
ignore = True # 忽略为True
break
if ignore:
continue # 跳过本次匹配
if 'tag' in config: # 如果样式选项包含对部分字符添加tag
tag_texts = config['tag']['match'].finditer(text_match) # 根据配置的正则表达式匹配要添加tag的字符
for tag_text in tag_texts: # 对每一个匹配到的~~~~~~
for tag_index in range(match_start + tag_text.span()[0], match_start + tag_text.span()[1]): # 用于遍历匹配到的字符
style_list[tag_index] += config['tag']['style']
# 为匹配到的字符添加样式
for match_index in range(match_start, match_end): # 用于遍历匹配到的字符
# 这里用 match index 来精确读写列表里的元素,毕竟 re.Match 返回的 span 是两个标点,得遍历
style_list[match_index] += config['style'] # 字体样式列表的 [match_index] += config['style'] 的样式
style_list[match_index].show = show_style # 设置显示属性变为 False
# 为每一个显示的字符设置显示属性
for shown_text in shown_texts: # 每一个显示的匹配项
for shown_index in range(match_start + shown_text.span()[0], match_start + shown_text.span()[1]):
style_list[shown_index].show = True
# 字体样式列表的 [shown_index] 设置显示属性变为 True
# 开始根据配置好的样式输出HTML文本
style_list[0].prefix += style_list[0].HTML() # 不管怎么说都要在最前面加一个字符标识
for style_index in range(1, len(style_list)):
if style_list[style_index].show: # 如果这个字符显示
if not style_list[style_index - 1].show: # 如果前面一个字符不显示(且这个字符显示)
style_list[style_index].prefix += style_list[style_index].HTML() # 那么就直接给这个字符的前缀添加
else: # 开始根据前面的情况处理每种单独的标签
if not style_list[style_index - 1].same_font(style_list[style_index]):
style_list[style_index - 1].suffix += style_list[style_index - 1].HTML_font(suffix=True)
style_list[style_index].prefix += style_list[style_index].HTML_font()
if not style_list[style_index - 1].same_bold(style_list[style_index]):
style_list[style_index - 1].suffix += style_list[style_index - 1].HTML_bold(suffix=True)
style_list[style_index].prefix += style_list[style_index].HTML_bold()
if not style_list[style_index - 1].same_italic(style_list[style_index]):
style_list[style_index - 1].suffix += style_list[style_index - 1].HTML_italic(suffix=True)
style_list[style_index].prefix += style_list[style_index].HTML_italic()
else: # 如果这个字符不显示
if style_list[style_index - 1].show: # 如果前面一个字符显示(且这个字符不显示)
style_list[style_index - 1].suffix += style_list[style_index - 1].HTML(suffix=True)
# 如果前面一个字符也不显示那就直接 pass
if style_list[-1].show:
style_list[-1].suffix += style_list[-1].HTML(suffix=True)
# 输出最终的 HTML 文本
formatted_HTML_text = '' # 初始化一下
for style in style_list: # 每一个样式
if style.show: # 如果这个字符显示
formatted_HTML_text += style.prefix + style.text + style.suffix # 文本的后面附加一下
del style_list # 主动删掉 style_list 释放内存
return formatted_HTML_text # 返回DONE

View File

@ -1,25 +0,0 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
from libs.pyglet.text import DocumentLabel
class FontsLabel(DocumentLabel):
"""
一个基于HTMLLabel的 可以同时在一行字里面显示多种字体的 Label
"""
def __init__(self, x, y, width, height):
super().__init__(x, y, width, height)
self._text = 'a'
self.formatted_text = 'a'

View File

@ -1,254 +0,0 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
from utils import translate
from Difficult_Rocket.guis.format import html
from Difficult_Rocket import DR_options
# from libs import pyglet
from libs.pyglet import font
from libs.pyglet.text import Label, HTMLLabel
from libs.pyglet.window import key
from libs.pyglet.gui import widgets
from libs.pyglet.sprite import Sprite
from libs.pyglet.shapes import Rectangle
from libs.pyglet.image import AbstractImage
from libs.pyglet.graphics import Batch, Group
from libs.pyglet.text.document import FormattedDocument
from libs.pyglet.text.layout import IncrementalTextLayout
# from libs import pyperclip
from libs.pyperclip import paste
__all__ = ['Parts', 'InputBox']
class Parts(widgets.WidgetBase):
"""
parts
"""
def __init__(self,
x: int,
y: int,
width: int,
height: int,
textures: AbstractImage,
# textures,
batch: Batch,
parts_data: dict):
super().__init__(x, y, width, height)
self.sprite = Sprite(img=textures, x=x, y=y, batch=batch)
self._value = 0
if not DR_options['InputBox_use_TextEntry']:
class InputBox(widgets.WidgetBase):
"""
input box
"""
def __init__(self,
x: int, y: int, width: int, height: int,
message: str = '',
font_name: str = translate.微软等宽,
font_size: int = 15,
font_bold: bool = False,
font_italic: bool = False,
font_stretch: bool = False,
font_dpi: int = 100,
text_color: [int, int, int] = (187, 187, 187, 255),
out_line_color: [int, int, int] = (37, 116, 176),
cursor_color: [int, int, int] = (187, 187, 187),
select_color: [int, int, int] = (63, 115, 255),
out_line: int = 2,
batch: Batch = None,
group: Group = None):
if batch is None:
batch = Batch()
if group is None:
group = Group()
super().__init__(x, y, width, height)
self.enabled = False
self._text = message
self._cursor_poi = 0
self.font = font.load(name=font_name, size=font_size,
bold=font_bold, italic=font_italic, stretch=font_stretch,
dpi=font_dpi)
self.font_height = self.font.ascent - self.font.descent
self.out_bound = out_line
if DR_options['InputBox_use_TextEntry']:
# 基于IncrementalTextLayout的处理系统
self._doc = FormattedDocument(message)
# self._doc.set_style()
self._layout = IncrementalTextLayout(self._doc, self.font, width, height,
batch=batch, group=group)
self._input_box = widgets.TextEntry(x, y, width, height,
self._doc, self._layout,
batch=batch, group=group)
else:
# 基于Label的处理系统
self._input_box = Label(x=x + out_line, y=y + out_line,
width=width, height=self.font_height + self.out_bound * 2,
color=text_color,
font_name=font_name, font_size=font_size,
batch=batch, group=group,
text=message)
self._HTML_box = HTMLLabel(x=x + out_line, y=y + out_line + 30,
width=width, height=self.font_height + self.out_bound * 2,
batch=batch, group=group,
text=message)
self._out_box = Rectangle(x=x - out_line, y=y - out_line,
color=out_line_color,
width=width + (out_line * 2), height=height + (out_line * 2),
batch=batch, group=group)
self._光标 = Rectangle(x=x + out_line, y=y + out_line,
color=cursor_color,
width=1, height=self.font_height,
batch=batch, group=group)
self._选择框 = Rectangle(x=x, y=y, width=0, height=self.font_height,
color=select_color)
self._选择的字 = Label(x=x, y=y, width=0, height=self.font_height,
color=text_color,
font_name=font_name, font_size=font_size,
batch=batch, group=group,
text='')
"""
输入框的属性
"""
# 本身属性
@property
def text(self) -> str: # 输入框的文本
return self._text
@text.setter
def text(self, value) -> None:
assert type(value) is str, 'Input Box\'s text must be string!'
self._text = value
self._input_box.text = value
self._HTML_box.text = html.decode_text2HTML(value, show_style=True)
@property
def cursor_poi(self) -> int: # 光标位置
return self._cursor_poi
@cursor_poi.setter
def cursor_poi(self, value) -> None:
assert type(value) is int, 'Input Box\'s cursor poi must be int!'
self._cursor_poi = value
self._光标.x = self.x + self.out_bound + self._input_box.content_width
# 渲染时属性
@property
def opacity(self) -> int: # 透明度
return self._input_box.opacity
@opacity.setter
def opacity(self, value: int) -> None:
assert type(value) is int, 'Input Box\'s opacity must be int!'
self._input_box.opacity = value
self._out_box.opacity = value
self._选择的字.opacity = value
self._选择框.opacity = value
self._光标.opacity = value
@property
def visible(self) -> bool: # 是否可见
return self._input_box.visible
@visible.setter
def visible(self, value: bool) -> None:
assert type(value) is bool, 'Input Box\'s visible must be bool!'
self._input_box.visible = value
self._out_box.visible = value
self._选择的字.visible = value
self._选择框.visible = value
self._光标.visible = value
@property
def value(self) -> str:
return self._text
"""
事件调用
"""
def _update_position(self):
self._input_box.position = self._x + self.out_bound, self._y + self.out_bound
self._out_box.position = self._x - self.out_bound, self._y - self.out_bound
self._光标.position = self._x + self.out_bound, self._y + self.out_bound
# 输入东西
def on_text(self, text: str):
if self.enabled:
if text in ('\r', '\n'):
if self.text:
self.dispatch_event('on_commit', self.text)
else:
self.text = f'{self.text[:self.cursor_poi]}{text}{self.text[self.cursor_poi:]}'
self.cursor_poi += len(text)
# 移动光标
def on_text_motion(self, motion):
if self.enabled:
# 根据按键处理
# 单格移动光标(上下左右)
if motion in (key.MOTION_UP, key.MOTION_LEFT): # 往上一个移动
self.cursor_poi = max(0, self._cursor_poi - 1)
elif motion in (key.MOTION_DOWN, key.MOTION_RIGHT): # 往下一个移动
self.cursor_poi = min(len(self.text), self._cursor_poi + 1)
# 大前后移动(开头或结尾)
elif motion in (key.MOTION_BEGINNING_OF_LINE, key.MOTION_BEGINNING_OF_FILE, key.MOTION_PREVIOUS_PAGE): # 开头
self.cursor_poi = 0
elif motion in (key.MOTION_END_OF_LINE, key.MOTION_END_OF_FILE, key.MOTION_NEXT_PAGE): # 结尾
self.cursor_poi = len(self.text)
# 删除操作
elif motion == key.MOTION_BACKSPACE:
if self.text: # 如果有文字
self.text = f'{self.text[:self.cursor_poi - 1]}{self.text[self.cursor_poi:]}'
self.cursor_poi = max(0, self._cursor_poi - 1)
elif motion == key.MOTION_DELETE:
if self.text and self.cursor_poi != len(self.text) - 1: # 如果有文字,并且光标不在最后
self.text = f'{self.text[:self.cursor_poi]}{self.text[self.cursor_poi + 1:]}'
# 剪贴板操作
elif motion == key.MOTION_COPY:
pass
elif motion == key.MOTION_PASTE:
paste_text = paste()
self.text = f'{self.text[:self.cursor_poi]}{paste_text}{self.text[self.cursor_poi:]}'
self.cursor_poi += len(paste_text)
def on_text_motion_select(self, motion):
pass
def on_mouse_press(self, x, y, buttons, modifiers):
if self._check_hit(x, y) and self._input_box.visible:
self.enabled = True
else:
self.enabled = False
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
pass
def on_mouse_release(self, x, y, buttons, modifiers):
pass
def on_commit(self, text: str):
pass
InputBox.register_event_type('on_commit')
else:
class InputBox(widgets.TextEntry):
pass

View File

@ -1,47 +0,0 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
import os
import sys
import logging
if __name__ == '__main__': # been start will not run this
sys.path.append('/bin/libs')
sys.path.append('/bin')
from Difficult_Rocket.utils import tools
from Difficult_Rocket.utils.translate import tr
from Difficult_Rocket.api.delivery import Delivery
from Difficult_Rocket.utils.new_thread import new_thread
# TODO 改变服务端启动逻辑 0.6.0会写完的(
class Server:
def __init__(self, net_mode='local', Dev: Delivery = Delivery):
# father class __init__()
# mp.Process.__init__(self)
# logging
self.logger = logging.getLogger('server')
# value
self.process_id = 'Server'
self.process_name = 'server process'
# config
self.config = tools.load_file('configs/main.config')
self.dev = Dev
self.net_mode = net_mode
self.logger.info(tr.lang('server', 'setup.done'))
def run(self):
self.logger.info(tr.lang('server', 'os.pid_is').format(os.getpid(), os.getppid()))

View File

@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.22)
project(cprint VERSION 0.0.1 LANGUAGES C)
#
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_C_STANDARD 99)
#
add_compile_options(-O3)
add_compile_options(-Wall)
add_compile_options(-Werror)
#add_compile_options(-shared)
#add_compile_options(-o ../../cprint.dll)
# py3.8 path
include_directories(.)
include_directories(C:\\Users\\shenjack.SHENJACK-5600X\\AppData\\Local\\Programs\\Python\\Python38\\include\\.)
#
#add_executable(cprint cprint.c)
#
#add_executable(cprint cprint.c)
add_executable(py_cprint py_cprint.c)

View File

@ -0,0 +1,12 @@
Write-Output ==========_win-py3.8_==========
python3.8.exe ./setup.py build
Write-Output ==========_win-py3.10_==========
python3.10.exe ./setup.py build
Write-Output ==========_wsl-py3.8_==========
wsl.exe python3 setup.py build
Write-Output ==========_wsl-py3.10_==========
wsl.exe python3.10 setup.py build

View File

@ -0,0 +1,66 @@
import _winapi
import subprocess
import os
os.system('')
reset = '\033[0m'
print('A 000')
do = False
def rgb(r: int, g: int, b:int) -> tuple:
return 2, r, g, b
# i_list = list(range(30, 39, 1))
# # i_list = [39]
# j_list = list(range(40, 49, 1))
# # j_list = [49]
#
# for i in i_list:
# for j in j_list:
# print(f'\033[{i};{j}m{i}|{j} {reset}', end='|')
# print()
# print()
def color_print(*args):
args = [str(i) for i in args]
out = '|'.join(args)
line = ';'.join(args)
print(f'\033[{line}m{out}\033[0m')
if os.name == "nt":
from ctypes import windll
from ctypes.wintypes import BOOL, HANDLE, WORD
handle = _winapi.GetStdHandle(_winapi.STD_OUTPUT_HANDLE)
kernel32 = windll.LoadLibrary("Kernel32.dll")
SetConsoleAttribute = kernel32.SetConsoleTextAttribute
SetConsoleAttribute.argtypes = (HANDLE, WORD)
SetConsoleAttribute.restype = BOOL
# FOREGROUND_INTENSITY|FOREGROUND_RED
res: bool = SetConsoleAttribute(handle, 5)
print(res)
string = "Hello World!"
_winapi.WriteFile(handle, string.encode("utf-8"), 0)
else:
pass
# exit(0)
color_print(94)
color_print(41, 93)
color_print(36, 40)
print()
color_print(48, *rgb(200, 100, 20), 34)
color_print(48, *rgb(255, 161, 72))
color_print(48, *rgb(255, 161, 72), 38, *rgb(1, 50, 255))
color_print(48, *rgb(178, 112, 50), 38, *rgb(98, 96, 167))
print()
color_print(48, *rgb(100, 10, 10), )
exit(0)

View File

@ -0,0 +1,11 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
from colorama import Fore, Back, Style
print(Fore.RED + 'some red text')
print(Back.GREEN + 'and with a green background')
print(Style.DIM + 'and in dim text')
print(Style.RESET_ALL)
print('back to normal now')

View File

@ -0,0 +1,41 @@
import os
# include 目录
include_paths = ["C:\\Users\\shenjack.SHENJACK-5600X\\AppData\\Local\\Programs\\Python\\Python38\\include\\."]
# 编译选项
compile_options = {
"-shared": None,
"-O3": None,
"-Wall": None,
"-Werror": None,
"-o": "./py_cprint.dll"
}
include_command = "-I "
# 处理 include 目录命令
for path in include_paths:
include_command = "{}, {}".format(include_command, path)
else:
if len(include_paths) != 0:
include_command = include_command[:3] + include_command[4:]
compile_option_command = ""
# 处理编译选项
for option, key in compile_options.items():
if key is None:
compile_option_command = "{} {} ".format(compile_option_command, option)
else:
compile_option_command = "{} {} {}".format(compile_option_command, option, key)
print(include_command, compile_option_command)
compile_command = "gcc.exe ./py_cprint.c {}{}".format(include_command, compile_option_command)
print(compile_command)
os.system(compile_command)

View File

@ -0,0 +1,30 @@
//
// Created by shenjack on 2022/6/24.
//
//#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
int CcPrint(PyObject *self, PyObject *args, PyObject *kwargs){
char *print_str;
char *line_end = NULL; // 准备参数
static char *kwlist[] = {"some_stuf", "end", NULL}; // 准备参数列表
if(!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", kwlist, &print_str, &line_end)){
return 0;
};
return 1;
};
// 如果你非得调用我·····
int main(){
printf("aaaa");
if(false){
CcPrint(PyLong_FromLong(1), PyLong_FromLong(1), PyLong_FromLong(1));
};
return 0;
};

View File

@ -0,0 +1,9 @@
from objprint import objprint
from ctypes import cdll
cprint = cdll.LoadLibrary("./cprint.dll")
# objprint(cprint)

View File

@ -0,0 +1,65 @@
//
// Created by shenjack on 2022/7/6.
//
#define PY_SSIZE_T_CLEAN
#define Py_size long long int
#include <Python.h>
#include <stdint.h>
static PyObject *pycprint_print(PyObject *self, PyObject *args){
const char *text;
if(!PyArg_ParseTuple(args, "s", &text)){ // 解析 text
return NULL;
};
printf("%s", text);
Py_RETURN_NONE;
};
static PyObject *pycpint_printf(PyObject *self, PyObject *args, PyObject *kwargs){
printf("args == NULL: %d\n", args == NULL);
printf("kwargs == NULL: %d\n", kwargs == NULL);
const char *end = "\n";
const char *sep = " ";
if(args != NULL){ // 传入了字符串
Py_ssize_t text_len = PyTuple_Size(args);
printf("text_len = %lld\n", (Py_size)text_len);
char *text_list;
char **text_lists = malloc(sizeof(char) * text_len);
const char *args_text = malloc(sizeof(char) * text_len);
PyArg_ParseTuple(args, , &);
};
if(kwargs != NULL){ // 传入了 end 或者 sep
Py_ssize_t kwargs_len = PyDict_Size(kwargs);
printf("kwargs_len = %lld\n", (Py_size) kwargs_len);;
char *kwlist[] = {"end", "sep", NULL};
PyArg_ParseTupleAndKeywords(args, kwargs, "ss", kwlist, &end, &sep);
};
Py_ssize_t text_len = PyTuple_Size(args);
printf("%s", end);
Py_RETURN_NONE;
};
static PyMethodDef PyCprintMethods[] = {
{"print", pycprint_print, METH_VARARGS, "直接使用c的printf输出"},
{"printf", (PyCFunction)(void(*))pycpint_printf, METH_VARARGS | METH_KEYWORDS,
"传入类似py print然后进行format的print"},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef pycprintmodule = {
PyModuleDef_HEAD_INIT,
"pycprint",
"直接调用c的printf",
-1,
PyCprintMethods
};
PyMODINIT_FUNC PyInit_pycprint(void){
return PyModule_Create(&pycprintmodule);
}

View File

@ -0,0 +1,17 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
from build import pycprint
pycprint.print("aaa\n")
pycprint.printf("aaa\n", "aaa", "aaa", end='')
print()
pycprint.printf()
pycprint.printf("aaa\n", "aaa", "aaa")

View File

@ -4,10 +4,6 @@
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
def print(text: str) -> None: ... # 直接调用fprint
def printf(text: str) -> None: ... # 测试中

View File

@ -0,0 +1,30 @@
from setuptools import setup, Extension
import shutil
import os
pycprint = Extension('pycprint',
sources=['py_cprint.c'])
setup(name='PyCprint',
version='0.0.1',
author='shenjack',
author_email='3695888@qq.com',
description='这是一个用于直接调用c的printf的库',
ext_modules=[pycprint])
def dir_not_temp(path: str):
return path.find('temp') and os.path.isdir(os.path.join('build', path))
build_dir = os.listdir('./build')
build_dir = list(filter(dir_not_temp, build_dir))
# 用列表推导式把 是文件夹 且 名字里没有 temp 的抽出来
print(build_dir)
os.chdir('build')
# 把运行路径迁移过去方便copy
for build in build_dir:
copy = os.listdir(build)
shutil.copy(os.path.join(build, copy[0]), './')

View File

@ -0,0 +1,15 @@
Write-Output ---------------------开始测试---------------------
Write-Output ==========_win-py3.8_==========
python3.8.exe ./py_cprint.py
Write-Output ==========_win-py3.10_==========
python3.10.exe ./py_cprint.py
Write-Output ==========_wsl-py3.8_==========
wsl.exe python3 py_cprint.py
Write-Output ==========_wsl-py3.10_==========
wsl.exe python3.10 ./py_cprint.py
Write-Output ---------------------结束测试---------------------

View File

@ -6,26 +6,15 @@
- [GitHub](https://github.com/shenjackyuanjie/Difficult-Rocket)
- [gitee](https://gitee.com/shenjackyuanjie/Difficult-Rocket)
- [npm](https://www.npmjs.com/package/Difficult-Rocket)
# 本分支是 SRtool 的开发分支 与Difficult Rocket基本无关
[![Generic badge](https://img.shields.io/badge/SemVer-2.0.0-blue.svg)](https://Semver.org/)
[![Generic badge](https://img.shields.io/badge/编写于_Python_版本-3.8.10-blue.svg)](https://Python.org)
[![Generic badge](https://img.shields.io/badge/编写于_Pyglet_版本-2.0dev11-blue.svg)](https://pyglet.org)
[![Generic badge](https://img.shields.io/badge/Python-_3.8_|_3.9_|_3.10_-blue.svg)](https://Python.org)
## 版本
[![Generic badge](https://img.shields.io/badge/Release-0.6.1-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
[![Generic badge](https://img.shields.io/badge/Pre_Release-0.6.1-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
[![Generic badge](https://img.shields.io/badge/Devloping-0.6.2-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
## English README please look [here](../README.md)
> 这是一个用Python制作的类Simple Rocket游戏(简称:火箭模拟器)
## 优势
> 相对于原版SR比较“轻量化”
- 因为窗口框架、整体结构、API接口跟DR相同所以作为Difficult Rocket的分支存在
- 以后DR的API和库更新也会更新到这里
- 另外,这里的很多函数就直接中文编程了
- 另外的话,这个分支就不会怎么对英文做支持了(lazy)
- pyglet的库还是会照常更新的
-
## [计划特性列表](./plan_features)
- [microsoft TODO](https://to-do.microsoft.com/sharing?InvitationToken=Q6SN1kdtitK8cwFktFl71gSnsRMNmrH7CC7kHY_Tq6ReMRwHgInP4_q5ie2IwrHx8)

BIN
SRtool-py1.0.zip Normal file

Binary file not shown.

25
SRtool/__init__.py Normal file
View File

@ -0,0 +1,25 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021 by shenjackyuanjie
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
version = '1.1'
__version__ = version
playing = False
if playing:
from .api import new_thread
@new_thread('think')
def think(some_thing_to_think):
gotcha = 'think_result'
return gotcha

42
SRtool/api/Exp.py Normal file
View File

@ -0,0 +1,42 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021 by shenjackyuanjie
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
__all__ = ['TexturesError',
'LanguageError',
'CommandError',
'TestError']
class Error(Exception):
"""基础 Exception"""
pass
class TexturesError(Error):
"""材质相关 error"""
pass
class CommandError(Error):
"""命令解析相关 error"""
pass
class LanguageError(Error):
"""lang 文件相关 error"""
pass
class TestError(Error):
"""就像名字一样 用于测试的 error"""
pass

View File

@ -7,7 +7,7 @@
import functools
import inspect
import threading
from Difficult_Rocket import crash
from SRtool import crash
from typing import Optional, Callable
"""

23
SRtool/api/thread.py Normal file
View File

@ -0,0 +1,23 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021 by shenjackyuanjie
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
import threading
from SRtool import crash
class Threads(threading.Thread):
def run(self):
if crash.record_thread:
crash.all_thread.append(self)
super().run()

359
SRtool/api/tools.py Normal file
View File

@ -0,0 +1,359 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021 by shenjackyuanjie
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
import os
import sys
import time
import math
import decimal
import logging
import traceback
import configparser
from typing import List
from xml.dom.minidom import parse
if __name__ == '__main__': # been start will not run this
sys.path.append('/bin/libs')
sys.path.append('/bin')
from libs import json5
# logger
tools_logger = logging.getLogger('part-tools')
"""
file configs
"""
def file_type(file_name):
f_type = file_name[file_name.rfind('.') + 1:] # 从最后一个.到末尾 (截取文件格式)
return f_type
def report_file_error(filetype: str, error_type, filename: str, stack: any):
error = traceback.format_exc()
if isinstance(error_type, FileNotFoundError):
log = 'no {} file was found!: \n file name: {} \n file type: {} \n stack: {} \n traceback: {}'.format(filetype, filename, filetype, stack,
error)
elif isinstance(error_type, KeyError):
log = 'no stack in %s file: %s \n file type: %s \n stack: %s' % (filetype, filename, filetype, stack)
else:
log = 'some error has been found! \n error type: %s \n file name: %s \n file type: %s \n stack: %s' % (error_type, filename, filetype, stack)
tools_logger.exception(log)
def load_file(file_name: str, stack=None) -> dict:
f_type = file_name[file_name.rfind('.') + 1:] # 从最后一个.到末尾 (截取文件格式)
try:
if (f_type == 'json5') or (f_type == 'json'):
try:
with open(file_name, 'r', encoding='utf-8') as jf: # jf -> json file
rd = json5.load(jf)
except UnicodeDecodeError:
with open(file_name, 'r', encoding='gbk') as jf:
rd = json5.load(jf)
tools_logger.info('文件 %s 解码错误已重新使用gbk编码打开' % file_name)
if stack is not None:
rd = rd[stack]
return rd
elif f_type == 'xml':
xml_load = parse(file_name)
if stack is not None:
xml_get = xml_load.getElementsByTagName(stack)
return xml_get
else:
return xml_load
elif (f_type == 'config') or (f_type == 'conf') or (f_type == 'ini'):
cp = configparser.ConfigParser() # cp -> config parser
cp.read(file_name) # config parser -> reader
rd = {}
for section in cp.sections():
rd[section] = {}
for data in cp[section]:
rd[section][data] = cp[section][data]
if stack:
rd = rd[stack]
return rd
except FileNotFoundError:
log = 'no {} file was found!: \n file name: {} \n file type: {} \n stack: {}'.format(f_type, file_name, f_type, stack)
tools_logger.error(log)
raise
except KeyError:
log = 'no stack in {} file {} was found! \n file type: {} \n file name: {} \n stack: {}'.format(f_type, file_name, f_type, file_name, stack)
tools_logger.error(log)
raise
except Exception as exp:
log = 'some error has been found!\n error type: {} \n file name: {} \n file type: {} \n stack: {}'.format(type(exp), file_name, f_type, stack)
tools_logger.error(log)
raise
# main config
main_config_file = load_file('./configs/main.config')
def get_At(name, in_xml, need_type=str):
"""
get Attribute from a XML tree
will raise TypeError if input is not str or list
XML no! Json5 yes!
"""
name_type = type(name)
if name_type == list:
At_list = []
for need_name in name:
if in_xml.hasAttribute(need_name):
get = in_xml.getAttribute(need_name)
At_list.append(need_type(get))
else:
continue
return At_list
elif name_type == str:
if in_xml.hasAttribute(name):
At = in_xml.getAttribute(name)
else:
return None
else:
raise TypeError('only str and list type is ok but you give me a' + name_type + 'type')
return need_type(At)
def default_name_handler(name_: str) -> str:
"""
won't change the string
just return one
"""
name = name_
name = name.replace('{time.time}', str(time.time()))
name = name.replace('{dir}', str(os.getcwd()))
name = name.replace('{py_v}', str(sys.version.split(' ')[0]))
name = name.replace('{version}', str(main_config_file['runtime']['version']))
name = name.replace('{write_v}', str(main_config_file['runtime']['write_py_v']))
return name
def name_handler(name: str, formats: dict = None) -> str:
if formats is None:
return default_name_handler(name)
name = default_name_handler(name)
for need_replace in formats:
replace = formats[need_replace]
if need_replace == '{date}':
if '{date}' in formats:
replace = time.strftime(formats['{date}'], time.gmtime(time.time()))
else:
replace = time.strftime(main_config_file['runtime']['date_fmt'], time.gmtime(time.time()))
name = name.replace(need_replace, replace)
return name
"""
some tools
"""
yes = ['true', '1', 1, 1.0, True]
no = ['false', '0', 0, 0.0, False, None]
def format_bool(thing) -> bool:
"""
:param thing 啥都行只要是能传进来的都可以
如果看起来像"True" 比如 'true','1',1
就返回 True
如果看起来像"False" 比如 'false','0',0
就返回 False
都不像就 raise TypeError
感谢来自MCDReforged的各位同志你能在MCDR群里聊除了MCDR的任何东西
"""
if (thing in yes) or (isinstance(thing, str) and thing.lower() in yes):
return True
elif (thing in no) or (isinstance(thing, str) and thing.lower() in no):
return False
else:
raise TypeError("Need a 'like bool' not a {}".format(thing))
level_ = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL',
logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL]
def log_level(level):
if level in level_:
if (level == 'DEBUG') or (level == logging.DEBUG):
return logging.DEBUG
if (level == 'INFO') or (level == logging.INFO):
return logging.INFO
if (level == 'WARNING') or (level == logging.WARNING):
return logging.WARNING
if (level == 'ERROR') or (level == logging.ERROR):
return logging.ERROR
if (level == 'CRITICAL') or (level == logging.CRITICAL):
return logging.CRITICAL
else:
raise ValueError('Need a like logging.level thing not anything else')
# linear_algebra
def C_R_P(position, degrees): # stand for calculation
"""
very thanks for lenny from pyglet developer
https://github.com/LennyPhoenix
this part of code is write by him
"""
radians = degrees * (math.pi / 180)
cos = math.cos(radians)
sin = math.sin(radians)
rotated_pos = (position[0] * cos - position[1] * sin, position[0] * sin + position[1] * cos)
return rotated_pos
"""
Physics calculation
"""
def is_decimal(A: any) -> bool:
if isinstance(A, decimal.Decimal):
return False
else:
return True
def F_D(A: decimal, B: decimal) -> decimal:
if is_decimal(A) and is_decimal(B):
return A / B
def F_Mu(A: decimal, B: decimal) -> decimal:
if is_decimal(A) and is_decimal(B):
return A * B
def F_Mi(A: decimal, B: decimal) -> decimal:
if is_decimal(A) and is_decimal(B):
return A - B
def F_A(A: decimal, B: decimal) -> decimal:
if is_decimal(A) and is_decimal(B):
return A + B
def D_C(listA: list, listB: list): # stand for Duplicate check
"""
usage:\n
input two list\n
the fun will do duplicate check and sort then\n
the fun won't return any thing just change the list now
"""
for unit in listB:
if unit in listA:
listA.remove(unit)
listB.remove(unit)
else:
continue
listA.sort()
listB.sort()
def S_C_float_check(SC): # stand for Scientific notation's float check
"""
formats:
SC list format:docs.basic_config.json:basic_number"""
while SC[0] >= 10:
SC[0] = F_D(SC[0], 10)
SC[1] += 1
while SC[0] < 1:
SC[0] = F_Mu(SC[0], 10)
SC[1] -= 1
def S_N_M(*SN): # stand for Scientific notation multiple
"""
formats:
A & B & C list format:docs.basic_config.json:basic_number"""
if len(SN) < 2:
raise TypeError('it need more than 1!')
elif len(SN) == 2:
return __S_N_M(SN[0], SN[1])
else:
R = __S_N_M(SN[0], SN[1])
for A in SN[2:]:
R = __S_N_M(R, A)
return R
def __S_N_M(A, B):
"""
formats:
A & B list format:docs.basic_config.json:basic_number"""
R = [F_Mu(A[0], B[0]), A[1] + B[1]]
S_C_float_check(R)
Unit1, Unit2 = A[2] + B[2], A[3] + B[3]
if Unit1 is None:
Unit1 = []
D_C(Unit1, Unit2)
R += [Unit1, Unit2]
return R
def S_N_D(A, B): # stand for Scientific notation divided
"""
formats:
A & B list format:docs.basic_config:basic_number"""
R = [F_D(A[0], B[0]), A[1] - B[1]]
S_C_float_check(R)
Unit1, Unit2 = A[2] + B[3], A[3] + B[2]
if Unit1 is None:
Unit1 = []
D_C(Unit1, Unit2)
R += [Unit1, Unit2]
return R
def G_C(M, m, R, G): # stand for gravity calculation
"""
formats:
M : ship's mass
m : planet's mass
R : distance to the planet
G : Gravitational constant
M & m & R format: docs.basic_config:basic_number
"""
g = configs.basic_force()
A = S_N_M(M, m, G)
g = S_N_D(A, S_N_M(R, R))
return g
def distance(A, B):
"""
formats:
A & B format: docs.basic_config:basic_poi
"""
poi_dis = configs.basic_poi()
for x in A, B:
x = decimal.Decimal(str(x))
xd = A[0] - B[0]
yd = A[1] - B[1]
poi_dis[0] = xd
poi_dis[1] = yd
# 勾股定理
poi_dis[0] **= 2
poi_dis[1] **= 2
poi_dis.append(poi_dis[0] + poi_dis[1])
poi_dis[2] **= 0.5
return poi_dis[2]

414
SRtool/client.py Normal file
View File

@ -0,0 +1,414 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021 by shenjackyuanjie
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
# system function
import os
import sys
import time
import logging
import traceback
import configparser
from decimal import Decimal
from fractions import Fraction
if __name__ == '__main__': # been start will not run this
sys.path.append('/bin/libs')
sys.path.append('/bin')
# SR tool function
from SRtool import translate
from SRtool.api.Exp import *
from SRtool.translate import tr
from SRtool.command import line
from SRtool.api import tools
from SRtool.api.new_thread import new_thread
# libs function
from libs import pyglet
from libs import xmltodict
from libs.pyglet import shapes
from libs.pyglet.graphics import Batch
from libs.pyglet.window import key, mouse, Window
class Client:
def __init__(self):
start_time = time.time_ns()
# logging
self.logger = logging.getLogger('client')
# config
self.config = tools.load_file('configs/main.config')
# value
self.process_id = 'Client'
self.process_name = 'Client process'
self.process_pid = os.getpid()
self.caption = tools.name_handler(self.config['window']['caption'], {'version': self.config['runtime']['version']})
self.window = ClientWindow(width=int(self.config['window']['width']),
height=int(self.config['window']['height']),
fullscreen=tools.format_bool(self.config['window']['full_screen']),
caption=self.caption,
resizable=tools.format_bool(self.config['window']['resizable']),
visible=tools.format_bool(self.config['window']['visible']),
file_drops=True)
self.logger.info(tr.lang('client', 'setup.done'))
end_time = time.time_ns()
self.use_time = end_time - start_time
self.logger.info(tr.lang('client', 'setup.use_time').format(Decimal(self.use_time) / 1000000000))
self.logger.debug(tr.lang('client', 'setup.use_time_ns').format(self.use_time))
def start(self):
self.window.start_game() # 游戏启动
# TODO 写一下服务端启动相关,还是需要服务端啊
class ClientWindow(Window):
def __init__(self, *args, **kwargs):
start_time = time.time_ns()
super().__init__(*args, **kwargs)
"""
:param dev_list: 共享内存
:param dev_dic: 共享内存
:param logger: logger
:param net_mode: 网络模式 # local / ip
"""
# logging
self.logger = logging.getLogger('client')
# value
self.run_input = False
self.center_x = self.width // 2
self.center_y = self.height // 2
# configs
pyglet.resource.path = ['./textures/', './files']
pyglet.resource.reindex()
self.main_config = tools.load_file('configs/main.config')
self.game_config = tools.load_file('configs/game.config')
# dic
self.environment = {}
self.textures = {} # all textures
self.runtime = {}
self.坐标轴 = {'batch': Batch()}
self.part_list = {}
self.坐标点 = {'x': {}, 'y': {}}
# FPS
self.FPS = Decimal(int(self.main_config['runtime']['fps']))
self.SPF = Decimal('1') / self.FPS
# batch
self.part_batch = Batch()
self.label_batch = Batch()
# frame
self.frame = pyglet.gui.Frame(self, order=20)
self.M_frame = pyglet.gui.MovableFrame(self, modifier=key.LCTRL)
self.back_ground = shapes.Rectangle(0, 0, self.width, self.height, color=(60, 63, 65))
icon = pyglet.resource.image('icon.png')
self.set_icon(icon)
del icon
# setup
self.setup()
# 命令显示
self.command_group = pyglet.graphics.Group(0)
self.command = line.CommandLine(x=50, y=30, # 实例化
width=self.width - 100, height=40,
length=int(self.game_config['command']['show']),
batch=self.label_batch, group=self.command_group)
self.push_handlers(self.command)
self.command.set_handler('on_command', self.on_command)
self.command.set_handler('on_message', self.on_message)
# self.input_box = InputBox(x=50, y=30, width=300, height=20,
# batch=self.label_batch) # 实例化
# self.push_handlers(self.input_box)
# self.input_box.enabled = True
# fps显示
self.fps_label = pyglet.text.Label(x=10, y=self.height - 10,
width=self.width - 20, height=20,
anchor_x='left', anchor_y='top',
font_name=translate.微软等宽无线, font_size=20,
multiline=True,
batch=self.label_batch, group=self.command_group)
# 设置刷新率
pyglet.clock.schedule_interval(self.update, float(self.SPF))
# 完成设置后的信息输出
self.logger.info(tr.lang('window', 'setup.done'))
self.logger.info(tr.lang('window', 'os.pid_is').format(os.getpid(), os.getppid()))
end_time = time.time_ns()
self.use_time = end_time - start_time
self.logger.info(tr.lang('window', 'setup.use_time').format(Decimal(self.use_time) / 1000000000))
self.logger.debug(tr.lang('window', 'setup.use_time_ns').format(self.use_time))
def setup(self):
self.load_fonts()
self.加载坐标轴()
def 加载坐标轴(self):
self.坐标轴['x'] = shapes.Line(x=0, y=self.center_y,
x2=self.width, y2=self.center_y,
width=3,
batch=self.坐标轴['batch'])
self.坐标轴['y'] = shapes.Line(x=self.center_x, y=0,
x2=self.center_x, y2=self.height,
width=3,
batch=self.坐标轴['batch'])
self.坐标轴['x'].color = (204, 102, 110)
self.坐标轴['x'].opacity = 250
self.坐标轴['y'].color = (204, 102, 110)
self.坐标轴['y'].opacity = 250
self.坐标轴['scale'] = 60
self.坐标轴['long'] = 5
self.坐标轴['point_opacity'] = 250
self.加载坐标点(True)
# @new_thread('坐标点加载')
def 加载坐标轴上的点(self, name: str):
del self.坐标点[name]
self.坐标点[name] = {}
for i in range(-self.坐标轴[f'scale_{name}'], self.坐标轴[f'scale_{name}'] + 1):
if name == 'x':
x, y, x2, y2 = self.center_x + (i * self.坐标轴['scale']), self.center_y - self.坐标轴['long'], \
self.center_x + (i * self.坐标轴['scale']), self.center_y + self.坐标轴['long']
else:
x, y, x2, y2 = self.center_x + self.坐标轴['long'], self.center_y + (i * self.坐标轴['scale']), \
self.center_x - self.坐标轴['long'], self.center_y + (i * self.坐标轴['scale'])
self.坐标点[name][i] = shapes.Line(x=x, y=y, x2=x2, y2=y2, width=3,
color=(41, 123, 203),
batch=self.坐标轴['batch'])
self.坐标点[name][i].opacity = self.坐标轴['point_opacity']
def 加载坐标点(self, flush: bool = False):
if 'scale_x' in self.坐标轴:
if flush or self.center_x // self.坐标轴['scale'] != self.坐标轴['scale_x']:
# 如果坐标轴的缩放比例发生变化 或者坐标轴的位置发生变化 或窗口长度发生变化
self.坐标轴['scale_x'] = self.center_x // self.坐标轴['scale']
self.加载坐标轴上的点('x')
else:
self.坐标轴['scale_x'] = self.center_x // self.坐标轴['scale']
self.加载坐标轴上的点('x')
if 'scale_y' in self.坐标轴:
if flush or self.center_y // self.坐标轴['scale'] != self.坐标轴['scale_y']:
self.坐标轴['scale_y'] = self.center_y // self.坐标轴['scale']
self.加载坐标轴上的点('y')
else:
self.坐标轴['scale_y'] = self.center_y // self.坐标轴['scale']
self.加载坐标轴上的点('y')
def load_fonts(self):
fonts_folder_path = self.main_config['runtime']['fonts_folder']
# 加载字体路径
for fonts_folders in os.listdir(fonts_folder_path):
# 从字体路径内加载字体文件夹
for files in os.listdir(os.path.join(fonts_folder_path, fonts_folders)):
# 从字体文件夹加载字体(或是字体类文件夹)
if os.path.isfile(os.path.join(fonts_folder_path, fonts_folders, files)):
# 如果是字体文件,则直接加载
pyglet.font.add_file(os.path.join(fonts_folder_path, fonts_folders, files))
else: # 否则,遍历加载字体类文件夹并加载
for font in os.listdir(os.path.join(fonts_folder_path, fonts_folders, files)):
pyglet.font.add_file(os.path.join(fonts_folder_path, fonts_folders, files, font))
# @new_thread('window load_editor')
def load_Editor(self):
pass
def start_game(self) -> None:
self.run_input = True
self.read_input()
pyglet.app.run()
@new_thread('window read_input', daemon=True)
def read_input(self):
self.logger.debug('read_input start')
while self.run_input:
get = input()
if get in ('', ' ', '\n', '\r'):
continue
if get == 'stop':
self.run_input = False
try:
self.on_command(line.CommandText(get))
except CommandError:
self.logger.error(traceback.format_exc())
self.logger.debug('read_input end')
@new_thread('window save_info')
def save_info(self):
config_file = configparser.ConfigParser()
config_file.read('configs/main.config')
config_file['window']['width'] = str(self.width)
config_file['window']['height'] = str(self.height)
config_file.write(open('configs/main.config', 'w', encoding='utf-8'))
"""
draws and some event
"""
def update(self, tick: float):
decimal_tick = Decimal(str(tick)[:10])
def on_draw(self, *dt):
self.clear()
self.back_ground.draw()
self.draw_batch()
def on_resize(self, width: int, height: int):
super().on_resize(width, height)
self.fps_label.y = height - 10
self.center_x = width // 2
self.center_y = height // 2
# 刷新坐标轴的位置
self.坐标轴['x'].position = [0, self.center_y,
self.width, self.center_y]
self.坐标轴['y'].position = [self.center_x, 0,
self.center_x, self.height]
# 刷新坐标轴上的点的坐标
self.坐标轴['scale'] = 60
self.加载坐标点()
for x in range(-self.坐标轴['scale_x'], self.坐标轴['scale_x'] + 1):
self.坐标点['x'][x].position = (x * self.坐标轴['scale'] + self.center_x, self.center_y - 5,
x * self.坐标轴['scale'] + self.center_x, self.center_y + 5)
for y in range(-self.坐标轴['scale_y'], self.坐标轴['scale_y'] + 1):
self.坐标点['y'][y].position = (self.center_x - 5, y * self.坐标轴['scale'] + self.center_y,
self.center_x + 5, y * self.坐标轴['scale'] + self.center_y)
# 刷新加载出来的图片的坐标
if 'textures' in self.runtime:
self.runtime['textures'].position = (self.center_x - (self.runtime['textures'].width / 2),
self.center_y - (self.runtime['textures'].height / 2))
def draw_batch(self):
self.part_batch.draw()
self.label_batch.draw()
if 'textures' in self.runtime:
self.坐标轴['batch'].draw()
def load_textures(self, path: str):
try:
image = pyglet.image.load(path)
x = self.center_x - (image.width / 2)
y = self.center_y - (image.height / 2)
self.runtime['textures'] = pyglet.sprite.Sprite(x=x, y=y,
img=image, batch=self.part_batch)
del image
except FileNotFoundError:
self.logger.error(tr.lang('window', 'textures.file_not_found').format(path))
def load_xml(self, path: str):
try:
with open(path, encoding='utf-8') as xml_file:
xml_json = xmltodict.parse(xml_file.read())
except FileNotFoundError:
self.logger.error(tr.lang('window', 'xml.file_not_found').format(path))
"""
command line event
"""
def on_command(self, command: line.CommandText):
self.logger.info(tr.lang('window', 'command.text').format(command))
if command.match('stop'):
self.dispatch_event('on_close', 'command') # source = command
elif command.match('default'):
self.set_size(int(self.config_file['window_default']['width']), int(self.config_file['window_default']['height']))
elif command.match('textures'):
if command.match('file'):
name = command.text
self.load_textures(name)
elif command.match('set'):
if command.match('long'):
self.坐标轴['long'] = int(command)
self.加载坐标点(True)
elif command.match('opacity'):
self.坐标轴['point_opacity'] = int(command)
self.加载坐标点(True)
elif command.match('scale'):
self.坐标轴['scale'] = int(command)
self.加载坐标点(True)
def on_message(self, message: line.CommandLine.text):
self.logger.info(tr.lang('window', 'message.text').format(message))
def on_file_drop(self, x, y, paths: str):
f_type = tools.file_type(paths[0])
if f_type in ('png', 'jpg', 'jpeg'):
self.load_textures(paths[0])
self.logger.info(tr.lang('window', 'file.drop').format(paths))
"""
keyboard and mouse input
"""
def on_mouse_motion(self, x, y, dx, dy) -> None:
pass
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers) -> None:
pass
def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
self.logger.debug(f'{x}, {y}, {scroll_x}, {scroll_y}')
if 'textures' in self.runtime:
if self.runtime['textures'].scale > 0.1 and self.runtime['textures'].scale + (scroll_y * 0.1) > 0.1:
self.runtime['textures'].scale += (scroll_y * 0.1)
elif scroll_y > 0:
self.runtime['textures'].scale += (scroll_y * 0.1)
# 设置self.runtime['textures']的位置
self.runtime['textures'].position = (self.center_x - (self.runtime['textures'].width / 2),
self.center_y - (self.runtime['textures'].height / 2))
def on_mouse_press(self, x, y, button, modifiers) -> None:
self.logger.debug(tr.lang('window', 'mouse.press').format([x, y], tr.lang('window', 'mouse.{}'.format(mouse.buttons_string(button)))))
if 'textures' in self.runtime:
# 在点击的位置添加一个红色的半径为3的圆
self.坐标轴['point'] = shapes.Circle(x, y, 3, color=(255, 255, 255), batch=self.坐标轴['batch'])
x = Decimal(x - self.center_x)
y = Decimal(y - self.center_y)
scale_x = Fraction(x / self.坐标轴['scale'])
scale_y = Fraction(y / self.坐标轴['scale'])
self.logger.info(f'x: {float(scale_x)}|{scale_x.limit_denominator(1000)} y: {float(scale_y)}|{scale_y.limit_denominator(1000)}')
def on_mouse_release(self, x, y, button, modifiers) -> None:
self.logger.debug(tr.lang('window', 'mouse.release').format([x, y], tr.lang('window', 'mouse.{}'.format(mouse.buttons_string(button)))))
def on_key_press(self, symbol, modifiers) -> None:
if symbol == key.ESCAPE and not (modifiers & ~(key.MOD_NUMLOCK |
key.MOD_CAPSLOCK |
key.MOD_SCROLLLOCK)):
self.dispatch_event('on_close')
self.logger.debug(tr.lang('window', 'key.press').format(key.symbol_string(symbol), key.modifiers_string(modifiers)))
def on_key_release(self, symbol, modifiers) -> None:
self.logger.debug(tr.lang('window', 'key.release').format(key.symbol_string(symbol), key.modifiers_string(modifiers)))
def on_text(self, text):
if text == '\r':
self.logger.debug(tr.lang('window', 'text.new_line'))
else:
self.logger.debug(tr.lang('window', 'text.input').format(text))
if text == 't':
pass
# self.input_box.enabled = True
def on_text_motion(self, motion):
motion_string = key.motion_string(motion)
self.logger.debug(tr.lang('window', 'text.motion').format(motion_string))
def on_text_motion_select(self, motion):
motion_string = key.motion_string(motion)
self.logger.debug(tr.lang('window', 'text.motion_select').format(motion_string))
def on_close(self, source: str = 'window') -> None:
self.logger.info(tr.lang('window', 'game.stop_get').format(tr.lang('window', f'game.{source}_stop')))
self.logger.info(tr.lang('window', 'game.stop'))
if self.run_input:
self.run_input = False
self.save_info()
super().on_close()
self.logger.info(tr.lang('window', 'game.end'))

View File

@ -1,6 +1,6 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# Copyright © 2021 by shenjackyuanjie
# All rights reserved
# -------------------------------
@ -11,24 +11,72 @@ github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
# system function
import re
import time
import logging
from typing import Union
from decimal import Decimal
# from DR
from utils import translate
from Difficult_Rocket.utils import new_thread
from Difficult_Rocket.command.api import CommandText
from SRtool import translate
from SRtool.api.new_thread import new_thread
# from libs.pyglet
from libs import pyglet
from libs.pyglet import font
from libs.pyglet.text import Label
from libs.pyglet.window import key
from libs.pyglet.gui import widgets
from libs.pyglet.graphics import Batch, Group
logger = logging.getLogger('command_line')
class CommandText:
"""
CommandLine返回的字符可以用来搜索
"""
def __init__(self, text: str):
self.text = text
def find(self, text: str) -> bool:
finding = re.match(text, self.text)
if finding:
return True
else:
return False
def match(self, text: str) -> bool:
finding = re.match(text, self.text)
print(self.text + '|' + text)
if finding: # 如果找到了
try:
next_find = self.text[finding.span()[1]]
# 这里try因为可能匹配到的是字符串末尾
except IndexError:
next_find = ' '
# 直接过滤掉
print(self.text + '|' + text + '|' + next_find)
if next_find == ' ':
self.text = self.text[finding.span()[1] + 1:]
print(self.text + text + next_find)
return True
# 将匹配到的字符串,和最后一个匹配字符后面的字符删除(相当暴力的操作)
return False
else:
return False
def greedy(self, ):
pass
def __str__(self):
return str(self.text)
def __int__(self):
return int(self.text)
class CommandLine(widgets.WidgetBase):
"""
@ -68,7 +116,7 @@ class CommandLine(widgets.WidgetBase):
self._line = Label(x=x, y=y, batch=batch, text=self.text,
color=(100, 255, 255, 255),
anchor_x='left', anchor_y='bottom',
font_size=font_size, font_name=translate.微软等宽,
font_size=font_size, font_name=translate.鸿蒙简体,
group=fg_group)
self._label = [Label(x=x + 10, y=y + self.command_distance + (line * self.command_split), batch=batch, text='a',
anchor_x='left', anchor_y='bottom',
@ -186,8 +234,6 @@ class CommandLine(widgets.WidgetBase):
"""
def on_text(self, text):
# 这里的大部分东西都会在最近被重写
# TODO 重写成基于新的 InputBox 的解析
if self.editing:
if text in ('\r', '\n'): # goto a new line
if not self.text:
@ -195,7 +241,7 @@ class CommandLine(widgets.WidgetBase):
elif self.text[0] == self._command_text:
self.dispatch_event('on_command', CommandText(self.text[1:]))
else:
self.dispatch_event('on_message', CommandText(self.text))
self.dispatch_event('on_message', self.text)
# on_message 和 on_command 可能会覆盖 self.text 需要再次判定
if self.text:
self.command_view = -1

101
SRtool/guis/widgets.py Normal file
View File

@ -0,0 +1,101 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021 by shenjackyuanjie
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
from SRtool import translate
from libs import pyglet
from libs.pyglet import font
from libs.pyglet.text import Label
from libs.pyglet.gui import widgets
from libs.pyglet.sprite import Sprite
from libs.pyglet.shapes import Rectangle
from libs.pyglet.graphics import Batch, Group
from libs.pyglet.image import AbstractImage
__all__ = ['Parts']
class Parts(widgets.WidgetBase):
"""
parts
"""
def __init__(self,
x: int,
y: int,
width: int,
height: int,
textures: AbstractImage,
batch: Batch,
parts_data: dict):
super().__init__(x, y, width, height)
self.sprite = Sprite(img=textures, x=x, y=y, batch=batch)
self._value = 0
class InputBox(widgets.WidgetBase):
"""
input box
"""
def __init__(self,
x: int,
y: int,
width: int,
height: int,
message: str = '',
font_name: str = translate.鸿蒙简体,
font_size: int = 15,
text_color: [int, int, int] = (0, 0, 0, 255),
out_line_color: [int, int, int] = (255, 255, 255),
out_line: int = 2,
batch: Batch = Batch(),
group: Group = Group()):
super().__init__(x, y, width, height)
self._text = message
self.text = self._text
self.字体 = font.load(font_name, font_size)
self.字高 = self.字体.ascent - self.字体.descent
self.外框距离 = out_line
self._输入框 = Label(x=x + out_line, y=y + out_line,
width=width, height=height,
color=text_color,
font_name=font_name, font_size=font_size,
batch=batch, group=group,
text=message)
self._外框 = Rectangle(x=x-out_line, y=y-out_line,
color=out_line_color,
width=width + (out_line * 2), height=height + (out_line * 2),
batch=batch, group=group)
self._光标 = Rectangle(x=x+out_line, y=y+out_line,
width=1, height=self.字高,
batch=batch, group=group)
@property
def text(self):
return self._text
@text.setter
def text(self, value):
assert type(value) is str, 'Input Box\'s text must be string!'
self._text = value
self._输入框.text = value
@property
def value(self):
return self.text
def _update_position(self):
self._输入框.position = self._x + self.外框距离, self._y + self.外框距离
self._外框.position = self._x - self.外框距离, self._y - self.外框距离
self._光标.position = self._x + self.外框距离, self._y + self.外框距离

View File

@ -22,9 +22,9 @@ if __name__ == '__main__': # been start will not run this
sys.path.append('/bin/libs')
sys.path.append('/bin')
from Difficult_Rocket import client, server
from Difficult_Rocket.utils import tools
from Difficult_Rocket.utils.translate import tr
from SRtool import client
from SRtool.api import tools
from SRtool.translate import tr
class Game:
@ -52,11 +52,8 @@ class Game:
self.logger.info(tr['main']['logger.created'])
# version check
self.python_version_check()
self.setup()
self.client = client.Client()
def setup(self) -> None:
self.client = client.Client(net_mode='local')
self.server = server.Server(net_mode='local')
def python_version_check(self) -> None: # best 3.8+ and write at 3.8.10
self.logger.info('%s %s' % (tr['main']['version.now_on'], self.on_python_v))
@ -67,21 +64,5 @@ class Game:
warning = tools.name_handler(tr['main']['version.best3.8+'])
self.logger.warning(warning)
# @new_thread('main')
def _start(self):
self.server.run()
threaded = False
if threaded:
try:
game_process = multiprocessing.Process(target=self.client.start(), name='pyglet app')
game_process.start()
game_process.join()
except:
return -1
else:
return 1
else:
self.client.start()
def start(self) -> None:
self._start()
self.client.start()

View File

@ -1,6 +1,6 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# Copyright © 2021 by shenjackyuanjie
# All rights reserved
# -------------------------------
@ -11,14 +11,10 @@ github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
import inspect
import objprint
from typing import Union
from Difficult_Rocket.utils import tools
from Difficult_Rocket.exception.language import *
from SRtool.api import tools
from SRtool.api.Exp import *
"""
这部分代码使用了中文编程why
@ -26,27 +22,6 @@ from Difficult_Rocket.exception.language import *
"""
class Tr:
"""
我不装了我就复刻tr
"""
def __init__(self):
self.config_regs = {}
def add_config(self, configs: dict) -> None:
frame = inspect.currentframe()
self.config_regs[frame.f_back.f_code.co_filename] = configs
def __call__(self, *args, **kwargs):
frame = inspect.currentframe()
if frame.f_back.f_code.co_filename in self.config_regs:
...
else:
...
class Lang:
"""
用于创建一个对应语言的翻译类
@ -60,11 +35,10 @@ class Lang:
lang.lang(xxx, xxx)来获取翻译过的值
"""
def __init__(self, language: str = 'zh-CN') -> None:
def __init__(self, language: str = 'zh-CN'):
self.语言 = language
self.翻译结果 = tools.load_file(f'configs/lang/{language}.toml')
self.默认翻译 = tools.load_file('configs/lang/zh-CN.toml')
self.直接返回原始数据 = True
def __str__(self) -> str:
return self.语言
@ -76,17 +50,15 @@ class Lang:
try:
return self.默认翻译[item]
except KeyError:
raise TranslateKeyNotFound(f'there\'s no key {item} in both {self.语言} and zh-CN')
raise LanguageError(f'there\'s no key {item} in both {self.语言} and zh-CN')
def __setitem__(self, key, value) -> None:
def __setitem__(self, key, value):
if key == 'language' or key == 'lang':
try:
self.翻译结果 = tools.load_file(f'configs/lang/{value}.toml')
self.语言 = value
except FileNotFoundError:
if self.直接返回原始数据:
return None
raise TranslateKeyNotFound(f'{value}\'s language toml file not found')
raise LanguageError(f'{value}\'s language json5 file not found')
else:
raise NotImplementedError
@ -95,14 +67,9 @@ class Lang:
self.翻译结果 = tools.load_file(f'configs/lang/{language}.toml')
self.语言 = language
except FileNotFoundError:
raise TranslateKeyNotFound(f'{language}\'s language toml file not found')
raise LanguageError(f'{language}\'s language json5 file not found')
def lang(self, *args) -> Union[int, str, list, dict]:
# frame = inspect.currentframe()
# # print("调用当前log的文件名:", frame.f_back.f_code.co_filename)
# objprint.objprint(frame.f_back.f_code,
# honor_existing=False,
# depth=2)
try:
结果 = self.翻译结果
for 选项 in args:
@ -115,9 +82,7 @@ class Lang:
结果 = 结果[选项]
return 结果
except KeyError:
if self.直接返回原始数据:
return args
raise TranslateKeyNotFound(f'there\'s no key {args} in both {self.语言} and zh-CN')
raise LanguageError(f'there\'s no key {args} in both {self.语言} and zh-CN')
def 翻译(self, *args) -> Union[int, str, list, dict]:
return self.lang(args)
@ -130,19 +95,17 @@ tr = Lang('zh-CN')
HOS = 'HarmonyOS Sans'
HOS_S = 'HarmonyOS Sans SC'
HOS_T = 'HarmonyOS Sans TC'
HOS_I = 'HarmonyOS Sans Italic'
HOS_C = 'HarmonyOS Sans Condensed'
HOS_CI = 'HarmonyOS Sans Condensed Italic'
HOS_NA = 'HarmonyOS Sans Naskh Arabic'
HOS_NAU = 'HarmonyOS Sans Naskh Arabic_UI'
鸿蒙字体 = HOS
鸿蒙简体 = HOS_S
鸿蒙繁体 = HOS_T
鸿蒙斜体 = HOS_I
鸿蒙窄体 = HOS_C
CC = 'Cascadia Code'
CM = 'Cascadia Mono'
CCPL = 'Cascadia Code PL'
CMPL = 'Cascadia Mono PL'
微软等宽 = CC
微软等宽无线 = CM
微软等宽带电线 = CCPL
微软等宽带电线无线 = CMPL
鸿蒙斜窄体 = HOS_CI
鸿蒙阿拉伯 = HOS_NA
鸿蒙阿拉伯UI = HOS_NAU

61
SRtool/unpack_textures.py Normal file
View File

@ -0,0 +1,61 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021 by shenjackyuanjie
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
from SRtool.api import tools
import os
import PIL.Image
import json5
def rewrite_config(name, save_name):
load_xml = tools.load_file(name)
load_xml = load_xml.documentElement
sprites = load_xml.getElementsByTagName('sprite')
pic_path = load_xml.getAttribute('imagePath')
poise = {'image_name': pic_path, 'images': {}}
for sprite in sprites:
poi = tools.get_At(['x', 'y', 'w', 'h'], sprite, int)
poi.append(tools.get_At('r', sprite, str))
save_image = tools.get_At('n', sprite, str)
if save_image.find('PNG') != -1:
save_image = save_image[:-3] + 'png'
poise['images'][save_image] = poi
with open(save_name, 'w') as file:
json5.dump(poise, file)
def cut_and_save(config, save_path):
with open(config) as con:
configs = json5.load(con)
pic = PIL.Image.open('textures/' + configs['image_name'])
try:
os.mkdir('textures/' + save_path)
except Exception as exp:
print(exp)
for config_ in configs['images']:
config__ = configs['images'][config_]
save_name = 'textures/%s/%s' % (save_path, config_)
x, y, w, h, t = config__[0], config__[1], config__[2], config__[3], config__[4]
crop_box = [x, y, x + w, y + h]
pic_ = pic.crop(crop_box)
if t == 'y':
pic_ = pic_.rotate(90, expand=True)
print(save_name)
pic_.save(save_name)
def All_in_one_cut(xml, path):
json_name = xml[:-4] + '.json5'
rewrite_config(xml, json_name)
cut_and_save(json_name, path)

View File

@ -1,17 +0,0 @@
{
'Solar System': {
'description': '',
'planets': {
'earth': {
'description': '',
'gravity': 9.81,
'radius': 63710000,
'map_color': [
103,
157,
255
]
}
}
}
}

View File

@ -1,31 +0,0 @@
{
'Editor': {
'runtime': {
'toolbar.dark': 'ToolbarDark.png',
'toolbar.light': 'ToolbarLight.png',
'button_side.dark': 'ButtonDarkSide.png',
'button_side.light': 'ButtonLightSide.png'
},
'toggle_button': {
'stage': 'ToolbarIconStaging.png',
'add_part': 'ToolbarIconAddPart.png',
'menu': 'ToolbarIconMenu.png'
},
'push_button': {
'zoom': 'ToolbarIconZoom.png',
'zoom.in': 'ToolbarIconZoomIn.png',
'zoom.out': 'ToolbarIconZoomOut.png',
'play': 'ToolbarIconPlay.png',
'rotate': 'RotateButton.png',
'trash_can': 'TrashCan.png'
}
},
'Runtime': {
},
'Parts': {
'battery': 'Battery.png',
'beam': 'Beam.png',
'cover_bottom': 'CoverBottom.png',
'nose_cone': 'NoseCone.png'
}
}

View File

@ -1 +0,0 @@
theme: jekyll-theme-slate

View File

@ -1,39 +0,0 @@
{
'language': 'language',
'textures': {
'back_ground_space': 'xxx.png',
'planet': {
'xxx': 'xxx.png'
},
'flame': {
'xxx': 'xxx.png'
}
},
'basic_number': {
'name': [
'float',
// Decimal class
'int',
[
'unit'
],
[
'unit'
],
'name = float × 10^int × unit(s) ÷ unit(s)'
]
},
'basic_force': {
'name': [
'x',
'y',
//x&y format:basic_number/unit1:[m]/unit2:[]'
]
},
'basic_poi': {
'name': [
'x',
'y'
]
}
}

View File

@ -1,79 +0,0 @@
{
Game_threads: {
orbit_demo: {
ship_info: {
mass: 'basic_config:basic_number',
force: 'basic_config:basic_force'
}
}
},
client: {
'self.view': [
'space',
'map',
'menu',
'build'
],
'self.textures': {
'first name of textures(defaut: difficult_rocket)': {
'name of image or name of list': 'pyglet.image class or dict',
/*
这里说明一下你即可以直接主列表下直接放image也可以再细分
会直接检测是列表还是image
另外 可 在文件夹同级放image文件
*/
nothing: 'nothing'
}
},
'self.parts': {
'ship name': {
brain: [
'part type',
// part type
'turn',
// type:float
'is mirror',
// type:bool
[
'basic_config.basic_poi',
'basic_config.basic_poi'
]
/*brain的坐标记录由两部分组成
第一部分是brain所在区块的区块坐标(区块的大小暂定2^64m大小从恒星中心开始算普通的平面直角坐标系)
第二部分是brain所在区块内的相对坐标(左上角00)*/
/*rua 我用中文了!
飞船的'大脑'(直译)没有'特殊值'
也就是说'大脑'只是一个'壳'(服务端同理)
只会计算位置、方向之类的统一数据
需要改的话发issue 嘿嘿
*/
],
'part ID': [
// part id
'part type',
// part type
'turn',
// type:float 0 is up clockwise
'is mirror',
// type:bool
[
'basic_config.basic_poi'
],
{
'special value 1': 'xxx',
'special value 2': 'xxx',
/*继续继续
这里的“特殊值”指的是
除去上面写的类型、角度、镜像、位置之外的其他属性
比如燃料罐的燃料量、太阳能板的打开状态
需要渲染一些特殊项的时候
比如对接之后传输燃料、渲染太阳能板
的时候可以用到
*/
nothing: 'nothing'
}
]
}
}
}
}

View File

@ -1,6 +0,0 @@
{
'keys': {
'function-1': 'keys-1',
'function-2': 'keys-2'
}
}

View File

@ -1,17 +0,0 @@
{
'System name': {
'description': 'xxx',
'planets': {
'planets xxx': {
'description': 'xxx',
'gravity': 'x.xx N/kg',
'radius': 'xxx m',
'map_color': [
'R',
'G',
'B'
]
}
}
}
}

View File

@ -1,13 +0,0 @@
{
'width': 'int',
'height': 'int',
'full_screen': 'true/false',
// bool
'caption': 'xxx',
// {version} -> version of SR
'resizable': 'true',
// bool
'visible': 'true',
// bool
'style': 'xxx(in list)'
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 571 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 366 KiB

View File

@ -1,43 +0,0 @@
# Difficult Rocket 计划特性页面
这里会用中文列出。DR未来的计划特性已经做出来的也会有标注
别问为什么用中文问就是写不动English了
正文开始
注:文件名指的是本文件夹里的详细说明文件的文件名,如果没有则代表没有详细说明
| 特性描述 | 文件名 | 状态 |
| :----: | :----: | :----: |
| 轨道规划 | orbit-plan | planing |
| 部件可成环 | multi-connect | planing |
| 多指令舱控制 | multi-control | planing |
| 自定义部件旋转角度 | custom-turn-angle | planing |
| 自定义warp速度 | custom-warp-speed | planing |
| Dv计算 | Dv-calculation | planing |
| socket 联机 | online-play | planing |
| 操作界面可视化轨道 | visible-orbit | planing |
| 可堆叠部件 | part-stack | planing |
| 可压缩结构 | part-zip | planing |
| 部件平移 | part-move | planing |
| 存档额外信息 | extra-save-info | planing |
| 自定义部件分组开关 | custom-stage-on-off | planing |
# 文件范例
# 中文简称 文件名`英文名称`
## 日期
## 发起人
## 状态
## 描述
### 底层机制 `实现方法(大致)`
### 效果
## 别的什么的

View File

@ -1,29 +0,0 @@
# 存档额外信息 extra save info
## 20210514
## shenjackyuanjie
## planing
## 描述
存档中会额外保存一些信息
### 底层机制
保存存档时会读取 `partlist` 中的部件信息
比如部件碰撞箱、重量等
并保存到存档中
### 效果
存档会根据部件使用情况
增大体积(直到所有种类的部件都被用)
## 别的什么的
没了

View File

@ -1,15 +0,0 @@
# 部件可成环 multi-connect
## 2021-4-25
## shenjackyuanjie(writer)
## 描述
### 底层机制
单个部件可以同时连接到2个或两个以上部件
### 效果
可以搞点 环世界 之类的巨构

View File

@ -1,32 +0,0 @@
# 多指令舱控制 multi-control
## 2021-4-25
## shenjackyuanjie(writer)
## planing
## 描述
### 示例1
可以让多个指令舱同时进行动作
比如一个空间站由很多部分组成
每一个部分都由不同的指令舱控制
多指令舱控制就可以实现空间站所有部分统一加速、减速
其实也是某种程度上的统一控制
### 示例2
在同时发射多枚火箭/卫星时
可以让火箭在操作其他火箭的时候继续燃烧
就是说操纵A火箭的时候B火箭还能继续燃烧
### 底层机制

View File

@ -1,15 +0,0 @@
# 中文简称 文件名
## 日期
## 发起人
## 状态
## 描述
### 底层机制
### 效果
## 别的什么的

View File

@ -1,28 +0,0 @@
# pyglet相关
pyglet 坐标轴原点是左上角
# 坐标记录相关
记录的是部件碰撞箱中心的相对于控制仓碰撞箱中心的相对坐标
然后控制仓的坐标是单独记录的
记录的是区块坐标+区块内坐标
# 渲染
屏幕坐标系需要*100有待测试
# 素材提供
[背景候选1号](background.png)
来自 @底层萌新 QQ1744251171
| 项目 | 油麦菜 | 小白菜 | 绿萝 |
| :----: | :----: | :----: | :----: |
| 对照组 | 882 | 625 | 117 |
| 40° (高温) | --- | 646 | --- |
| 50° (高温) | 639 | 580 | --- |
| 60° (高温) | 1094 | 400 | --- |
| 70° (高温) | 674 | 1054 | --- |

View File

@ -1,96 +1,52 @@
# Difficult Rocket Update Logs
- 感谢 `Github copilot` 的翻译(甚至这句话也是`copilot`翻译的)
- 也就意味着以后的更新日志是中文记录+`copilot`翻译的(当然,也有可能是`Easy Translate`翻译的)
- Thanks `Github copilot` for translate (lazy yes!)
- Means the update logs will lodge in Chinese and translated by `copilot`
- 感谢 `Github copilot` 的翻译(甚至这句话也是copilot翻译的)
# SR tool PC Update Logs
- 从~~0.6.1~~1.0版本开始这个更新日志将主要用于记录SRtool的更新
- 并且使用中文记录更新
- ~~github copilot 真好用~~
## Readme First!
##### most badge can be clicked and jump
[![Generic badge](https://img.shields.io/badge/SemVer-2.0.0-blue.svg)](https://Semver.org/)
![Generic badge](https://img.shields.io/badge/Version-0.6.1-yellow.svg)
![Generic badge](https://img.shields.io/badge/Version-1.0-yellow.svg)
- [![Readme-github](https://img.shields.io/badge/Readme-Github-blue.svg?style=flat-square&logo=Github)](https://github.com/shenjackyuanjie/Difficult-Rocket)
- [![Readme-gitee](https://img.shields.io/badge/Readme-Gitee-blue.svg?style=flat-square&logo=Gitee)](https://gitee.com/shenjackyuanjie/Difficult-Rocket)
- [![Readme-gitee](https://img.shields.io/badge/Readme-中文(点我!)-blue.svg?style=flat-square)](README-cn.md)
- Using [SemVer 2.0.0](https://semver.org/) to manage version
## 20220627
## 20220511 V 0.6.3
- 咕了好久的 update log 了
- github copilot 卒了,所以没有英文
- GitHub copy alot break , so no English
## 202112 V 1.1
### Change
- 将 `api/Exp` 改为文件夹 `api/Exp/__init__.py`
- 再次重写了 `client.load_fonts()` 现在改为直接加载单独的 `pyglet_load_fonts_folder()`
- 更新了 `command/` 里的一大堆东西
- 退钱!开摆!
- 以后DR的更新日志不会再在这里同步咕咕咕
- 没啥
- 同步了DR的更新虽说其实没有
## 20211110 V 1.0 (V 0.6.1)
## 202202xx V 0.6.2
### Add
[然后就很快被替换成MCDR的了]: <> (- 添加模块 `semver` 和协议 &#40;`LICENSE.txt`&#41;)
[Add soon been replace by MCDR]: <> ( - Add modules `semver` Add LICENSE &#40;`LICENSE.txt`&#41;)
- 添加了 `libs.MCDR` 文件夹 (`new_thread`没有包含在内)
- Add `libs.MCDR` folder (`new_thread` not included)
- 添加对 mod 的支持(还在写啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊)
- 计划写个设计文档
- Plan to write a design document
## ~~202111 202112xx 20220119~~ 20220207 V 0.6.1
~~争取12月内发一个release~~
~~行了这都2022年了我接着摸等我考完试(20220110)再发~~
20220207 可算是发了ruaaaa
- 热烈祝贺1.0的发布!
- lazy了1.1再把一些版本参数改成1.1吧
### Change
- 修改了 readme 文件的语言切换格式
- Change the language switch format in readme
- 更新了所有文件的版权信息 (2021-2022)
- Update all files copyright information (2021-2022)
- 重命名 `Difficult_Rocket.py` -> `DR.py`
- 用于修复 `Pycharm` 检测模块时总是会把主文件检测成主程序,导致一些模块总是检测不到的问题
- Rename `Difficult_Rocket.py` -> `DR.py`
- Use it to fix `Pycharm` module detection problem
- When the main file is detected as the main program, some modules will always be detected as the main program
- 把`api/translate`移动到根目录下
- move `api/translate` to root directory
- 现在命令会慢慢消失,而不是立即消失
- Now the command will disappear slowly, not immediately
- 重写了一遍` client.load_fonts()`
- rewrite `client.load_fonts()`
- 重写了 `tools.load_file()` 的错误处理和 `.config` 文件的解析方式
- 现在 `.config` 文件解析后会直接返回一个 `ConfigParser` 对象
- 也就意味着不能再直接遍历 `.config` 文件返回的解析 ~~谁遍历.config文件啊~~
- 同时也意味着可以直接用解析好的 `.config` 文件来修改 `.config` 文件
- rewrite `tools.load_file()` error handling and `.config` file parsing method
- now `.config` file parsing after return `ConfigParser` object
- that means you can not directly traverse `.config` file return parsing ~~who traverse .config file~~
- also means you can directly use parsed `.config` file to modify `.config` file
- 为 `pyglet` 添加 `Ctrl+C``Ctrl+V` 的快捷键解析
- add `Ctrl+C` and `Ctrl+V` shortcut for `pyglet`
- 更新 `pyglet``2.0dev13`
- update `pyglet` to `2.0dev13`
### Command
- `log_tick` 指令改为 `fps log`
- command `log_tick` change to `fps log`
- `maxfps` 指令改为 `fps max`
- command `maxfps` change to `fps max`
- `minfps` 指令改为 `fps min`
- command `minfps` change to `fps min`
- 现在可以使用`set long xxx(int)` 指令来在拖入图片后设置坐标轴点的长度
- Now you can use `set long xxx(int)` command to set the length of the axis point
- `set scale xxx(int)` 用于设置坐标缩放
- `set scale xxx(int)` to set the scale of the coordinate
- 删除了`fps`相关指令(因为没有fps记录器了)
- Delete `fps` related command (because there is no fps recorder now)
- 命令内容输出使用`CommandText`而不是`str`
- 也就是说可以使用`CommandText.match`来匹配命令内容
@ -101,21 +57,8 @@
### Add
- 添加内置字体`Cascadia_Code`
- add built-in font `Cascadia_Code`
- 添加模块 `xmltodict` `pyperclip`
- add modules `xmltodict` `pyperclip`
- 添加了`json5` `pyglet` `pyperclip` `xmltodict` 的协议
- 非常感谢上述模块的作者和维护者们
- added `json5` `pyglet` `pyperclip` `xmltodict` LICENSE
- thanks a lot to above module's author and maintainer
- 继续~~重~~新写了一个基于 `HTMLLabel``HTMLformatedLabel`
- 同时为他写了一个 `decode_text2HTML` 工具(这也是咕咕咕的一大部分原因)
- add a `HTMLformatedLabel` Label based on `HTMLLabel`
- also write a `decode_text2HTML` tool (also a big reason why lazy)
- 增加内置模块 `toml` 和对应的 `LICENSE.txt`
- Added built-in module `toml` and corresponding `LICENSE.txt`
- `gui/widgets.py` InputBox
- making
## 20211025 V 0.6.0
@ -123,22 +66,24 @@
### Change
- 现在 `Difficult Rocket` 只适用于 python3.8+
- 因为 `:=` 的使用
- now `Difficult Rocket` will only fit python3.8+
- because `:=`
- 现在主程序崩溃时的报告处理方式有了新的方式
- now main crash report handler have new way to handler crash
- 现在字体文件夹的名字改为 `HarmonyOS_Sans`
- now fonts' folder's name is `HarmonyOS_Sans`
- now `Difficult Rocket` will only fit python3.8+
- because `:=`
- 现在 `Difficult Rocket` 只适用于 python3.8+
- 因为 `:=` 的使用
- now main crash report handler have new way to handler crash
- 现在主程序崩溃时的报告处理方式有了新的方式
- now fonts' folder's name is `HarmonyOS_Sans`
- 现在字体文件夹的名字改为 `HarmonyOS_Sans`
### Add
- `Difficult_Rocket.graphics.widgets.Parts`
- have many costume value
- now `libs/fonts` have `HarmonyOS_Sans` font
- 有很多自定义数值
- `libs/fonts` now have `HarmonyOS_Sans` font
- 现在 `libs/fonts``HarmonyOS_Sans` 字体
- handler of `on_key_press` and `on_key_release` and `on_text`
- `on_key_press``on_key_release``on_text` 的处理方式
- 添加了 `on_key_press``on_key_release``on_text` 的处理方式
- `game.config` config file
- `lang/en-us.json5` now up to date with `lang/zh-CN.json5`
- `translate/Lang.翻译` same as `Lang.lang`
@ -181,7 +126,6 @@
- `/default`
- switch window size to default size
## 20210928 V 0.5.2
### Change
@ -231,7 +175,6 @@
- `tr[xxx]` can also use but won't solve error when item not found
- so best use `tr.lang(xx, xx)`
## 20210902 V 0.5.1
### Change
@ -248,7 +191,6 @@
- `bin/api/Exp.py` some Exception
- `bin/api/translate` to create a `translate` class that can reload language
## 20210823 V 0.5.0
### Change
@ -268,7 +210,6 @@
- `name_hanlder` in `configs.py`
## 20210811 V 0.4.6
### DEBUG
@ -295,7 +236,6 @@
- delete some useless code
- delete some useless file
## 20210723 V 0.4.5
### DEBUG
@ -313,7 +253,6 @@
- Pre-installed `pyglet` upgrade from `1.5.16` -> `1.5.18`
- Pre-installed `json5` upgrade from `0.9.5` -> `0.9.6`
## 20210708 V 0.4.4
### PS
@ -336,7 +275,6 @@
- `test_logging_conf.py`
- `test_speed_of_sprite.py`
## 2021/06/26 V 0.4.3
### DEBUG
@ -353,7 +291,6 @@
- add performance_test folder
- add some performances test
## 2021/05/24 V 0.4.2
### DEBUG
@ -370,7 +307,6 @@
- debug name_format
## 2021/04/17 V 0.4.1
PS:
@ -392,7 +328,6 @@ PS:
- plan to change config file format to .config (plan to)
- reformat all files (including libs)
## 2021/04/09 V 0.2.3/4
### Add
@ -410,7 +345,6 @@ PS:
- `{date}` can be successful use in `tools.name_handler()` (if you define the format of date)
- log file's filename incorrect (should be `xxxx-xx-xx xx-xx-xx DR.log` but be `{date} DR.log`)
## 2021/03/27 V 0.2.2/1
### Add

BIN
docs/v1.0/演示1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
docs/v1.0/演示2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

BIN
files/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
files/EGYF22.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
files/STYF21.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -1,12 +0,0 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""

201
libs/json5/LICENSE.txt Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -25,16 +25,24 @@ DEBUG = 10
NOTSET = 0
"""
DETAIL = 5
class LogFileCache:
"""日志文件缓存"""
def __init__(self, file_name: str = 'logs//log.log', flush_time: Optional[Union[int, float]] = 1, cache_entries_num: int = 10):
def __init__(self, file_name: str = 'logs//log.log', flush_time: Optional[Union[int, float]] = 1, log_cache_lens_max: int = 10):
"""
@param file_name: 日志文件名称
@param flush_time: 刷新日志缓存写入文件的时长间隔
@param log_cache_lens_max: 日志缓存在自动写入前的最大缓存长度
"""
# 配置相关
self._logfile_name = file_name # log 文件名称
self.flush_time = flush_time # 缓存刷新时长
self.cache_entries_num = cache_entries_num
self.cache_entries_num = log_cache_lens_max
# 写入缓存数
self.cache_count = 0
# 日志缓存表
@ -45,6 +53,7 @@ class LogFileCache:
self.threaded_write = threading.Timer(1, self._log_file_time_write)
def end_thread(self):
"""结束日志写入进程,顺手把目前的缓存写入"""
self.thread_lock.acquire(blocking=True)
self.threaded_write.cancel()
if self.cache_count:
@ -66,7 +75,6 @@ class LogFileCache:
def _log_file_time_write(self) -> None:
"""使用 threading.Timer 调用的定时写入日志文件的函数"""
with self.with_thread_lock:
...
if self.cache_count == 0:
return None
...
@ -93,7 +101,7 @@ class Logger:
else:
...
def make_log(self, level: str,
def make_log(self, level: int,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
@ -104,61 +112,45 @@ class Logger:
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False) -> None:
self.make_log(level='detail', *values, sep=sep, end=end, flush=flush)
self.make_log(level=DETAIL, *values, sep=sep, end=end, flush=flush)
def debug(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False) -> None:
...
self.make_log(level=DEBUG, *values, sep=sep, end=end, flush=flush)
def info(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False) -> None:
...
self.make_log(level=INFO, *values, sep=sep, end=end, flush=flush)
def warning(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False) -> None:
...
self.make_log(level=WARNING, *values, sep=sep, end=end, flush=flush)
def error(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False) -> None:
...
self.make_log(level=ERROR, *values, sep=sep, end=end, flush=flush)
def fatal(self,
*values: object,
sep: Optional[str] = ' ',
end: Optional[str] = '\n',
flush: Optional[bool] = False) -> None:
...
self.make_log(level=FATAL, *values, sep=sep, end=end, flush=flush)
# class LoggerManager:
# """shenjack牌logger"""
#
# def __init__(self):
# self.configs = {}
#
# def add_config(self, name: str, config: dict) -> dict:
# self.configs[name] = config
# return self.configs
#
# def get_logger(self, name: str = 'root', config: dict = None) -> Logger:
# """相当于 logging.getLogger(name='root')"""
# if config is not None:
# self.add_config(name, config)
# return Logger(config=self.configs)
global_configs = {
logger_configs = {
'root': {
'level': DEBUG,
'color': {
@ -171,3 +163,24 @@ global_configs = {
...: ...
}
}
def add_dict_config_to_global(some_dict: dict, name: str) -> dict:
"""
@param some_dict: 一个你丢进来的 logger 设置
@param name: 这个 logger 设置的名称
@return: 修改过的 logger 配置
"""
logger_configs[name] = some_dict
return logger_configs
def add_kwargs_to_global(**kwargs) -> dict:
"""
@param kwargs:
@return:
"""
...

30
libs/pyglet/LICENSE.txt Normal file
View File

@ -0,0 +1,30 @@
Copyright (c) 2006-2008 Alex Holkner
Copyright (c) 2008-2021 pyglet contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of pyglet nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,7 +1,7 @@
# ----------------------------------------------------------------------------
# pyglet
# Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2022 pyglet contributors
# Copyright (c) 2008-2021 pyglet contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@ -114,11 +114,11 @@ _is_pyglet_doc_run = hasattr(sys, "is_pyglet_doc_run") and sys.is_pyglet_doc_run
vertex_source = """#version 150 core
in vec3 translate;
in vec2 translate;
in vec4 colors;
in vec3 tex_coords;
in vec2 scale;
in vec3 position;
in vec2 position;
in float rotation;
out vec4 vertex_colors;
@ -140,13 +140,12 @@ vertex_source = """#version 150 core
m_scale[1][1] = scale.y;
m_translate[3][0] = translate.x;
m_translate[3][1] = translate.y;
m_translate[3][2] = translate.z;
m_rotation[0][0] = cos(-radians(rotation));
m_rotation[0][1] = sin(-radians(rotation));
m_rotation[1][0] = -sin(-radians(rotation));
m_rotation[1][1] = cos(-radians(rotation));
gl_Position = window.projection * window.view * m_translate * m_rotation * m_scale * vec4(position, 1.0);
gl_Position = window.projection * window.view * m_translate * m_rotation * m_scale * vec4(position, 0, 1);
vertex_colors = colors;
texture_coords = tex_coords;
@ -248,6 +247,7 @@ class SpriteGroup(graphics.Group):
def unset_state(self):
glDisable(GL_BLEND)
glBindTexture(self.texture.target, 0)
self.program.stop()
def __repr__(self):
@ -286,15 +286,16 @@ class Sprite(event.EventDispatcher):
_scale_y = 1.0
_visible = True
_vertex_list = None
group_class = SpriteGroup
def __init__(self,
img, x=0, y=0, z=0,
img, x=0, y=0,
blend_src=GL_SRC_ALPHA,
blend_dest=GL_ONE_MINUS_SRC_ALPHA,
batch=None,
group=None,
subpixel=False):
usage='dynamic',
subpixel=False,
program=None):
"""Create a sprite.
:Parameters:
@ -304,8 +305,6 @@ class Sprite(event.EventDispatcher):
X coordinate of the sprite.
`y` : int
Y coordinate of the sprite.
`z` : int
Z coordinate of the sprite.
`blend_src` : int
OpenGL blend source mode. The default is suitable for
compositing sprites drawn from back-to-front.
@ -316,14 +315,18 @@ class Sprite(event.EventDispatcher):
Optional batch to add the sprite to.
`group` : `~pyglet.graphics.Group`
Optional parent group of the sprite.
`usage` : str
Vertex buffer object usage hint, one of ``"none"``,
``"stream"``, ``"dynamic"`` (default) or ``"static"``. Applies
only to vertex data.
`subpixel` : bool
Allow floating-point coordinates for the sprite. By default,
coordinates are restricted to integer values.
`program` : `~pyglet.graphics.shader.ShaderProgram`
A custom ShaderProgram.
"""
self._x = x
self._y = y
self._z = z
self._img = img
if isinstance(img, image.Animation):
self._animation = img
@ -334,19 +337,16 @@ class Sprite(event.EventDispatcher):
else:
self._texture = img.get_texture()
self._batch = batch or graphics.get_default_batch()
self._group = self.group_class(self._texture, blend_src, blend_dest, self.program, 0, group)
self._subpixel = subpixel
self._create_vertex_list()
@property
def program(self):
if isinstance(self._img, image.TextureArrayRegion):
if isinstance(img, image.TextureArrayRegion):
program = get_default_array_shader()
else:
program = get_default_shader()
return program
self._batch = batch or graphics.get_default_batch()
self._group = SpriteGroup(self._texture, blend_src, blend_dest, program, 0, group)
self._usage = usage
self._subpixel = subpixel
self._create_vertex_list()
def __del__(self):
try:
@ -430,12 +430,12 @@ class Sprite(event.EventDispatcher):
def group(self, group):
if self._group.parent == group:
return
self._group = self.group_class(self._texture,
self._group.blend_src,
self._group.blend_dest,
self._group.program,
0,
group)
self._group = SpriteGroup(self._texture,
self._group.blend_src,
self._group.blend_dest,
self._group.program,
0,
group)
self._batch.migrate(self._vertex_list, GL_TRIANGLES, self._group, self._batch)
@property
@ -482,49 +482,49 @@ class Sprite(event.EventDispatcher):
self._texture = texture
def _create_vertex_list(self):
self._vertex_list = self.program.vertex_list_indexed(
4, GL_TRIANGLES, [0, 1, 2, 0, 2, 3], self._batch, self._group,
colors=('Bn', (*self._rgb, int(self._opacity)) * 4),
translate=('f', (self._x, self._y, self._z) * 4),
scale=('f', (self._scale*self._scale_x, self._scale*self._scale_y) * 4),
rotation=('f', (self._rotation,) * 4),
tex_coords=('f', self._texture.tex_coords))
usage = self._usage
self._vertex_list = self._batch.add_indexed(
4, GL_TRIANGLES, self._group, [0, 1, 2, 0, 2, 3],
'position2f/%s' % usage,
('colors4Bn/%s' % usage, (*self._rgb, int(self._opacity)) * 4),
('translate2f/%s' % usage, (self._x, self._y) * 4),
('scale2f/%s' % usage, (self._scale*self._scale_x, self._scale*self._scale_y) * 4),
('rotation1f/%s' % usage, (self._rotation,) * 4),
('tex_coords3f/%s' % usage, self._texture.tex_coords))
self._update_position()
def _update_position(self):
if not self._visible:
self._vertex_list.position[:] = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self._vertex_list.position[:] = (0, 0, 0, 0, 0, 0, 0, 0)
else:
img = self._texture
x1 = -img.anchor_x
y1 = -img.anchor_y
x2 = x1 + img.width
y2 = y1 + img.height
vertices = (x1, y1, 0, x2, y1, 0, x2, y2, 0, x1, y2, 0)
verticies = (x1, y1, x2, y1, x2, y2, x1, y2)
if not self._subpixel:
self._vertex_list.position[:] = tuple(map(int, vertices))
self._vertex_list.position[:] = tuple(map(int, verticies))
else:
self._vertex_list.position[:] = vertices
self._vertex_list.position[:] = verticies
@property
def position(self):
"""The (x, y, z) coordinates of the sprite, as a tuple.
"""The (x, y) coordinates of the sprite, as a tuple.
:Parameters:
`x` : int
X coordinate of the sprite.
`y` : int
Y coordinate of the sprite.
`z` : int
Z coordinate of the sprite.
"""
return self._x, self._y, self._z
return self._x, self._y
@position.setter
def position(self, position):
self._x, self._y, self._z = position
self._vertex_list.translate[:] = position * 4
self._x, self._y = position
self._vertex_list.translate[:] = (position[0], position[1]) * 4
@property
def x(self):
@ -537,7 +537,7 @@ class Sprite(event.EventDispatcher):
@x.setter
def x(self, x):
self._x = x
self._vertex_list.translate[:] = (x, self._y, self._z) * 4
self._vertex_list.translate[:] = (x, self._y) * 4
@property
def y(self):
@ -550,20 +550,7 @@ class Sprite(event.EventDispatcher):
@y.setter
def y(self, y):
self._y = y
self._vertex_list.translate[:] = (self._x, y, self._z) * 4
@property
def z(self):
"""Z coordinate of the sprite.
:type: int
"""
return self._z
@z.setter
def z(self, z):
self._z = z
self._vertex_list.translate[:] = (self._x, self._y, z) * 4
self._vertex_list.translate[:] = (self._x, y) * 4
@property
def rotation(self):
@ -629,7 +616,7 @@ class Sprite(event.EventDispatcher):
self._scale_y = scale_y
self._vertex_list.scale[:] = (self._scale * self._scale_x, self._scale * scale_y) * 4
def update(self, x=None, y=None, z=None, rotation=None, scale=None, scale_x=None, scale_y=None):
def update(self, x=None, y=None, rotation=None, scale=None, scale_x=None, scale_y=None):
"""Simultaneously change the position, rotation or scale.
This method is provided for convenience. There is not much
@ -640,8 +627,6 @@ class Sprite(event.EventDispatcher):
X coordinate of the sprite.
`y` : int
Y coordinate of the sprite.
`z` : int
Z coordinate of the sprite.
`rotation` : float
Clockwise rotation of the sprite, in degrees.
`scale` : float
@ -655,10 +640,8 @@ class Sprite(event.EventDispatcher):
self._x = x
if y:
self._y = y
if z:
self._z = z
if x or y or z:
self._vertex_list.translate[:] = (self._x, self._y, self._z) * 4
if x or y:
self._vertex_list.translate[:] = (self._x, self._y) * 4
if rotation:
self._rotation = rotation
self._vertex_list.rotation[:] = (rotation,) * 4
@ -818,47 +801,3 @@ class Sprite(event.EventDispatcher):
Sprite.register_event_type('on_animation_end')
class AdvancedSprite(pyglet.sprite.Sprite):
"""Is a sprite that lets you change the shader program during initialization and after
For advanced users who understand shaders."""
def __init__(self,
img, x=0, y=0, z=0,
blend_src=GL_SRC_ALPHA,
blend_dest=GL_ONE_MINUS_SRC_ALPHA,
batch=None,
group=None,
subpixel=False,
program=None):
self._program = program
if not program:
if isinstance(img, image.TextureArrayRegion):
self._program = get_default_array_shader()
else:
self._program = get_default_shader()
super().__init__(img, x, y, z, blend_src, blend_dest, batch, group, subpixel)
@property
def program(self):
return self._program
@program.setter
def program(self, program):
if self._program == program:
return
self._group = self.group_class(self._texture,
self._group.blend_src,
self._group.blend_dest,
program,
0,
self._group)
self._batch.migrate(self._vertex_list, GL_TRIANGLES, self._group, self._batch)
self._program = program

View File

@ -1,7 +1,7 @@
# ----------------------------------------------------------------------------
# pyglet
# Copyright (c) 2006-2008 Alex Holkner
# Copyright (c) 2008-2022 pyglet contributors
# Copyright (c) 2008-2021 pyglet contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@ -324,12 +324,11 @@ class _GlyphBox(_AbstractBox):
def place(self, layout, i, x, y, context):
assert self.glyphs
program = get_default_layout_shader()
try:
group = layout.group_cache[self.owner]
except KeyError:
group = layout.group_class(self.owner, program, order=1, parent=layout.group)
group = layout.group_class(self.owner, get_default_layout_shader(), order=1, parent=layout.group)
layout.group_cache[self.owner] = group
n_glyphs = self.length
@ -357,19 +356,19 @@ class _GlyphBox(_AbstractBox):
for start, end, color in context.colors_iter.ranges(i, i + n_glyphs):
if color is None:
color = (0, 0, 0, 255)
if len(color) != 4:
raise ValueError("Color requires 4 values (R, G, B, A). Value received: {}".format(color))
colors.extend(color * ((end - start) * 4))
indices = []
# Create indices for each glyph quad:
for glyph_idx in range(n_glyphs):
indices.extend([element + (glyph_idx * 4) for element in [0, 1, 2, 0, 2, 3]])
for i in range(n_glyphs):
indices.extend([element + (i * 4) for element in [0, 1, 2, 0, 2, 3]])
vertex_list = program.vertex_list_indexed(n_glyphs * 4, GL_TRIANGLES, indices, layout.batch, group,
position=('f', vertices),
colors=('Bn', colors),
tex_coords=('f', tex_coords))
vertex_list = layout.batch.add_indexed(n_glyphs * 4, GL_TRIANGLES, group,
indices,
('position2f/dynamic', vertices),
('colors4Bn/dynamic', colors),
('tex_coords3f/dynamic', tex_coords),
'translation2f/dynamic')
context.add_list(vertex_list)
@ -386,7 +385,6 @@ class _GlyphBox(_AbstractBox):
y1 = y + self.descent + baseline
y2 = y + self.ascent + baseline
x1 = x
for start, end, decoration in context.decoration_iter.ranges(i, i + n_glyphs):
bg, underline = decoration
x2 = x1
@ -394,38 +392,30 @@ class _GlyphBox(_AbstractBox):
x2 += glyph.advance + kern
if bg is not None:
if len(bg) != 4:
raise ValueError("Background color requires 4 values (R, G, B, A). Value received: {}".format(bg))
background_vertices.extend([x1, y1, x2, y1, x2, y2, x1, y2])
background_colors.extend(bg * 4)
if underline is not None:
if len(underline) != 4:
raise ValueError("Underline color requires 4 values (R, G, B, A). Value received: {}".format(underline))
underline_vertices.extend([x1, y + baseline - 2, x2, y + baseline - 2])
underline_colors.extend(underline * 2)
x1 = x2
if background_vertices:
background_indices = []
bg_count = len(background_vertices) // 2
for glyph_idx in range(bg_count):
background_indices.extend([element + (glyph_idx * 4) for element in [0, 1, 2, 0, 2, 3]])
background_list = program.vertex_list_indexed(bg_count, GL_TRIANGLES, background_indices,
layout.batch, layout.background_decoration_group,
position=('f', background_vertices),
colors=('Bn', background_colors))
background_list = layout.batch.add_indexed(len(background_vertices) // 2,
GL_TRIANGLES, layout.background_decoration_group,
[0, 1, 2, 0, 2, 3],
('position2f/dynamic', background_vertices),
('colors4Bn/dynamic', background_colors),
'translation2f/dynamic')
context.add_list(background_list)
if underline_vertices:
underline_list = program.vertex_list(len(underline_vertices) // 2, GL_LINES,
layout.batch, layout.foreground_decoration_group,
position=('f',underline_vertices),
colors=('Bn', underline_colors))
underline_list = layout.batch.add(len(underline_vertices) // 2,
GL_LINES, layout.foreground_decoration_group,
('position2f/dynamic', underline_vertices),
('colors4Bn/dynamic', underline_colors),
'translation2f/dynamic')
context.add_list(underline_list)
def delete(self, layout):
@ -548,9 +538,12 @@ layout_vertex_source = """#version 330 core
void main()
{
gl_Position = window.projection * window.view * vec4(position + translation, 0.0, 1.0);
mat4 translate_mat = mat4(1.0);
translate_mat[3] = vec4(translation, 1.0, 1.0);
vert_position = vec4(position + translation, 0.0, 1.0);
gl_Position = window.projection * window.view * translate_mat * vec4(position, 0, 1);
vert_position = vec4(position + translation, 0, 1);
text_colors = colors;
texture_coords = tex_coords.xy;
}
@ -564,11 +557,11 @@ layout_fragment_source = """#version 330 core
out vec4 final_colors;
uniform sampler2D text;
uniform bool scissor;
uniform bool scissor = false;
uniform vec4 scissor_area;
void main()
{
{
final_colors = vec4(text_colors.rgb, texture(text, texture_coords).a * text_colors.a);
if (scissor == true) {
if (vert_position.x < scissor_area[0]) discard; // left
@ -587,6 +580,7 @@ decoration_vertex_source = """#version 330 core
out vec4 vert_colors;
out vec4 vert_position;
uniform WindowBlock
{
mat4 projection;
@ -595,9 +589,12 @@ decoration_vertex_source = """#version 330 core
void main()
{
gl_Position = window.projection * window.view * vec4(position + translation, 0.0, 1.0);
mat4 translate_mat = mat4(1.0);
translate_mat[3] = vec4(translation, 1.0, 1.0);
vert_position = vec4(position + translation, 0.0, 1.0);
gl_Position = window.projection * window.view * translate_mat * vec4(position, 0, 1);
vert_position = vec4(position + translation, 0, 1);
vert_colors = colors;
}
"""
@ -608,7 +605,7 @@ decoration_fragment_source = """#version 330 core
out vec4 final_colors;
uniform bool scissor;
uniform bool scissor = false;
uniform vec4 scissor_area;
void main()
@ -628,10 +625,10 @@ def get_default_layout_shader():
try:
return pyglet.gl.current_context.pyglet_text_layout_shader
except AttributeError:
pyglet.gl.current_context.pyglet_text_layout_shader = shader.ShaderProgram(
shader.Shader(layout_vertex_source, 'vertex'),
shader.Shader(layout_fragment_source, 'fragment'),
)
_default_vert_shader = shader.Shader(layout_vertex_source, 'vertex')
_default_frag_shader = shader.Shader(layout_fragment_source, 'fragment')
default_shader_program = shader.ShaderProgram(_default_vert_shader, _default_frag_shader)
pyglet.gl.current_context.pyglet_text_layout_shader = default_shader_program
return pyglet.gl.current_context.pyglet_text_layout_shader
@ -639,10 +636,10 @@ def get_default_decoration_shader():
try:
return pyglet.gl.current_context.pyglet_text_decoration_shader
except AttributeError:
pyglet.gl.current_context.pyglet_text_decoration_shader = shader.ShaderProgram(
shader.Shader(decoration_vertex_source, 'vertex'),
shader.Shader(decoration_fragment_source, 'fragment'),
)
_default_vert_shader = shader.Shader(decoration_vertex_source, 'vertex')
_default_frag_shader = shader.Shader(decoration_fragment_source, 'fragment')
default_shader_program = shader.ShaderProgram(_default_vert_shader, _default_frag_shader)
pyglet.gl.current_context.pyglet_text_decoration_shader = default_shader_program
return pyglet.gl.current_context.pyglet_text_decoration_shader
@ -669,6 +666,7 @@ class TextLayoutGroup(graphics.Group):
def unset_state(self):
glDisable(GL_BLEND)
glBindTexture(self.texture.target, 0)
self.program.stop()
def __repr__(self):
@ -713,6 +711,7 @@ class ScrollableTextLayoutGroup(graphics.Group):
def unset_state(self):
glDisable(GL_BLEND)
glBindTexture(self.texture.target, 0)
self.program.stop()
def __repr__(self):
@ -870,8 +869,12 @@ class TextLayout:
self.content_height = 0
self._user_group = group
decoration_shader = get_default_decoration_shader()
self.background_decoration_group = self.decoration_class(decoration_shader, order=0, parent=self._user_group)
self.foreground_decoration_group = self.decoration_class(decoration_shader, order=2, parent=self._user_group)
self.group_cache = {}
self._initialize_groups()
if batch is None:
batch = graphics.Batch()
@ -891,21 +894,10 @@ class TextLayout:
self._dpi = dpi or 96
self.document = document
def _initialize_groups(self):
decoration_shader = get_default_decoration_shader()
self.background_decoration_group = self.decoration_class(decoration_shader, order=0, parent=self._user_group)
self.foreground_decoration_group = self.decoration_class(decoration_shader, order=2, parent=self._user_group)
@property
def group(self):
return self._user_group
@group.setter
def group(self, group):
self._user_group = group
self._initialize_groups()
self._update()
@property
def dpi(self):
"""Get DPI used by this layout.

3
merger.cmd Normal file
View File

@ -0,0 +1,3 @@
git fetch orgin
git checkout SRtool2
git merge --no-commit main

View File

@ -1,12 +0,0 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""

View File

@ -1,12 +0,0 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""

View File

@ -1,32 +0,0 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021 by shenjackyuanjie
# All rights reserved
# -------------------------------
"""
writen by shenjackyuanjie
mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
"""
this is a test of modding in Difficult Rocket
just a test
只是一个DR的mod测试
"""
# from libs
import semver
# from DR
from Difficult_Rocket import semver_game_version
from Difficult_Rocket.mods import MODInfo, semver_loader_version
mod_info = MODInfo(name="test mod",
version=semver.VersionInfo.parse("0.0.1"),
write_version=semver_game_version,
write_loader_version=semver_loader_version)
print(mod_info.serialize())

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with TexturePacker http://www.codeandweb.com/texturepacker-->
<!-- $TexturePacker:SmartUpdate:c3da6981dd09ea175913b0acbea04a91:2522e219d5331ca1ace210f7e450e2ba:022f5035775d68c88a4bf5838e336fc0$ -->
<!--Format:
n => name of the sprite
x => sprite x pos in texture
y => sprite y pos in texture
w => sprite width (may be trimmed)
h => sprite height (may be trimmed)
oX => sprite's x-corner offset (only available if trimmed)
oY => sprite's y-corner offset (only available if trimmed)
oW => sprite's original width (only available if trimmed)
oH => sprite's original height (only available if trimmed)
r => 'y' only set if sprite is rotated
-->
<TextureAtlas imagePath="CommonGui.png" width="512" height="512">
<sprite n="ButtonDown.png" x="184" y="2" w="180" h="50"/>
<sprite n="ButtonUp.png" x="2" y="2" w="180" h="50"/>
<sprite n="Checkbox.png" x="382" y="84" w="50" h="48"/>
<sprite n="CheckboxSelected.png" x="330" y="84" w="50" h="48"/>
<sprite n="Delete.png" x="434" y="98" w="48" h="48"/>
<sprite n="StagingButton.png" x="248" y="54" w="80" h="80"/>
<sprite n="StagingButtonDetacher.png" x="448" y="45" w="51" h="51"/>
<sprite n="StagingButtonEngine.png" x="448" y="2" w="57" h="41" r="y"/>
<sprite n="StagingButtonLander.png" x="166" y="54" w="80" h="80"/>
<sprite n="StagingButtonParachute.png" x="84" y="54" w="80" h="80"/>
<sprite n="StagingButtonSolarPanel.png" x="2" y="54" w="80" h="80"/>
<sprite n="StagingButtonWheel.png" x="366" y="2" w="80" h="80"/>
</TextureAtlas>

View File

@ -1,20 +0,0 @@
<Ship currentStage="0" throttle="0.000000" liftedOff="0">
<Parts>
<Part partType="pod-1" id="1" x="0.000000" y="0.750000" angle="0.000000" angleV="0.000000" activated="0"
exploded="0"/>
<Part partType="fueltank-2" id="9" x="0.000000" y="-2.000000" angle="0.000000" angleV="0.000000">
<Tank fuel="3000.000000"/>
</Part>
<Part partType="engine-2" id="10" x="0.000000" y="-5.500000" angle="0.000000" angleV="0.000000" activated="0"
exploded="0"/>
</Parts>
<Connections>
<Connection parentPart="1" parentAttachPoint="2" childPart="9" childAttachPoint="1"/>
<Connection parentPart="9" parentAttachPoint="2" childPart="10" childAttachPoint="1"/>
</Connections>
<Staging>
<Step>
<Activate Id="10"/>
</Step>
</Staging>
</Ship>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with TexturePacker http://www.codeandweb.com/texturepacker-->
<!-- $TexturePacker:SmartUpdate:a0aa9bc6be2bb5655cb4fa4a2170882a:21e08bdb23ee9b7670b2173fb0910c4a:816c6a1ba5837d6940814a1777d8d132$ -->
<!--Format:
n => name of the sprite
x => sprite x pos in texture
y => sprite y pos in texture
w => sprite width (may be trimmed)
h => sprite height (may be trimmed)
oX => sprite's x-corner offset (only available if trimmed)
oY => sprite's y-corner offset (only available if trimmed)
oW => sprite's original width (only available if trimmed)
oH => sprite's original height (only available if trimmed)
r => 'y' only set if sprite is rotated
-->
<TextureAtlas imagePath="Editor.png" width="512" height="512">
<sprite n="ButtonDarkSide.png" x="508" y="2" w="2" h="100"/>
<sprite n="ButtonLightSide.png" x="2" y="508" w="100" h="2" r="y"/>
<sprite n="DeleteButton.png" x="364" y="148" w="32" h="32"/>
<sprite n="DuplicateButton.png" x="406" y="84" w="80" h="80"/>
<sprite n="MirrorButton.png" x="324" y="14" w="80" h="80"/>
<sprite n="PartButton.png" x="2" y="2" w="320" h="100"/>
<sprite n="PartGroupHeader.PNG" x="2" y="104" w="45" h="320" r="y"/>
<sprite n="RotateButton.png" x="426" y="2" w="80" h="80"/>
<sprite n="ToolbarDark.PNG" x="324" y="8" w="100" h="4" r="y"/>
<sprite n="ToolbarIconAddPart.PNG" x="312" y="148" w="50" h="50"/>
<sprite n="ToolbarIconMenu.PNG" x="260" y="104" w="50" h="50"/>
<sprite n="ToolbarIconPlay.PNG" x="208" y="104" w="50" h="50"/>
<sprite n="ToolbarIconStaging.PNG" x="156" y="104" w="50" h="50"/>
<sprite n="ToolbarIconZoom.png" x="49" y="104" w="50" h="50"/>
<sprite n="ToolbarIconZoomIn.png" x="104" y="104" w="50" h="50"/>
<sprite n="ToolbarIconZoomOut.png" x="324" y="96" w="50" h="50"/>
<sprite n="ToolbarLight.PNG" x="324" y="2" w="100" h="4" r="y"/>
<sprite n="TrashCan.png" x="2" y="426" w="80" h="80"/>
</TextureAtlas>

View File

@ -1,8 +0,0 @@
<Ship currentStage="0" throttle="0.000000">
<Parts>
<Part partType="pod-1" id="1" x="0.000000" y="0.750000" angle="0.000000" angleV="0.000000" activated="0"
exploded="0"/>
</Parts>
<Connections/>
<Staging/>
</Ship>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with TexturePacker http://www.codeandweb.com/texturepacker-->
<!-- $TexturePacker:SmartUpdate:022b8f8460f1ea0ff69d1eea14387321:f2fa66d71fbd232ede864add391ceed7:8f9b2e8922d7ab8b20ca16d0ca656275$ -->
<!--Format:
n => name of the sprite
x => sprite x pos in texture
y => sprite y pos in texture
w => sprite width (may be trimmed)
h => sprite height (may be trimmed)
oX => sprite's x-corner offset (only available if trimmed)
oY => sprite's y-corner offset (only available if trimmed)
oW => sprite's original width (only available if trimmed)
oH => sprite's original height (only available if trimmed)
r => 'y' only set if sprite is rotated
-->
<TextureAtlas imagePath="Flame.png" width="256" height="256">
<sprite n="IonFlame-1.png" x="170" y="2" w="58" h="118"/>
<sprite n="RocketFlame-1.png" x="86" y="2" w="82" h="226"/>
<sprite n="RocketFlame-2.png" x="2" y="2" w="82" h="226"/>
</TextureAtlas>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -1,20 +0,0 @@
<Inputs>
<Input id="Activate" name="Activate Stage" key1="Space" key2="None" defaultKey1="Space" defaultKey2="None"/>
<Input id="ThrottleUp" name="Increase Throttle" key1="Shift" key2="Numpad +" defaultKey1="Numpad +"
defaultKey2="="/>
<Input id="ThrottleDown" name="Decrease Throttle" key1="Control" key2="Numpad -" defaultKey1="Numpad -"
defaultKey2="-"/>
<Input id="MaxThrottle" name="Max Throttle" key1="Numpad 1" key2="1" defaultKey1="Numpad 1" defaultKey2="1"/>
<Input id="KillThrottle" name="Kill Throttle" key1="Numpad 0" key2="X" defaultKey1="X" defaultKey2="Numpad 0"/>
<Input id="Left" name="Turn Left" key1="Left" key2="A" defaultKey1="Left" defaultKey2="A"/>
<Input id="Right" name="Turn Right" key1="Right" key2="D" defaultKey1="Right" defaultKey2="D"/>
<Input id="Backward" name="RCS Reverse" key1="Down" key2="S" defaultKey1="Down" defaultKey2="S"/>
<Input id="Forward" name="RCS Forward" key1="Up" key2="W" defaultKey1="Up" defaultKey2="W"/>
<Input id="StrafeLeft" name="RCS Left" key1="Q" key2="None" defaultKey1="Q" defaultKey2="None"/>
<Input id="StrafeRight" name="RCS Right" key1="E" key2="None" defaultKey1="E" defaultKey2="None"/>
<Input id="LockHeading" name="Lock Heading" key1="Enter" key2="None" defaultKey1="Enter" defaultKey2="None"/>
<Input id="SwitchView" name="Toggle Map" key1="Tab" key2="None" defaultKey1="Tab" defaultKey2="None"/>
<Input id="Pause" name="Pause" key1="P" key2="None" defaultKey1="P" defaultKey2="None"/>
<Input id="ZoomIn" name="Zoom In" key1="." key2="None" defaultKey1="." defaultKey2="None"/>
<Input id="ZoomOut" name="Zoom Out" key1="," key2="None" defaultKey1="," defaultKey2="None"/>
</Inputs>

View File

@ -1,240 +0,0 @@
<Runtime time="0.0" firstStageActivated="1" solarSystem="SmolarSystem.xml" shipId="1" podId="1">
<Nodes>
<PlanetNode name="Sun"/>
<PlanetNode name="Smercury" trueAnomaly="-2.404764"/>
<PlanetNode name="Smenus" trueAnomaly="0.853837"/>
<PlanetNode name="Smearth" trueAnomaly="-2.989081"/>
<PlanetNode name="Smoon" trueAnomaly="-0.743971"/>
<ShipNode id="1" planet="Smearth" planetRadius="637100.000000" x="131549.439018" y="988553.871112"
vx="1984.119629" vy="-286.065857">
<Ship version="1" liftedOff="1" touchingGround="0">
<Parts>
<Part partType="pod-1" id="1" x="131591.909721" y="988530.767108" angle="-3.137835"
angleV="0.001361" editorAngle="0">
<Pod throttle="0.000000" name="Player">
<Staging currentStage="1">
<Step>
<Activate Id="71" moved="1"/>
</Step>
</Staging>
</Pod>
</Part>
<Part partType="fueltank-4" id="58" x="131591.904838" y="988532.017353" angle="-3.137835"
angleV="0.001361" editorAngle="0">
<Tank fuel="560.876921"/>
</Part>
<Part partType="fueltank-2" id="70" x="131591.896049" y="988534.517230" angle="-3.138136"
angleV="0.001433" editorAngle="0">
<Tank fuel="2978.133332"/>
</Part>
<Part partType="engine-0" id="71" x="131591.887260" y="988537.017230" angle="-3.138018"
angleV="0.001435" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="rcs-1" id="72" x="131590.643120" y="988535.462909" angle="-3.138136"
angleV="0.001433" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="rcs-1" id="73" x="131593.143120" y="988535.471454" angle="-3.138136"
angleV="0.001433" editorAngle="0" activated="0" exploded="0" flippedX="1" flippedY="0"/>
<Part partType="rcs-1" id="59" x="131593.154838" y="988532.021991" angle="-3.137835"
angleV="0.001361" editorAngle="0" activated="0" exploded="0" flippedX="1" flippedY="0"/>
<Part partType="rcs-1" id="60" x="131590.654838" y="988532.012714" angle="-3.137835"
angleV="0.001361" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="dock-1" id="63" x="131591.913627" y="988529.767108" angle="-3.137835"
angleV="0.001361" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
</Parts>
<Connections>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="1" childPart="58"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="58" childPart="70"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="70" childPart="71"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="70" childPart="72"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="70" childPart="73"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="58" childPart="59"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="58" childPart="60"/>
<Connection parentAttachPoint="1" childAttachPoint="1" parentPart="1" childPart="63"/>
</Connections>
</Ship>
</ShipNode>
<ShipNode id="2" planet="Smearth" planetRadius="637100.000000" x="131549.439018" y="988533.871112"
vx="1984.119629" vy="-286.065857">
<Ship version="1" liftedOff="1" touchingGround="0">
<Parts>
<Part partType="pod-1" id="1" x="131549.439018" y="988533.871112" angle="0.000003"
angleV="-0.000000" editorAngle="0">
<Pod throttle="0.000000" name="Satellite">
<Staging currentStage="5">
<Step>
<Activate Id="44" moved="1"/>
</Step>
<Step>
<Activate Id="62" moved="1"/>
<Activate Id="64" moved="1"/>
<Activate Id="63" moved="1"/>
<Activate Id="60" moved="1"/>
<Activate Id="59" moved="1"/>
<Activate Id="61" moved="1"/>
</Step>
<Step>
<Activate Id="45" moved="1"/>
<Activate Id="46" moved="1"/>
</Step>
<Step>
<Activate Id="68" moved="1"/>
<Activate Id="69" moved="1"/>
</Step>
<Step>
<Activate Id="12" moved="1"/>
<Activate Id="14" moved="1"/>
<Activate Id="15" moved="1"/>
<Activate Id="23" moved="1"/>
</Step>
</Staging>
</Pod>
</Part>
<Part partType="fueltank-3" id="3" x="131549.439018" y="988529.121112" angle="0.000003"
angleV="-0.000000" editorAngle="0">
<Tank fuel="6000.000000"/>
</Part>
<Part partType="solar-1" id="12" x="131550.689018" y="988532.121112" angle="0.000003"
angleV="-0.000000" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="15" x="131548.189018" y="988532.121112" angle="0.000003"
angleV="-0.000000" editorAngle="0" activated="1" exploded="0" flippedX="1" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="23" x="131550.689018" y="988528.121112" angle="0.000003"
angleV="-0.000000" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="14" x="131548.189018" y="988528.121112" angle="0.000004"
angleV="-0.000000" editorAngle="0" activated="1" exploded="0" flippedX="1" flippedY="0"
extension="1.000000"/>
<Part partType="fueltank-2" id="17" x="131549.439018" y="988523.121112" angle="0.000004"
angleV="-0.000000" editorAngle="0">
<Tank fuel="3000.000000"/>
</Part>
<Part partType="fueltank-3" id="43" x="131549.439018" y="988517.121112" angle="3.141601"
angleV="-0.000000" editorAngle="2">
<Tank fuel="6000.000000"/>
</Part>
<Part partType="engine-3" id="44" x="131549.439018" y="988511.121112" angle="0.000008"
angleV="-0.000000" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="port-1" id="19" x="131547.939018" y="988524.121112" angle="0.000004"
angleV="-0.000000" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="port-1" id="16" x="131550.939018" y="988524.121112" angle="0.000004"
angleV="-0.000000" editorAngle="0" activated="0" exploded="0" flippedX="1" flippedY="0"/>
<Part partType="fueltank-0" id="72" x="131547.939995" y="988521.620990" angle="1.570809"
angleV="0.000000" editorAngle="1">
<Tank fuel="750.000000"/>
</Part>
<Part partType="strut-1" id="33" x="131543.439995" y="988521.620990" angle="0.000011"
angleV="0.000000" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="strut-1" id="39" x="131535.439995" y="988521.620868" angle="0.000019"
angleV="0.000000" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="fuselage-1" id="41" x="131530.439995" y="988521.620746" angle="0.000000"
angleV="0.000000" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="fueltank-3" id="40" x="131530.439995" y="988516.620746" angle="3.141593"
angleV="0.000000" editorAngle="2">
<Tank fuel="6000.000000"/>
</Part>
<Part partType="engine-3" id="45" x="131530.439995" y="988510.620746" angle="0.000000"
angleV="0.000000" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="strut-1" id="53" x="131530.439995" y="988526.620990" angle="4.712390"
angleV="-0.000000" editorAngle="3" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="strut-1" id="65" x="131530.439995" y="988534.621112" angle="4.712392"
angleV="-0.000000" editorAngle="3" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="fueltank-3" id="74" x="131531.439995" y="988539.621112" angle="1.570798"
angleV="-0.000000" editorAngle="1">
<Tank fuel="6000.000000"/>
</Part>
<Part partType="solar-1" id="62" x="131535.689995" y="988539.621112" angle="0.000002"
angleV="-0.000000" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="63" x="131527.189995" y="988539.621112" angle="0.000002"
angleV="-0.000000" editorAngle="0" activated="1" exploded="0" flippedX="1" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="64" x="131530.439995" y="988540.871112" angle="1.570799"
angleV="-0.000000" editorAngle="1" activated="1" exploded="0" flippedX="0" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="68" x="131529.189995" y="988521.620746" angle="0.000006"
angleV="-0.000000" editorAngle="0" activated="1" exploded="0" flippedX="1" flippedY="0"
extension="1.000000"/>
<Part partType="fueltank-0" id="73" x="131550.939018" y="988521.621112" angle="4.712385"
angleV="-0.000000" editorAngle="3">
<Tank fuel="750.000000"/>
</Part>
<Part partType="strut-1" id="34" x="131555.439018" y="988521.620990" angle="-0.000029"
angleV="0.000000" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="strut-1" id="35" x="131563.439018" y="988521.620868" angle="-0.000014"
angleV="0.000000" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="fuselage-1" id="42" x="131568.439018" y="988521.620746" angle="-0.000020"
angleV="0.000000" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="fueltank-3" id="37" x="131568.439018" y="988516.620746" angle="3.141593"
angleV="0.000000" editorAngle="2">
<Tank fuel="6000.000000"/>
</Part>
<Part partType="engine-3" id="46" x="131568.439018" y="988510.620746" angle="-0.000000"
angleV="0.000000" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="strut-1" id="50" x="131568.439018" y="988526.620990" angle="4.712388"
angleV="-0.000000" editorAngle="3" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="strut-1" id="67" x="131568.439018" y="988534.621112" angle="4.712386"
angleV="-0.000000" editorAngle="3" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="fueltank-3" id="75" x="131567.439018" y="988539.621112" angle="4.712387"
angleV="-0.000000" editorAngle="3">
<Tank fuel="6000.000000"/>
</Part>
<Part partType="solar-1" id="59" x="131563.189018" y="988539.621112" angle="-0.000003"
angleV="-0.000000" editorAngle="0" activated="1" exploded="0" flippedX="1" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="60" x="131571.689018" y="988539.621112" angle="-0.000003"
angleV="-0.000000" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="61" x="131568.439018" y="988540.871112" angle="4.712386"
angleV="-0.000000" editorAngle="3" activated="1" exploded="0" flippedX="1" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="69" x="131569.689018" y="988521.620746" angle="-0.000006"
angleV="-0.000000" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"
extension="1.000000"/>
</Parts>
<Connections>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="1" childPart="3"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="3" childPart="12"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="3" childPart="15"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="3" childPart="23"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="3" childPart="14"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="3" childPart="17"/>
<Connection parentAttachPoint="2" childAttachPoint="2" parentPart="17" childPart="43"/>
<Connection parentAttachPoint="1" childAttachPoint="1" parentPart="43" childPart="44"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="17" childPart="19"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="17" childPart="16"/>
<Connection parentAttachPoint="3" childAttachPoint="2" parentPart="17" childPart="72"/>
<Connection parentAttachPoint="1" childAttachPoint="4" parentPart="72" childPart="33"/>
<Connection parentAttachPoint="3" childAttachPoint="4" parentPart="33" childPart="39"/>
<Connection parentAttachPoint="3" childAttachPoint="4" parentPart="39" childPart="41"/>
<Connection parentAttachPoint="2" childAttachPoint="2" parentPart="41" childPart="40"/>
<Connection parentAttachPoint="1" childAttachPoint="1" parentPart="40" childPart="45"/>
<Connection parentAttachPoint="1" childAttachPoint="4" parentPart="41" childPart="53"/>
<Connection parentAttachPoint="3" childAttachPoint="4" parentPart="53" childPart="65"/>
<Connection parentAttachPoint="3" childAttachPoint="3" parentPart="65" childPart="74"/>
<Connection parentAttachPoint="2" childAttachPoint="2" parentPart="74" childPart="62"/>
<Connection parentAttachPoint="1" childAttachPoint="1" parentPart="74" childPart="63"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="74" childPart="64"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="41" childPart="68"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="17" childPart="73"/>
<Connection parentAttachPoint="1" childAttachPoint="3" parentPart="73" childPart="34"/>
<Connection parentAttachPoint="4" childAttachPoint="3" parentPart="34" childPart="35"/>
<Connection parentAttachPoint="4" childAttachPoint="3" parentPart="35" childPart="42"/>
<Connection parentAttachPoint="2" childAttachPoint="2" parentPart="42" childPart="37"/>
<Connection parentAttachPoint="1" childAttachPoint="1" parentPart="37" childPart="46"/>
<Connection parentAttachPoint="1" childAttachPoint="4" parentPart="42" childPart="50"/>
<Connection parentAttachPoint="3" childAttachPoint="4" parentPart="50" childPart="67"/>
<Connection parentAttachPoint="3" childAttachPoint="4" parentPart="67" childPart="75"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="75" childPart="59"/>
<Connection parentAttachPoint="1" childAttachPoint="2" parentPart="75" childPart="60"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="75" childPart="61"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="42" childPart="69"/>
</Connections>
</Ship>
</ShipNode>
<PlanetNode name="Smars" trueAnomaly="1.744006"/>
<PlanetNode name="Smupiter" trueAnomaly="1.325657"/>
<PlanetNode name="Smaturn" trueAnomaly="2.222602"/>
<PlanetNode name="Smuranus" trueAnomaly="-2.838979"/>
<PlanetNode name="Smeptune" trueAnomaly="-1.313070"/>
</Nodes>
</Runtime>

View File

@ -1,48 +0,0 @@
<Runtime time="0.0" firstStageActivated="0" solarSystem="SmolarSystem.xml">
<Nodes>
<ShipNode planet="Smoon" x="-3057.363037" y="174798.852783" vx="10" vy="-20">
<Ship currentStage="1" throttle="0.000000" liftedOff="1">
<Parts>
<Part partType="pod-1" id="1" x="-3057.363037" y="176898.852783" angle="-12.598453"
angleV="-0.000199" activated="0" exploded="0"/>
<Part partType="fueltank-1" id="101" x="-3057.419189" y="176897.103516" angle="-12.598453"
angleV="-0.000199">
<Tank fuel="977.479135"/>
</Part>
<Part partType="engine-0" id="102" x="-3057.467529" y="176895.604248" angle="-12.598512"
angleV="-0.000199" activated="1" exploded="0"/>
<Part partType="lander-1" id="103" x="-3058.676758" y="176896.893799" angle="-12.598512"
legAngle="0.000000" angleV="-0.000199" activated="0" exploded="0" lower="0" raise="0"
length="2.260000"/>
<Part partType="lander-1" id="104" x="-3056.177979" y="176896.813477" angle="-12.598512"
legAngle="0.000000" angleV="-0.000199" activated="0" exploded="0" lower="0" raise="0"
length="2.260000"/>
</Parts>
<Connections>
<Connection parentPart="1" parentAttachPoint="2" childPart="101" childAttachPoint="1"/>
<Connection parentPart="101" parentAttachPoint="2" childPart="102" childAttachPoint="1"/>
<Connection parentPart="101" parentAttachPoint="3" childPart="103" childAttachPoint="2"/>
<Connection parentPart="101" parentAttachPoint="4" childPart="104" childAttachPoint="1"/>
</Connections>
<Staging>
<Step>
<Activate Id="102"/>
</Step>
<Step>
<Activate Id="103"/>
<Activate Id="104"/>
</Step>
</Staging>
</Ship>
</ShipNode>
<PlanetNode name="Smercury" trueAnomaly="-2.465148"/>
<PlanetNode name="Smenus" trueAnomaly="0.822420"/>
<PlanetNode name="Smearth" trueAnomaly="-3.013170"/>
<PlanetNode name="Smoon" trueAnomaly="-2.138368"/>
<PlanetNode name="Smars" trueAnomaly="1.734006"/>
<PlanetNode name="Smupiter" trueAnomaly="1.324001"/>
<PlanetNode name="Smaturn" trueAnomaly="2.222000"/>
<PlanetNode name="Smuranus" trueAnomaly="-2.839185"/>
<PlanetNode name="Smeptune" trueAnomaly="-1.313185"/>
</Nodes>
</Runtime>

View File

@ -1,36 +0,0 @@
<Runtime time="0.0" firstStageActivated="0" solarSystem="SmolarSystem.xml">
<Nodes>
<ShipNode planet="Smearth" x="0.000420" y="637105.765029" vx="-0.000007" vy="-0.000000">
<Ship currentStage="0" throttle="0.000000" liftedOff="0">
<Parts>
<Part partType="pod-1" id="1" x="0.000420" y="637105.765029" angle="-0.000045" angleV="0.000003"
activated="0" exploded="0"/>
<Part partType="fueltank-0" id="210" x="0.000364" y="637104.515029" angle="-0.000045"
angleV="0.000004">
<Tank fuel="750.000000"/>
</Part>
<Part partType="engine-3" id="211" x="0.000253" y="637102.015029" angle="-0.000044"
angleV="0.000000" activated="0" exploded="0"/>
</Parts>
<Connections>
<Connection parentPart="1" parentAttachPoint="2" childPart="210" childAttachPoint="1"/>
<Connection parentPart="210" parentAttachPoint="2" childPart="211" childAttachPoint="1"/>
</Connections>
<Staging>
<Step>
<Activate Id="211"/>
</Step>
</Staging>
</Ship>
</ShipNode>
<PlanetNode name="Smercury" trueAnomaly="-2.465148"/>
<PlanetNode name="Smenus" trueAnomaly="0.822420"/>
<PlanetNode name="Smearth" trueAnomaly="-3.013170"/>
<PlanetNode name="Smoon" trueAnomaly="-2.138368"/>
<PlanetNode name="Smars" trueAnomaly="1.734006"/>
<PlanetNode name="Smupiter" trueAnomaly="1.324001"/>
<PlanetNode name="Smaturn" trueAnomaly="2.222000"/>
<PlanetNode name="Smuranus" trueAnomaly="-2.839185"/>
<PlanetNode name="Smeptune" trueAnomaly="-1.313185"/>
</Nodes>
</Runtime>

View File

@ -1,36 +0,0 @@
<Runtime time="0.0" firstStageActivated="1" solarSystem="SmolarSystem.xml">
<Nodes>
<ShipNode planet="Smearth" x="25086.400629" y="739149.589172" vx="287.729248" vy="608.873779">
<Ship currentStage="1" throttle="0.000000" liftedOff="1">
<Parts>
<Part partType="pod-1" id="1" x="25086.400629" y="739149.589172" angle="-0.630828"
angleV="-0.001682" activated="0" exploded="0"/>
<Part partType="fueltank-2" id="28" x="25084.778650" y="739147.368408" angle="-0.630828"
angleV="-0.001682">
<Tank fuel="3000"/>
</Part>
<Part partType="engine-2" id="29" x="25082.714319" y="739144.541992" angle="-0.630820"
angleV="-0.001677" activated="1" exploded="0"/>
</Parts>
<Connections>
<Connection parentPart="1" parentAttachPoint="2" childPart="28" childAttachPoint="1"/>
<Connection parentPart="28" parentAttachPoint="2" childPart="29" childAttachPoint="1"/>
</Connections>
<Staging>
<Step>
<Activate Id="29"/>
</Step>
</Staging>
</Ship>
</ShipNode>
<PlanetNode name="Smercury" trueAnomaly="-2.465148"/>
<PlanetNode name="Smenus" trueAnomaly="0.822420"/>
<PlanetNode name="Smearth" trueAnomaly="-3.013170"/>
<PlanetNode name="Smoon" trueAnomaly="-2.138368"/>
<PlanetNode name="Smars" trueAnomaly="1.734006"/>
<PlanetNode name="Smupiter" trueAnomaly="1.324001"/>
<PlanetNode name="Smaturn" trueAnomaly="2.222000"/>
<PlanetNode name="Smuranus" trueAnomaly="-2.839185"/>
<PlanetNode name="Smeptune" trueAnomaly="-1.313185"/>
</Nodes>
</Runtime>

View File

@ -1,128 +0,0 @@
<Runtime time="0.0" firstStageActivated="1" solarSystem="SmolarSystem.xml" shipId="4" podId="1">
<Nodes>
<PlanetNode name="Sun"/>
<PlanetNode name="Smercury" trueAnomaly="-2.404510"/>
<PlanetNode name="Smenus" trueAnomaly="0.853968"/>
<PlanetNode name="Smearth" trueAnomaly="-2.988980"/>
<PlanetNode name="Smoon" trueAnomaly="-0.737760"/>
<ShipNode id="2" planet="Smearth" planetRadius="637100.000000" x="293193.647224" y="949345.454115"
vx="-1913.992432" vy="625.777344">
<Ship version="1" liftedOff="1" touchingGround="0">
<Parts>
<Part partType="pod-1" id="124" x="293193.647224" y="949345.454115" angle="0.002169"
angleV="0.000000" editorAngle="0">
<Pod throttle="0.000000" name="Satellite">
<Staging currentStage="3">
<Step/>
<Step>
<Activate Id="127" moved="1"/>
<Activate Id="128" moved="1"/>
</Step>
<Step/>
</Staging>
</Pod>
</Part>
<Part partType="fueltank-2" id="125" x="293193.652106" y="949342.704115" angle="0.002169"
angleV="0.000000" editorAngle="0">
<Tank fuel="0.000000"/>
</Part>
<Part partType="port-1" id="126" x="293193.657966" y="949340.204115" angle="1.572965"
angleV="0.000000" editorAngle="1" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="solar-1" id="127" x="293194.901130" y="949343.206801" angle="0.002165"
angleV="0.000000" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="128" x="293192.402106" y="949343.201430" angle="0.002184"
angleV="0.000000" editorAngle="0" activated="1" exploded="0" flippedX="1" flippedY="0"
extension="1.000000"/>
</Parts>
<Connections>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="124" childPart="125"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="125" childPart="126"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="125" childPart="127"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="125" childPart="128"/>
</Connections>
</Ship>
</ShipNode>
<ShipNode id="4" planet="Smearth" planetRadius="637100.000000" x="293193.647224" y="949307.663588"
vx="-1913.992065" vy="625.777283">
<Ship version="1" liftedOff="1" touchingGround="0">
<Parts>
<Part partType="pod-1" id="1" x="293193.533942" y="949307.663588" angle="0.003367" angleV="0.000254"
editorAngle="0">
<Pod throttle="0.000000" name="Player">
<Staging currentStage="1">
<Step>
<Activate Id="104" moved="1"/>
</Step>
<Step>
<Activate Id="105" moved="1"/>
<Activate Id="106" moved="1"/>
<Activate Id="118" moved="1"/>
<Activate Id="117" moved="1"/>
</Step>
</Staging>
</Pod>
</Part>
<Part partType="dock-1" id="94" x="293193.531013" y="949308.663832" angle="0.003367"
angleV="0.000254" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="fueltank-4" id="98" x="293193.539802" y="949306.413588" angle="0.003367"
angleV="0.000254" editorAngle="0">
<Tank fuel="748.218618"/>
</Part>
<Part partType="rcs-1" id="102" x="293192.290778" y="949306.159682" angle="0.003367"
angleV="0.000254" editorAngle="0" activated="0" exploded="0" flippedX="1" flippedY="0"/>
<Part partType="rcs-1" id="101" x="293194.790778" y="949306.167983" angle="0.003367"
angleV="0.000254" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="fuselage-1" id="116" x="293193.542731" y="949304.913588" angle="0.002908"
angleV="0.000247" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="fueltank-2" id="97" x="293193.550544" y="949301.914076" angle="0.002562"
angleV="0.000318" editorAngle="0">
<Tank fuel="1495.416588"/>
</Part>
<Part partType="parachute-1" id="106" x="293192.298591" y="949302.410902" angle="1.573358"
angleV="0.000318" editorAngle="1" activated="0" exploded="0" flippedX="0" flippedY="0"
chuteX="293192.298591" chuteY="949302.410902" chuteAngle="0.000000" chuteHeight="0.000000"
inflation="0.100000" inflate="0" deployed="0" rope="0"/>
<Part partType="parachute-1" id="105" x="293194.798591" y="949302.417250" angle="4.714948"
angleV="0.000317" editorAngle="3" activated="0" exploded="0" flippedX="0" flippedY="0"
chuteX="293194.798591" chuteY="949302.417250" chuteAngle="0.000000" chuteHeight="0.000000"
inflation="0.100000" inflate="0" deployed="0" rope="0"/>
<Part partType="rcs-1" id="99" x="293194.804450" y="949300.667494" angle="0.002562"
angleV="0.000318" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="rcs-1" id="100" x="293192.304450" y="949300.660658" angle="0.002562"
angleV="0.000318" editorAngle="0" activated="0" exploded="0" flippedX="1" flippedY="0"/>
<Part partType="engine-1" id="104" x="293193.557380" y="949298.914076" angle="0.002547"
angleV="0.000317" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="parachute-1" id="118" x="293192.294685" y="949304.409926" angle="1.573830"
angleV="0.000242" editorAngle="1" activated="0" exploded="0" flippedX="0" flippedY="0"
chuteX="293192.294685" chuteY="949304.409926" chuteAngle="0.000000" chuteHeight="0.000000"
inflation="0.100000" inflate="0" deployed="0" rope="0"/>
<Part partType="parachute-1" id="117" x="293194.794685" y="949304.417250" angle="4.715351"
angleV="0.000243" editorAngle="3" activated="0" exploded="0" flippedX="0" flippedY="0"
chuteX="293194.794685" chuteY="949304.417250" chuteAngle="0.000000" chuteHeight="0.000000"
inflation="0.100000" inflate="0" deployed="0" rope="0"/>
</Parts>
<Connections>
<Connection parentAttachPoint="1" childAttachPoint="1" parentPart="1" childPart="94"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="1" childPart="98"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="98" childPart="102"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="98" childPart="101"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="98" childPart="116"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="116" childPart="97"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="97" childPart="106"/>
<Connection parentAttachPoint="4" childAttachPoint="1" parentPart="97" childPart="105"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="97" childPart="99"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="97" childPart="100"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="97" childPart="104"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="116" childPart="118"/>
<Connection parentAttachPoint="4" childAttachPoint="1" parentPart="116" childPart="117"/>
</Connections>
</Ship>
</ShipNode>
<PlanetNode name="Smars" trueAnomaly="1.744047"/>
<PlanetNode name="Smupiter" trueAnomaly="1.325664"/>
<PlanetNode name="Smaturn" trueAnomaly="2.222605"/>
<PlanetNode name="Smuranus" trueAnomaly="-2.838978"/>
<PlanetNode name="Smeptune" trueAnomaly="-1.313069"/>
</Nodes>
</Runtime>

View File

@ -1,151 +0,0 @@
<Runtime time="0.0" firstStageActivated="1" solarSystem="SmolarSystem.xml" shipId="1">
<Nodes>
<PlanetNode name="Sun"/>
<PlanetNode name="Smercury" trueAnomaly="-2.404911"/>
<PlanetNode name="Smenus" trueAnomaly="0.853761"/>
<PlanetNode name="Smearth" trueAnomaly="-2.989139"/>
<PlanetNode name="Smoon" trueAnomaly="-0.747577"/>
<ShipNode id="1" planet="Smearth" planetRadius="637100.000000" x="-15172.142281" y="998816.115241"
vx="2001.279663" vy="6.664629">
<Ship version="1" liftedOff="1" touchingGround="0">
<Parts>
<Part partType="pod-1" id="1" x="-8.231614" y="637101.491850" angle="1.570840" angleV="0.000000"
editorAngle="0">
<Pod throttle="0.000000" name="Player">
<Staging currentStage="1">
<Step>
<Activate Id="71" moved="1"/>
</Step>
</Staging>
</Pod>
</Part>
<Part partType="fueltank-4" id="58" x="-6.981614" y="637101.491905" angle="1.570840"
angleV="0.000000" editorAngle="0">
<Tank fuel="679.000000"/>
</Part>
<Part partType="fueltank-2" id="70" x="-4.481614" y="637101.492015" angle="1.570840"
angleV="0.000000" editorAngle="0">
<Tank fuel="2978.133332"/>
</Part>
<Part partType="engine-0" id="71" x="-1.981614" y="637101.492126" angle="1.570840" angleV="0.000000"
editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="rcs-1" id="72" x="-3.531669" y="637102.742057" angle="1.570840" angleV="0.000000"
editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="rcs-1" id="73" x="-3.531559" y="637100.242057" angle="1.570840" angleV="0.000000"
editorAngle="0" activated="0" exploded="0" flippedX="1" flippedY="0"/>
<Part partType="rcs-1" id="59" x="-6.981559" y="637100.241905" angle="1.570840" angleV="0.000000"
editorAngle="0" activated="0" exploded="0" flippedX="1" flippedY="0"/>
<Part partType="rcs-1" id="60" x="-6.981669" y="637102.741905" angle="1.570840" angleV="0.000000"
editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="dock-1" id="63" x="-9.231614" y="637101.491806" angle="1.570840" angleV="0.000000"
editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
</Parts>
<Connections>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="1" childPart="58"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="58" childPart="70"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="70" childPart="71"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="70" childPart="72"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="70" childPart="73"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="58" childPart="59"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="58" childPart="60"/>
<Connection parentAttachPoint="1" childAttachPoint="1" parentPart="1" childPart="63"/>
</Connections>
</Ship>
</ShipNode>
<ShipNode id="2" planet="Smearth" planetRadius="637100.000000" x="-15212.142281" y="998816.115241"
vx="2001.279663" vy="6.664629">
<Ship version="1" liftedOff="1" touchingGround="0">
<Parts>
<Part partType="pod-1" id="1" x="-15212.142281" y="998816.115241" angle="32.987629"
angleV="0.000000" editorAngle="0">
<Pod throttle="0.000000" name="Satellite">
<Staging currentStage="3">
<Step/>
<Step/>
<Step>
<Activate Id="45" moved="1"/>
<Activate Id="32" moved="1"/>
<Activate Id="33" moved="1"/>
<Activate Id="42" moved="1"/>
<Activate Id="43" moved="1"/>
<Activate Id="14" moved="1"/>
<Activate Id="16" moved="1"/>
</Step>
<Step>
<Activate Id="44" moved="1"/>
<Activate Id="29" moved="1"/>
</Step>
</Staging>
</Pod>
</Part>
<Part partType="fueltank-2" id="17" x="-15209.392281" y="998816.117713" angle="32.987629"
angleV="0.000000" editorAngle="0">
<Tank fuel="3000.000000"/>
</Part>
<Part partType="fueltank-2" id="39" x="-15205.392281" y="998816.121434" angle="32.987637"
angleV="0.000000" editorAngle="0">
<Tank fuel="3000.000000"/>
</Part>
<Part partType="detacher-1" id="44" x="-15203.142281" y="998816.123316" angle="32.987789"
angleV="0.000000" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="fueltank-1" id="28" x="-15201.892281" y="998816.124556" angle="32.987789"
angleV="0.000000" editorAngle="0">
<Tank fuel="1500.000000"/>
</Part>
<Part partType="detacher-1" id="29" x="-15200.642281" y="998816.125909" angle="32.987816"
angleV="0.000000" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="fueltank-2" id="26" x="-15198.392281" y="998816.128252" angle="32.987816"
angleV="0.000000" editorAngle="0">
<Tank fuel="2781.599989"/>
</Part>
<Part partType="solar-1" id="32" x="-15198.391305" y="998814.878252" angle="32.987816"
angleV="0.000000" editorAngle="0" activated="1" exploded="0" flippedX="1" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="33" x="-15198.393990" y="998817.378252" angle="32.987804"
angleV="0.000000" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"
extension="1.000000"/>
<Part partType="engine-0" id="45" x="-15195.892281" y="998816.130977" angle="32.987785"
angleV="0.000000" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="port-1" id="37" x="-15201.890817" y="998814.624556" angle="32.987789"
angleV="0.000000" editorAngle="0" activated="0" exploded="0" flippedX="0" flippedY="0"/>
<Part partType="port-1" id="38" x="-15201.893746" y="998817.624555" angle="32.987789"
angleV="0.000000" editorAngle="0" activated="0" exploded="0" flippedX="1" flippedY="0"/>
<Part partType="solar-1" id="43" x="-15205.393258" y="998817.371433" angle="32.987621"
angleV="0.000000" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="42" x="-15205.391305" y="998814.871433" angle="32.987667"
angleV="0.000000" editorAngle="0" activated="1" exploded="0" flippedX="1" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="16" x="-15209.391305" y="998814.867712" angle="32.987640"
angleV="0.000000" editorAngle="0" activated="1" exploded="0" flippedX="1" flippedY="0"
extension="1.000000"/>
<Part partType="solar-1" id="14" x="-15209.393258" y="998817.367712" angle="32.987614"
angleV="0.000000" editorAngle="0" activated="1" exploded="0" flippedX="0" flippedY="0"
extension="1.000000"/>
</Parts>
<Connections>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="1" childPart="17"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="17" childPart="39"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="39" childPart="44"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="44" childPart="28"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="28" childPart="29"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="29" childPart="26"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="26" childPart="32"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="26" childPart="33"/>
<Connection parentAttachPoint="2" childAttachPoint="1" parentPart="26" childPart="45"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="28" childPart="37"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="28" childPart="38"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="39" childPart="43"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="39" childPart="42"/>
<Connection parentAttachPoint="3" childAttachPoint="1" parentPart="17" childPart="16"/>
<Connection parentAttachPoint="4" childAttachPoint="2" parentPart="17" childPart="14"/>
</Connections>
</Ship>
</ShipNode>
<PlanetNode name="Smars" trueAnomaly="1.743982"/>
<PlanetNode name="Smupiter" trueAnomaly="1.325653"/>
<PlanetNode name="Smaturn" trueAnomaly="2.222601"/>
<PlanetNode name="Smuranus" trueAnomaly="-2.838979"/>
<PlanetNode name="Smeptune" trueAnomaly="-1.313070"/>
</Nodes>
</Runtime>

View File

@ -1,51 +0,0 @@
<Runtime time="0.0" firstStageActivated="1" solarSystem="SmolarSystem.xml">
<Nodes>
<PlanetNode name="Sun"/>
<PlanetNode name="Smercury" trueAnomaly="-2.461478"/>
<PlanetNode name="Smenus" trueAnomaly="0.824347"/>
<PlanetNode name="Smearth" trueAnomaly="-3.011693"/>
<PlanetNode name="Smoon" trueAnomaly="-0.558472"/>
<PlanetNode name="Smars" trueAnomaly="1.734620"/>
<PlanetNode name="Smupiter" trueAnomaly="1.324103"/>
<PlanetNode name="Smaturn" trueAnomaly="2.222037"/>
<PlanetNode name="Smuranus" trueAnomaly="-2.839172"/>
<PlanetNode name="Smeptune" trueAnomaly="-1.313178"/>
<ShipNode planet="Smearth" planetRadius="637100.000000" x="-6911387.325043" y="-7847054.502014" vx="416.325691"
vy="-404.786621">
<Ship currentStage="1" throttle="0.000000" liftedOff="1">
<Parts>
<Part partType="pod-1" id="1" x="34.123276" y="174041.952026" angle="-2.211172" angleV="-0.021909"
activated="0" exploded="0"/>
<Part partType="parachute-1" id="469" x="34.925148" y="174041.354523" angle="-2.211188"
angleV="-0.021736" activated="0" exploded="0" chuteX="34.925148" chuteY="174041.354523"
chuteAngle="0.000000" chuteHeight="0.000000" inflation="0.100000" inflate="0" deployed="0"/>
<Part partType="detacher-1" id="473" x="33.321407" y="174042.549500" angle="-2.211172"
angleV="-0.022005" activated="0" exploded="0"/>
<Part partType="fueltank-0" id="471" x="32.720005" y="174042.997620" angle="-2.211172"
angleV="-0.022005">
<Tank fuel="707.999998"/>
</Part>
<Part partType="engine-0" id="468" x="31.918139" y="174043.595123" angle="-2.211173"
angleV="-0.022095" activated="1" exploded="0"/>
</Parts>
<Connections>
<Connection parentPart="1" parentAttachPoint="1" childPart="469" childAttachPoint="1"/>
<Connection parentPart="1" parentAttachPoint="2" childPart="473" childAttachPoint="1"/>
<Connection parentPart="473" parentAttachPoint="2" childPart="471" childAttachPoint="1"/>
<Connection parentPart="471" parentAttachPoint="2" childPart="468" childAttachPoint="1"/>
</Connections>
<Staging>
<Step>
<Activate Id="468" moved="0"/>
</Step>
<Step>
<Activate Id="473" moved="0"/>
</Step>
<Step>
<Activate Id="469" moved="0"/>
</Step>
</Staging>
</Ship>
</ShipNode>
</Nodes>
</Runtime>

View File

@ -1,63 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with TexturePacker http://www.codeandweb.com/texturepacker-->
<!-- $TexturePacker:SmartUpdate:16abe940d658d4eeb641856d6352513c:f50dd8f5fe87f7c9efd5f5ad1b1735c2:b4da9324b5d92c57b73a9c864dd87fbf$ -->
<!--Format:
n => name of the sprite
x => sprite x pos in texture
y => sprite y pos in texture
w => sprite width (may be trimmed)
h => sprite height (may be trimmed)
oX => sprite's x-corner offset (only available if trimmed)
oY => sprite's y-corner offset (only available if trimmed)
oW => sprite's original width (only available if trimmed)
oH => sprite's original height (only available if trimmed)
r => 'y' only set if sprite is rotated
-->
<TextureAtlas imagePath='Menu.png' width='1024' height='1024'>
<sprite n='BackButton.png' x='970' y='2' w='50' h='42' r='y'/>
<sprite n='Button-Complete.png' x='994' y='489' w='20' h='19'/>
<sprite n='ButtonBackground.png' x='2' y='228' w='143' h='143'/>
<sprite n='ButtonFrame.png' x='662' y='81' w='145' h='145'/>
<sprite n='EmptyButtonFrame.png' x='515' y='81' w='145' h='145'/>
<sprite n='GameIconDummyDefense.png' x='355' y='149' w='142' h='141' r='y'/>
<sprite n='GameIconKerbal.PNG' x='2' y='575' w='143' h='143'/>
<sprite n='GameIconSimplePhysics.png' x='2' y='373' w='138' h='139'/>
<sprite n='GameIconSimplePlanes.png' x='147' y='228' w='141' h='142'/>
<sprite n='Header.PNG' x='515' y='2' w='306' h='77'/>
<sprite n='IconAbout.png' x='212' y='515' w='56' h='56'/>
<sprite n='IconCommunity.PNG' x='270' y='474' w='66' h='70'/>
<sprite n='IconExit.png' x='254' y='677' w='67' h='69'/>
<sprite n='IconLevelBlastOffPractice.png' x='174' y='149' w='92' h='76'/>
<sprite n='IconLevelDocking.png' x='68' y='940' w='105' h='74' r='y'/>
<sprite n='IconLevelDockingHard.png' x='2' y='833' w='74' h='105'/>
<sprite n='IconLevelEconomyOrbit.png' x='78' y='833' w='56' h='103' r='y'/>
<sprite n='IconLevelLandingPractice.png' x='2' y='149' w='92' h='77'/>
<sprite n='IconLevelLowFlyer.png' x='2' y='940' w='64' h='75' r='y'/>
<sprite n='IconLevelMaxSpeed.png' x='970' y='328' w='33' h='80'/>
<sprite n='IconLevelOptimumTrajectory.png' x='290' y='226' w='63' h='109' r='y'/>
<sprite n='IconLevelParachute.png' x='175' y='927' w='70' h='70'/>
<sprite n='IconLevelSmearthOrbit.png' x='96' y='720' w='54' h='103' r='y'/>
<sprite n='IconLevelSmoonLanding.png' x='268' y='149' w='85' h='75' r='y'/>
<sprite n='IconLevelSmoonOrbit.PNG' x='970' y='46' w='44' h='103' r='y'/>
<sprite n='IconLevelSmoonPunch.png' x='2' y='720' w='92' h='111' r='y'/>
<sprite n='IconSandboxSmars.png' x='238' y='779' w='100' h='100'/>
<sprite n='IconSandboxSmaturn.png' x='437' y='292' w='100' h='100'/>
<sprite n='IconSandboxSmearth.png' x='338' y='439' w='100' h='100'/>
<sprite n='IconSandboxSmenus.png' x='335' y='337' w='100' h='100'/>
<sprite n='IconSandboxSmeptune.png' x='249' y='575' w='100' h='100'/>
<sprite n='IconSandboxSmercury.png' x='152' y='677' w='100' h='100'/>
<sprite n='IconSandboxSmoon.png' x='233' y='372' w='100' h='100'/>
<sprite n='IconSandboxSmupiter.png' x='147' y='575' w='100' h='100'/>
<sprite n='IconSandboxSmuranus.png' x='136' y='825' w='100' h='100'/>
<sprite n='IconSettings.png' x='499' y='228' w='60' h='60'/>
<sprite n='IconTrainingAdvOrbit.png' x='107' y='515' w='103' h='56'/>
<sprite n='IconTrainingBuild.png' x='970' y='234' w='40' h='92'/>
<sprite n='IconTrainingDesign.png' x='96' y='149' w='76' h='77'/>
<sprite n='IconTrainingFlying.png' x='970' y='151' w='42' h='81'/>
<sprite n='IconTrainingOrbit.png' x='2' y='515' w='103' h='56'/>
<sprite n='IconTrainingSmearthOrbit.png' x='142' y='373' w='89' h='113' r='y'/>
<sprite n='IconlevelMaxThrust.png' x='970' y='410' w='33' h='77'/>
<sprite n='ModIcon.png' x='970' y='489' w='22' h='84' r='y'/>
<sprite n='SkinsButton.png' x='823' y='2' w='145' h='511' r='y'/>
<sprite n='SolarSystemButton.png' x='2' y='2' w='511' h='145'/>
</TextureAtlas>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Some files were not shown because too many files have changed in this diff Show More