Archive for fevereiro, 2009

Starting OpenGL

quinta-feira, fevereiro 12th, 2009

Last August I joined a small team of individuals who wanted to create
a game.   Through some dumb luck and opinion, I somehow convinced them
to work on an iPhone game.   Since I was the only developer, I was
nominated to “learn how” and so I set to it.

I have never programmed in OpenGL before, and really, never programmed
a game that wasn’t in Pascal or QBasic back in High School, so this
was certainly new territory.  I am a web application programmer by
trade, so most of my time as a developer has been spent interfacing
with databases through highly abstracted frameworks designed to make
features simple to implement and change.   OpenGL is certainly not one
of those frameworks.

OpenGL, while it does make life easier on the programmer, is only as
performant as you’re willing to get dirty.   The more you rely on the
framework, the less you’re going to get out of your game.   When
you’re on a desktop, this is something you can get by with, but when
you’re developing for a mobile device, every CPU cycle is precious,
and every byte of memory is sacred.  All we wanted to do was put
sprites on the screen and move them around.   Hmmm, this was going to
be harder than I thought.

I started off by taking the example “Crash Lander” app that Apple
shipped with the iPhone SDK and began tweaking.   I got my own sprites
appearing, and then got them rendering on a background of my choosing.
 So far so good.  We ended up creating a few “parallel to the screen”
planes to draw in where we put the background texture on and then I
spent quite a bit of time figuring out how gl_translate and gl_ortho
worked.   It wasn’t pretty.

Once I had abstracted things away, I was able to hack together a UI
and some animations.   They weren’t properly extracted and they
weren’t optimized, but they worked.   Oh, the joy of seeing your
“game” working.   At least it wasn’t exploding.

So, what I learned from all of this is that you have to approach
OpenGL programming from the same standpoint as any other kind of
programming:  with a willingness to make mistakes and refactor.   I
ended up finding another OpenGL programmer to make more progress since
my day job was demanding more time, but I can tell you now that I
would design and create a better STRUCTURE for the animation and user
input.   Learning Objective-C might be a battle, but it’s nothing
compared to the crap I did in college.

In conclusion :  Keep trying.  Move forward.   Refactor.   Retool.
Make changes.   Throw it away and start over.   Learn from your
mistakes.

(by Mark Simoneau)

IBOutlet & IBAction

segunda-feira, fevereiro 9th, 2009

Outlets

Outlets são variáveis de instancia que foram declaradas usando a palavra chave IBOutlet. A declaração de uma outlet no seu arquivo header deve ser parecida com isto:

IBOutlet UIButton *myButton;

IBOutlet não faz absolutamente nada no compilador. O seu objetivo é o de informar para o Interface Builder que está é a variável que será conectada a um objeto em um arquivo XIB (ou NIB).

Actions

Actions são métodos que são parte da seu controle de classe. Eles também são declarado com uma palavra chave específica, IBAction, que fala para o Interface Builder que este método é uma ação e pode ser disparada por um controle. Tipicamente, a declaração para um método de ação é parecida com:

-(IBAction)fazAlgo:(id)sender;

(by Ademar Varela)

Pondo o SDK para Trabalhar - Final

quinta-feira, fevereiro 5th, 2009

 

1 Na classe AcheNumeroViewController.h digite o seguinte código:

#import <UIKit/UIKit.h>

@interface AcheNumeroViewController : UIViewController <UITextFieldDelegate> {

IBOutlet UITextField *textField;

IBOutlet UILabel *label;

NSString *string;

NSString *numberGenerated;

}

@property(nonatomic, retain) UITextField *textField;

@property(nonatomic, retain) UILabel *label;

@property(nonatomic,copy) NSString *string;

@property(nonatomic, retain) NSString *numberGenerated;

-(void)updateString;

-(void)generate;

@end

2 Vamos observar alguns pontos importantes. As variáveis do tipo IBOutlet podem ser UITextField e UILabel, que são as duas principais variáveis para a nossa aplicação funcionar. Basicamente a variável textField vai receber o valor digitado pelo usuário e a label vai exibir o resultado, isto é, se o número está abaixo, acima ou certo. Precisamos prestar atenção também na variável tipo NSString, chamada numberGenerated. É esta variável que contém o número aleatório gerado que deverá ser descoberto.

3 Na classe AcheNumeroViewController.m, digite o código:

#import “AcheNumeroViewController.h”

@implementation AcheNumeroViewController

@synthesize textField;

@synthesize label;

@synthesize string;

@synthesize numberGenerated;

