Tuesday, November 30, 2010

Your Japanese Name for iOS, part 8

I suppose as some sort of balance to yesterday's activity, today I feel burned out. Even slow progress is some progress, so I should attempt to get at least some small thing done. So I'll attempt to get all the last frames of the movie files out today. Seems the simplest solution is just to get ALL the frames and discard everything except the last one. Which would be the same as just outputting them one after another overwriting the same file... I/O error. Okay, so get all and discard all but last.

Done. This gets last frame of each m4v file in the "m4v" directory and puts it in the "out" directory.

import os, shutil
TMPDIR = "blahfuck"
OUTDIR = "out"
for fn in os.listdir("m4v"):
for del_fn in os.listdir(TMPDIR): os.unlink("%s/%s" % (TMPDIR, del_fn))
os.system(r"ffmpeg -i m4v/" + fn + r" " + TMPDIR + r"/%d.png")
last = sorted(map(lambda x:int(x.replace(".png", "")), os.listdir(TMPDIR)))[-1]
outpath = "%s/%s" % (OUTDIR, fn.replace("m4v", "png"))
shutil.copyfile("%s/%s.png" % (TMPDIR, last), outpath)

Idea of getting the characters through SVG seems like a good one, but I can't start doing that now. So what to do instead? Maybe learn about how to post to Facebook. Nice, this SDK seems very easy to integrate. Comes with a simple demo app that posts to facebook stream. Adding this to my project also got me a neat JSON library. I will enjoy it.

Facebook login almost works, but do I really need it to post to the stream? Can't I just invoke the stream post dialog without this login hassle, I remember seeing it in some other app. But time to sleep now ...

Monday, November 29, 2010

Your Japanese Name for iOS, part 7

Next I'll need to come up with a dataset of all the segments and waypoints. For reusability, it would probably be best to have a vector representation of each segment. Seems likely that such a dataset doesn't exist yet, easiest way to get one would be to just draw one in some vector editor that lets me display a raster image in the background for reference.

Another option is just to make each segment in Gimp at retina display native resolution. It would be easier, but then porting this to some other resolution like to the iPad would be harder. Of course even for older iPhone I would need a half-res version, although for that I could just scale without redoing anything.

Hmm.. I'm already a bit familiar with Blender. I could make the characters there and get out a triangle list. This solution appeals to me, because I get to play with Blender :-) What would the output look like? I would have one file for each segment. A file that tells where the waypoints are in each segment. Then a file that describes how these segments relate to each character. The most natural way to describe this would be in JSON, and luckily there seems to exist an actively developed JSON library for Objective-C.

segments = {
0 : { // each segment has integer ID
"tris" : [
[0, 2], [1, 2], [1, 3], // coordinates for one triangle
[1, 2], [1, 2], [2, 3],
[0, 2], [4, 2], [1, 3], // each segment would consist of several triangles
...
],
"waypoints" : [
[1,2], // exactly two waypoints per segment
[3,4]
]
},
... more segments
}

characters = {
"ka" : [ // each character would consist of several segments laid over each other, order here is significant for drawing
{
"segment" : 0, // identifier of segment
"offset" : [1,2], // XY coordinates where the segment should appear
},
{
"segment" : 1,
"offset" : [2,3],
},
... // each character consists of multiple segments
],
"ki" : [ ... ],
...
}

It would be pretty straightforward to write a Python script that generates these. Probably less straightforward dealing with Objective-C types when reading them in. Alternatively could make that Python script just generate Objective-C so the types would already be correct and access easier.

Stuff I need:
- Install Blender and get it to work with my keyboard or buy a new keyboard that has numeric keypad
- Exporting triangles from Blender
- Figure out a way to comfortably choose waypoints (repetitive task)
- Also need some tool for composing characters from multiple segments



Uhh am I about to embark on creating some vector drawing program here? x_x Just as a fun thought, if these tools were really good, could I somehow get this task crowdsourced for all Japanese characters? There are thousands of them.

Came up with another option. Use SVG. There's an SVG editor in Javascript already available. It even knows how to overlay vectors on top of an image. Ooh, it has text support. So I don't even need images as I can draw on top of unicode text. For each character in katakana, go to SVG-editor and create a 1280 x 960 image with the desired character at position 400, 800 in size 900. Draw each segment (note: not stroke, a segment) on top of the character. Use as many segments as seems necessary to capture the desired path. Then, place rectangles on top of the complete character to get waypoints. Place them in the order the character should be drawn in. Use different color for each segment's rectangles so that they can be associated with each other. Save SVG (copy & paste) into a file like "a.svg".

