Color wrapup... Cutting PyLinkedColor to simplify my cursedly mortal, finite existence
This commit is contained in:
		
							parent
							
								
									3991ac13d6
								
							
						
					
					
						commit
						01706bd59d
					
				|  | @ -56,7 +56,7 @@ PyObject* PyInit_mcrfpy() | |||
|     using namespace mcrfpydef; | ||||
|     PyTypeObject* pytypes[] = { | ||||
|         /*SFML exposed types*/ | ||||
|         &PyColorType, &PyLinkedColorType, &PyFontType, &PyTextureType, | ||||
|         &PyColorType, /*&PyLinkedColorType,*/ &PyFontType, &PyTextureType, | ||||
| 
 | ||||
|         /*UI widgets*/ | ||||
|         &PyUICaptionType, &PyUISpriteType, &PyUIFrameType, &PyUIEntityType, &PyUIGridType, | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ PyColor::PyColor(sf::Color target) | |||
| PyObject* PyColor::pyObject() | ||||
| { | ||||
|     PyObject* obj = PyType_GenericAlloc(&mcrfpydef::PyColorType, 0); | ||||
|     Py_INCREF(obj); | ||||
|     PyColorObject* self = (PyColorObject*)obj; | ||||
|     self->data = data; | ||||
|     return obj; | ||||
|  | @ -57,7 +58,7 @@ PyObject* PyColor::repr(PyObject* obj) | |||
|     PyColorObject* self = (PyColorObject*)obj; | ||||
|     std::ostringstream ss; | ||||
|     sf::Color c = self->data; | ||||
|     ss << "<Color (" << c.r << ", " << c.g << ", " << c.b << ", " << c.a << ") " << ">"; | ||||
|     ss << "<Color (" << int(c.r) << ", " << int(c.g) << ", " << int(c.b) << ", " << int(c.a) << ")>"; | ||||
| 
 | ||||
|     std::string repr_str = ss.str(); | ||||
|     return PyUnicode_DecodeUTF8(repr_str.c_str(), repr_str.size(), "replace"); | ||||
|  | @ -66,8 +67,69 @@ PyObject* PyColor::repr(PyObject* obj) | |||
| 
 | ||||
| int PyColor::init(PyColorObject* self, PyObject* args, PyObject* kwds) | ||||
| { | ||||
|     using namespace mcrfpydef; | ||||
|     static const char* keywords[] = { "r", "g", "b", "a", nullptr }; | ||||
|     // TODO
 | ||||
|     PyObject* leader; | ||||
|     int r = -1, g = -1, b = -1, a = 255; | ||||
|     if (!PyArg_ParseTupleAndKeywords, args, kwds, "O|iii", leader, &g, &b, &a) | ||||
|     { | ||||
|         PyErr_SetString(PyExc_TypeError, "mcrfpy.Color requires a color object, 3-tuple, 4-tuple, color name, or integer values within 0-255 (r, g, b, optionally a)"); | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     // if the "r" arg is already a color, yoink that color value
 | ||||
|     if (PyObject_IsInstance(leader, (PyObject*)&PyColorType)) | ||||
|     { | ||||
|         self->data = ((PyColorObject*)leader)->data; | ||||
|         return 0; | ||||
|     } | ||||
|     // else if the "r" arg is a 3-tuple, initialize to (r, g, b, 255)
 | ||||
|     //     (if the "r" arg is a 4-tuple, initialize to (r, g, b, a))
 | ||||
|     else if (PyTuple_Check(leader)) | ||||
|     { | ||||
|         if (PyTuple_Size(leader) < 3 && PyTuple_Size(leader) > 4) | ||||
|         { | ||||
|             PyErr_SetString(PyExc_TypeError, "Invalid tuple length: mcrfpy.Color requires a color object, 3-tuple, 4-tuple, color name, or integer values within 0-255 (r, g, b, optionally a)"); | ||||
|             return -1; | ||||
|         } | ||||
|         r = PyLong_AsLong(PyTuple_GetItem(leader, 0)); | ||||
|         g = PyLong_AsLong(PyTuple_GetItem(leader, 1)); | ||||
|         b = PyLong_AsLong(PyTuple_GetItem(leader, 2)); | ||||
|         //a = 255; //default value
 | ||||
| 
 | ||||
|         if (PyTuple_Size(leader) == 4) | ||||
|         { | ||||
|             a = PyLong_AsLong(PyTuple_GetItem(leader, 3)); | ||||
|         } | ||||
| 
 | ||||
|         // value validation
 | ||||
|         if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 || a < 0 || a > 255) | ||||
|         { | ||||
|             PyErr_SetString(PyExc_ValueError, "Color values must be between 0 and 255."); | ||||
|             return -1; | ||||
|         } | ||||
|         self->data = sf::Color(r, g, b, a); | ||||
|     } | ||||
|     // else if the "r" arg is a string, initialize to {color lookup function value}
 | ||||
|     else if (PyUnicode_Check(leader)) | ||||
|     { | ||||
|         PyErr_SetString(Py_NotImplemented, "Color names aren't ready yet"); | ||||
|         return -1; | ||||
|     } | ||||
|     // else - 
 | ||||
|     else if (!PyLong_Check(leader)) | ||||
|     { | ||||
|         PyErr_SetString(PyExc_TypeError, "mcrfpy.Color requires a color object, 3-tuple, 4-tuple, color name, or integer values within 0-255 (r, g, b, optionally a)"); | ||||
|         return -1; | ||||
|     } | ||||
|     r = PyLong_AsLong(leader); | ||||
|     //   assert r, g, b are present and ints in range (0, 255) - if not enough ints were provided to the args/kwds parsed by init, g and/or b will still hold -1.
 | ||||
|     if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 || a < 0 || a > 255) | ||||
|     { | ||||
|         PyErr_SetString(PyExc_ValueError, "R, G, B values are required, A value is optional; Color values must be between 0 and 255."); | ||||
|         return -1; | ||||
|     } | ||||
|     self->data = sf::Color(r, g, b, a); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -78,10 +140,12 @@ PyObject* PyColor::pynew(PyTypeObject* type, PyObject* args, PyObject* kwds) | |||
| 
 | ||||
| PyObject* PyColor::get_member(PyObject* obj, void* closure) | ||||
| { | ||||
|     // TODO
 | ||||
|     return Py_None; | ||||
| } | ||||
| 
 | ||||
| int PyColor::set_member(PyObject* obj, PyObject* value, void* closure) | ||||
| { | ||||
|     // TODO
 | ||||
|     return 0; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										35
									
								
								src/UI.h
								
								
								
								
							
							
						
						
									
										35
									
								
								src/UI.h
								
								
								
								
							|  | @ -11,7 +11,7 @@ | |||
| #include "PyCallable.h" | ||||
| #include "PyTexture.h" | ||||
| #include "PyColor.h" | ||||
| #include "PyLinkedColor.h" | ||||
| //#include "PyLinkedColor.h"
 | ||||
| 
 | ||||
| enum PyObjectsEnum : int | ||||
| { | ||||
|  | @ -610,38 +610,38 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c | |||
|         */ | ||||
| 
 | ||||
|         // fetch correct member data
 | ||||
|         //sf::Color color;
 | ||||
|         sf::Color color; | ||||
|         //sf::Color (*cgetter)();
 | ||||
|         //void (*csetter)(sf::Color);
 | ||||
|         std::function<void(sf::Color)> csetter; | ||||
|         std::function<sf::Color()> cgetter; | ||||
|         //std::function<void(sf::Color)> csetter;
 | ||||
|         //std::function<sf::Color()> cgetter;
 | ||||
|         if (member_ptr == 0) | ||||
|         { | ||||
|             //color = self->data->text.getFillColor();
 | ||||
|             color = self->data->text.getFillColor(); | ||||
|             //return Py_BuildValue("(iii)", color.r, color.g, color.b);
 | ||||
|             //csetter = &self->data->text.setFillColor;
 | ||||
|             //cgetter = &self->data->text.getFillColor;
 | ||||
|             csetter = [s = self->data](sf::Color c){s->text.setFillColor(c);}; | ||||
|             cgetter = [s = self->data](){return s->text.getFillColor();}; | ||||
|             //csetter = [s = self->data](sf::Color c){s->text.setFillColor(c);};
 | ||||
|             //cgetter = [s = self->data](){return s->text.getFillColor();};
 | ||||
|         } | ||||
|         else if (member_ptr == 1) | ||||
|         { | ||||
|             //color = self->data->text.getOutlineColor();
 | ||||
|             color = self->data->text.getOutlineColor(); | ||||
|             //return Py_BuildValue("(iii)", color.r, color.g, color.b);
 | ||||
|             //csetter = &self->data->text.setOutlineColor;
 | ||||
|             //cgetter = &self->data->text.getOutlineColor;
 | ||||
|             csetter = [s = self->data](sf::Color c){s->text.setOutlineColor(c);}; | ||||
|             cgetter = [s = self->data](){return s->text.getOutlineColor();}; | ||||
|             //csetter = [s = self->data](sf::Color c){s->text.setOutlineColor(c);};
 | ||||
|             //cgetter = [s = self->data](){return s->text.getOutlineColor();};
 | ||||
|         } | ||||
| 
 | ||||
|         // initialize new mcrfpy.Color instance
 | ||||
|         //pyColorObj->data = std::make_shared<sf::Color>(color);
 | ||||
|         //PyLinkedColor::fromPy(pyColorObj).set(color);
 | ||||
|         auto linkedcolor = PyLinkedColor(csetter, cgetter, self->data, member_ptr); | ||||
|         //auto linkedcolor = PyLinkedColor(csetter, cgetter, self->data, member_ptr);
 | ||||
|         //linkedcolor.set(color); // don't need to set a linked color!
 | ||||
|          | ||||
|         //return pyColor;
 | ||||
|         return linkedcolor.pyObject(); | ||||
|         return PyColor(color).pyObject(); | ||||
|     } | ||||
| 
 | ||||
|     static int PyUICaption_set_color_member(PyUICaptionObject* self, PyObject* value, void* closure) | ||||
|  | @ -649,7 +649,7 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c | |||
|         auto member_ptr = reinterpret_cast<long>(closure); | ||||
|         //TODO: this logic of (PyColor instance OR tuple -> sf::color) should be encapsulated for reuse
 | ||||
|         int r, g, b, a; | ||||
|         if (PyObject_IsInstance(value, (PyObject*)&PyLinkedColorType)) | ||||
|         if (PyObject_IsInstance(value, (PyObject*)&PyColorType)) | ||||
|         { | ||||
|             // get value from mcrfpy.Color instance
 | ||||
|             /*
 | ||||
|  | @ -659,10 +659,11 @@ static int PyUIDrawable_set_click(PyUIGridObject* self, PyObject* value, void* c | |||
|             b = color->data->b; | ||||
|             a = color->data->a; | ||||
|             */ | ||||
|             std::cout << "Build LinkedColor" << std::endl; | ||||
|             auto lc  = PyLinkedColor::fromPy(value); | ||||
|             std::cout << "Fetch value" << std::endl; | ||||
|             auto c = lc.get(); | ||||
|             //std::cout << "Build LinkedColor" << std::endl;
 | ||||
|             //auto lc  = PyLinkedColor::fromPy(value);
 | ||||
|             auto c = ((PyColorObject*)value)->data; | ||||
|             //std::cout << "Fetch value" << std::endl;
 | ||||
|             //auto c = lc.get();
 | ||||
|             r = c.r; g = c.g; b = c.b; a = c.a; | ||||
|             std::cout << "got " << int(r) << ", " << int(g) << ", " << int(b) << ", " << int(a) << std::endl; | ||||
|         } | ||||
|  |  | |||
|  | @ -1,221 +1,51 @@ | |||
| #print("Hello mcrogueface") | ||||
| import mcrfpy | ||||
| import cos_play | ||||
| # Universal stuff | ||||
| font = mcrfpy.Font("assets/JetbrainsMono.ttf") | ||||
| texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16) #12, 11) | ||||
| texture_cold = mcrfpy.Texture("assets/kenney_ice.png", 16, 16) #12, 11) | ||||
| texture_hot = mcrfpy.Texture("assets/kenney_lava.png", 16, 16) #12, 11) | ||||
| texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16) | ||||
| 
 | ||||
| # Test stuff | ||||
| mcrfpy.createScene("boom") | ||||
| mcrfpy.setScene("boom") | ||||
| ui = mcrfpy.sceneUI("boom") | ||||
| box = mcrfpy.Frame(40, 60, 200, 300, fill_color=(255,128,0), outline=4.0, outline_color=(64,64,255,96)) | ||||
| ui.append(box) | ||||
| # build test widgets | ||||
| 
 | ||||
| #caption = mcrfpy.Caption(10, 10, "Clicky", font, (255, 255, 255, 255), (0, 0, 0, 255)) | ||||
| #box.click = lambda x, y, btn, type: print("Hello callback: ", x, y, btn, type) | ||||
| #box.children.append(caption) | ||||
| mcrfpy.createScene("pytest") | ||||
| mcrfpy.setScene("pytest") | ||||
| ui = mcrfpy.sceneUI("pytest") | ||||
| 
 | ||||
| test_sprite_number = 86  | ||||
| sprite = mcrfpy.Sprite(20, 60, texture, test_sprite_number, 4.0) | ||||
| spritecap = mcrfpy.Caption(5, 5, "60", font) | ||||
| def click_sprite(x, y, btn, action): | ||||
|     global test_sprite_number | ||||
|     if action != "start": return | ||||
|     if btn in ("left", "wheel_up"): | ||||
|         test_sprite_number -= 1 | ||||
|     elif btn in ("right", "wheel_down"): | ||||
|         test_sprite_number += 1 | ||||
|     sprite.sprite_number = test_sprite_number # TODO - inconsistent naming for __init__, __repr__ and getsetter: sprite_number vs sprite_index | ||||
|     spritecap.text = test_sprite_number | ||||
| # Frame | ||||
| f = mcrfpy.Frame(25, 19, 462, 346, fill_color=(255, 92, 92)) | ||||
| # fill (LinkedColor / Color):    f.fill_color | ||||
| # outline (LinkedColor / Color): f.outline_color | ||||
| # pos (LinkedVector / Vector):   f.pos | ||||
| # size (LinkedVector / Vector):  f.size | ||||
| 
 | ||||
| sprite.click = click_sprite # TODO - sprites don't seem to correct for screen position or scale when clicking | ||||
| box.children.append(sprite) | ||||
| box.children.append(spritecap) | ||||
| box.click = click_sprite | ||||
| # Caption | ||||
| c = mcrfpy.Caption(512+25, 19, "Hi.", font) | ||||
| # fill (LinkedColor / Color):    c.fill_color | ||||
| #color_val = c.fill_color | ||||
| print(c.fill_color) | ||||
| print("Set a fill color") | ||||
| c.fill_color = (255, 255, 255) | ||||
| print("Lol, did it segfault?") | ||||
| # outline (LinkedColor / Color): c.outline_color | ||||
| # font (Font):                   c.font | ||||
| # pos (LinkedVector / Vector):   c.pos | ||||
| 
 | ||||
| f_a = mcrfpy.Frame(250, 60, 80, 80, fill_color=(255, 92, 92)) | ||||
| f_a_txt = mcrfpy.Caption(5, 5, "0", font) | ||||
| # Sprite | ||||
| s = mcrfpy.Sprite(25, 384+19, texture, 86, 9.0) | ||||
| # pos (LinkedVector / Vector):   s.pos | ||||
| # texture (Texture):             s.texture | ||||
| 
 | ||||
| f_b = mcrfpy.Frame(340, 60, 80, 80, fill_color=(92, 255, 92)) | ||||
| f_b_txt = mcrfpy.Caption(5, 5, "0", font) | ||||
| # Grid | ||||
| g = mcrfpy.Grid(10, 10, texture, 512+25, 384+19, 462, 346) | ||||
| # texture (Texture):             g.texture | ||||
| # pos (LinkedVector / Vector):   g.pos | ||||
| # size (LinkedVector / Vector):  g.size | ||||
| 
 | ||||
| f_c = mcrfpy.Frame(430, 60, 80, 80, fill_color=(92, 92, 255)) | ||||
| f_c_txt = mcrfpy.Caption(5, 5, "0", font) | ||||
| for _x in range(10): | ||||
|     for _y in range(10): | ||||
|         g.at((_x, _y)).color = (255 - _x*25, 255 - _y*25, 255) | ||||
| g.zoom = 2.0 | ||||
| 
 | ||||
| [ui.append(d) for d in (f, c, s, g)] | ||||
| 
 | ||||
| ui.append(f_a) | ||||
| f_a.children.append(f_a_txt) | ||||
| ui.append(f_b) | ||||
| f_b.children.append(f_b_txt) | ||||
| ui.append(f_c) | ||||
| f_c.children.append(f_c_txt) | ||||
| print("built!") | ||||
| 
 | ||||
| import sys | ||||
| def ding(*args): | ||||
|     f_a_txt.text = str(sys.getrefcount(ding)) + " refs" | ||||
|     f_b_txt.text = sys.getrefcount(dong) | ||||
|     f_c_txt.text = sys.getrefcount(stress_test) | ||||
| # tests | ||||
| 
 | ||||
| def dong(*args): | ||||
|     f_a_txt.text = str(sys.getrefcount(ding)) + " refs" | ||||
|     f_b_txt.text = sys.getrefcount(dong) | ||||
|     f_c_txt.text = sys.getrefcount(stress_test) | ||||
| 
 | ||||
| running = False | ||||
| timers = [] | ||||
| 
 | ||||
| def add_ding(): | ||||
|     global timers | ||||
|     n = len(timers) | ||||
|     mcrfpy.setTimer(f"timer{n}", ding, 100) | ||||
|     print("+1 ding:", timers) | ||||
| 
 | ||||
| def add_dong(): | ||||
|     global timers | ||||
|     n = len(timers) | ||||
|     mcrfpy.setTimer(f"timer{n}", dong, 100) | ||||
|     print("+1 dong:", timers) | ||||
| 
 | ||||
| def remove_random(): | ||||
|     global timers | ||||
|     target = random.choice(timers) | ||||
|     print("-1 timer:", target) | ||||
|     print("remove from list") | ||||
|     timers.remove(target) | ||||
|     print("delTimer") | ||||
|     mcrfpy.delTimer(target) | ||||
|     print("done") | ||||
| 
 | ||||
| import random | ||||
| import time | ||||
| def stress_test(*args): | ||||
|     global running | ||||
|     global timers | ||||
|     if not running: | ||||
|         print("stress test initial") | ||||
|         running = True | ||||
|         timers.append("recurse") | ||||
|         add_ding() | ||||
|         add_dong() | ||||
|         mcrfpy.setTimer("recurse", stress_test, 1000) | ||||
|         mcrfpy.setTimer("terminate", lambda *args: mcrfpy.delTimer("recurse"), 30000) | ||||
|         ding(); dong() | ||||
|     else: | ||||
|         #print("stress test random activity") | ||||
|         #random.choice([ | ||||
|         #    add_ding, | ||||
|         #    add_dong, | ||||
|         #    remove_random | ||||
|         #    ])() | ||||
|         #print(timers) | ||||
|         print("Segfaultin' time") | ||||
|         mcrfpy.delTimer("recurse") | ||||
|         print("Does this still work?") | ||||
|         time.sleep(0.5) | ||||
|         print("How about now?") | ||||
| 
 | ||||
| 
 | ||||
| stress_test() | ||||
| 
 | ||||
| 
 | ||||
| # Loading Screen | ||||
| mcrfpy.createScene("loading") | ||||
| ui = mcrfpy.sceneUI("loading") | ||||
| #mcrfpy.setScene("loading") | ||||
| logo_texture = mcrfpy.Texture("assets/temp_logo.png", 1024, 1024)#1, 1) | ||||
| logo_sprite = mcrfpy.Sprite(50, 50, logo_texture, 0, 0.5) | ||||
| ui.append(logo_sprite) | ||||
| logo_sprite.click = lambda *args: mcrfpy.setScene("menu") | ||||
| logo_caption = mcrfpy.Caption(70, 600, "Click to Proceed", font, (255, 0, 0, 255), (0, 0, 0, 255)) | ||||
| #logo_caption.fill_color =(255, 0, 0, 255) | ||||
| ui.append(logo_caption) | ||||
| 
 | ||||
| 
 | ||||
| # menu screen | ||||
| mcrfpy.createScene("menu") | ||||
| 
 | ||||
| for e in [ | ||||
|     mcrfpy.Caption(10, 10, "Crypt of Sokoban", font, (255, 255, 255), (0, 0, 0)), | ||||
|     mcrfpy.Caption(20, 55, "a McRogueFace demo project", font, (192, 192, 192), (0, 0, 0)), | ||||
|     mcrfpy.Frame(15, 70, 150, 60, fill_color=(64, 64, 128)), | ||||
|     mcrfpy.Frame(15, 145, 150, 60, fill_color=(64, 64, 128)), | ||||
|     mcrfpy.Frame(15, 220, 150, 60, fill_color=(64, 64, 128)), | ||||
|     mcrfpy.Frame(15, 295, 150, 60, fill_color=(64, 64, 128)), | ||||
|     #mcrfpy.Frame(900, 10, 100, 100, fill_color=(255, 0, 0)), | ||||
|     ]: | ||||
|     mcrfpy.sceneUI("menu").append(e) | ||||
| 
 | ||||
| def click_once(fn): | ||||
|     def wraps(*args, **kwargs): | ||||
|         #print(args) | ||||
|         action = args[3] | ||||
|         if action != "start": return | ||||
|         return fn(*args, **kwargs) | ||||
|     return wraps | ||||
| 
 | ||||
| @click_once | ||||
| def asdf(x, y, btn, action): | ||||
|     print(f"clicky @({x},{y}) {action}->{btn}") | ||||
| 
 | ||||
| @click_once | ||||
| def clicked_exit(*args): | ||||
|     mcrfpy.exit() | ||||
| 
 | ||||
| menu_btns = [ | ||||
|     ("Boom", lambda *args: 1 / 0), | ||||
|     ("Exit", clicked_exit),  | ||||
|     ("About", lambda *args: mcrfpy.setScene("about")),  | ||||
|     ("Settings", lambda *args: mcrfpy.setScene("settings")),  | ||||
|     ("Start", lambda *args: mcrfpy.setScene("play")) | ||||
|     ] | ||||
| for i in range(len(mcrfpy.sceneUI("menu"))): | ||||
|     e = mcrfpy.sceneUI("menu")[i] # TODO - fix iterator | ||||
|     #print(e, type(e)) | ||||
|     if type(e) is not mcrfpy.Frame: continue | ||||
|     label, fn = menu_btns.pop() | ||||
|     #print(label) | ||||
|     e.children.append(mcrfpy.Caption(5, 5, label, font, (192, 192, 255), (0,0,0))) | ||||
|     e.click = fn | ||||
| 
 | ||||
| 
 | ||||
| # settings screen | ||||
| mcrfpy.createScene("settings") | ||||
| window_scaling = 1.0 | ||||
| 
 | ||||
| scale_caption = mcrfpy.Caption(180, 70, "1.0x", font, (255, 255, 255), (0, 0, 0)) | ||||
| #scale_caption.fill_color = (255, 255, 255) # TODO - mcrfpy.Caption.__init__ is not setting colors | ||||
| for e in [ | ||||
|     mcrfpy.Caption(10, 10, "Settings", font, (255, 255, 255), (0, 0, 0)), | ||||
|     mcrfpy.Frame(15, 70, 150, 60, fill_color=(64, 64, 128)), # + | ||||
|     mcrfpy.Frame(300, 70, 150, 60, fill_color=(64, 64, 128)), # - | ||||
|     mcrfpy.Frame(15, 295, 150, 60, fill_color=(64, 64, 128)), | ||||
|     scale_caption, | ||||
|     ]: | ||||
|     mcrfpy.sceneUI("settings").append(e) | ||||
| 
 | ||||
| @click_once | ||||
| def game_scale(x, y, btn, action, delta): | ||||
|     global window_scaling | ||||
|     print(f"WIP - scale the window from {window_scaling:.1f} to {window_scaling+delta:.1f}") | ||||
|     window_scaling += delta | ||||
|     scale_caption.text = f"{window_scaling:.1f}x" | ||||
|     mcrfpy.setScale(window_scaling) | ||||
|     #mcrfpy.setScale(2) | ||||
| 
 | ||||
| settings_btns = [ | ||||
|     ("back", lambda *args: mcrfpy.setScene("menu")), | ||||
|     ("-", lambda x, y, btn, action: game_scale(x, y, btn, action, -0.1)), | ||||
|     ("+", lambda x, y, btn, action: game_scale(x, y, btn, action, +0.1)) | ||||
|     ] | ||||
| 
 | ||||
| for i in range(len(mcrfpy.sceneUI("settings"))): | ||||
|     e = mcrfpy.sceneUI("settings")[i] # TODO - fix iterator | ||||
|     #print(e, type(e)) | ||||
|     if type(e) is not mcrfpy.Frame: continue | ||||
|     label, fn = settings_btns.pop() | ||||
|     #print(label, fn) | ||||
|     e.children.append(mcrfpy.Caption(5, 5, label, font, (192, 192, 255), (0,0,0))) | ||||
|     e.click = fn | ||||
|  |  | |||
|  | @ -0,0 +1,221 @@ | |||
| #print("Hello mcrogueface") | ||||
| import mcrfpy | ||||
| import cos_play | ||||
| # Universal stuff | ||||
| font = mcrfpy.Font("assets/JetbrainsMono.ttf") | ||||
| texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16) #12, 11) | ||||
| texture_cold = mcrfpy.Texture("assets/kenney_ice.png", 16, 16) #12, 11) | ||||
| texture_hot = mcrfpy.Texture("assets/kenney_lava.png", 16, 16) #12, 11) | ||||
| 
 | ||||
