<![CDATA[SteveBarnegren.com - Home/Blog]]>Thu, 07 Jan 2016 07:45:17 -0800Weebly<![CDATA[Attack Of The Clone Apps]]>Wed, 03 Dec 2014 22:14:35 GMThttp://www.stevebarnegren.com/homeblog/attack-of-the-clone-appsWhat do you do when some unscrupulous developer intentionally clones your app? I'm not talking about the type of clone whereby an app has the same concept as your own, that's just the domain of the not-so-innovative developer. No, I'm talking about something that's arguably much more destructive. A developer who creates an app which is intentionally designed to be mistaken for your own. It has the the same name and the same icon. An app that's trying to steal your app's identity.

I released an iOS application called 'Translator Keyboard' at the beginning of October. It was the first app (that I'm aware of) to provide language translation from within a keyboard extension. During the first week of release it was featured on a variety of well known tech sites including MacRumours and TechCrunch. Soon after this, Apple featured the app globally on the main page of the App Store. Of course, this increased visibility led to a substantial number of downloads, and I consider it to be my first truly successful independent release. Two months on the number of downloads is tailing off, but there is still enough revenue being generated by the app to make it worthwhile for me to continue working on it.

On the 23rd November, however, another app was released - 'Translator Keyboard Universal'. Here's the two application icons side by side. Look familiar?
White globe. Blue background. Keyboard at the bottom. It's incomprehensible that someone would see my application reviewed on a website, search for 'Translator Keyboard' and download the wrong one, right?

It's not just the name and the icon, though. Here's the splash screens:
This is so perfect I'm almost impressed; the way that the 'Universal' appears as though it's been scrawled on afterwards, like an afterthought that wasn't planned for in the original artwork design. As a customer it would be easy to assume that it's the new 'Universal' version of my application, and that mine is some sort of old 'not universal' version. Why on earth would you want to download the non-universal version?

Oh, and don't even get me started on the irony of that Copyright notice.

Lets see what they have to say about their app. They'd at least write their own app description, surely?

'Write in another language straight from your keyboard! It’s quick and easy to switch between translator keyboard and your normal keyboard. You can use translator keyboard in any app - write text messages, send e-mails, or translate your text to another language anywhere anywhere you like. Choose from many languages to translate to!'

Of course they wouldn't, it's word for word lifted from my description!
It saddens me that another developer would do this. Since this app has been released I've seen a noticeable reduction in downloads. In fact they've dropped by about half. Can it really have that much of an effect? I think so, yes. 

From a consumer standpoint, they're presented with two applications. Both have the same name and icon design. One's cheaper and appears to have more features. It's a no-brainer. Unfortunately, even when people specifically search for my application by name, I can't prevent them from stumbling across the impostor.
The developer's business model is fairly simple:

- Copy the name of another application, and append some sort of enhancement to the name. It could be 'SomeApp Universal', 'SomeApp Pro' or 'SomeApp HD'.
- Make sure that the artwork for the app closely resembles the artwork of the original application, so that consumers will think that they are related.
- Sell the app for cheaper than the original application. No one will question it, especially as he mentions that the app is on sale at the beginning of his description.

I should clarify that I have no issue with other people creating keyboards that include language translation. I was lucky to be first to market with this type of application, but I'm not under the impression that the idea was uniquely my own. In fact I know that I was not the only developer who was trying to bring this sort of product to market for the launch of iOS 8, and some of the other efforts I've seen have been really great.

I don't, however, appreciate someone trying to intentionally create confusion between their app and my own for their own profit. I put the time and effort in to marketing my app, which is the only reason anyone would be searching for the phrase 'Translator Keyboard' in the first place. It's a shame that some of those people will purchase an app which isn't the one they read about.

It's not as though it's a victimless crime either, lost sales means lost income for me. The real shame is that this isn't even a bad product, and could probably legitimately compete in the translation-keyboard-extensions market.

I have had some contact with the developer, who is insistent that this app has in no way copied mine. I've also contacted Apple, although it looks like their main course of action is to just put the two developers in contact with each other to squabble between themselves, and to be honest I don't blame them for not wanting to get involved in these type of disputes.

I've requested that the developer changes the name and the icon design. I know that the icon design isn't particularly innovative; I made it myself, and I'm no graphic designer. It's still the main way people identify my product, and it's unique enough not to be copied purely by chance. Regarding the name; as far as I'm concerned, 'Translator Keyboard' is my product name. Sure, it's more of a descriptive name than anything else, and I don't feel that I own that phrase, but as far as iOS-apps-with-keyboard-extensions-that-perform-language-translation go, get your own bloody name.


I'm unsure as to the scale of this problem on the App Store. Is this just an isolated incident, or is it a big problem in the store? If you've got any stories to share, post them in the comments.

Edit: Apple contacted the developers, and they have agreed to change the name and logo of their app. Thanks to everyone who has shared this post and shown their support.
]]>
<![CDATA[Game Kit Helper For C++ (Cocos2d-X)]]>Mon, 06 Jan 2014 13:52:46 GMThttp://www.stevebarnegren.com/homeblog/game-kit-helper-for-c-cocos2d-xI've been working with Cocos2d-x a lot recently. Writing games in C++ allows you to develop for a wide range of platforms simultaneously, but unfortunately makes interfacing with iOS specific features such as Game Center that little bit trickier, as they are all written in Objective-C.

