Archive for the 'Uncategorized' Category

11
Mar
21

Working hard on Android dialogs

Since more than tree weeks I’ve been busy working with a solution to the Android Dialog Issues that RF was born with. What issues, you might ask? Well, they look ugly and are quite small compared to the screen size available. The reason for this is that when I created RummyFight almost 9 years ago there was no good way to open a dialog with the perceived same size on different devices with different screens and resolutions.

And as a matter of fact: There still is no good way of doing it.
So I had to invent my own solution.

Step 1:
Replace all dialogs where there are no text inputs with a bitmap solution based on AndEngine. This way I can have pixel perfect control of where I place items, what they would look like, how they behave etc. For this to be possible I had to invent a whole new interface system with buttons, views, lables, images etc. Once everything looked ok I begun converting some dialogs. These are the first results:

Old Profile Dialog


New Profile Dialog


Old ProfileGalleryDialog


New ProfileGalleryDialog

I think you agree with me that the new dialogs look a LOT better. Unfortunately there is a lot of work left which leads me to the next step

Step 2:
Create a solution for all dialogs containing text inputs, html content and complex word wraps… with Emoji support!
The only way to do this without reinventing the wheel is to actually use the View components but since I really dislike the layout based system in Android where everything must be placed in relation to another object (Place button to the right of the text, below the headline etc) I decided to create my own coordinate based system meaning I will be able to place my buttons “10 pixels from the bottom, centered”.

So how will I solve this in a system where this isn’t really possible?
Well, this is what I’ve been doing for the last 2 weeks.

First, I had to find out how to convert pixels to screen coordinates so that a window covering 50% of the screen’s with will do that regardless if the screen is 800 pixels wide or 2400px. This wasn’t very difficult since I could get the device’s resolution and divide it by my “Game Resultion” (which is 800 by the way). So if I want to place a button at coordinate 100,200, I just have to multiply 100 with screenwidth/gamewidth to get the pixel coordinate.

Sure, I must also calculate if there are black borders at the sides or above/below the game to find the right coordinate but that’s not very hard either.

Then we have the font sizes. Regardless of what you might think the same solution is not possible to use with fonts. Sure, I still use the same function for it’s placement but the size of the font is more difficult to calculate since the user might have chosen another size for the device system font and I want RF to use the system fonts. So what did I do? Well, the first time a dialog is opened in RF, I create an invisible text object with 20 ‘M’ in it with the font size 50dp. I then check if the string is wider that half the screen. If so, reduce the size to 49 and check again… and again… and again until the string is half the screen size. Store that value and use it as a scaling factor for all other fonts.

Ugly as hell… but actually working 🙂

Now I mentioned there are no pixel perfect positioning system in Android layouts. Well, there actually are one: RelativeLayout.

You can place any object in that layout and set it’s leftmargin and topmargin to your chosen X and Y as long as you can convert your game coordinates to screen coordinates… which I now can.

Ugly as hell #2… but working really well.

Are we done now?
Well, unfortunately not. Since I have built my own dialog system for textviews I also have to handle everything regarding soft keyboard, vertical moving of the dialogs so that you can still press the buttons while the keyboard is visible etc. I also have to explicit hide the keyboard when the user closes a dialog.

But that’s ok. I have already done all that on the iOS version so I can use the same methods of thinking.

So, is that all for now?
Well, perhaps.

Next time I hope to have the replacement dialog for the chat window done. This is by far the most difficult dialog in the whole app since it’s using emojis, word wraps, spannable texts with different colors and a whole lot more.
Keep your fingers crossed.


23
Feb
21

Updating the Android version

Now when the majority of all changes are implemented in the coming iOS version, the work has begun implementing them in the Android version too.

This is unfortunately not a matter of cut and paste since the two projects are two completely different code bases. The apps just look the same. Behind the interface the iOS version is written in Objective-C using Cocos2d as the main graphics engine. The Android version is written in Java and uses AndEngine GLES-2 as the main graphics engine.