| # Test stuff | ||||
| mcrfpy.createScene("boom") | ||||
| mcrfpy.setScene("boom") | ||||
| ui = mcrfpy.sceneUI("boom") | ||||
| box = mcrfpy.Frame(40, 60, 200, 300, fill_color=(255,128,0), outline=4.0, outline_color=(64,64,255,96)) | ||||
| ui.append(box) | ||||
| 
 | ||||
| #caption = mcrfpy.Caption(10, 10, "Clicky", font, (255, 255, 255, 255), (0, 0, 0, 255)) | ||||
| #box.click = lambda x, y, btn, type: print("Hello callback: ", x, y, btn, type) | ||||
| #box.children.append(caption) | ||||
| 
 | ||||
| test_sprite_number = 86  | ||||
| sprite = mcrfpy.Sprite(20, 60, texture, test_sprite_number, 4.0) | ||||
| spritecap = mcrfpy.Caption(5, 5, "60", font) | ||||
| def click_sprite(x, y, btn, action): | ||||
|     global test_sprite_number | ||||
|     if action != "start": return | ||||
|     if btn in ("left", "wheel_up"): | ||||
|         test_sprite_number -= 1 | ||||
|     elif btn in ("right", "wheel_down"): | ||||
|         test_sprite_number += 1 | ||||
|     sprite.sprite_number = test_sprite_number # TODO - inconsistent naming for __init__, __repr__ and getsetter: sprite_number vs sprite_index | ||||
|     spritecap.text = test_sprite_number | ||||
| 
 | ||||