This should have all the info in it necessary for revealing the character as it is swiped by finger on the phone.

Have to be more careful in the transitions between segments. I can see a gap between first two segments of A here.

Realized something. I should definitely make these based on our calligraphy videos instead of on an existing font, because then the videos and the vector art would match exactly, making it possible to do some cool transitions between them in the future (for what purpose I'm not sure). Also it would clarify the issue on copyright, as I wouldn't be basing the art on any existing font.

So I need the last frame of each of these videos in order to do this. Sounds like a job for ffmpeg.
ffmpeg -vframes 1 -i frametest.m4v -f image2 output.png

This gets the first frame. But how to get the last one?

Mega Jump

One of my favorite iPhone games is "Mega Jump". It really is a game made with this platform in mind.

In the game you control a character by tilting the phone from left to right. The character jumps higher and higher the more stuff it collects. I love the simplicity of the controls. Many games attempt to be like PC games and have dual virtual joysticks, but that doesn't really work well. In Mega Jump there is no need to touch the screen at all during the game. I love the graphics too. As you can see it has that "cel shaded" feel to it, solid colors with thick black borders.

And particles!

The game would be just fine as it is and pretty successful too I think, but what really sets it apart is how it entices the player to come back. You play it a few times, and just when you're about to get tired it unlocks something for you. You see, every time you play you get kind of experience points, and these unlock new levels, bonuses and characters. So when you return to the game, it will have something new in it to try, even though the gameplay itself is as simple as ever.

Your Japanese Name for iOS, part 6

Got some good suggestions for playing audio. Looked at Finch and OpenAL. One thing in common seems to be that background loops are played with AVAudioPlayer. Apple's "oalTouch" example seems to be easiest for background music playback. It didn't loop though, but docs say it should be possible to get it to loop, so I'm hopeful. Also a bit optimistically I'm hoping that I could instantiate multiple AVAudioPlayers for each sound. None of the examples seems to be doing that, so maybe there's a reason why it doesn't work, but docs say it should.

Got background music to play. Bought sound from iStockphoto. Converted from WAV to M4A through iTunes and customized a snippet from oalTouch example:

bgURL = [[NSURL alloc] initFileURLWithPath: [[NSBundle mainBundle] pathForResource:@"koto" ofType:@"m4a"]];
bgPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:bgURL error:nil];
bgPlayer.numberOfLoops = -1;
[bgPlayer play];

It really does seem to be a perfectly seamless loop. Listened for a few minutes and got tired of it already :-)

Next I should see what happens when headphones are plugged / unplugged. In Mega Jump the music just continues playing. Apple guidelines say the music should stop, but I don't think that's suitable for me because there would be no way for playback to continue, just like there isn't in Mega Jump. Well, I suppose I could show a big pause button, but it seems like overkill.

Great, seems the sound continues by default, so don't need to handle it at all.

Next, how to fade in and out the sound of chimes when finger is moved around. Cool, found fade out example code.

Works as advertised. Found a new case again. User puts finger down, drags, lifts finger up, drags at another point. Sound abruptly ending and new starting sounds painful. Instead should let chimes from old movement fade out while the new sound starts. I was wrong to think I only need 3 channels. Luckily AVAudioPlayer handles this transparently, so I just need to instantiate a new player each time the user puts their finger down. May cause problems if user taps a hundred times within a second. That would allocate a hundred players with all the sounds mixed together, will have to test to see if it's a problem.

Now chimes overlap and fade out as I originally planned. And yes, tapping too fast turns out to be a problem. This device is slow enough that by mixing too much this naively I can apparently max out the CPU. Well, I'll just have to cancel the oldest sound if some maximum mixing amount is reached.

Done. Next should start planning how to separate Japanese characters into drawable blocks. The structure is such that each word consists of several characters, each character consists of several strokes and each stroke consists of several segments. Each segment has a start and end waypoint that need to be touched in order for the segment to be completed.

Sunday, November 28, 2010

Your Japanese Name for iOS, part 5

"I'd rather use a few days to make a simple mixer" <-- famous last words?

There's some stuff I didn't consider.