Sure, the ideas and code approaches are the same but I need to rewrite the code. Let’s take an easy example. We want to create a string with the text “The player Richard is excluded from the fight” where “Richard” is a variable and “The player … is excluded from the fight” is a string that is in different languages depending on where the player is from.

So in iOS:
NSString *strText = [NSString stringWithFormat:AMLocalizedString(@”str_playerexcluded”, nil), strPlayerName];

In Android:
String strText = String.format(this.getResources().getString(R.string.str_playerexcluded), strPlayerName);


So yes, they are similar but still I can’t cut and paste anything.

And regarding 2D-graphics. Let’s assume we have a bitmap (Say… a ball) that we want to rotate a full 360′ in 5 seconds.

In Cocos2d (for iOS):
id rot = [CCActionRotate actionWithDuration:5 angle:360];
[pBall runAction:rot];


In AndEngine (for Android)
RotationModifier rot = new RotationModifier(5, 0, 360);
pBall.registerEntityModifier(rot);

So it’s a lot of work and that’s why the Android version will take some time more to be finished.

Right now I’m working hard on the new Dialogs for the Android version. Up until now the dialogs (pop up windows) have looked rubbish on the Android version and that’s because I’ve used the built in Android views which are difficult to make beautiful since there is no pixel positioning. You always have to place an object “next to” or “below” or “above” something else. Not “At position 100,50”. So I have instead created my own dialog system mimicing the dialog system on iOS so that it will be easy for me in the future to create new dialogs.

While doing that I stumbled upon a problem: Word wrap of text.
This is neatly built in in the iOS system but not so well in AndEngine. Sure, there is a word wrap function that automatically wraps a string by word or letter if it doesn’t fit but unfortunately it doesn’t take newlines into account. If I have a string looking like this “I want to have a dog\nAnd a cat\nAnd a small bird that says beeep”, it would look like this on iOS:

I want to have a dog
And a cat
And a small bird that
says beeep


Unfortunately AndEngine gives me this:
I want to have a dog And
a cat And a small bird that
says beeep


So for the first time since I began using AndEngine I had to jump into it’s code and make some changes in the following files:
AutoWrap.java (at line 16)
NEWLINESANDWORDS,

FontUtils.java (at line 155)
case NEWLINESANDWORDS:
return FontUtils.splitLinesByNewlinesAndWords(pFont, pText, pResult, pAutoWrapWidth);

And then add this function in the same file:
private static > L splitLinesByNewlinesAndWords(final IFont pFont, final CharSequence pText, final L pResult, final float pAutoWrapWidth) {
ArrayList newArr = new ArrayList(1);
splitLines(pText, pResult);
for(CharSequence strLine : pResult) {
if (strLine.equals(“”)) newArr.add(” “);
else splitLinesByWords(pFont, strLine, newArr, pAutoWrapWidth);
}
return (L) newArr;
}


The code is a little ugly but it actually works so I will leave it as this and maybe return another day to make it better.

10
Feb
21

Working on v2.11 for Android and iOS

I will try to release all four apps at the same time in a week or so (RummyFight, RummyFight-Lite for iOS and RummyFight, RummyFight-Free for Android).

The release will be called v2.11 and will contain a lot of bug fixes but also new features. This is what I have added/changed/implemented so far

TRANSLATIONS
* Replaced the german word Reihen (Runs) to Straßen
* Replaced the swedish word Gåva (Gift) to Present
* Replaced the swedisg word Lista (Bookmarks) to Vänlista

DIALOGS
* Close button now has a click sound
* When using english language, ProfileDialog now translates LastActive
* HTML information is now in correct size when used in dialogs
* Individual Statistics is now redesigned to look better
* You can now write a private note on a player (to remember something for yourself)
* If a player has played Tetpuz, his/her best score is now shown in ProfileDialog
* You can now change your own description in ProfileDialog
* FeedbackDialog in ABOUT now looks and fit the screen better
* In CHAT, click and longpress on a profile pic has now swapped functionality
* In WaitMatchDialog a click on a profile pic now plays the click sound