| sprite.click = click_sprite # TODO - sprites don't seem to correct for screen position or scale when clicking | ||||
| box.children.append(sprite) | ||||
| box.children.append(spritecap) | ||||
| box.click = click_sprite | ||||
| 
 | ||||
| f_a = mcrfpy.Frame(250, 60, 80, 80, fill_color=(255, 92, 92)) | ||||
| f_a_txt = mcrfpy.Caption(5, 5, "0", font) | ||||
| 
 | ||||
| f_b = mcrfpy.Frame(340, 60, 80, 80, fill_color=(92, 255, 92)) | ||||
| f_b_txt = mcrfpy.Caption(5, 5, "0", font) | ||||
| 
 | ||||
| f_c = mcrfpy.Frame(430, 60, 80, 80, fill_color=(92, 92, 255)) | ||||
| f_c_txt = mcrfpy.Caption(5, 5, "0", font) | ||||
| 
 | ||||
| 
 | ||||
| ui.append(f_a) | ||||
| f_a.children.append(f_a_txt) | ||||
| ui.append(f_b) | ||||
| f_b.children.append(f_b_txt) | ||||
| ui.append(f_c) | ||||
| f_c.children.append(f_c_txt) | ||||
| 
 | ||||
| import sys | ||||
| def ding(*args): | ||||
|     f_a_txt.text = str(sys.getrefcount(ding)) + " refs" | ||||
|     f_b_txt.text = sys.getrefcount(dong) | ||||
|     f_c_txt.text = sys.getrefcount(stress_test) | ||||
| 
 | ||||
