Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Selba Ward  (Read 33953 times)

0 Members and 1 Guest are viewing this topic.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6194
  • Thor Developer
    • View Profile
    • Bromeon
Re: Selba Ward
« Reply #60 on: January 09, 2016, 04:36:59 pm »
I'm not sure how I feel about API's complexity, especially in complex code. I have been concious of keeping the APIs relatively complex i.e. the more complex the object, the more flexibility; the more simple the object, the more restrictive.
It's normal that complexity increases with functionality. What I was referring to is that the complexity of your API increases beyond that, because there are many methods for convenience. The same functionality can be easily provided with a fraction of the public methods, and I think it would help the user get a quicker overview and know what to use in which situation.

I am assuming you are referring to Console Screen when you mention create()?
Yes, and I assumed it would do the same as the constructor. Based on that: create() methods that (re-)initialize the object made sense in C++98 where it was expensive to copy-assign another object. With C++11 move semantics, this is almost free, and creating a new object assures that it's in a fresh state. One doesn't need to maintain code duplication in constructor and create().

Now that I realized it's not the same, I think the method should be renamed. "create" without further specifying the object leads to the assumption that a new object of the same class is created. Why not "resizeGrid"? And is that change actually needed or can the user achieve the same by creating a new object?

I'm not sure if or-ing enumerators is better than explicit booleans.

console.printAt(pos, 'A');
console.printCharAt(pos, 'A', true);
console.printCharAt(pos, 'A', true, true);
console.printCharAt(pos, 'A', sf::Color::White);
console.printCharAt(pos, 'A', sf::Color::White, true);
console.printCharAt(pos, 'A', sf::Color::White, sf::Color::Black);
There are 6 possible argument combinations for this simple method. The difference between those calls, as well as the meaning of the magic true values is impossible to know without learning the API by heart. Even when seeing the function declaration, it's still unclear what happens exactly when colors are overwritten -- which color is then used?

Expressivity is a core criterion for API quality. In my opinion, function overloads and default parameters are overused here -- interestingly, you did not use it for one of its main purposes: type inference. There's no harm in treating single chars and std::strings the same. By the way, character types should be char, not unsigned char. std::string also uses char.

It may be overkill in this situation, but since you use a lot of foreground-background color pairs, why not treat them as first-class citizens? For example as a type with named constructor idiom:
struct ColorPair
{
    static ColorPair foreground(const sf::Color& color);
    static ColorPair background(const sf::Color& color);
    static ColorPair pair(const sf::Color& foregroundColor, const sf::Color& backgroundColor);
    static ColorPair none(); // maybe find better names

    // members and private constructor
};

With that, the method calls are much more expressive. A user actually knows what happens when reading the code, without even knowing the exact declarations, or even worse, the implementation.
console.printAt(pos, 'A', ColorPair::foreground(...));
console.printAt(pos, 'A', ColorPair::background(...));
console.printAt(pos, 'A', ColorPair::pair(..., ...));
console.printAt(pos, 'A', ColorPair::none());

I suppose that the reference and pointer parameter overloads can be confusing. The main reason behind the null pointer overloads is to allow specifying parameters via reference instead of pointer but also allow nullifying such object.
But what do you gain by that? The "advantage" of omitting & at call site is shadowed by the confusion arising from the possibility to pass nullptr, but not T*. I've never seen an API that does that.

What you're actually looking for are optional types. They will soon be introduced as std::optional in C++, and my library Aurora already provides them. They're very easy to use:
aurora::Optional<int> x = 32;              // contains a value
aurora::Optional<int> y;                   // is empty
aurora::Optional<int> z = aurora::nullopt; // is empty

if (x)                                     // check if not empty
   output(*x);                             // access stored int value


The default values for "enabled" boolean setters, in my view, make more sense grammatically. I think I would personally prefer enable and disable methods, or the method not having "Enabled" in its name, but I used this naming scheme to be closer to how SFML names its methods.
But SFML does not allow setXyEnabled() without a parameter.

I think it's a fundamental design question: do you want to make all users happy and leave it up to them what style to use, or is your focus on a concise API that precisely says "in order to achieve that, you must do this". I personally prefer the latter option by far, because:
  • Users can get a quick overview over the functionality when there's no redundancy.
  • It's clear that two different methods are actually different and don't just seem so.
  • Different users of my API understand each other, because there's only one style.
  • There's a consistency throughout my API. Users knowing my API style can use new classes directly, as they're used to the API and have expectations that are fulfilled.
  • I have less maintenance overhead as a developer, and potentially fewer bugs.