GENERIC
* Texts in buttons now always fit (size changed if needed)

CHAT
* Times in the chat now updates every second
* New “Start Fight”-button in the chat allowing quick starts with people in the chat

LOBBY
* Chat icon is now a little animated
* New icon (Gift) that is visible if there is a gift not yet viewed in a fight
* A Fight is now alerting also if it’s only 10 minutes or less left
* Fixed bug that made a fight still “flash” even though you had accepted it

BOARD
* FightClock is now moved in from off screen
* Possibility to Disable/Enable a theme from within a fight
* Dutch text in FastForward-button does fit now

NEWFIGHT
* Listbox is corrected so that all friends fit (if you have many)
* Added search filter for “Last active”. (Latest day, latest week etc)
* Increased number of possible search results from 50 to 100
* Filter on age does not anymore return players without their age set

TETPUZ
* Instructions for dutch players are now in dutch instead of swedish 🙂
* Highscore names are now clickable and opens ProfileDialog
* Fixed bug that sometimes didn’t save scores correctly in server

GIFTS
* New Gift: Sadness
* New Gift: Balloons
* New Gift: (I won’t tell you this one – you will have to find it yourself)
* Fireworks fixed and works now again
* Improved the looks of Hearts-gift and Broom-gift
* Color corrected some gifts that was more yellow than others

All these things are implemented in the next iOS version now. Next week I will implement them in Android too.

RummyFight is unfortunately NOT the same app for both systems but two completely different projects and code so I can’t use anything from one system to another. If I add a balloon to iOS, I have to open the Android project and add the balloon there too.

But that’s just the way it is.

02
Feb
21

RummyFight-Lite for iOS

Since about two weeks we finally have a free version of RummyFight for iOS too. There has “always” been a free version for Android called RummyFight-Free but now the same app exists for iOS too but it’s called RummyFight-Lite since the word “Free” is forbidden by Apple in an app name.

And since RF-Lite had some new features compared to the paid version, that one too was updated with the new code so now we have both RF and RF-Lite v2.10 available for iOS.

I hope you like them

07
May
20

Version 2.0 (And 2.01) released for Android

Last summer, Google dropped the support for Google Cloud Messaging and now demanded only the usage of Firebase Cloud Messaging to send and receive notifications to an app.

Now, one could think that it just would be a matter of implementing Firebase then? Well, unfortunately RummyFight-Android was created using Eclipse and Firebase can only be implemented using Android Studio which meant I had to migrate the whole project to Android Studio.

Of course the automatic migration would not work since it’s such a complex project so the only way for me to succeed was to create a blank project in Android Studio and import piece by piece into it, adjusting every part of the source and resources to work in this new environment.

If that wasn’t enough, I had to do something about my usage of AndEngine. It’s a 2D graphics library that I had always used for all the dragging, dropping, updating of the interface etc. In the old RummyFight I used AndEngine GLES1 (For OpenGL 1.0) and of course that doesn’t work in Android Studio. However there exists a GLES2 version (For OpenGL 2.0) that could be hacked into working so I tried that and actually succeeded.

A lot of things had changed in the GLES2 version though so I needed to go though all code and redesign a lot and also re-invent the wheel some since a few functions was removed. That is the reason for the Fireworks looking different in v2.0. The particle system had changed a lot since GLES1 so I had to create a completely new fireworks solution.

I also had to change a lot regarding the fetching of profile pics and theme backgrounds to make them work in GLES2.

But eventually the app finally compiled and I could start testing it… realizing there were yet a lot of things to fix.

One of them was the popup of dialogs. GLES1 ran on uiThread but GLES2 on backgroundThread meaning that if someone clicks on a player name, the app would crash when opening the profile dialog since it MUST be opened on the uiThread.

So I had to find all places where i open a dialog and surround the code with