| def dong(*args): | ||||
|     f_a_txt.text = str(sys.getrefcount(ding)) + " refs" | ||||
|     f_b_txt.text = sys.getrefcount(dong) | ||||
|     f_c_txt.text = sys.getrefcount(stress_test) | ||||
| 
 | ||||
| running = False | ||||
| timers = [] | ||||
| 
 | ||||
| def add_ding(): | ||||
|     global timers | ||||
|     n = len(timers) | ||||
|     mcrfpy.setTimer(f"timer{n}", ding, 100) | ||||
|     print("+1 ding:", timers) | ||||
| 
 | ||||
| def add_dong(): | ||||
|     global timers | ||||
|     n = len(timers) | ||||
|     mcrfpy.setTimer(f"timer{n}", dong, 100) | ||||
|     print("+1 dong:", timers) | ||||
| 
 | ||||
| def remove_random(): | ||||
|     global timers | ||||
|     target = random.choice(timers) | ||||
|     print("-1 timer:", target) | ||||
|     print("remove from list") | ||||
|     timers.remove(target) | ||||
|     print("delTimer") | ||||
|     mcrfpy.delTimer(target) | ||||
|     print("done") | ||||
| 
 | ||||
| import random | ||||
| import time | ||||
| def stress_test(*args): | ||||
|     global running | ||||
|     global timers | ||||
|     if not running: | ||||
|         print("stress test initial") | ||||
|         running = True | ||||
|         timers.append("recurse") | ||||
|         add_ding() | ||||
|         add_dong() | ||||
|         mcrfpy.setTimer("recurse", stress_test, 1000) | ||||
|         mcrfpy.setTimer("terminate", lambda *args: mcrfpy.delTimer("recurse"), 30000) | ||||
|         ding(); dong() | ||||
|     else: | ||||
|         #print("stress test random activity") | ||||
|         #random.choice([ | ||||
|         #    add_ding, | ||||
|         #    add_dong, | ||||
|         #    remove_random | ||||
|         #    ])() | ||||
|         #print(timers) | ||||
|         print("Segfaultin' time") | ||||
|         mcrfpy.delTimer("recurse") | ||||
|         print("Does this still work?") | ||||
|         time.sleep(0.5) | ||||
|         print("How about now?") | ||||
| 
 | ||||