I don't say you should follow this style, I merely want to give you some insights in how I design interfaces in my libraries and what criteria are important to me personally.
« Last Edit: January 09, 2016, 04:45:30 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: first SFML book

Hapax

  • Hero Member
  • *****
  • Posts: 2775
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Selba Ward
« Reply #61 on: January 09, 2016, 06:02:51 pm »
I think the method should be renamed. "create" without further specifying the object leads to the assumption that a new object of the same class is created. Why not "resizeGrid"? And is that change actually needed or can the user achieve the same by creating a new object?
I have to admit that I'm not fully sure why it was called create to start with. I can probably assume that it meant create new internal screen as all the internal data (the screen content) is recreated or something like that. Obviously I realised that resize() gave the impression that the size of the final visual representation would change. The method is needed as it gives the ability to change the actual content; it could be compared perhaps to changing a display "mode". Creating a new object to do just this seems to be overkill. A lot of the setup stays the same when "resizing the grid" - texture setup, colours etc..
In conclusion, the method needs renaming. However, resizeGrid is not exactly what I would like as grid is not a word I have associated with the set-up elsewhere. I've just now started to like "changeMode()"  ;D

I'm not sure if or-ing enumerators is better than explicit booleans.
I'm not sure if or-ing enumerators is better than explicit booleans. It may just be seeing it too much during Windows programming that has put me off. I'll have to re-evaluate this;D
I think it's probably much better. I'm not even sure why I said this. I generally use enums instead of booleans at any possible occasion as who knows when its dedicated state might expand to a possible 3 or more states. It's the or-ing together that I generally avoid, though I will make an effort to involve this technique in the future.

The difference between those calls, as well as the meaning of the magic true values is impossible to know without learning the API by heart. Even when seeing the function declaration, it's still unclear what happens exactly when colors are overwritten -- which color is then used?
The method is designed to be used with internal stored ("current") colours and is therefore a simple method that prints a character at the location with the current colours (as is normal in a console's display). The overrides are to allow a colour other than the current colours to be temporarily used for that single "print". The reason the booleans are also an option is to allow the ability to print at a location without changing the colours that are already at that location.
Therefore, this method can do three things, print the character at the location:
1) without changing the colour(s) at its destination,
2) by replacing the colours at the destination with the current colour(s),
3) by replacing the colours at the destination with the specified colour(s).

It may be overkill in this situation, but since you use a lot of foreground-background color pairs, why not treat them as first-class citizens? For example as a type with named constructor idiom
Although the colours are sometimes available to be changed together, they refer to two completely separate things. The main (or foreground) colour is the 'important' colour whereas background colour can be relatively trivial and/or ignored. In times when the background is disabled, its colour would be useless and therefore should be able to be ignored.

interestingly, you did not use [function overloads] for one of its main purposes: type inference. There's no harm in treating single chars and std::strings the same.
I think I had some trouble with calling internal methods using type inference. e.g. calling printCharAt from printAt. I can't remember fully and I'll look into maybe combining the two. It's possible I may just have been trying to be explicit. However, I can't at the moment think of a reason why I wouldn't like printing characters as also using print or printAt. I will definitely look into this.

By the way, character types should be char, not unsigned char. std::string also uses char.
This was intentional as 'tiles' can also be specified by actual value and negative numbers would not be intuitive here.

I suppose that the reference and pointer parameter overloads can be confusing. The main reason behind the null pointer overloads is to allow specifying parameters via reference instead of pointer but also allow nullifying such object.
But what do you gain by that? The "advantage" of omitting & at call site is shadowed by the confusion arising from the possibility to pass nullptr, but not T*. I've never seen an API that does that.
The point here is to allow passing by reference. Things like textures, however, obviously need to be able to be nullified. Realising now, there's no need to allow a null pointer to do this, especially when a normal pointer is not accepted. This can be done with no parameter at all or a differently named method:
1) setTexture();
2) resetTexture();
although reset isn't that clear. Neither is clear(). nullifyTexture() is clear but ugly. noTexture() or unlinkTexture() seem average. unassociateTexture() seems too verbose.

What you're actually looking for are optional types. They will soon be introduced as std::optional in C++, and my library Aurora already provides them. They're very easy to use
I will have a look into optional types. I don't know much about them at the moment.
Unfortunately, using aurora in this case is not an option. My aim is to have Selba Ward unlinked from any other library (I remove any dependance from my own libraries before adding them to the collection).