- If I have a big sound, it needs to be streamed from disk because there might not be enough memory to load it all in. I could try to make this easier by having a shorter loop.
- Sound needs to stop if user plugs their headphones in / out or attaches their iThing to an external sound system ("audio route change").
- Also need to stop playing if the user receives call / sms on iPhone.
- What if the user closes the app in the middle (applicationWillResignActive). How to resume playing at correct pos? (maybe just restart sounds)
- What if the user is already playing music on their iThing when they start the app? (AVAudioSession setCategory)
- A lot of this example code is in C. I do know C, but had forgotten how long-winded it can get. Spending a long time staring at code pieces and realizing that oh, this snippet of several lines just gets one value from some structure. Compared to Python there are no exceptions, have to deal with handling memory, numbers can overflow.

Back in the day I did manage to play sounds in DOS by loading sound files myself and streaming them to my SoundBlaster over DMA, so I should be able to handle this. Just gotten a bit comfy with modern conveniences and suddenly being thrown back into the jungle.

Asking the HiveMind for advice

Saturday, November 27, 2010

Your Japanese Name for iOS, part 4

Today I probably won't have much time to work on this, but let's see if I can suitable fail / success / complete sounds on iStockPhoto.

...

Finding sounds is a lot of work!

Character drawn correctly -sound


As background, one of the "koto loop" melodies from iStockPhoto. Update: this one

Maybe this one mixed in after all the characters have been drawn correctly and the final result is displayed in gold.

But what about failure sound? Or "finger touched down" sound. Actually what I'd really want for that is for wind chimes to be played while the finger is progressing on the character. But when the finger is lifted up, the sound shouldn't abruptly stop. Instead it should fade out, maybe even echo a bit. This seems to call for some sound library. What was that famous one? Oh yeah, fmod. They were porting like crazy, let's see if they have an iOS version... Seems they do. But it's $500 per product, out of my budget. I'd rather use a few days to make a simple mixer, I think there was some source code in some Apple example. Yes.

Whoa, feel a bit overwhelmed. Let's see what I really want to do here.

Channel 1: Looping soundtrack, always full volume.
Channel 2: Wind chimes, starts full, doesn't loop, fades out at any point.
Channel 3: Buddha bell / gong / wrong. Never overlap, full volume, no loop.

If I had the API of my dreams, what would it look like? First it would start like
SoundSystem *sounds = [SoundSystem soundSystemWithLoop:@"koto.mp3"]; // start with koto ambience on channel 0
[sounds play:@"chimes.mp3" channel:1 looping:YES volume:0.0];

Then when the user puts their finger down, I'd like to
[sounds fadeTo:1.0 channel:1 delay:0.05];

And when they release their finger
[sounds fadeTo:0 channel:1 delay:0.3];

For the other sounds I could
[sounds play:@"buddha_bell.png" channel:2];

Basically just play looping or not, caching known sounds and controlling the volume of each channel.

Friday, November 26, 2010

Your Japanese Name for iOS, part 3

Goal for today will be to:
- Initialize offscreen buffer (CGBitmapContextCreate?)
- Draw to offscreen buffer with some kind of brush
- Flip offscreen buffer so that it's visible for debugging purposes

I've seen a few examples of CGBitmapContextCreate, but my biggest question right now is how to know what kind of buffer to create. Depending on the device the resolution differs.

...

Managed to get something on the screen. Got the default context for the view with UIGraphicsGetCurrentContext and drew some stuff. Was surprised that every time all the previous contents disappeared. So actually this default context isn't a bitmap at all?

Trying to make an offscreen buffer. self.frame.size seems to give same values both on old iPhone and iPhone 4, so it would seem to be the size of the display in points, not in pixels. Yes, it seems you can't depend on these values, other people on the internets are having problems with app not working as expected on retina display when doing this. So should take the scaling value into account I suppose.

I see some example code calling CGBitmapContextCreate with NULL as first argument. The first arg is supposed to be the data used for the bitmap context. Seems like a big no-no to have it be NULL. Or maybe it's a magic arg that causes the function to allocate its own space somehow?

"In iOS 4.0 and later, and Mac OS X v10.6 and later, you can pass NULL if you want Quartz to allocate memory for the bitmap. This frees you from managing your own memory, which reduces memory leak issues."

...

[UIScreen mainScreen].scale is 2 on retina display, 1 on older iPhone. So it seems the width of the offscreen buffer should be [UIScreen mainScreen].scale*self.frame.size.width pixels and similarly for height. Seems that many code snippets floating around on the net are missing this detail and then wonder why their bitmaps look pixelated.

