funcao1grau-paradownload.zip 71671 bytes
O objetivo é obter um sprite percorrendo trajetória retilinea em nossa tela. Para isso, vamos usar o auxilio da Equacao do 1º grau, sabendo que o grafico dela é uma reta. f(x) = ax + b Posicao inicial -> (x1, y1) Posicao Final -> (x2, y2) Essas duas posições são passadas na chamada do método “MoveTo”. (Esse metodo será detalhado mais adiante) Em relacao a posicao inicial e final; imagine esses 2 vetores como o inicio da reta e o fim da reta em um plano cartesiano. O fim da reta é o local aonde eu quero que o meu Sprite esteja. Sabendo-se que: f(x1) = y1 -> ax1 + b = y1 e f(x2) = y2 -> ax2 + b = y2 Obtivemos 2 equações: ax1 + b = y1 e ax2 + b = y2 Montando o sistema, temos: 
Invertendo a coluna1 com a 2: 
Utilizando o metodo do escalonamento:  = y2 - y1)
Resolvendo a 2º equacao e achando o valor de "a": (-ax1 + ax2) = y2 - y1 a(x2 - x1) = y2 - y1 Resultado que usaremos dentro do metodo "MoveTo": )
Achando o valor de "b"; substituindo o valor de "a" na 1º equacao: b + ax1 = y1 .x1 = y1)
 = y1)
Resultado que usaremos dentro do metodo "MoveTo" )
Aplicando os conhecimentos obtidos acima, no código: Criando uma classe graficoFuncaoPrimeiroGrau, para guardar nossas informações referentes a uma funcao do primeiro grau, fica: public class graficoFuncaoPrimeiroGrau {private Vector2 p1; // Representa a posicao inicial em que foi solicitado o inicio da trajetoria private Vector2 p2; // Representa a ultima posicao da reta private bool emTrajetoria; // indica se esta ou nao em trajetoria //Sabendo que a equação do Grafico da Funcao do 1º grau é f(x) = ax + b private float a; // representa o a da equacao private float b; // representa o b da equacao ... /// /// Indica para onde o Sprite vai mover-se; percorrendo uma trajetoria retilinea até o /// vetor passado no parametro _p2 /// /// Posicao Inicial /// Posicao Final. A trajetoria do Sprite acabará neste ponto public void MoveTo(Vector2 _p1, Vector2 _p2) {this.p1 = _p1; this.p2 = _p2; if ((p2.X - p1.X) == 0) { throw new Exception("Divisao por 0");
} //Calculo dos valores de a e b. this.a = (p2.Y - p1.Y) / (p2.X - p1.X); this.b = p1.Y - ((p1.X * p2.Y - (p1.X * p1.Y)) / (p2.X - p1.X)); //No momento em que eu chamo o metodo "MoveTo", é iniciada a trajetoria this.emTrajetoria = true;
} //f(x) = a*x + b private float func(float x) {return ((a * x) + b);
} /// /// Para percorrer a trajetoria retilinea requisitada com o metodo "MoveTo", /// eu devo está chamando este metodo; passando a posicao atual do Sprite, /// obtendo, assim, o meu y apartir da posicao X que eu esteja. /// /// Posicao Atual do Sprite /// public Vector2 getPosition(Vector2 posicao) {if ( (int)posicao.X == (int)p2.X) {emTrajetoria = false;
} return new Vector2(posicao.X, func(posicao.X));
}
}
}
Criando uma Classe Sprite para obtermos o resultado esperado, que é um sprite percorrendo uma trajetoria retilinea na tela: class Sprite:DrawableGameComponent {SpriteBatch sb; Texture2D textura; Vector2 posicao; // posicao atual do Sprite graficoFuncaoPrimeiroGrau gfpg; ... public override void Update(GameTime gameTime) {if (Mouse.GetState().LeftButton == ButtonState.Pressed) {try {Vector2 p2 = new Vector2(Mouse.GetState().X, Mouse.GetState().Y); gfpg.MoveTo(this.posicao, p2);
catch (Exception e) {}
} if (gfpg.EmTrajetoria) {this.posicao = gfpg.getPosition(this.posicao); /*Verifica se o P2(posicao final) está a direita ou a esquerda *em relação a posicao inicial passada no momento da chamada *do metodo "MoveTo" * */ if (gfpg.P1.X < gfpg.P2.X) this.posicao.X++;
else this.posicao.X--;
} base.Update(gameTime);
} ...
}
O resultado final pode ser visto no arquivo anexo. Gostaria que vocês postassem dúvidas e sugestões, pois é o meu primeiro artigo, e nao sei se fui claro o suficiente. Espero que o conhecimento passado aqui tenha sido útil para futuras implementações em nossos jogos. Obrigado! |