The default values for "enabled" boolean setters, in my view, make more sense grammatically. I think I would personally prefer enable and disable methods, or the method not having "Enabled" in its name, but I used this naming scheme to be closer to how SFML names its methods.
But SFML does not allow setXyEnabled() without a parameter.
That's actually my point: I think that it should.
setXyEnabled() sounds like it should set it to enabled so allowing it to disable doesn't make much sense. Grammatically, setEnabled(false) sounds like it isn't going to do anything.
I will probably move away from using "enabled" in methods in the future and don't usually use it elsewhere. It was used in Selba Ward because SFML uses it. It allows it without parameters because it makes (more) sense without them.
I will consider removing "enabled" from switches i.e. setXy(bool)

I think it's a fundamental design question: do you want to make all users happy and leave it up to them what style to use, or is your focus on a concise API that precisely says "in order to achieve that, you must do this". I personally prefer the latter option by far, because:
  • Users can get a quick overview over the functionality when there's no redundancy.
  • It's clear that two different methods are actually different and don't just seem so.
  • Different users of my API understand each other, because there's only one style.
  • There's a consistency throughout my API. Users knowing my API style can use new classes directly, as they're used to the API and have expectations that are fulfilled.
  • I have less maintenance overhead as a developer, and potentially fewer bugs.
I don't say you should follow this style, I merely want to give you some insights in how I design interfaces in my libraries and what criteria are important to me personally.
I actually loved that you wrote this. The two options of design were both taken into consideration during development. That is, they are both evident. Obviously, they cannot co-exist comfortably so one must choose one or the other. I have not do so and I think I have tried to include the former too much while the latter is the logical choice. I will definitely make a conscious effort to be more mindful of sticking closer to latter design choice.
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

Hapax

  • Hero Member
  • *****
  • Posts: 2775
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Selba Ward
« Reply #62 on: January 13, 2016, 03:25:14 am »
Update Console Screen to version 1.1.

Reworked some of the code, added new features, and changed a few things to be more consistent.

Some of the new features:
Customisable colour palettes with indexed colours,
Colour commands that generate colours automatically,
Text-editing-style cursor controls.

The palette and the way to specify colours is the largest change. See the Colours section of the wiki for more information.
It also does away with the seemingly random boolean parameters that were mentioned in the discussion above with Nexus.

A number of the points (e.g. create(), null pointers, type inference of printAt(), unsigned char and unclear boolean parameters) in that discussion with Nexus have been addressed and I would like to thank him for the critique as it helps make me look at and consider things from a different perspective, so thank you!

Although the GitHub commit message should contain a lot of specific information about the update, I intend to create a "changelog" to describe the update in a more human way.

I still have plans for Console Screen. In fact, the screen buffers feature that I want to implement had already been somewhat started. You can see the screenbuffer vector already sat there waiting and it's been there since v1.0! ;D

That said, if you have any suggestions for something a console screen should be able to do, or just a palette that you think should be included, let me know!  :)
(these are the palettes that are already included)
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

shadowmouse

  • Sr. Member
  • ****
  • Posts: 302
    • View Profile
Re: Selba Ward
« Reply #63 on: January 13, 2016, 08:37:46 am »
With palette, is there a reason you made it an enum class, rather than just a class that could be constructed from either, a preset palette, a list of colours, or a list of other palettes, and could have its own methods like setBrightness() for example? I only ask, because this would make it easier to modify palettes and use them for several objects. Also, is there any difference between greyscale and grayscale? It is nice to see the British spelling included, as I already have to live with littering my code with words like 'color', however I feel the inclusion of both goes against thr idea of simplifying the API if they aren't actually different.

Hapax

  • Hero Member
  • *****
  • Posts: 2775
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Selba Ward
« Reply #64 on: January 13, 2016, 10:14:42 pm »
The Palette enum class is simply the choice of preset palettes. You can create your own palette, colour by colour, or alter the preset ones after loading - again, colour by colour. This is obviously not the most convenient way to work with palettes if you use them often and switch custom palettes a lot but I'm not sure if that would be used. It's a possible future upgrade, of course - switching in full palettes. Even better would be the ability to load and save palettes from a file - and that is a considered upgrade - but depends on how much request I get for that.
The next palette upgrade, I think, would be adding or setting multiple colours at once:
cs.addPaletteColor({sf::Color::Black, sf::Color::Red, sf::Color::Green, sf::Color::Blue, sf::Color::White});
although this could get ugly quickly if the palette is large. Allowing an entire vector to be passed kind of relocates the work. Instead of adding colours to the palette, you add colours to the vector before passing it to Console Screen.
Another reason why file work would be useful  ;D