...

- (CGSize)offscreenBufferSizeInPixels {
float scale = [UIScreen mainScreen].scale;
CGSize sizeInPoints = self.frame.size;
CGSize sizeInPixels = CGSizeMake(sizeInPoints.width * scale, sizeInPoints.height * scale);
return sizeInPixels;
}

- (CGContextRef)createOffscreenContext {
CGSize size = [self offscreenBufferSizeInPixels];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, size.width*4, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);

// "Because you use a lower-left origin when drawing into a bitmap or PDF context, you must
// compensate for that coordinate system when rendering the resulting content into a view."
CGContextTranslateCTM(context, 0, size.height);
CGContextScaleCTM(context, 1.0, -1.0);
return context;
}

...

Now that I have a presumably empty offscreen context, how do I blit it to screen?

Answer:

CGImageRef offscreenContextAsImage = CGBitmapContextCreateImage(offscreenContext);
CGSize fsize = [self offscreenBufferSizeInPixels];
CGContextDrawImage(context, CGRectMake(0, 0, fsize.width, fsize.height), offscreenContextAsImage);

Strangely, even though I didn't wrap with UIImage, I had to comment out CGContextTranslateCTM and CGContextScaleCTM to get it to display correctly. Hit a new problem now; if I draw shapes for a while I get a memory warning. Am I reallocating something repeatedly? Let's see if I can use Instruments to see what it is even before I try to guess.

Ran Instruments by selecting Run > Run with Performance Tool > Allocations in Xcode. As I paint more things memory usage very gradually goes up. Starting at under 2MB it gradually goes to nearly 4MB as I draw more shapes, and then the application gets terminated. Tried another tool called "Leaks". It says the leaked object is a CGImage and that the responsible frame is CGTypeCreateInstanceWithAllocator. Hmm...

...

Aha, apparently CGBitmapContextCreateImage can actually allocate memory (or lazily copy-on-write, anyway) and not just get a pointer to existing image data. So I should CGImageRelease(offscreenContextAsImage). Works without leaks after this change, but disappointed with how slow this is. Only getting maybe ~15fps.

...

Mission accomplished. Can draw with a brush now, but it's slower than I hoped.

Thursday, November 25, 2010

Your Japanese Name 2

Instead of just showing the result, maybe challenge user to draw it themselves.



Something like this. Except with less suck. Would it be better to reveal a readymade image as the user draws, or let them draw freeform? Unsure. If readymade, have to do some clipping / masking magic to reveal it in the direction the user is dragging their finger. If freeform, need to do other kind of magic to make it look like calligraphy.

Stuff I need:
- Initialize offscreen buffer (CGBitmapContextCreate?)
- Draw to offscreen buffer with some kind of brush
- Flip offscreen buffer so that it's visible for debugging purposes
- Use said buffer as a mask (could just copy alpha values or use some compositing operation if such exists)
- Every katakana character with pieces separated such that they can be revealed in order
- Looping background music
- Graphics for mascot / teacher character
- Success sound
- Fail sound
- Completion sound
- Design for title screen
- Copy for character dialog
- Graphics for dialog bubble
- Background texture
- Figure out how to play background loop and sound effects simultaneously (3rd party library needed?)
- Post to Facebook feed
- Post as email (might need own server)

Standard stuff like before:
- App store icons (6 different ones)
- 512x512 art for iTunes?
- App store description
- App store screenshots
- Feedback button
- Default.png for app quick launch



Or maybe it should be upright after all? Samuel L. Jackson as the mascot, giving totally wrong advice. Also, could just show text. Who needs a mascot.

Your Japanese Name for iOS, 1

Regardless that it doesn't have great long term potential, I've decided next to make a version of my Facebook app Your Japanese Name for iPhone / iPod Touch. The FB version has over half a million installs, although recently usage has gone to a mere 1600 monthly users. This was because I was unsuccessful at quickly converting it from a profile-based app to a feed-based one, although I did eventually do so.

There are already some similar apps in the App Store, but I believe I can get some installs if I can leverage the FB userbase. If I still have the list of user IDs stored somewhere, I should be able to inform users of the iOS version through a notification and get some installs that way. Since the App Store likely shows more popular apps first, it should push my version to the top, where it would then remain as it would enjoy extra installs from being the first listed app.

