Velocidade e abstração com XNA no Windows Phone 7

A velocidade pode ser calculada pela distancia ao longo do tempo. Pela matemática (ou "matematicamente" , pois acredite, a palavra existe) a formula é V = D / T

Este cálculo é mais útil a partir de certa distância percorrida e por certo período de tempo (o que está relativamente conectado) para calcular a média de velocidade. Isto pelo simples fato de aceleração e desaceleração que objetos sofrem na vida real. Até mesmo a Ferrari mais potente que você conhece sofre do mesmo mal, além de pontos como resistência, inércia e demais fatores que podem ou não ser relevantes para nós. Aí, o que depende é o nível de realidade que desejamos empregar em nossa física para o deslocamento de objetos.

Agora definiremos uma certa velocidade a frente do tempo pois distancia e tempo ainda não nos interessam. Nosso exercício não exigirá tal precisão.

Está confuso? Não se preocupe, exercícios práticos sempre tornam o conceito mais simples.

"Velocity " ,sendo uma propriedade pública, podemos utiliza-la fora da nossa classe. Mas para testarmos, vamos adicionar um novo método na classe que criamos para mover um Sprite baseando-nos em velocidade

Sabe de que classe estamos falando? Se você disse "nossa querida Sprite class!" parabéns! Se não, sugiro a leitura do post Criando uma simples classe Sprite com XNA no Windows Phone 7

Para acompanhar este lab/post, vá ao post anterior e crie esta classe ok? Estaremos esperando você bem aqui Smiley

Para dar continuidade, vamos falar um pouco mais sobre "escrever código reutilizável" e "abstração" antes de continuar falando de velocidade. Se formos rápido demais na construção de games, nos perderemos em importantes conceitos de programação.

Abstrair o código XNA é importante para construir a base de um jogo, ou pelo menos parte dele.

Agora, se o game fosse feito para outras plataformas como Windows e XBOX, aí meu amigo, seria essencial, mas não vamos complicar nosso exemplo (pois sei que o assunto não é tão simples para quem está começando) mas para você ter uma boa visão do que estamos falando, você teria que ter a necessidade de reescrever seu código algumas vezes, adaptando-o para diferentes plataformas (e linguagens , acredite ou não!!) para começar a identificar as similaridades e então entender onde você deveria "desacoplar responsabilidades" do seu código.

Na nossa classe Sprite queremos abstrair duas coisas. A primeira é o Loading da imagem. Isto acontece no LoadContent() . A segunda é o Drawing , que é executado do Draw() .

Para abstrair no XNA estes dois aspectos, precisamos ter nossos próprios Load() e Draw() na própria Sprite class certo? (se não estiver entendendo muito bem, não se preocupe, apenas continue a leitura, exercícios, e se necessário releia o artigo quantas vezes achar que pode facilitar seu entendimento)

Para cumprir nosso objetivo, nossa classe precisa ter acesso ao ContentManager e SpriteBatch.

Podemos fazer isto passando os objetos necessários para o construtor da classe Sprite.

Mão no código

 using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;

namespace Sprite_Demo
{
/// <summary>
/// This is the main type for your game
/// </summary>
/// 


public class Sprite
{
private ContentManager p_content;
private SpriteBatch p_spriteBatch;
public Texture2D image;
public Vector2 position;
public Color color;


public Sprite(ContentManager content, SpriteBatch spriteBatch)
{
p_content = content;
p_spriteBatch = spriteBatch;

image = null;
position = Vector2.Zero;
color = Color.White;
}


public bool Load(string assetName)

{

try
{
image = p_content.Load<Texture2D>(assetName);
}
catch (Exception) { return false; }
return true;

}

public void Draw()
{
p_spriteBatch.Draw(image, position, color);
}

}





public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Viewport viewport;
Sprite cave;


public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";

// Frame rate is 30 fps by default for Windows Phone.
TargetElapsedTime = TimeSpan.FromTicks(333333);

// Extend battery life under lock.
InactiveSleepTime = TimeSpan.FromSeconds(1);
}



/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here

base.Initialize();
}

/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);

// TODO: use this.Content to load your game content here


//get screen dimensions 
viewport = GraphicsDevice.Viewport;

//creating a Sprite
cave = new Sprite(Content, spriteBatch);
cave.Load("cave");

//center the cave sprite on screen

float x = (viewport.Width - cave.image.Width) / 2;
float y = (viewport.Height - cave.image.Width) / 2;

cave.position = new Vector2(x, y);

//set color

cave.color = Color.White;

}

/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}

/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();

// TODO: Add your update logic here

base.Update(gameTime);
}

/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);

// TODO: Add your drawing code here

spriteBatch.Begin();

//draw the cave
cave.Draw();

spriteBatch.End();

base.Draw(gameTime);
}
}
}

Mesmo conceito de exemplos anteriores. Estamos fazendo pequenas otimizações que a primeira vista parecem que nos trazem poucos benefícios. Mas pegue os conceitos e tente empregá-los em projetos maiores e mais complexos, inclusive, nesta caso, portando nosso game para outras plataformas compatíveis com o XNA.

Otimização de código é um tema muito rico e com o tempo, o que você acredita ser uma boa prática, verá que não é tão boa assim, e irá melhorar sua lógica a cada novo projeto.

Nos próximos posts continuaremos a falar sobre velocidade e também sobre temas importantes e básicos no mundo do desenvolvimento, como tratamentos de erro por exemplo.

Até mais!

 

Posts anteriores

Visão geral do MVA - entendendo o roteiro de Windows Phone

O Windows Mobile e o Windows Phone

Visão geral do Windows Phone 7.5 (codinome Mango)

Visão geral do conceito Metro

Visão geral do SDK do Windows Phone

Visão geral das ferramentas de desenvolvimento para Windows Phone

Visão geral do Emulador

Testando sua app no device

Criando Protótipos

O que é o Windows Phone Marketplace parte 1 - Publicando sua app no Marketplace

O que é o Windows Phone Marketplace parte 2 - Publicando sua app no Marketplace

Marketplace Test Kit

Crie seu primeiro projeto XNA 4.0 para Windows Phone 7

Entendendo o User Input no Windows Phone 7 com XNA

Utilizando gestos no Windows Phone 7

Desenhando Bitmaps com XNA no Windows Phone 7

Tratando Bitmaps como Sprites utilizando XNA no Windows Phone 7

Desenhando muitos bitmaps com XNA no Windows Phone 7

Desenhando muitos bitmaps com XNA no Windows Phone 7 - parte 2

Criando uma simples classe Sprite com XNA no Windows Phone 7

Transformando Sprites com XNA no Windows Phone 7