runOnUiThread(new Runnable() {
    public void run() {
        OpenTheDamnDialogHere();
    }
});

What I then believed was the last step to do was to make the app accepted by Google Play which meant creating new, larger icons it it to take into account that newer phones and tablets with higher resolutions have been released the last 4 years. That included app icons, notification icons etc. Apparently app icons should be round now, not square… but still needs to be square if the app is installed on an older device.

Notification icons I said? Hmmm… Oh, new rules from Google. They must be black and white only now if you use a modern device. Ok, draw a new one black&white then and include code to distinguish what Android version are used and select the appropriate icon.

And while on the topic of notifications: Firebase supports two types of messages: Notifications and data. However if I send a notification message to RummyFight while it’s in the background, the receiving device will only play the standard notification sound. Since there is an option in RF-Settings to select your own sound I wanted that function to be kept which meant that Data-Message what the way to go and give all the logic to the app instead of the system.

Then, of course I had to change in the server how these messages were sent to the devices but at last I got it working.

Ok, back to releasing it to Google Play.
Create APK, upload it, all looks good… then a BIG WARNING:
“The app uses READ_PHONE_STATE – This is not recommended”

What? It does not!!!

Actually it was a bug in Android that added this permission by itself but I found a solution that worked. I added READ_PHONE_STATE in the code and then immediately removed it efterwards, hehehe 🙂

New upload – rejected since not all parts of the app was 64 bit code. What??? I thought all java would compile into 32 and 64 bit automatically? Yes, but there were parts of andEngine that was only 32 bit. Luckily some nice people on the net had managed to create 64 bit libraries of andEngine that I could import and finally the app was accepted by Google.

They informed me a release could take up to 7 days to be accepted so I started working on other things but already after 18 hours the new version was live… and it crashed hard!

After some debugging and looking at crash reports I realized that this only happened on Android 9 and 10. Seems that the http object used in the app to fetch info from the servers is totally ok to use up until Android 8. From 9 and forward another object must be used… or at least explicit support for the old version must be stated.

I stated!
<uses-library android:name=”org.apache.http.legacy” android:required=”false”/>
and also added a policy saying that http requests to *.rummyfight.se is allowed, not only https.

Then I submitted v2.01 and keeping my thumbs really hard it will work this time.

Damn it’s difficult to maintain a 8 year old project where the latest release was done 4 years ago.

30
Nov
17

So, what’s next?

Now when v1.60 for iOS is released and seems to be working fairly well, it’s time to think about what to do next.

  1. I will very soon release v1.61 of RummyFight for iOS. There are some small bugs in the app I want to take care of as soon as possible. Nothing major but still a bit annoying maybe. One example is that all dialog windows (like the chat etc) look quite small on iPads. This is because they are not scaling the same way as the game itself does. I have already starting the work on this.
  2. It’s time to create a new update for the Android version too. The reason I haven’t done that in a year is that Google has dropped their support for Eclipse as the main developer’s suite and wants all developers to use Android Studio instead. RummyFight has always been an Eclipse project and it’s quite tricky to migrate existing projects to Android Studio which has left me with a perfectly fine project impossible to compile and submit to Google since about a year. I have however begun the migration to Android Studio and as soon as I’m done with that I can start working with the code again.

So, that’s just about what I can say right now. Feel free to comment on this post with suggestions that could improve RummyFight. New ideas are always welcome.

28
Nov
17

v1.60 for iOS now released

So, now that v1.60 finally is released I thought I could summarize what’s new or changed in it

IN GENERAL
To be able to create a version of RummyFight that works on iOS11, I needed to update the developer suite called XCode. For that to even install I needed to update the Mac OS. The problem was though that my Mac was too old for that so I had to get a new Mac first. Then I installed the newest OS, downloaded XCode, opened the project and thought this would be easy.

But noooo.