If this takes a week to make and starts doing $1 / day in profit, I wouldn't think it was a waste of time. Looking at this list of iphone app sales it seems possible.

Wednesday, November 24, 2010

What to make next

Now that I have some idea how much effort it is to make something, I've begun to think about what I really want to do next for iOS. I haven't really decided yet, but I've realized I do have some constraints limiting my search space. First of all, the app can be something that takes years to make, but it has to be possible to release an initial version to get feedback on in 2-3 weeks. I'm not patient enough to quietly work on something for a long time with no outside input. Once I get some, it becomes much easier to continue. An episodic game for example would suit my work habits well.

Secondly, it has to have the potential to make some money. I need to eat. It's difficult to code while dead (believe me I've tried). For this reason I've considered making some sort of utility app that could be expensive enough to even be marketed online, but haven't really come up with any ideas. I just don't know any industries / topics well enough. What do I know? I know something about Japanese and programming, but that's about it. Doesn't make me at all unique as a developer. I don't feel there are any tasks in my real life that I would need an app for. There's already plenty of Japanese study apps. I could port "Your Japanese Name" to the iOS though since it wouldn't be that long of a project and I would have an existing userbase on Facebook to advertise to and even some assets for the port.

Third, while for a short period I can work on a subject that doesn't interest me all that much (like the Acey Deucey card game in my previous test), for a project that might extend to years I should pick something that I would enjoy working on. So topics that interest me? Well, I really like the survival genre. Robinson Crusoe, Cast Away, サバイバル, Alive, Lost in Blue etc. I really enjoyed all of them. Another genre I like are business simulations like Sid Meier's Railroads!, Aerobiz Supersonic, Lemon Tycoon, ゲーム発展国. Also life simulations like Jones on the Fast Lane and The Sims (although there was too much menial detail in The Sims) appealed to me. I like to imagine what the far future would be like, so scifi and space themes are good too.



For sound I like soundscapes (sea waves, thunderstorm, busy city etc.), not music. However memorable title music is always good. Chiptunes are great. Ambient style slow paced music is acceptable though, if there has to be some. With graphics I like anime cel art style clean outlines with solid fills or 8bit graphics. Point of view can be from above, bird's eye, even isometric or platformer style, anything goes. Luckily it seems the masses agree with my retro taste, most people don't seem to prefer hyper realism. I think game art should communicate an idea simply and not try to render it in full detail.

How to combine enough of my interests to make sure that if I find myself working on a project still 10 years from now, it would be something I like? Survival + business sim + oldskool. This really sounds like Lost in Blue. So is the answer just to make a Lost in Blue -type game? Survival business sim sounds almost like a contradiction, but I think Lost in Blue does have that. As you proceed you get better tools and with these you get even more resources to play with, that's the core appeal of a business sim.

If I add +Japan and +scifi to include those interest too,.. A guy stuck on a Japanese spaceship with all of the crew dead, left to gather oxygen, food (frozen free-floating sushi?) and such supplies to survive. Wow, the directions this could take are pretty vast. Makes me want to play this. Trying to plan out a game before I've realized it's really really really hard to come up with game designs. So it should be something extremely simple or it will be impossible to pull off before getting more experience with making games.

"A design written on paper and a design in your head is always a fluffy success story. A design created in code (or a paper prototype) is a working machine that must function according the unyielding rules of player psychology. The first is fantasy."

Oh yeah, I like cats too. Cat in space? Jonesy!

Update: Exploring a space ship with the crew dead is extremely cliche. Also, this hardly even qualifies as any sort of "idea", as it's just some vague description of a storyline and doesn't really say anything about the gameplay.

Friday, November 19, 2010

Acey Deucey part 16

Took about 3 hours to get all the certificate stuff to a passable state. I didn't quite understand what I was doing, but hopefully the zip file is now acceptably signed. If I understood correctly, I needed some kind of different certificate for releasing the app than I did for testing it.



Acey Deucey part 15


In-Between is an easy-to-learn single player betting card game. Three cards
are dealt, one of them face down. After the betting amount is decided
the hidden card is revealed. The pot doubles if the value of the hidden
card falls in between or is equal to the two other cards. Otherwise the
pot is lost. Historically this type of card game has also been known as
"Acey Deucey" or "Sheets".

KEY FEATURES
* Use this game to improve your ability to judge probabilities.