Steffen Itterheim's 'Game Kit Helper' makes integrating Game Center in to iOS projects a painless affair. We can't easily drop it straight into our C++ projects, however, as it's an Objective-C class, so I've written an C++ wrapper for it to simplify things. This wrapper unfortunately doesn't include Game Center's multiplayer functionality, as it's not a functionality that I require at the moment. It does allow you to submit scores and achievements, load the Game Center views, and receive data from Game Center, for instance to build your own custom views. At some point I'll add the multiplayer functionality when I need it.

Grab the source code from my GitHub, and I'll explain how to use it.
Setup and Overview
You should have three classes, GKHWrapperCpp, GameKitHelper and GKHDelegate, as well as a header file called GKCppAlternatives. When adding these to your project, if you are using Cocos2d-x, don't save them to the Classes folder, as this one is shared between all of the platforms, and Game Centre is an iOS only feature. These classes will only compile for iOS anyway, as they use Objective-C, so a better plan would be to locate them somewhere within the iOS folder.

You will also need to link to the GameKit framework, you can do this in Xcode by going to Build Phases->Link With Binary Libraries and adding GameKit.framework.

Make sure you add your app to iTunes Connect, and setup Game Center. This is fairly easy to do, and there's plenty of tutorials online, so I won't cover that here.

Here's a brief overview of what the classes do:

GKHWrapperCpp

Use this class to communicate with Game Center, for instance, to send scores or achievements.

GKHDelegate

This class is used to receive data from Game Centre, for instance, to receive a list of the player friends, get a list of achievements, or get the top ten global scores. In Objective-C a class can be conform to a protocol to receive this data. C++ doesn't use protocols, but we can just use inheritance to the same effect.

As C++ supports multiple inheritance, any existing class you have can inherit from this one, even if it already inherits from another. Any class that inherits from this one will be able to receive Game Center data, I'll include some code examples of how to do this later on. You might not need to use this class, depending on what your requirements are.

GameKitHelper

This is Steffen's original class, although I've modified it to work with the GKHDelegate, and added a set of functions to convert between Objective-C and C++ types. You won't ever need to call this class directly.

GKCppAlternatives

There are several Objective-C classes that are used to hold the data that is received from game center. This header file defines basic structs containing C++ types that can hold this same data. You may not need to use these, depending on your requirements.

Using GKHWrapperCpp to submit data to Game Center
Logging in to Game Center

The first thing you need to do is log the player in to Game Center. Usually you'll want to do this as soon as possible, so in the applicationDidFinishLaunching() method of AppDelegate.cpp is the best place to do this. Make sure you include "GKHWrapperCpp.h", then declare an instance of GKHWrapperCpp and call the authenticateLocalPlayer() function:

GKHWrapperCpp gkh;
gkh.authenticateLocalPlayer();

I've declared this instance of GKHWrapperCpp on the stack. The wrapper itself holds no information, it's only a way of communicating with Steffen's class. As Steffen's class is a singleton, you will always be communicating with the same instance. You can declare a new GKHWrapperCpp anywhere you need one, there's no need to pass around a pointer to it.