I'm not sure why a palette would need a setBrightness() function.
Are you suggesting adding colour manipulation to Console Screen? However convenient that would be, I'm not sure that it is its primary role and colour manipulation can be easily performed elsewhere, plus, externally, you could perform any colour transformations required.

Greyscale and Grayscale. Right. I made this class for myself so I used Greyscale. When I decided to include Console Screen in Selba Ward for others and rewrote it from scratch, I added the Grayscale. Funnily enough, when I committed the new version to GitHub, I was still deliberating over including both. I ended up having faith that people would not get confused because "it's obvious that it's just both spellings and they are the same". I guess I may have erred slightly. Grayscale is, then, included for convenience and, ironically, was to reduce to confusion as to why "it's spelt wrongly". If it was a common and focal part of the class (like Color, for example), I'd probably remove one of them but since it's only used occasionally (how often do you load a palette?), and is only an enum value, I'm not sure removing it would help.
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6194
  • Thor Developer
    • View Profile
    • Bromeon
Re: Selba Ward
« Reply #65 on: January 13, 2016, 10:36:48 pm »
It is nice to see the British spelling included, as I already have to live with littering my code with words like 'color'
British? ;) As a non-native English speaker, I was not biased towards one dialect. Eventually, American English's tendency of having simpler words and its bigger popularity in programming made me use it almost exclusively.

If it was a common and focal part of the class (like Color, for example), I'd probably remove one of them but since it's only used occasionally (how often do you load a palette?), and is only an enum value, I'm not sure removing it would help.
It would, that's exactly what I meant with "redundancy in the API is confusing" ;)
It being rare may even add to the confusion, as the first association is usually "this can't be, I must have missed something".

I'm actually curious what the intent behind such duplication is (this is not a rethorical question, I really would like to understand that decision). To me, it seems weird to provide things in different dialects just to let people choose... You don't provide different code conventions either, for reasons of consistency; why doesn't this reasoning apply to other kinds of code duplication (parameter types/order, dialect, pointer/reference)?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: first SFML book

shadowmouse

  • Sr. Member
  • ****
  • Posts: 302
    • View Profile
Re: Selba Ward
« Reply #66 on: January 13, 2016, 11:22:44 pm »
I haven't looked through much of the code of the library and was just going off the file you linked so I may have misunderstood things. I was suggesting that a palette could be used by multiple objects of different types, and that you might want to change the brightness for example of that palette (which in my examlke is being used as a whole program colour scheme).

Nexus, I understand the rationale behind using the American spellings, I just innately dislike the oversimplification of words to something which to me just looks like someone didn't know how to spell and guessed. For the record, that is my personal opinion, I do not intend to go on a large rampage and demand things be changed, I just liked seeing someone using what I have always known as the 'correct' spelling after years of having to use what I've always known as the 'incorrect' spelling. Can you tell I'm being careful because I'm used to people turning the subject into a giant fight?

Hapax

  • Hero Member
  • *****
  • Posts: 2775
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Selba Ward
« Reply #67 on: January 13, 2016, 11:31:37 pm »
British?
I believe the "official" term is now "British English".

I'm not sure removing it would help.
It would, that's exactly what I meant with "redundancy in the API is confusing" ;)
It being rare may even add to the confusion, as the first association is usually "this can't be, I must have missed something".

I'm actually curious what the intent behind such duplication is (this is not a rethorical question, I really would like to understand that decision). To me, it seems weird to provide things in different dialects just to let people choose... You don't provide different code conventions either, for reasons of consistency; why doesn't this reasoning apply to other kinds of code duplication (parameter types/order, dialect, pointer/reference)?
The reason behind including "grayscale" was explained above: I thought it might reduce confusion for people feeling they have to use the "wrong" spelling. I am not firmly set on this decision and it looks like I may have been right (in my deliberations) to remove grayscale. Really, I should not have added it in the first place.

Which parts do you think those kinds of code duplication apply to?
Dialect, I understand is certainly in Console Screen in the Palette enumeration value and l will very likely remove one of them. If I'm to understand your point here, it's that you think I should keep "grayscale" and remove "greyscale"?
I think pointer/reference usage is pretty consistent as I avoid pointers as much as possible. Is it just the pointer/reference parameters options that I provided in some classes that you refer to? I will be removing them; I have already removed Console Screen's null pointer overload.
I'd like to know more about what you mean by 'inconsistent parameters types/order'.