* Great as a first introduction to card games. Card suits do not matter
in this game, so it is enough to be familiar with the different card ranks
Ace, number cards, Jack, Queen and King.

* Unlike many card games, here the odds are in your favor. Once you learn
how to play there is no limit how high you can reach.

The following is not recommended for use in this field: pot. Your app may be rejected if you use this term.

Heh.

Acey Deucey part 14

iOS required icons:

29x29 Icon-Small.png
50x50 Icon-Small-50.png
57x57 Icon.png
58x58 Icon-Small@2x.png
72x72 Icon-72.png
114x114 Icon@2x.png

We've come pretty far considering the whole screen size of the popular Nokia 3310 from ten years ago was just 84 x 48 pixels.

Spent whole morning trying to get UISlider to work. Turns out you can't just set slider maximumValue and value to your desired amounts, because setting maximumValue won't work if current value is higher than it. This was causing the setting code to fail depending on game situation. Safe thing is to first set value to 0, then set maximumValue and then the value.

Thursday, November 18, 2010

Acey Deucey part 13

Instead of buying a sound of audience going "awwww" (when lost game) from istockphoto, I thought I'd record one myself.. surprisingly difficult to say a disappointed "aww" without sounding sarcastic. Spent hours trying to find suitable sounds. Time to give up and make the game a bit more silent than I intended. Better to have silence than an unsuitable sound.

Can't quite figure out how to save the app state when it goes into the background, so skipping that for now too.

TODO:
- UISlider should update properly and have a reasonable default.
- Touching "send feedback" in rules screen should actually do something.
- App store icon, description, screenshots etc.



Update: Are you kidding me? I need to create six different sizes of icons?

Tuesday, November 16, 2010

Acey Deucey part 12

Basic game works well enough now to be played.



TODO:
- Broke retina display support. Need to tweak card PNG to make it work again.
- Screen for going broke.
- Win / lose sound (maybe "awww" and applause). "Cards being dealt" sound. Possibly "cards going away", "ran out of money" sounds.
- App store icon, description, screenshots etc.
- Have to keep track of the "deck" at least so far as not to deal two identical cards.
- Default.png for quick launch.
- Support recovering app state if user gets a call / exits and returns.
- Rules screen.

Noticed that at some point I went from Ace representing 14 to it meaning 1. Also changed my mind in that equality is now considered winning.

Acey Deucey part 11

This is how the main screen will now look. Must stop tweaking it finally.



Got reply from Apple. Apparently I got my bank details all wrong. They even sent me a screenshot of what I'm supposed to input in that screen. Awesome. I've now used 10 days on this app. Pretty good progress. Not amazing progress, but I'm glad I haven't encountered any showstopper bugs either. Starting to feel a bit exhausted, feeling some reluctance to put any cool transitions between game states.

Lose screen:



A bit lame IMO.

Monday, November 15, 2010

Acey Deucey part 10

Experimented a bit with font shadows, set background for the controls. Slider works.



Top part of the app is begging for a dark bar to be put there. Maybe show balance and feedback link there?

Acey Deucey part 9

The cards now appear with a nice slide, slowing down seemingly because of friction. Did it "the right way", using CAKeyframeAnimation and a curve for the card movement. Also got a "flip" sound working. Now with the sound and 3D flipping animation it feels very satisfying to flip a card. This is starting to feel like a real app now.



TODO:
- Figure out how to get updates from UISlider so that bet can be chosen.
- Broke retina display support. Need to tweak card PNG to make it work again.
- Game logic itself. Is A < B < C is the winning situation, or would A <= B <= C be acceptable (better odds for player).
- Screens for win, lose, going broke.
- Win / lose sound (maybe "awww" and applause). "Cards being dealt" sound. Possibly "cards going away", "ran out of money" sounds.
- App store icon, description, screenshots etc.
- Maybe space below controls should be wood / something else, not green tabletop.

Update: I knew it was possible to condense the explanation even more: "Value in between wins"

Sunday, November 14, 2010

Acey Deucey part 8

Started doing "paperwork" so that it would be ready so I can submit the app when it's finished. Learned I need to use "iTunes Connect" to upload the app. Went to site, contracts and payment info was there too. Tried to enter my bank info, wasn't in the list of banks. Used their contact form to ask it to be set. Wondering if I'll get a reply.

Next: Need to learn how to do transitions / animations on iOS so I can slide the cards in. I want to do it the "right way" instead of updating location of the cards directly.