The old version of RummyFight did it’s own memory management. It allocated and deallocated data itself without any help from iOS. The problem was that Apple now has decided that all apps should use the built in ARC instead (Automatic Reference Counting) which deallocates data when it’s not needed anymore. Normally this works just fine but sometimes it guesses wrong which turned out to be a big debug problem for me.

Anyway, sure. I removed all deallocations in my code and changed the structure some… but still RummyFight was using an external 2D graphics engine called Cocos2D and that one did also it’s own deallocations. Cocos2D is huge and I don’t know my way around all it’s code so I instead chose to update it to version 3, which supported ARC. Fun thing though: Cocos2D v3 was very different from v2 so I had to rewrite almost all usage of that engine. Sometimes small changes, like that the color white was called 255,255,255 in the old version and 1.0, 1.0, 1.0 in the new one. Not difficult but cumbersome. I mean, the source code of RummyFight is more than 30.000 lines now. Lots to look through

But some changes were bigger, like how to use Actions callbacks, using animated sprites, adding textures from pictures etc. So this was a BIG challenge for me and it took a lot of time. The majority of the 1.5 years that this update has taken has had to do with the conversion to Cocos2d v3.

Anyway… next obstacle.
When the old version of RummyFight was created, only iPhone 3 and 4 existed (and the iPad of course). Since the app was an iPhone app (not a universal), it did however work on the iPad too even though it was scaled and didn’t really look good. Now, the new version has to deal with iPhone 5, 6, 8, X and multiple types of iPads. All with different resolutions, screen sizes, aspect ratios etc.

So I needed to find a solution to that too. What would I do with the extra space on wide screens. How should I handle the extreme resolutions now available in the new phones, etc. How would it affect the positioning av things in the app if the screen was three times larger than the app originally was built for. Would a button placed at coordinate 320,160 still be in the middle of the screen or down to the lower left now?

Well, it turned out it was the lower left so EVERY coordinate in the app had to be changed from absolute to relative. Like, “Place this button 10% to the left of the middle of the screen” etc.

But finally I found out a way to do it and piece by piece all screens started to look close to the old ones.

dump_lobby_ipad
Here’s a screen capture from an iPad. You can see that I’ve added black borders to the top and bottom for that kind of screen size.

dump_lobby
Here is the same screen from an iPhone 8 where you can see I’ve added graded green space to the left and right.

SO OK. GIVE ME THE RUN DOWN ON ALL NEWS AND CHANGES
Ok, we start with the Lobby above. Nothing much there is changed. However a few small bugs are fixed though and also some translation fixes of words too long to fit. Visually it looks more or less the same apart from the Footer which now looks the same on all screens (it didn’t before). The Top on all pages are now also animated and the buttons are not completely static anymore. I thought it would bring some life into the app again.

dump_greengameSo, what’s changed inside the Fights then? Well, as you can see the player in turn is now a big yellow panel instead of just yellow text. Also, clicking on the stack of tiles in the upper right corner now opens a window with detailed fight history: When someone made a meld, how many tiles it used, when an opponent did a NewTile etc.

Also fixed a bug which has been around since RummyFight v1.0: When placing bad tiles on the board only the last placed tile were flashing, showing it is bad. Now all bad tiles flash.

Oh yeah, you might notice the clock in the upper right corner? It shows how many hours, minutes and seconds you have left before you are timed out. Great for Speedgames.

Also updated and changed a few of the Gifts, including a new version of the Hoarder song. A nice little addition too is that you now can cancel the download of a theme by tapping on the download dialog window. Pretty handy if you are on a slow connection or something.

dump_tetpuzTetpuz has gotten a makeover with new tile graphics. I’ve also added the MINE-section in the highscores (showing YOUR best scores) and also how many submitted scores there are.

I’ve also added a visual explosion animation when blowing up a bomb and tweaked the numbers a little to make the debris move better. And yeah, almost forgot: Try to tilt your device while having debris at the bottom of the screen. I’ve always wanted to add that feature 😉

