Compare commits
3 Commits
main
...
second-dev
Author | SHA1 | Date | |
---|---|---|---|
2ee3b96a45 | |||
5042f490da | |||
9fb2f717ea |
3
.gitignore
vendored
@ -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
@ -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:
|
||||
|
@ -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
|
@ -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'))
|
@ -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
|
@ -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)
|
@ -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!
|
@ -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'
|
@ -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
|
@ -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()))
|
19
Difficult_Rocket/utils/cprint/CMakeLists.txt
Normal 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)
|
12
Difficult_Rocket/utils/cprint/build.ps1
Normal 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
|
66
Difficult_Rocket/utils/cprint/color_print.py
Normal 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)
|
11
Difficult_Rocket/utils/cprint/colors.py
Normal 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')
|
41
Difficult_Rocket/utils/cprint/compile.py
Normal 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)
|
||||
|
30
Difficult_Rocket/utils/cprint/cprint.c
Normal 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;
|
||||
};
|
9
Difficult_Rocket/utils/cprint/dll_load.py
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
from objprint import objprint
|
||||
|
||||
from ctypes import cdll
|
||||
|
||||
cprint = cdll.LoadLibrary("./cprint.dll")
|
||||
|
||||
# objprint(cprint)
|
||||
|
65
Difficult_Rocket/utils/cprint/py_cprint.c
Normal 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);
|
||||
}
|
17
Difficult_Rocket/utils/cprint/py_cprint.py
Normal 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")
|
@ -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: ... # 测试中
|
30
Difficult_Rocket/utils/cprint/setup.py
Normal 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]), './')
|
15
Difficult_Rocket/utils/cprint/test.ps1
Normal 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 ---------------------结束测试---------------------
|
27
README.md
@ -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基本无关
|
||||
|
||||
[](https://Semver.org/)
|
||||
[](https://Python.org)
|
||||
[](https://pyglet.org)
|
||||
[](https://Python.org)
|
||||
|
||||
## 版本
|
||||
|
||||
[](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||
[](https://github.com/shenjackyuanjie/Difficult-Rocket/releases)
|
||||
[](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
25
SRtool/__init__.py
Normal 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
@ -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
|
@ -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
@ -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
@ -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
@ -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'))
|
@ -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
@ -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.外框距离
|
@ -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()
|
@ -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
@ -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)
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
'Solar System': {
|
||||
'description': '',
|
||||
'planets': {
|
||||
'earth': {
|
||||
'description': '',
|
||||
'gravity': 9.81,
|
||||
'radius': 63710000,
|
||||
'map_color': [
|
||||
103,
|
||||
157,
|
||||
255
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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'
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
theme: jekyll-theme-slate
|
@ -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'
|
||||
]
|
||||
}
|
||||
}
|
@ -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'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
'keys': {
|
||||
'function-1': 'keys-1',
|
||||
'function-2': 'keys-2'
|
||||
}
|
||||
}
|
@ -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'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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)'
|
||||
}
|
Before Width: | Height: | Size: 454 KiB |
Before Width: | Height: | Size: 402 KiB |
Before Width: | Height: | Size: 571 KiB |
Before Width: | Height: | Size: 366 KiB |
@ -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 |
|
||||
|
||||
# 文件范例
|
||||
|
||||
# 中文简称 文件名`英文名称`
|
||||
|
||||
## 日期
|
||||
|
||||
## 发起人
|
||||
|
||||
## 状态
|
||||
|
||||
## 描述
|
||||
|
||||
### 底层机制 `实现方法(大致)`
|
||||
|
||||
### 效果
|
||||
|
||||
## 别的什么的
|
@ -1,29 +0,0 @@
|
||||
# 存档额外信息 extra save info
|
||||
|
||||
## 20210514
|
||||
|
||||
## shenjackyuanjie
|
||||
|
||||
## planing
|
||||
|
||||
## 描述
|
||||
|
||||
存档中会额外保存一些信息
|
||||
|
||||
### 底层机制
|
||||
|
||||
保存存档时会读取 `partlist` 中的部件信息
|
||||
|
||||
比如部件碰撞箱、重量等
|
||||
|
||||
并保存到存档中
|
||||
|
||||
### 效果
|
||||
|
||||
存档会根据部件使用情况
|
||||
|
||||
增大体积(直到所有种类的部件都被用)
|
||||
|
||||
## 别的什么的
|
||||
|
||||
没了
|
@ -1,15 +0,0 @@
|
||||
# 部件可成环 multi-connect
|
||||
|
||||
## 2021-4-25
|
||||
|
||||
## shenjackyuanjie(writer)
|
||||
|
||||
## 描述
|
||||
|
||||
### 底层机制
|
||||
|
||||
单个部件可以同时连接到2个或两个以上部件
|
||||
|
||||
### 效果
|
||||
|
||||
可以搞点 环世界 之类的巨构
|
@ -1,32 +0,0 @@
|
||||
# 多指令舱控制 multi-control
|
||||
|
||||
## 2021-4-25
|
||||
|
||||
## shenjackyuanjie(writer)
|
||||
|
||||
## planing
|
||||
|
||||
## 描述
|
||||
|
||||
### 示例1
|
||||
|
||||
可以让多个指令舱同时进行动作
|
||||
|
||||
比如一个空间站由很多部分组成
|
||||
|
||||
每一个部分都由不同的指令舱控制
|
||||
|
||||
多指令舱控制就可以实现空间站所有部分统一加速、减速
|
||||
|
||||
其实也是某种程度上的统一控制
|
||||
|
||||
### 示例2
|
||||
|
||||
在同时发射多枚火箭/卫星时
|
||||
|
||||
可以让火箭在操作其他火箭的时候继续燃烧
|
||||
|
||||
(就是说操纵A火箭的时候,B火箭还能继续燃烧)
|
||||
|
||||
### 底层机制
|
||||
|
@ -1,15 +0,0 @@
|
||||
# 中文简称 文件名
|
||||
|
||||
## 日期
|
||||
|
||||
## 发起人
|
||||
|
||||
## 状态
|
||||
|
||||
## 描述
|
||||
|
||||
### 底层机制
|
||||
|
||||
### 效果
|
||||
|
||||
## 别的什么的
|
28
docs/rua!.md
@ -1,28 +0,0 @@
|
||||
# pyglet相关
|
||||
|
||||
pyglet 坐标轴原点是左上角
|
||||
|
||||
# 坐标记录相关
|
||||
|
||||
记录的是部件碰撞箱中心的相对于控制仓碰撞箱中心的相对坐标
|
||||
|
||||
然后控制仓的坐标是单独记录的
|
||||
|
||||
记录的是区块坐标+区块内坐标
|
||||
|
||||
# 渲染
|
||||
|
||||
屏幕坐标系需要*100(有待测试)
|
||||
|
||||
# 素材提供
|
||||
|
||||
[背景候选1号](background.png)
|
||||
来自 @底层萌新 QQ:1744251171
|
||||
|
||||
| 项目 | 油麦菜 | 小白菜 | 绿萝 |
|
||||
| :----: | :----: | :----: | :----: |
|
||||
| 对照组 | 882 | 625 | 117 |
|
||||
| 40° (高温) | --- | 646 | --- |
|
||||
| 50° (高温) | 639 | 580 | --- |
|
||||
| 60° (高温) | 1094 | 400 | --- |
|
||||
| 70° (高温) | 674 | 1054 | --- |
|
@ -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
|
||||
[](https://Semver.org/)
|
||||

|
||||

|
||||
|
||||
- [](https://github.com/shenjackyuanjie/Difficult-Rocket)
|
||||
- [](https://gitee.com/shenjackyuanjie/Difficult-Rocket)
|
||||
- [-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` 和协议 (`LICENSE.txt`))
|
||||
[Add soon been replace by MCDR]: <> ( - Add modules `semver` Add LICENSE (`LICENSE.txt`))
|
||||
- 添加了 `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
After Width: | Height: | Size: 53 KiB |
BIN
docs/v1.0/演示2.png
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
docs/字体展示.pptx
BIN
files/1.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
files/EGYF22.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
files/STYF21.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
@ -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
@ -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.
|
@ -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
@ -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.
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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
@ -0,0 +1,3 @@
|
||||
git fetch orgin
|
||||
git checkout SRtool2
|
||||
git merge --no-commit main
|
@ -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
|
||||
"""
|
@ -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
|
||||
"""
|
@ -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())
|
Before Width: | Height: | Size: 46 KiB |
@ -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>
|
@ -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>
|
Before Width: | Height: | Size: 16 KiB |
@ -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>
|
@ -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>
|
Before Width: | Height: | Size: 155 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 30 KiB |
@ -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>
|
Before Width: | Height: | Size: 4.8 KiB |
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
Before Width: | Height: | Size: 61 KiB |