Update: Learned the "right way" is to use layer animations. Each iOS UIView is "layer-backed". Layers can be manipulated to conveniently create cool effects. They're sort of like frame buffers on which the views are rendered to and these layers can also be moved around, opacity changed etc. Had to add quartz framework to the project to use them.

Saturday, November 13, 2010

Acey Deucey part 7

Great progress. Made a card class, can use poker-style abbreviations to make a card. This creates a 9 of diamonds and shows it on the screen:

card = [[UIPlayingCard alloc] initWithString:@"9d"];
[self.view addSubview:card];
[card release];



Also got a 3d animation of the card flipping working, and made it super convenient to call too:

[card turn];

Would it be possible to explain how to play the game to the user in one line of text? "You win if the hidden rank is in between" doesn't make me quite satisfied yet.

Showing how many chips the player has left in lower left also hurts my eyes. It naturally wants to go to the upper left, where since dawn of time player scores have been shown, but I'd somehow want to dedicate the upper area to showing only the table.

Idea: Could get rid of all the controls by representing the balance and bet as stacks of chips that can be dragged around. The hidden card could be turned by touching it. But this was supposed to be a minimum viable app and that seems to go beyond it. Maybe if for whatever reason this app sells a bit (which I know it won't because this isn't a card game anyone actually plays), I can go back and update it to version two where it uses chips.

Thursday, November 11, 2010

Acey Deucey part 6

Suddenly feel very noobish. Have no idea how things relate to each other, how to get debugger to show me something, how to maintain memory, what magic is behind NIB files etc. Just flailing for something to grab onto. So it was like a triumph to get anything to show that I created from code.

My first few lines of code that actually created something. This loads cards.png and shows it on the screen. Might leak memory, not entirely sure (Update: yes, it leaked because addSubView incremented retain count).

UIImage *img = [UIImage imageNamed:@"cards.png"]; // who should release this?
self.sub = [[UIImageView alloc] initWithImage:img];
[sub release]; // to get retain count to 1
[self.view addSubview:sub];


Output:

Wednesday, November 10, 2010

Acey Deucey part 5



Mockup of main game screen. I don't actually have code for displaying the cards yet. Somehow I need to split my image into several smaller ones to have an UIImage for each. The big image will be 2MB in memory. An older iPod touch has 128MB of RAM so doesn't seem like an issue. Documentation did warn about having visible images larger than 1024 x 1024 (OpenGL thing I guess), which my image is. But I'm not attempting to display it all at once.

Tuesday, November 09, 2010

Acey Deucey part 4

More needed stuff:
- Have to keep track of the "deck" at least so far as not to deal two identical cards. For now I'll be content just checking when dealing that the card isn't on the table yet.
- Icon for the app. I'm guessing the icon, name and description of the app are about as important as the app itself.
- "Kaching" sound when winning the bet (if more than $0).

Today I hope to learn how to move UIImageViews around from code. So far haven't figured out the IB connection problem.

Question: I created a property and an IBOutlet for it in FirstViewController, why doesn't it appear in IB?
Answer: In FirstView.xib had to change "File's Owner" "Class Identity" into FirstViewController

Acey Deucey part 3

tab bar icons

retina display tab bar icons

Realized I needed them in two different resolutions, one for retina display and one for normal. It wasn't as simple as just resizing it, since at these small resolutions resizing turns things into mush. Had to redraw. Spent about 1.5 hours on making the icons, getting the icons to the tab bar and getting it to recognize the 2x icons too. Didn't realize had to drag the files to xcode it didn't just find the @2x files on disk.

Imagined in what kind of situation an iPhone user would play a card game. Probably on the bus, back seat of a car etc. when killing time. That means background ambience might be a bad idea, there might be other people around. Instead a simple card flip sound will do. Listened to a bunch of different samples and found a suitable one on istockphoto. Now need to cut the wanted sound out somehow.

So a new thing to figure out:
- How to play a sound (not mixed)

Monday, November 08, 2010

Acey Deucey part 2

Just a progress report. Did mockups of screens on a whiteboard, then started moving them to IB. Instead of just downloading some casino table background from iStockphoto, spent an hour making it from scratch in Gimp. Found an example from somewhere on how to flip a view with that cool 3D effect (UIView setAnimationTransition). Spent more time than I wanted in trying to support retina display (the higher res new iPhone). Decided not to make a reusable playing card class, instead I'll just deal with UIImageView objects directly. Had funny moment where I realized there are playing card values between 1-14, but only 13 different cards in each suit. How is that possible? Ace is 1 and 14. Of course.