- (void)viewDidLoad {

textField.clearButtonMode = UITextFieldViewModeWhileEditing;

label.text = textField.placeholder;

[self generate];

}

- (void)updateString {

if ([textField.text intValue] > [numberGenerated intValue]) {

label.text = @”acima, tente de novo”;

}

if ([textField.text intValue] < [numberGenerated intValue]) {

label.text = @”abaixo, tente de novo”;

}

if ([textField.text intValue] == [numberGenerated intValue]) {

[self viewDidLoad];

label.text = @”acertou, tente outro”;

}

}

- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {

if (theTextField == textField) {

[textField resignFirstResponder];

        [self updateString];

}

return YES;

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

[textField resignFirstResponder];

textField.text = self.string;

[super touchesBegan:touches withEvent:event];

}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

return (interfaceOrientation == UIInterfaceOrientationPortrait);

}

- (void)didReceiveMemoryWarning {

[super didReceiveMemoryWarning]; 

}

-(void)generate{

int generated = 1 + random() % 100;

numberGenerated = [NSString stringWithFormat:@"%d", generated];

}

- (void)dealloc {

[numberGenerated release];

[textField release];

[label release];

[super dealloc];

}

@end

4 A função viewDidLoad é onde a nossa aplicação começa. Nela colocamos o textField para receber as informações do usuário via teclado e gerar o número que deve ser adivinhado, usando a chamada [self generate]. Repare que existe uma função chamada generate. Nela é criado um número aleatório por meio da função random, e depois atribuímos este número na variável numberGenerated. É preciso atenção na forma de atribuição pois, quem conhece outras linguagens como o C, vai perceber diferenças.

5 Quando o usuário escolhe um número e depois aperta a tecla Return, a função updateString é chamada. Isto ocorre por causa da função textFieldShouldReturn. Ao executar a função updateString, a aplicação compara se o número informado pelo usuário é o mesmo que foi gerado e exibe o resultado dessa análise, que pode ser acima, abaixo ou certo. Para este resultado ser exibido, usamos a variável label. Reparem que quando o usuário acerta, executamos novamente a aplicação por meio da função viewDidLoad, aquela que dissemos ser uma das primeiras a serem executadas.

6 Falta pouco agora. As variáveis textField e label possuem um prefixo diferente das demais, o IBOutlet. O prefixo IB destas variáveis indica que elas precisam ser definidas no Interface Builder, um ambiente gráfico para criação de aplicativos. Dê um duplo clique em resource AcheNumeroViewController.xib na pasta Resources.

7 No Interface Builder temos algumas janelas que nos interessam, a View e a Library. Na última, selecione a aba Objects > Library > Input & Views. Ali estão os elementos de input e output à sua disposição. Vamos escolher o text. Clique o elemento text e o arraste para a janela View. Faça o mesmo com o elemento Label, e tente deixar a janela View como está na ilustração.

fig10-codigo-passo6-ib