| 
 | ||||
| stress_test() | ||||
| 
 | ||||
| 
 | ||||
| # Loading Screen | ||||
| mcrfpy.createScene("loading") | ||||
| ui = mcrfpy.sceneUI("loading") | ||||
| #mcrfpy.setScene("loading") | ||||
| logo_texture = mcrfpy.Texture("assets/temp_logo.png", 1024, 1024)#1, 1) | ||||
| logo_sprite = mcrfpy.Sprite(50, 50, logo_texture, 0, 0.5) | ||||
| ui.append(logo_sprite) | ||||
| logo_sprite.click = lambda *args: mcrfpy.setScene("menu") | ||||
| logo_caption = mcrfpy.Caption(70, 600, "Click to Proceed", font, (255, 0, 0, 255), (0, 0, 0, 255)) | ||||
| #logo_caption.fill_color =(255, 0, 0, 255) | ||||
| ui.append(logo_caption) | ||||
| 
 | ||||
| 
 | ||||
| # menu screen | ||||
| mcrfpy.createScene("menu") | ||||
| 
 | ||||
| for e in [ | ||||
|     mcrfpy.Caption(10, 10, "Crypt of Sokoban", font, (255, 255, 255), (0, 0, 0)), | ||||
|     mcrfpy.Caption(20, 55, "a McRogueFace demo project", font, (192, 192, 192), (0, 0, 0)), | ||||
|     mcrfpy.Frame(15, 70, 150, 60, fill_color=(64, 64, 128)), | ||||
|     mcrfpy.Frame(15, 145, 150, 60, fill_color=(64, 64, 128)), | ||||
|     mcrfpy.Frame(15, 220, 150, 60, fill_color=(64, 64, 128)), | ||||
|     mcrfpy.Frame(15, 295, 150, 60, fill_color=(64, 64, 128)), | ||||
|     #mcrfpy.Frame(900, 10, 100, 100, fill_color=(255, 0, 0)), | ||||
|     ]: | ||||
|     mcrfpy.sceneUI("menu").append(e) | ||||
| 
 | ||||