Submitting Scores

Submitting scores is easy, simply call the submitScoreToCatagory(int64_t s, std::string c) function, here's how to submit a score of 10 to the leaderboardID "com.myGame.MyLeaderBoard":

int score = 10;
GKHWrapperCpp gkh;
gkh.submitScoreToCatagory(score, "com.myGame.myLearderBoard");


Reporting Achievements

Report achievements using the reportAchievement(std::string identifier, float percentComplete, bool showCompletionBanner) function. You will need to pass in the id of an achievement you've set up in iTunes Connect, a percentage complete, and and a bool. Set this to true if you want to see the 'Achievement Unlocked' Game Center banner, or false if you don't. The banner will only show if the percentage complete is 100, so there's no need to perform an extra check for this. Here's an example:

GKHWrapperCpp gkh;
float percentComplete = 100;
gkh.reportAchievement("com.myGame.myAchievement", percentComplete, true);


You can also call the resetAchievements() function to reset all the player's achievements.


Displaying Game Center views

Call to the showLeaderBoard() and showAchievements() functions to display the Leaderboard and Achievements views, respectively.

Using GKHDelegate to receive data from Game Center
If you want to receive any data from Game Center, for instance, to populate a custom Leaderboard, or to receive a notification when a score is submitted, then you need to create a class that inherits from GKHDelegate. If you have a class that already inherits from another, you can add this class to the list of parent classes by separating them with a comma. As an example, to inherit from this class from Cocos2d-x's HelloWorld class, which already inherits from cocos2d::Layer, you should declare the class like this:

#include "cocos2d.h"
#include "GKHDelegate.h"


class HelloWorld : public cocos2d::Layer, public GKHDelegate{
}


The first thing to do is to tell the GameKitHelper which class is the delegate, you can do this by passing in a pointer to your class when you create it.

GKHWrapperCpp gkh;
gkh.setDelegate(this);


If you no longer want to receive data from Game Center, or if your delegate class will no longer exist, then be sure to call gkh.setDelegate(nullptr), or your app will crash.

GKHDelegate contains a set of virtual functions that will be called when data is received from game Center. These functions print the data they receive to the console, which can be useful for debugging. If you don't want to see the debugging data, then, simply set call setDebug(false). Bear in mind, if you won't see the debug data if you have overridden the function in your own class, so you will need to call the GKHDelegate version. For instance, to see the debug data in your class' onAchievementReported(GKAchievementCpp achievement) function, your code should look like this:

void YourClass::onAchievementReported(GKAchievementCpp achievement){

     GKHDelegate::onAchievementReported(achievement);

     //Your code here


}

The functions in GKHDelegate are all fairly self-explanatory. If you want to receive some specific data, then the general pattern is to make a call to Game Center through GKHWrapperCpp, and then receive that data in your class that inherits from GKHDelegate.

As an example, you could call GKHWrapperCpp's 
retrieveTopTenAllTimeGlobalScores(std::string catagory) function, and then receive this data through GKHDelegate's onScoresReceived(std::vector<GKScoreCpp> scores) function. Notice that this will supply you with a std::vector of GKScoreCpp structs. All of these structs are defined in the GKCppAlternatives header, so you can easily see what data they contain.


I think I've covered everything, hope it's of some use! Any problems, let me know in the comments below.
]]>
<![CDATA[Animated Labels For Cocos2d-x]]>Thu, 02 Jan 2014 23:55:41 GMThttp://www.stevebarnegren.com/homeblog/animated-labels-for-cocos2d-xI've been working on a Cocos2d-x app recently that has required a lot of animated menus. A little design objective of mine for this app was to not have any elements just appear on screen, but to animate every visual element in and out.

For most of my text labels I'm using cocos2d::LabelBMFont. Of course, we can run an action on any class that inherits from cocos2d::Node, and LabelBMFont is no exception. The issue with this, however, is that running an action on the whole label at once just looks a bit boring.

To create more exciting animation, we need to run actions on the individual letters. As I've found myself wanting to do this frequently, I've created a CCLabelBMFontAnimated class, that encapsulates all the functionality required to do this.