8 Os elementos estão criados, mas ainda falta dizer quais as funções de cada um. Quem controla as funções dos elementos do Interface Builder é a classe File’s Owner. Use o botão direito do mouse (ou use a tecla [Control] e clique em File’s Owner. Na janela, procure dentro de Outlet a variável label, vá até o circulo no final da linha de um click e arraste para cima do elemento label. 

9 Repita o processo com o elemento textField.

10 Estamos prontos. Volte para o XCode e execute a aplicação usando o simulador.

fig12-codigo-passo-10

O objetivo dessa matéria foi de apresentar como é o desenvolvimento para o iPhone, mostrando as ferramentas necessárias (XCode e SDK). Continuaremos nas próximas edições da MAC+, ampliando alguns conceitos. Mande um email para editor@macmais se tiver alguma dúvida ou ideia para ser desenvolvida em artigos futuros.

Matéria publicada na revista MAC+

(by Ademar Varela)

Pondo o SDK para Trabalhar - Parte 4

quarta-feira, fevereiro 4th, 2009

Vamos adiante. Na pasta Other Sources, daremos uma olhada no arquivo chamado main.m.  Ele é o primeiro a ser executado no aplicativo.

#import <UIKit/UIKit.h>

int main(int argc, char *argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int retVal = UIApplicationMain(argc, argv, nil, nil);

    [pool release];

    return retVal;

}

 

Quem conhece a linguagem C (ou C++) percebeu que o código é bem familiar. Acredite, isto não é coincidência . A linguagem Objective-C (ObjC para os íntimos) usada pelo XCode é derivada da linguagem C, assim como C++. Por isso esta semelhança. Bom, não vamos fazer grandes dissertações sobre a linguagem, apenas salientar os objetivos da função UIApplicationMain. Basicamente, ela cria o aplicativo, carrega o resource principal do Interface Builder e o executa. Você pode chamar esta função a partir de uma thread principal do programa e, tipicamente, ela é usada na chamada da função main do software. Como já disse, não vamos nos aprofundar nesse código, e vamos deixar o main.m intacto.

Agora vamos voltar nossos olhos para a pasta Classes. Nela estão todas as classes que iremos utilizar na nossa aplicação: AcheNumeroAppDelegate.h, AcheNumeroAppDelegate.m, AcheNumeroViewController.h e AcheNumeroViewController.m. Para os iniciados em C ou C++, basta dizer que os arquivos com extensão .h são os arquivos header e os .m são os arquivos source. Para quem não conhece, basta entender que .h e .m trabalham em conjunto, o primeiro tem as declarações dos códigos que serão usados no segundo.

Vamos compreender o que o assistente fez para a gente até agora. Ele criou dois pares de classes que vão controlar a nossa aplicação: AcheNumeroAppDelegate e AcheNumeroViewController. Na AcheNumeroAppDelegate ele irá delegar (distribuir) o controle da aplicação para um formato View e na AcheNumeroViewController é quando vamos controlar o comportamento da nossa aplicação. Lembrem-se, no inicio da nossa aplicação escolhemos uma aplicação tipo View-BasedApplication.

#import “AcheNumeroAppDelegate.h”

#import “AcheNumeroViewController.h”

@implementation AcheNumeroAppDelegate

@synthesize window;

@synthesize viewController;

- (void)applicationDidFinishLaunching:(UIApplication *)application {    

    // Override point for customization after app launch    

    [window addSubview:viewController.view];

    [window makeKeyAndVisible];

}

- (void)dealloc {

    [viewController release];

    [window release];

    [super dealloc];

}

@end

Reparem que na segunda linha do código. Estamos incluindo o par de classes AcheNumeroViewController, a principio o “.h” e por conseqüência o “.m”. E na oitava, [window addSubview:viewController.view] estamos dando o controle para a View.

Chegamos agora no momento de entender o que a nossa aplicação vai ter que fazer. A idéia é bem simples. Ele vai gerar um número aleatório e o usuário vai tentar adivinhá-lo. Em cada tentativa, o programa vai dizer se o número informado está abaixo ou acima do número gerado. Para isso usaremos dois componentes de programação, o elemento Label e o elemento TextField.

Matéria publica na revista MAC+

(by Ademar Varela)

Pondo o SDK para trabalhar - Parte 3

terça-feira, fevereiro 3rd, 2009

Como podemos ver, existem várias pastas de trabalho, mas vamos destacar algumas: Classes, Other Sources, Resources, Frameworks e Products.

 

Na pasta Classes teremos todas as classes que iremos codificar na nossa aplicação. Neste primeiro momento, temos os seguintes arquivos:

 

- AcheNumeroAppDelegate.h 

- AcheNumeroAppDelegate.m

- AcheNumeroViewController.h

- AcheNumeroViewController.m

 

Na pasta Other Sources ficam os arquivos fontes do programa. Por enquanto, temos os seguintes arquivos:

 

- AcheNumero_Prefix.pch

- main.m

 

Na pasta Resources estão os resources do aplicativo. Lá podemos encontrar:

 

- AcheNumeroViewController.xib

- MainWindow.xib

- Info.plist

 

Na pasta Frameworks temos:

 

- UIKit.framework

- Foundation.framework

- CoreGraphics.framework

 

Na pasta Products temos:

 

- AcheNumero.app

 

Na medida que usarmos estes arquivos, vamos conhecer melhor a funcionalidade de cada um deles. Primeiramente, vamos falar do arquivo Info.plist (que está na pasta Resource). Ele possui uma lista de todas as informações pertinentes ao aplicativo que queremos criar. É nele que está definido o nome  que vai aparecer na tela do iPhone (Bundle Name), o nome do arquivo executável (Executable file) entre outras informações. Todas elas foram preenchidas pelo assistente e, neste momento, vamos deixar alguns desses parâmetros do jeito que estão. Vamos trocar o ícone (Icon File) e o nome que aparecerá na tela.

 

1 Para adicionar o ícone, você precisa escolher uma imagem e depois arrastar o arquivo para a pasta Resources.

 

2 Na tela que aparece, perguntando se você deseja copiar o ícone para dentro da pasta do projeto, marque a opção Copy items into destination group’s folder (if needed) e também Recursively create groups for any added folders. O Reference Type deve ser o padrão (default) e o Text Encoding fica em Unicode (UTF-8).

 

3 Clique em Info.plist e preencha o Icon File com o nome do ícone (com a extensão). No meu exemplo, o ícone se chama “mixer_256.png”.

 

Matéria publicada na revista MAC+

(by Ademar Varela)

Pondo o SDK para Trabalhar - Parte 2

segunda-feira, fevereiro 2nd, 2009

 

XCode é seu amigo

Para desenvolver programas para o iPhone, vamos usar o software chamado XCode, que está disponível no DVD de instalação do Mac OS X. Basicamente, o XCode é um ambiente de programação que permite ao desenvolvedor trabalhar de uma forma amigável. Depois de instalado, está pode ser encontrado em /Developer/Applications.

 

A seguir, você precisa instalar o SDK do iPhone. E o que diabos é esse SDK? É o kit de desenvolvimento de software específico para o celular da Apple. Nele temos toda a documentação, código e utilitários (inclusive um simulador do iPhone) para que seja possível desenvolver aplicações de acordo com um padrão de desenvolvimento para o iPhone. Você deve fazer o download do SDK no site da Apple (http://developer.apple.com/iphone/program/download.html). Para isso, é preciso ter uma conta no programa de desenvolvedores da Apple (ADC), que pode ser criada sem problemas (existem diversos modelos, pagos ou não).

 

Tudo pronto, é hora de começar. Abra o XCode. Você verá a tela de início do programa, com as opções de ver tutorias em vídeos, exemplos de código e a biblioteca de referência do iPhone, além de links para se registrar na Apple como desenvolvedor e ainda participar do programa iPhone Developer, que dará direito a publicar seus aplicativos na App Store, mediante o pagamento de uma taxa de US$ 100. Mas o que importa agora é iniciar um projeto para iPhone. Então, vamos fechar esta janela e criar um projeto.

 

fig02-xcode-a-seu-amigo-21

 

 

 

1 Selecione o menu File > New Project. O XCode vai apresentar vários modelos (templates).

fig03-file-new-project

 

2 Selecione iPhone > Application > View-BasedApplication e pressione o botão Choose.

3 Informe o nome do projeto que deseja criar. No nosso caso, vamos digitar AcheNumero e depois salvar. Pronto, o aplicativo já foi criado. Para ter certeza que tudo está bem, selecione o menu Build > Build and Run.

4 Você verá a janela do simulador do iPhone. Aqui você pode simular o toque no visor usando o mouse e o botão Home também funciona com o toque do mouse. Quando você clicar no ícone AcheNumero, a nossa aplicação será executada.

É óbvio que o aplicativo não fez nada, já que só executamos o assistente que o XCode gera automaticamente. Ele prepara toda a estrutura de um projeto, deixando o pronto para ser usado. O código do programa precisa ser escrito.

Matéria publicada na revista MAC+

(by Ademar Varela)

Pondo o SDK para trabalhar - Parte 1

domingo, fevereiro 1st, 2009

Depois de um longo e tenebroso inverno, o iPhone chegou ao Brasil. E com ele, a App Store, uma loja de aplicativos online com milhares de programas e jogos (pelo menos para alguns países) para serem comprados. Além de ser um excelente iPod, smartphone, acessar a internet, o iPhone (e, por carona, o iPod touch), ganhou muito mais usabilidade com o a loja online. E muita gente está ganhando muito dinheiro com a App Store.

 

Desenvolver aplicativos para o iPhone é a nova onda do momento. Muitos desenvolvedores partiram para esse novo “El Dourado”, em busca de fama e fortuna. E, se você conhece a linguagem Objective-C e já teve contato com o XCode, ambiente de programação da Apple, também chegou a hora de tirar o seu quinhão desse filão.

 

Mas antes de começar, é preciso fazer uma distinção entre os dois modelos de aplicativos existentes para o iPhone: os Web e os nativos. Os programas via Web ficam na internet e usam o Safari para funcionar. Os softwares nativos são aqueles instalados dentro do iPhone e utilizam janelas para interagir com o usuário. Apesar de duramente criticadas pelos desenvolvedores, as aplicações Web, ao contrario do que se possa imaginar, não precisa iniciar um browser para fazê-la funcionar, pois quando se elabora este tipo de programa, pode-se colocar um ícone para iniciá-la. Quando o usuário clica no aplicativo, uma rotina informa que é necessário usar o navegador e faz isto automaticamente e de maneira transparente, dando a impressão, muitas vezes, que se trata de uma aplicação nativa.

Matéria publicada na revista MAC+

(by Ademar Varela)