| def click_once(fn): | ||||
|     def wraps(*args, **kwargs): | ||||
|         #print(args) | ||||
|         action = args[3] | ||||
|         if action != "start": return | ||||
|         return fn(*args, **kwargs) | ||||
|     return wraps | ||||
| 
 | ||||
| @click_once | ||||
| def asdf(x, y, btn, action): | ||||
|     print(f"clicky @({x},{y}) {action}->{btn}") | ||||
| 
 | ||||
| @click_once | ||||
| def clicked_exit(*args): | ||||
|     mcrfpy.exit() | ||||
| 
 | ||||
| menu_btns = [ | ||||
|     ("Boom", lambda *args: 1 / 0), | ||||
|     ("Exit", clicked_exit),  | ||||
|     ("About", lambda *args: mcrfpy.setScene("about")),  | ||||
|     ("Settings", lambda *args: mcrfpy.setScene("settings")),  | ||||
|     ("Start", lambda *args: mcrfpy.setScene("play")) | ||||
|     ] | ||||
| for i in range(len(mcrfpy.sceneUI("menu"))): | ||||
|     e = mcrfpy.sceneUI("menu")[i] # TODO - fix iterator | ||||
|     #print(e, type(e)) | ||||
|     if type(e) is not mcrfpy.Frame: continue | ||||
|     label, fn = menu_btns.pop() | ||||
|     #print(label) | ||||
|     e.children.append(mcrfpy.Caption(5, 5, label, font, (192, 192, 255), (0,0,0))) | ||||
|     e.click = fn | ||||
| 
 | ||||