I haven't looked through much of the code of the library and was just going off the file you linked so I may have misunderstood things. I was suggesting that a palette could be used by multiple objects of different types, and that you might want to change the brightness for example of that palette (which in my examlke is being used as a whole program colour scheme).
Ah, okay. The palette is only included in Console Screen. It's simply a list of colours that can be chosen by index instead of specifying a full colour each directly each time.
Also, all drawable objects in Selba Ward are independant of each other. However much that can be convenient and easy to use, one of the tradeoffs is that it objects can include code repetition (in that several objects have need of similar code).

I understand the rationale behind using the American spellings, I just innately dislike the oversimplification of words to something which to me just looks like someone didn't know how to spell and guessed.
I don't think they are "simplified"; I often find them downright confusing. It's weird when you have to translate from English to English.
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6194
  • Thor Developer
    • View Profile
    • Bromeon
Re: Selba Ward
« Reply #68 on: January 17, 2016, 11:50:49 am »
Don't worry, I won't debate about American vs. British English ;)
(Straya's gonna rule anyway mate 8))

The problem is when you mix both, and use two different terms to identify the same thing. The other forms of duplication have been mentioned in my previous posts, e.g. pointer/reference:
void method(..., T* param);
void method(..., T& param);
and unnecessary combinations of parameter type/order:
console.printCharAt(pos, 'A');
console.printCharAt(pos, 'A', true);
console.printCharAt(pos, 'A', true, true);
console.printCharAt(pos, 'A', sf::Color::White);
console.printCharAt(pos, 'A', sf::Color::White, true);
console.printCharAt(pos, 'A', sf::Color::White, sf::Color::Black);
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: first SFML book

Hapax

  • Hero Member
  • *****
  • Posts: 2775
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Selba Ward
« Reply #69 on: January 18, 2016, 12:13:32 am »
You're right, of course, and I will be moving one. I'm just stuck on which one. I think I'm being swayed though; if I'm already using "color", I should probably use "gray" :(

The duplication of methods for references and pointers have been already removed from Console Screen. I will be fixing the other few in time.

and unnecessary combinations of parameter type/order:
Console Screen no longer has "printCharAt", and printAt no longer accepts booleans :p (have a look at the v1.1 documentation if you have time)
It does have (only) a few options: location and content + foreground (optional) + background (optional).
However, there are type combinations for a reason: convenience. You've mentioned you don't like things that are "only" for convenience but that's the sole reason the print methods exist at all. You can do all of the same things manually using the other methods, setValue, setColor, or even poke, but the convenience of the print methods is the central premise of the usage of Console Screen. Printing in this way can allow much cleaner code, and it's based on how BASIC would have drawn in a simple way to the screen.
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

Hapax

  • Hero Member
  • *****
  • Posts: 2775
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Selba Ward
« Reply #70 on: February 05, 2016, 04:58:40 am »
Added new object: Tile Map



Main things needed for this are: tileset texture, level data (in a vector or similar), and a camera position. Have a look at the (interactive/movable) simple example that generated this screenshot  :)
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

Hapax

  • Hero Member
  • *****
  • Posts: 2775
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Selba Ward
« Reply #71 on: March 12, 2016, 02:46:45 am »
I haven't posted here for a while as I didn't want the thread to become a constant update of "oo look; I just added a line of code!"
However, I've still been updating/upgrading things on GitHub as some of you may already know/have realised.

Here are some of the most recent updates:



Tile Map
(now version 1.3)
Since version 1.0:
  • Smooth Scroll to allow pixel scrolling,
  • Camera Target to allow specifying which tile is the focal point of the camera position,
  • Texture Offset to allow tile set to be a sub-texture rather than having to be at top-left of the texture,
  • Ability to customise default value of tile for "out-of-bounds" tiles
  • Retrieval of which level position is at a given co-ordinate (where in the map is this point?),
  • Retrieval of which tile is at a given co-ordinate (which tile is at this point?),
  • Co-ordinate of any part of the level (where is this part of the map?),
The three final points above all take into account the tile map's transformations so can simplify, for example, clicking on a tile even when it's been rotated.



Progress Bar
Now at version 1.1, Progress Bar can use textured for both the background and the bar.
Progress Bar also supplied the locations of three points at the progress bar's current position: top, centre, and bottom. These points take into account the transformations so it's possible to lock onto the bar's edge and draw other things.
Here's a screenshot that is textured and also shows the three points by locking three circles to them (red - top, yellow - centre, green - bottom):

The interactive code that generated the above screenshot can be found here.



Sprite 3D
Now at version 1.1, Sprite 3D can take a three-dimensional origin; that is, you can now specify a depth (z) for the origin. The 3D rotations transform around this origin. This means that the sprite can now rotate around a point not on its own plane!



Console Screen
(now version 1.3)
By far, the largest project inside the Selba Ward collection, Console Screen has been updated to version 1.3 (the last post here about it was for 1.1, which was the major update that introduced palettes and colour commands)
Since v1.1:
  • Ability to "paint" colours. This allows multiple cell colours to be manipulated at once in a similar way to printing but without affecting the characters/cell values (kind of like a highlighter),[/lli]
    • Cell Attributes. Each cell can store multiple "flags" to enabled/disabled certain states for that cell.
      These attributes are:
      • Inverse - displays the colour and background colour of that cell swapped,
      • Bright - displays fully bright (darkens the colour if disabled)
      • FlipX - displays the tile flipped horizontally,
      • FlipY - displays the tile flipped vertically
    • Painting Attributes. Attributes can also be "painted" in the same way as colours.
    • Clipboards. Multiple clipboards/buffers can be stored and recalled at will. Buffers can be the entire screen or just a rectangular region and they can be "pasted" at any position
    • Double-height. A cell can now be a part of a double-height cell using the "stretch" ability. The top and bottom halves can be used together or separately. Double-height cells can have both top and bottom printed at once automatically - using printStretchedAt()
    Here's a screenshot showing some of the latest features (attributes, double-height):

    In that screenshot, you can see the Selba Ward title being double-height. Below it, it's being display flipped vertically (but not stretched) and it also has the bright attribute switched off (it's on by default).
    "Console Screen" also has attributes painted over it: a switched-off bright attribute over "Console" and a switched-on inverse attribute over part of both "Console" and "Screen".
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