CCLabelBMFontAnimated is able to run an action on a letter at a specified index, on all letters at once, on each letter sequentially, or on each letter sequentially in reverse. When running an action sequentially, a duration can be passed in, that will alter the time delay between each letter.

I've also included a handful of animations, as can been seen here:
There is also the option to get the label to remove itself on completion of the action (useful, for instance, if the action is a fly past, or animate out), and also the option to pass in a CallFunc action, to be executed when the action has completed.

Download/View the source code on my github: https://github.com/SteveBarnegren/CCLabelBMFontAnimated
]]>
<![CDATA[Asteroid Blaster]]>Thu, 12 Sep 2013 00:27:45 GMThttp://www.stevebarnegren.com/homeblog/asteroid-blasterIt's been a while since my last post, so here's a preview of what I've been working on. I'm putting the finishing touches on 'Asteroid Blaster', fingers crossed it should hit the App Store within the next few weeks.
]]>
<![CDATA[Shaker Box Is Out!]]>Thu, 18 Jul 2013 18:07:11 GMThttp://www.stevebarnegren.com/homeblog/shaker-box-is-outPicture
Shaker Box is now available on the App Store!

Shaker Box is a collection of high quality playable shakers for the iPhone, iPod touch and iPad. Thanks to a few generous people I managed to borrow a wide selection of shakers to sample, and there's a few quirky homemade ones thrown in there too. Here's the feature list for version 1.0:
  • Shake Mode - Shake your phone like a real shaker!
  • Tap Mode
  • Loop Mode
  • 13 professionally recorded shaker sounds
  • 4/4 and 3/4 time signatures

A big thank you to everyone who has already grabbed a copy! You can find out more on the Shaker Box page.
]]>
<![CDATA[Chipmunk Physics]]>Wed, 17 Jul 2013 14:36:07 GMThttp://www.stevebarnegren.com/homeblog/chipmunk-physicsRecently I've been playing around with the Chipmunk2D physics engine, and I've been having a lot of fun applying various forces to things to make them bounce around. It's incredibly satisfying to set up a Chipmunk simulation, and observe how objects interact with each other with different mass, elasticity and friction settings.

So why Chipmunk? You may also have heard of Box2D, which is the physics engine of choice for the majority of physics based iOS games. I did quite a bit of research before deciding which engine to go for, and in the end settled on Chipmunk, mainly due to the fact that it is a commercial product (In the form of Chipmunk Pro), and therefore is constantly maintained and updated. Chipmunk is gaining popularity, and although is still less widely used that Box2D, it has a more certain future, and recent updates have brought many new modern features that Box2D lacks.

In order to put Chipmunk through its paces, I've put together a fairly basic Angry Birds clone for iPhone using Chipmunk and Cocos2d. It's a fairly simple clone; there are no menus and only three levels, but it plays reasonably similar to the original. It took about two days to put together, and served as a pretty good introduction to Chipmunk. As there's not a lot written about Chipmunk, I thought I'd jot down a few thoughts.

Integration of Chipmunk was fairly straight-forward following the documentation. There's relatively few step-by-step tutorials compared to the more established Box2D engine though, so digging through the class reference is a must. Chipmunk is included as part of Cocos2d, so there is plenty of information on the Cocos2d forum regarding using the two together.

Performance-wise, Chipmunk is FAST. I'm using a fixed time step integration, and for this project I've been able to step the physics simulation 200 times per second and still achieve a constant 60fps on an iPhone 4.

Chipmunk is written in C, but an Objective-C wrapper is included with the pro version, referred to as 'Objective Chipmunk'. The Object-Oriented syntax of Objective Chipmunk makes it much more convenient to work with, and helps greatly with debugging, so I'm choosing to work with it over the C API.

So here it is, an Angry Birds clone using Chipmunk2D and Cocos2d!
]]>
<![CDATA[New Website]]>Thu, 04 Jul 2013 19:43:21 GMThttp://www.stevebarnegren.com/homeblog/new-websiteI have a new website! It's pretty bare at the moment, but the plan is to fill it with loads of awesome stuff.

This home page should serve as a sort of blog/news-feed related to things that I'm up to. I've never done the whole blogging thing before, so hopefully I'll have something worthwhile to post about.

So check back soon, and with any luck this won't still be the only post...]]>