Stuff I feel unsure about
- How to structure the whole program, where should the game itself be? Maybe look at examples for inspiration.
- UIImageViews provide some way to offset the image, right? Right? So I can just have one huge image that has all the cards. (edit: UIImageView seemed to have no such property. Yikes, UIImage docs say to avoid images larger than 1024x1024 and mine is currently bigger.)
- How do I change the tab bar texts for tabs?

Stuff I realized I need:
- Default.png for quick launch.
- May need icons for tab bar tabs.
- One image for front of card and one of back to animate transition between them. So need to move them together too.
- Maybe there should be a white outline in where the cards are supposed to go, just like on a real casino table.

Weird aspirations:
- It would be cool if there was a background casino atmosphere sound, kind of like the background theme in "shufflepuck cafe".
- It would be awesome if the background "audience" made some amusing comments about the situation in the game. Like if you bet a lot when the odds are really bad someone would whisper "I can't believe he didn't fold!". Or if you reach some high dollar amount you could get flirted on. But all of this kind of subtle.
- It would be good if the cards casted a shadow (and of course were a bit higher too) while they are being dealt.

Saturday, November 06, 2010

Acey Deucey

Decided to make a card game from an old Atari BASIC games book. It's called "Acey Deucey" (not to the backgammon-like game), "In-Between" or "Sheets". There are many variations to the rules, but I'll go with exactly the simple rules as in that BASIC program. You are initially dealt two cards, then you bet and after that one more card is dealt to you. You will win the amount you bet if the value of the third card is between the two cards that were dealt to you and lose if it wasn't.

To make things simpler, Ace always means 14. "In between" means strictly in-between, not equal. Stuff that's on my mind now about this:

- Where to get the card faces. I think there was some free set. Ah here it is. If I understand correctly, it is free even for commercial use (I might want to try AdMob just for fun).
- Card animation should be slide in + flip. Flipping should be that "pseudo 3d" flipping if possible (compress horizontally), but how to do it? At least two options, UIViewAnimationTransitionFlipFromRight (or something similar) to switch between views, or use OpenGL (Mixing UIKit with OpenGL)

Friday, November 05, 2010

iPhone dev 21

Got the flashlight app running on my iPod. Now how do I submit it to the app store?

"If your app doesn't do something useful or provide some form of lasting entertainment, it may not be accepted."

Oh.

"If your App looks like it was cobbled together in a few days, or you're trying to get your first practice App into the store to impress your friends, please brace yourself for rejection. We have lots of serious developers who don't want their quality Apps to be surrounded by amateur hour."

Blush.

iPhone dev - provisioning profile

Doing all of the certification magic again. Last time I did it I didn't really leave myself any helpful notes, but this page was really helpful about it. Biggest gotcha was that the dev portal "Provisioning Assistant" doesn't work on Chrome. It seems like it does, but just fails at creating the provisioning profile.

And what is a "provisioning profile"? From Apple dev portal: "A Provisioning Profile is a collection of your App ID, Apple device UDID, and iOS Development Certificate that allows you to install your application on your device."

Flashlight app works

You turn on the app. Screen goes white. That's it. Now, how do I get this into the store?

iPhone dev continued after 2 year hiatus

Exactly two years ago I got an iPhone and a mac to develop apps with. I was making good progress on an iPhone game, but then I accidentally scratched the surface of the phone with a key in my pocket, and it stopped working. Somehow I lost motivation to develop for it after that, even though I did get a new iPhone some time later. Now I want to give it a try again. I want to get the easiest possible minimal app into the app store, just to lift my spirits. I want to browse the store and look at it while thinking "I made that (crappy app)". With "minimal" I mean really minimal, it has to be the simplest thing that could possibly pass the review process, so that means a flashlight app.

I want the app to display a white screen when turned on. That's it. It won't even have a way to turn the light off, because that would be more than is strictly necessary. I'm not sure if I'll be required to put some kind of credits or explanation with the app, or will just a white screen suffice. At least I'll need an icon. Or could that be just a white rectangle? For name I could go with something like "Quick Flashlight". In the explanation I should say that it really doesn't do anything at all except make the screen all white.