fiona / myrmidon Goto Github PK
View Code? Open in Web Editor NEWA Python framework for rapid game development.
A Python framework for rapid game development.
The current_fps
value is not updated when using Kivy, as it creates a stub clock object which always returns 0 as the number of frames per second.
A generic particle system would be handy.
It would be nice to have a tilemap drawer, to saving the overhead of rendering individual tiles as processes.
It would be cool if entities could be attached to a parent entity so that all positioning, scaling, rotation, z-indexing, etc is relative to the parent (a bit like a scene graph). Additionally these entities would be destroyed when the parent is destroyed.
One issue with this is that of naming. We already have the concept of a parent, child and sibling, and these mean something else (is that feature really necessary?). One naming option is to refer to them as sub and super entities, though this could be confused with object inheritence.
Currently signalling sucks and doesn't make any sense.
It uses the weird DIV paradigm of sending arbitrary codes to entities to tell them to do things. Having separate methods for killing/sleeping/freezing would be better, while keeping the same robust tree mechanism.
Rename S_KILL to Destroy.
Rename S_FREEZE to Stop_Execute and Start_Execute. (Add Toggle_Execute).
Rename S_SLEEP to Hide and Show (Add Toggle_Display).
Fade in / fade out / fade to colour functions would be good, with the option to have them blocking or non-blocking
Pausing an entity for x
ticks currently requires the following:
for frame, total in Game.timer_ticks(x):
yield
It would be much cleaner and the intention would be more obvious with something like the following:
Entity.sleep(x)
The mouse object has attributes for when the mouse buttons have been released, but not for when they are first pressed down.
It would be nice if Myrmidon allowed you to create primitives such as lines, circles and rectangles. These would be objects that persisted, like Entities, and could be moved around the screen, rotated, scaled, etc. See Div2/Fenix/Bennu for an example of how this might work. Bennu returns a handle to the newly created object.
A function to set the window title would be useful
When an entity's state ends, the entity is destroyed. It would follow logically that the program should end when the first (main) entity ends. One would expect control to return to where this first entity's constructor was invoked, but this doesn't appear to be the case.
It would be great to be able to define position in a process's graphic which is considered the process's centre (called the hotspot in Click & Create)
Should be target_fps and current_fps.
Horizontal and vertical flip flags for processes
When a process's "execute" generator runs to completion, the process is left alive. This seems highly counter-intuitive (and differs from fenix and pygame-fenix for no discernable reason). It would make more sense for the process to be killed by the framework at this point.
It would be handy to have scroll processes - that is, processes where their x and y coordinates exist in some world space and their actual screen position is determined by their position relative to some camera coordinates. There could be multiple cameras mapped to multiple screen regions (for split-screen)
get_screen_draw_position
returns a position in screen coordinates at which to place the top left coordinate of the scaled quad, before rotation is applied. This is difficult to work with, if we want to override the screen draw behaviour, because of how much must be taken into consideration when writing an implementation of it.
Instead, get_screen_draw_position
could return the screen coordinates at which to place the entity (at its centre point), allowing scaling and rotation to be applied as a separate concern. It could be renamed to reflect this change to something like get_screen_position
It would be super nice if there were arbitrary functions you could attach to states that run when you enter and exit them.
If a process is signaled S_KILL twice in the same frame, an exception is raised because some cleanup has already taken place in the graphics engine and expects to only be run once.
It is very easy to signal the same process twice - e.g. if the process signals itself at the end of a loop and some global cleanup also attempts to kill it in the same frame. Could it not handle the double signal a bit more gracefully?
angle_between_points returns an angle between -180 and 180 whereas most other angle-related methods use angles between 0 and 360. This is what normalise_angle returns, for example. The method should be changed to return an angle between 0 and 360, instead.
Entity.collide_with currently returns a namedtuple containing a boolean to indicate whether a collision occured, and the entity collided with. This could be simplified to just return the entity or None, and the truthiness of the result could still be used for boolean checks, e.g:
collision = self.collide_with(entities)
or
if self.collide_with(entities):
...
As far as I can tell, the signal
function doesn't exist anymore, so the constants S_SLEEP
, S_WAKE
, etc should be removed.
Currently all the keycodes used are Pygames and this is silly and stupid as refering to them causes crashes when using the Kivy backend.
No reason why we shouldn't have our own. Taking SDL's wouldn't be a problem though to keep compatibility with the main implementation.
You've used British English spellings everywhere apart from the alignment constants i.e. ALIGN_CENTER
Traceback (most recent call last):
File "feature_test.py", line 363, in <module>
Application()
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/Entity.py", line 142, in __init__
Game.run_game()
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/Game.py", line 221, in run_game
cls.engine['window'].open_window()
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/engine/window/pygame/engine.py", line 81, in open_window
self.callback(0.0)
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/Game.py", line 283, in app_loop_callback
cls.engine['gfx'].draw_entities(cls.entity_draw_list)
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/engine/gfx/opengl/engine.py", line 102, in draw_entities
list(map(self.draw_single_entity, self.entities_z_order_list))
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/engine/gfx/opengl/engine.py", line 177, in draw_single_entity
entity.draw()
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/engine/gfx/opengl/engine.py", line 510, in draw
glTranslatef(self.scale_point[0], self.scale_point[1], 0)
AttributeError: 'Text' object has no attribute 'scale_point'
DIV had a super neat kickin'-rad process viewer it called it's "debugger". You could visually view a list of all processes and on-the-fly edit and view their parameters.
It was amazing and invaluable and I always wanted to add it to Myrmidon as a "killer-feature" of sorts.
It would be nice if it was possible to scale an entity on just the X or just the Y axis to do stretching effects. The scaling would take affect before rotation, so for example an arrow stretched out lengthways would still be stretched lengthways regardless of its rotation.
.+.
.' __:.
+--------+ +----------------+ .' .'| :+
| -----> | | ---------:=- | .' .' .'
+--------+ +----------------+ .' .' .'
original scaled on x axis +: .' .'
'. .'
'+'
rotated
A function for retrieving a list of processes by type (i.e. what signal does but without the signal part) would be useful
There are several entity properties related to translation, scaling and rotation which are a bit confused in their definitions and are difficult to work with.
get_screen_draw_position
: returns the screen coordinates at which to place the top left corner of the quad, after scaling but before rotationget_centre_point
: returns an offset from the top left corner of the entity. Defines where the entity's position is relative to its image. Scaling is performed around this point but rotation isn't - rotation is always done around the centre of the entity.get_scale_point
: the definition of this is unknownTo simplify this, maybe get_screen_draw_position
could be removed and the other two properties could be replaced with hot_spot
which defines the entitiy's position relative to it's graphic, the centre of rotation and the centre of scaling. hot_spot
would be in pixels, measured from the top left of the graphic.
It would be great if there was documentation to lay out what an engine implementation requires in terms of methods and objects returned.
Pleeeeeease consider having processes draw from their centre by default, rather than the top left corner
Traceback (most recent call last):
File "feature_test.py", line 349, in <module>
Application()
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/Entity.py", line 142, in __init__
Game.run_game()
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/Game.py", line 221, in run_game
cls.engine['window'].open_window()
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/engine/window/pygame/engine.py", line 81, in open_window
self.callback(0.0)
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/Game.py", line 283, in app_loop_callback
cls.engine['gfx'].draw_entities(cls.entity_draw_list)
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/engine/gfx/opengl/engine.py", line 102, in draw_entities
list(map(self.draw_single_entity, self.entities_z_order_list))
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/engine/gfx/opengl/engine.py", line 177, in draw_single_entity
entity.draw()
File "/home/mark/venvs/myrmidon/local/lib/python2.7/site-packages/myrmidon/engine/gfx/opengl/engine.py", line 500, in draw
y = draw_y + (entity.image.height/2) * self.scale
NameError: global name 'entity' is not defined
Signal method takes tree parameter, but father, son, bro, and bigbro attribute are not implemented which the tree functionality depends on.
I think some collision detection routines would be useful e.g. bounding box, radius
Text objects are not drawn flipped when flip_horizontal
or flip_vertical
is set to True
. They remain unflipped.
If centre_point
is [-1, -1]
, Myrmidon uses the centre of the graphic instead, but this prevents the user from actually using [-1, -1]
as the centre point. If None
was used to denote this preference instead, this would be less confusing.
S_FREEZE stops a process executing, but S_SLEEP is supposed to both stop and hide the process. Currently it only stops it, same as S_FREEZE
Currently the audio backend can only be be used for loading, not playing. Methods and routines need adding for this.
The default state generator, execute must be declared with the same arguments that should be passed into the constructor. It would be less "magic" to let the user declare an actual __init__
method with the arguments and not require arguments for the generator.
A downside to this is that the user would have to remember to invoke Entity.__init__
or else the entity setup wouldn't complete properly. A possible way of ironing out this might be to move the entity setup to the __new__
method instead although a) this might be just as "magic" and b) it might just be moving the problem
It would be handy to be able to signal processes by type (or supertype) as well as by type name.
An alternative backend which makes use of OpenGL vertex and fragment shaders to render sprites faster.
(Just putting this here for completeness)
It would be handy if entites could handle their own animation playback, to reduce the amount of boilerplate required to increment an entity's image through a sequence each frame. The interface would be more akin to audio playback whereby there are methods to start, stop, pause, resume and change animations:
start_animation(anim, fps=15, loop=False)
starts an animation playing and returns immediatelystop_animation()
ends the currently playing animationpause_animation()
pauses the currently playing animationresume_animation()
continues playing a paused animationchange_animation(fps=15, loop=False)
alters the parameters of the currently playing animationis_animating()
returns True if an animation is playingwait_for_animation()
generator that yields while an animation is playingstart_animation
would be passed a sequence of images, and the entity's image
property would be automatically updated asynchronously, through each image in the sequence, until the end of the animation is reached. The image
would remain as the final frame of the last-played animation until it is either set to something else or another animation is started. The fps
parameter would define the animation speed, in frames per second (the frame delay would be calculated using on the target fps of the game).
I get this error when updating the text
property of a text object using Kivy, but only after a while i.e. not every time. It happens for the "complex_example" game too, where it happens immediately.
INFO:kivy:[Base ] Leaving application in progress...
Traceback (most recent call last):
WARNING:kivy:stderr: Traceback (most recent call last):
File "main.py", line 40, in <module>
WARNING:kivy:stderr: File "main.py", line 40, in <module>
Window()
WARNING:kivy:stderr: Window()
File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/Entity.py", line 143, in __init__
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/Entity.py", line 143, in __init__
Game.run_game()
WARNING:kivy:stderr: Game.run_game()
File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/Game.py", line 221, in run_game
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/Game.py", line 221, in run_game
cls.engine['window'].open_window()
WARNING:kivy:stderr: cls.engine['window'].open_window()
File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/engine/window/kivy/engine.py", line 145, in open_window
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/engine/window/kivy/engine.py", line 145, in open_window
self.kivy_app.run()
WARNING:kivy:stderr: self.kivy_app.run()
File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/app.py", line 825, in run
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/app.py", line 825, in run
runTouchApp()
WARNING:kivy:stderr: runTouchApp()
File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/base.py", line 484, in runTouchApp
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/base.py", line 484, in runTouchApp
EventLoop.window.mainloop()
WARNING:kivy:stderr: EventLoop.window.mainloop()
File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/core/window/window_pygame.py", line 378, in mainloop
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/core/window/window_pygame.py", line 378, in mainloop
self._mainloop()
WARNING:kivy:stderr: self._mainloop()
File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/core/window/window_pygame.py", line 282, in _mainloop
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/core/window/window_pygame.py", line 282, in _mainloop
EventLoop.idle()
WARNING:kivy:stderr: EventLoop.idle()
File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/base.py", line 324, in idle
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/base.py", line 324, in idle
Clock.tick()
WARNING:kivy:stderr: Clock.tick()
File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/clock.py", line 483, in tick
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/clock.py", line 483, in tick
self._process_events()
WARNING:kivy:stderr: self._process_events()
File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/clock.py", line 615, in _process_events
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/clock.py", line 615, in _process_events
event.tick(self._last_tick, remove)
WARNING:kivy:stderr: event.tick(self._last_tick, remove)
File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/clock.py", line 374, in tick
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/clock.py", line 374, in tick
ret = callback(self._dt)
WARNING:kivy:stderr: ret = callback(self._dt)
File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/Game.py", line 255, in app_loop_callback
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/Game.py", line 255, in app_loop_callback
entity._iterate_generator()
WARNING:kivy:stderr: entity._iterate_generator()
File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/Entity.py", line 167, in _iterate_generator
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/Entity.py", line 167, in _iterate_generator
return_val = next(self._state_generators[self._current_state])
WARNING:kivy:stderr: return_val = next(self._state_generators[self._current_state])
File "/home/mark/venvs/space/lib/python3.4/site-packages/game_common-0.0.1-py3.4.egg/game_common/gui.py", line 20, in execute
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/game_common-0.0.1-py3.4.egg/game_common/gui.py", line 20, in execute
File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/engine/gfx/kivy/engine.py", line 429, in text
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/engine/gfx/kivy/engine.py", line 429, in text
self.destroy_text_image()
WARNING:kivy:stderr: self.destroy_text_image()
File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/engine/gfx/kivy/engine.py", line 444, in destroy_text_image
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/engine/gfx/kivy/engine.py", line 444, in destroy_text_image
self.image.destroy()
WARNING:kivy:stderr: self.image.destroy()
File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/engine/gfx/kivy/engine.py", line 342, in destroy
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/myrmidon/engine/gfx/kivy/engine.py", line 342, in destroy
self.image.remove_from_cache()
WARNING:kivy:stderr: self.image.remove_from_cache()
File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/core/image/__init__.py", line 482, in remove_from_cache
WARNING:kivy:stderr: File "/home/mark/venvs/space/lib/python3.4/site-packages/kivy/core/image/__init__.py", line 482, in remove_from_cache
pat = type(f)(u'%s|%d|%d')
WARNING:kivy:stderr: pat = type(f)(u'%s|%d|%d')
TypeError: NoneType takes no arguments
WARNING:kivy:stderr: TypeError: NoneType takes no arguments
Currently the first Entity that's created is a special case during it's initialisation - It does not immediately return and starts off the main Myrmidon loop because I was being a smart arse.
Then as the program runs it stops being special - you can happily destroy the initial entity.
The two choices are make the initial Entity more special (an explicit root object) or less special (you create it and then have to manually start the myrmidon program off) I prefer the second option. It's more flexible, explicit and less magical.
When text objects have None font objects, or Font objects are not given a file name we should fall back to a consistent default font.
The Pygame stuff relies on Pygames default font and the Kivy stuff poops it's pants.
Please consider making "colour" an argument of Game.write_text
, as text colour is something that is required almost as often as position, font and alignment.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.