IN THE END
Of course there are multiple other things changed in the app too but these are the ones I can remember straight from the top of my head.

I would say that 80% of my work has been invested in just making the code compile again. Then 10% has been about debugging and sorting out issues related to the ARC (memory management – objects disappeared before the app was done with them etc). The last 10% is related to the new features and making them work.

Add almost three whole days of work including a long phone call to tech support in USA just to be able to upload the app to Apple for review and acceptance. It’s almost ridiculous how difficult it is to release apps to them. You really need to be a rocket scientist for that.

SO WHAT’S NEXT?
Well, let’s wait a little and see how well this v1.60 works in reality before making any new plans. I mean, surely there will be a need to fix some urgent new bugs. And then we have christmas. I have 2 kids, a wife, three cats, a horse, 50 fish, 2 axolotl lizards, a job and a life. Give me a time to breathe and we will see what 2018 will bring to RummyFight.

More than 30.000 lines of code now! How about that

 

23
Nov
17

Now we are CLOSE

Been working like a maniac the last week with the new “RummyFight for iOS8 and above” and as far as I can see in my papers I have now only ONE bug left to fix before it’s possible to release it.

When I woke up this morning there were TWO bugs left but I have finally made the notifications to work in the new version too, without having to change anything in the servers.

So, why did it take so long and what’s left then?

Well, the thing is. When I originally developed RummyFight there was the iPhone3 and iPhone4 only. The main difference (for me) between them were just that the iPhone4 had twice the resolution, meaning that I had to include two versions of all graphics and also recalculate everything’s positions according to the detected screen size.

Then… the iPad came, then the iPhone 5 (with a different screen ratio), then iPads with retina resolution, larger iPads, larger phones etc etc.

So, what I needed to do was build a coordinate system and layout capable of handling all these different screen modes.

And I think I’ve made it.

The new version of RummyFight will still work on iPhone 4 and then it will look like this:
iPhone4
Pretty similar to the old verison, right?

Then there’s the iPhone 5, 6, 7, 8 etc which uses a wider screen:
iPhone8s
Looks almost the same but there are some shaded borders to the left and right.

And finally, the iPads which have a very different screen ratio. This is what it will look like on them:
iPad2
This is a mix between the iPhone4 and iPhone5 modes but with black borders at the top and bottom.

So, the last thing to fix is that the coordinate system doesn’t quite work for iPads in the NEWFIGHT section. The players dragged to the seats have an offset I need to fix.

But otherwise, it seems to work elsewhere.
So, fix this in the coming day or so… breathe for an hour or two.

And then release!

/Totta

05
Nov
17

Well, how about that?

Skärmavbild 2017-11-05 kl. 14.47.44

Still quite a few bugs to fix before it’s worth releasing but it actually works now. I can even play and make melds with it. However, as I said, there are still bugs left that I need to fix, like Theme Pictures being positioned on top of everything else and in the wrong sizes, accessing the camera from SETTINGS makes the app crash and several other things.

But it does work.
Nobody is more surprised than me.

16
Oct
17

Making progress

I’m finally making some progress again with the new iOS version that should work with iOS 11. There are SOOO many things that need to be changed in the source code and some parts that have to be completely rewritten.

Due to the size of the RummyFight source code it is very difficult to know exactly what to rewrite and how, just to test if it’s working so instead of wasting a lot of time on this I have instead started programming a completely different app.

Why you ask?

Well, that app is using a lot of the same things as RummyFight. It can access pictures in the camera roll, it can open the camera, it can render bitmaps on the screen and allow them to be moved etc.

So while creating this new app, I’m also learning how to do things “the new way” and as soon as I have figured something out, I switch to the RummyFight project and implement working changes there.

So, now RummyFight can once again access the camera roll, open the camera, download theme pics and render them in the correct sizes etc.

Next task is to solve some memory issues that makes the app crash very often since the ARC is deallocating objects before I’m done with them.

Hope to find a strategy for this soon.
Keep your fingers crossed.




Categories