| 
 | ||||
| # settings screen | ||||
| mcrfpy.createScene("settings") | ||||
| window_scaling = 1.0 | ||||
| 
 | ||||
| scale_caption = mcrfpy.Caption(180, 70, "1.0x", font, (255, 255, 255), (0, 0, 0)) | ||||
| #scale_caption.fill_color = (255, 255, 255) # TODO - mcrfpy.Caption.__init__ is not setting colors | ||||
| for e in [ | ||||
|     mcrfpy.Caption(10, 10, "Settings", font, (255, 255, 255), (0, 0, 0)), | ||||
|     mcrfpy.Frame(15, 70, 150, 60, fill_color=(64, 64, 128)), # + | ||||
|     mcrfpy.Frame(300, 70, 150, 60, fill_color=(64, 64, 128)), # - | ||||
|     mcrfpy.Frame(15, 295, 150, 60, fill_color=(64, 64, 128)), | ||||
|     scale_caption, | ||||
|     ]: | ||||
|     mcrfpy.sceneUI("settings").append(e) | ||||
| 
 | ||||
| @click_once | ||||
| def game_scale(x, y, btn, action, delta): | ||||
|     global window_scaling | ||||
|     print(f"WIP - scale the window from {window_scaling:.1f} to {window_scaling+delta:.1f}") | ||||
|     window_scaling += delta | ||||
|     scale_caption.text = f"{window_scaling:.1f}x" | ||||
|     mcrfpy.setScale(window_scaling) | ||||
|     #mcrfpy.setScale(2) | ||||
| 
 | ||||
| settings_btns = [ | ||||
|     ("back", lambda *args: mcrfpy.setScene("menu")), | ||||
|     ("-", lambda x, y, btn, action: game_scale(x, y, btn, action, -0.1)), | ||||
|     ("+", lambda x, y, btn, action: game_scale(x, y, btn, action, +0.1)) | ||||
|     ] | ||||
| 
 | ||||
| for i in range(len(mcrfpy.sceneUI("settings"))): | ||||
|     e = mcrfpy.sceneUI("settings")[i] # TODO - fix iterator | ||||
|     #print(e, type(e)) | ||||
|     if type(e) is not mcrfpy.Frame: continue | ||||
|     label, fn = settings_btns.pop() | ||||
|     #print(label, fn) | ||||
|     e.children.append(mcrfpy.Caption(5, 5, label, font, (192, 192, 255), (0,0,0))) | ||||
|     e.click = fn | ||||
		Loading…
	
		Reference in New Issue