Tukimitzu

  • Full Member
  • ***
  • Posts: 117
  • Anti-Hero Member
    • View Profile
Re: Selba Ward
« Reply #72 on: April 28, 2016, 06:25:29 pm »
I didn't know 9-patch was a thing until now. Seems like such a nice feature, I'll definitely try it.
I'm curious, what is/was/will be the Spinning Card?

Hapax

  • Hero Member
  • *****
  • Posts: 2775
  • My number of posts is shown in hexadecimal.
    • View Profile
Re: Selba Ward
« Reply #73 on: April 29, 2016, 12:10:42 am »
Nine patch was pretty new to me too but I couldn't not create it as soon as I found it! I really need to remember to use it. It's so awesome!  :)

Spinning Card is/was a simple and light class that could be used to rotate a sprite horizontally or vertically in a pseudo 3D way.
I wanted to challenge the idea that the only way to "spin a card" was to animated its width or height and decided that animating its corners in an ellipse gave the impression of depth.
It takes a sprite, duplicates its setup and then splits it into a number of triangles (I think it stands at 8) to help slightly avoid the texture distortion that occurs when primitives are stretched. The "card" was intended to be used for the animation (of a spin) only and then destroyed afterwards where you would continue to use the original sprite.
Also, it can only rotate horizontally or vertically - never both at the same time.

It is included for both nostalgia and for people that either already used it or want a very light class to do this task. However, it has very little use since Sprite 3D renders it pretty useless. Sprite 3D can completely replace a standard sprite and is used in the same way, rather than just a temporary animation object. It also splits the object into a customisable number of triangles - to the point where you could be having a quad per texture pixel (or more!) if absolutely necessary. Still, it can be used with only triangles as with a normal sprite.

To clarify, Spinning Card is the original idea and Sprite 3D is the successor of that idea and should be used instead.
Selba Ward - SFML drawables
Kairos - Timing Library
Rectangular Boundary Collision - Rectangular SAT Collision

@Hapaxiation - Hapaxia on Twitter

Tukimitzu

  • Full Member
  • ***
  • Posts: 117
  • Anti-Hero Member
    • View Profile
Re: Selba Ward
« Reply #74 on: April 29, 2016, 04:12:42 pm »
Ah, I see now. Nice little features to have, I'll add the library to my toolbox :)

 

anything