<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MXStudio &#187; Marcio Silva</title>
	<atom:link href="http://www.mxstudio.com.br/author/marcio/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mxstudio.com.br</link>
	<description>Macromedia e Adobe - Artigos, colunas, tutorias e muito mais...</description>
	<lastBuildDate>Sun, 29 Jan 2012 11:31:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Papervision 3D: Primeiros Passos</title>
		<link>http://www.mxstudio.com.br/desenvolvimento/flash/papervision-3d-primeiros-passos/</link>
		<comments>http://www.mxstudio.com.br/desenvolvimento/flash/papervision-3d-primeiros-passos/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 13:30:39 +0000</pubDate>
		<dc:creator>Marcio Silva</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[Papervision3d]]></category>

		<guid isPermaLink="false">http://www.mxstudio.com.br/?p=3330</guid>
		<description><![CDATA[Olá Pessoal, Sou Márcio Silva, e neste tutorial mostrarei os primeiros passos para que você possa começar a desenvolver seus aplicativos, jogos e animações utilizando o Papervision3D Engine. Pré-requisitos: Conhecimento em Action Script 3.0. Conhecimento em Adobe Flash CS4. O que é Papervision 3D? Papervision 3D (P3D) é uma Engine Open Source para criação de [...]]]></description>
			<content:encoded><![CDATA[<link href="http://www.mxstudio.com.br/webgerenciador/_css/PadraoCss.css" rel="stylesheet" type="text/css" />
<script src="http://www.mxstudio.com.br/js/ColorCode.js"></script></p>
<p style="text-align: justify;">Olá Pessoal,</p>
<p style="text-align: justify;">Sou Márcio Silva, e neste tutorial mostrarei os primeiros passos para que você possa começar a desenvolver seus aplicativos, jogos e animações utilizando o Papervision3D Engine.</p>
<p style="text-align: justify;">Pré-requisitos:  Conhecimento em Action Script 3.0.  Conhecimento em Adobe Flash CS4.</p>
<p style="text-align: justify;"><strong>O que é Papervision 3D?</strong></p>
<p style="text-align: justify;">Papervision 3D (P3D) é uma Engine Open Source para criação de Cenas 3D no Adobe Flash. Com esta engine podemos manipular de uma forma simplificada elementos 3D, escondendo detalhes de baixo nível. Esta engine não realiza cálculos físicos, como por exemplo gravidade, atrito, colisão elástica e inelástica, entre outros. Para isto é necessário a utilização de outras engines destinadas apenas a realizar cálculos físicos, isto será tema de outros tutoriais.</p>
<p style="text-align: justify;"><strong>Como começar?</strong></p>
<p style="text-align: justify;">Como escrevi nos pré-requisitos, é indispensável o conhecimento de básico ao intermediário no Action Script 3.0. A API do P3D é totalmente orientada a objetos e possui uma documentação de código muito boa. Neste tutorial, utilizo como ferramenta o Adobe Flash CS4 para programar e rodar a aplicação.</p>
<p style="text-align: justify;">
<p style="text-align: justify;"><strong>Passo 1</strong> &#8211; Primeiramente você deve baixar o P3D que está hospedado no Google Code: <a href="http://code.google.com/p/papervision3d/">http://code.google.com/p/papervision3d/</a>.</p>
<p style="text-align: justify;"><strong>Passo 2 &#8211; </strong>Crie um pasta com o nome de sua escolha e descompacte o conteúdo do arquivo <strong>.ZIP</strong> .</p>
<p style="text-align: justify;"><strong>Passo 3 </strong>- Abra o Adobe Flash CS4, e crie um novo arquivo <strong>.FLA </strong>do tipo AS3 com o nome <strong>PlaneP3D.fla. </strong>Coloque as seguintes configurações:</p>
<p style="text-align: justify;"><a href="http://www.mxstudio.com.br/wp-content/uploads/2010/03/img3.png"><img src="http://www.mxstudio.com.br/wp-content/uploads/2010/03/img3.png" alt="Configurações" title="Configurações" width="199" height="263" class="alignnone size-full wp-image-3332" /></a></p>
<p style="text-align: justify;"><strong>Passo 4 &#8211; </strong>Para que o Adobe Flash encontre as definições de classe do Papervision 3D é necessário configurar o Library Path. Vá em <strong>Edit-&gt;Preferencces-&gt;Action Script, </strong>clique em <strong>ActionScript 3.0 Settings. </strong>Informe o diretório onde você descompactou o Papervision 3D. No meu caso ficou como mostrado abaixo:</p>
<p style="text-align: justify;"><a href="http://blog.creativerender.com/wp-content/uploads/2010/03/img2.png"><img class="aligncenter size-full wp-image-49" title="Classpath" src="http://blog.creativerender.com/wp-content/uploads/2010/03/img2.png" alt="" width="451" height="530" /></a></p>
<p style="text-align: justify;"><strong>Passo 5 &#8211; </strong>Crie um Action Script File (<strong>.AS</strong>) com o nome de <strong>PlaneP3D.as</strong>.<strong> </strong></p>
<p style="text-align: justify;"><strong> </strong> <strong>Passo 6 &#8211; </strong>No arquivo <strong>PlaneP3D.as </strong>coloque o seguinte código.</p>
<div id="codigo" title="AS">
package<br />
{<br />
	import flash.display.Sprite;<br />
	import flash.events.Event;<br />
	import org.papervision3d.cameras.Camera3D;<br />
	import org.papervision3d.render.BasicRenderEngine;<br />
	import org.papervision3d.scenes.Scene3D;<br />
	import org.papervision3d.view.Viewport3D;<br />
	import org.papervision3d.objects.primitives.Plane;</p>
<p>	public class Plane extends Sprite<br />
	{<br />
		public var viewport:Viewport3D = new Viewport3D();<br />
		public var scene:Scene3D = new Scene3D();<br />
		public var camera:Camera3D = new Camera3D();<br />
		public var renderer:BasicRenderEngine = new BasicRenderEngine();<br />
		public var plane:Plane = new Plane();</p>
<p>		public function Plane()<br />
		{<br />
			addChild(viewport);<br />
			scene.addChild(plane);<br />
			renderer.renderScene(scene, camera, viewport);<br />
			addListeners ();<br />
		}</p>
<p>		private function addListeners ()<br />
		{<br />
			addEventListener(Event.ENTER_FRAME, render);<br />
		}</p>
<p>		private function render (e:Event)<br />
		{<br />
			plane.x +=3;<br />
			renderer.renderScene(scene, camera, viewport);<br />
		}<br />
	}<br />
}</p></div>
<p><strong>Alguns comentários sobre o código</strong></p>
<p><strong>O que é Viewport3D?</strong></p>
<p>Para explicar o que é a Viewport3D, só fazer uma analogia à tela de cinema, onde é projetado o filme para que seja possível assistí-lo. Portanto, é uma região retangular onde é projetado a Cena 3D.</p>
<p><strong>O que é uma Camera3D?</strong></p>
<p><strong> </strong>A Camera utilizada aqui é a mesma que você já conhece do cinema, ela grava o que acontece no mundo e projeta na tela (View Port).</p>
<p><strong>O que é Scene3D?</strong></p>
<p>A Cena 3D é basicamente o mundo que se deseja ver.</p>
<p><strong>O que é BasicRenderEngine?</strong></p>
<p>Fazendo novamente analogia ao cinema,  o Basic Render Engine é o Diretor, ele grita &#8220;Ação&#8221; e tudo acontece: A Camera começa a filmar, projetando a Cena na View Port. Por isso nada acontece se ele não &#8220;ordenar&#8221; através do método <em>renderScene ().</em></p>
<p>O Construtor da classe <strong>Plane </strong>dá o pontapé inicial adicionando a <strong>View Port </strong>ao stage, pois o restante dos objetos serão renderizados dentro dela. Todos os objetos pertencentes à Cena, neste caso o Plano, devem ser adicionados ao objeto <strong>scene. </strong>Como nesta cena o plano será deslocado para a direita à cada <strong>ENTER_FRAME</strong>, um listener foi adicionado.</p>
<p>Pronto, se você não pressionou <strong>CTRL + ENTER </strong>para ver o que acontece, pressione agora e veja o resultado.</p>
<p>Veja o resultado final aqui <a href="http://blog.creativerender.com/wp-content/uploads/2010/03/PlaneP3D.swf">PlaneP3D</a>.</p>
<p>Baixe os arquivos deste tutorial: <a href="http://blog.creativerender.com/wp-content/uploads/2010/03/papervision_beginner.zip" target="_blank">http://blog.creativerender.com/wp-content/uploads/2010/03/papervision_beginner.zip</a></p>
<p><strong>Autor: M&aacute;rcio Silva &#8211; Colunista de Flash &amp; ActionSctipt MXSTUDIO.</strong><br />
Site: <a href="http://www.creativerender.com" target="_blank">www.creativerender.com</a> e <a href="http://www.marciosilva.net" target="_blank">www.marciosilva.net</a>
</p>
<p>Qualquer d&uacute;vida envie um e-mail para <a href="mailto:contato@creativerender.com" target="new">contato@creativerender.com</a> ou acesse nosso <a href="http://www.mxstudio.com.br/forum/index.php?showforum=127" target="forum">f&oacute;rum</a></p>
<p><script>FormatAS(new Array('AS'))</script> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.mxstudio.com.br/desenvolvimento/flash/papervision-3d-primeiros-passos/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Plugin Twitter para o Mootools &#8211; Parte 1</title>
		<link>http://www.mxstudio.com.br/desenvolvimento/javascript/plugin-twitter-para-o-mootools-parte-1/</link>
		<comments>http://www.mxstudio.com.br/desenvolvimento/javascript/plugin-twitter-para-o-mootools-parte-1/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 15:53:20 +0000</pubDate>
		<dc:creator>Marcio Silva</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[mootools]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.mxstudio.com.br/?p=2796</guid>
		<description><![CDATA[Olá Pessoal, Nesta primeira parte será mostrado a construção de um plugin/extensão do Mootools para recuperar tweets do twitter desejado. Para o correto funcionamento deste tutorial você deverá baixar a versão 1.2 ou superior do mootools. Agora, crie um arquivo chamado Twitter.js, é nele que o plugin será desenvolvido. Utilizando o ferramental disponilizado pelo mootools [...]]]></description>
			<content:encoded><![CDATA[<p>Olá Pessoal,</p>
<p>Nesta primeira parte será mostrado a construção de um plugin/extensão do Mootools para recuperar tweets do twitter desejado. Para o correto funcionamento deste tutorial você deverá baixar a <a title="Mootools Download" href="http://mootools.net/download" target="_blank">versão 1.2 ou superior do mootools.</a></p>
<p>Agora, crie um arquivo chamado Twitter.js, é nele que o plugin será desenvolvido. Utilizando o ferramental disponilizado pelo mootools a implementação inicia-se com a definição da classe Twitter:</p>
<pre lang="js" line="1">
var Twitter = new Class ({

	Implements : [Options,Events],

	getOptions : function()
	{
		return {
			url :  "http://localhost/twitter.php?user_timeline=", //proxy para carregar os tweets
			refreshTime : 5000, //intervalo de tempo para atualizar os tweets
			user : 'mapsiva', //login do usuário
			count : 2, //quantidade de tweets que devem ser retornados
			container : $('twitterContainer') //elemento HTML que onde os tweets serão listados
		};
	},

	initialize: function (options)
	{
		this.setOptions(this.getOptions(), options);
	},
</pre>
<p>No trecho de código acima apenas definimos a classe Twitter, é informado que será estendido as classes Events e Options do mootools.</p>
<p>O método <em>initialize()</em>, é o construtor da classe Twitter, portanto quando fizermos <em>new Twitter()</em> este método será invocado. Nele apenas são recuperados os opções como parâmetro.<br />
O método <em>getOptions()</em> servirá para retornar as opções configuráveis de nosso plugin.</p>
<pre lang="js" line="20">
        getPublicTimeLine : function ()
	{
		var url = this.options.url + this.options.user ;

		this._ajax (url);
	},
</pre>
<p>Por opção própria, adotei todos os métodos &#8220;privados&#8221; ou internos começados por &#8216;_&#8217; (anderline).  O método <em>getPublicTimeLine()</em> é responsável por requisitar os tweets do usuário configurado.</p>
<pre lang="js" line="26">
        _ajax : function (_url)
	{
		new Request(
		{
			method: 'get',
			url: _url,
			data: {'count' : this.options.count},
			onRequest: this._onRequest.bind(this),
			onComplete: this._onComplete.bind(this),
			onFailure: this._onFailure.bind(this)

		}).send();
	},
</pre>
<p>O método <em>_ajax()</em> faz uma requição via Ajax para o proxy de tweets configurado, por que não podemos fazer requisições direto ao site do twitter via javascript por razões de segurança. Algumas funcões Handler são informadas.</p>
<pre lang="js" line="39">
        _onComplete : function (response)
	{
		var tweets = JSON.decode (response);

		tweets.each (this._showTweet.bind(this));
	},
</pre>
<p>O método <em> _onComplete()</em> será invocado quando a requisição resultar em sucesso, a requisição feita pelo proxy ao Twitter retornará um conjunto de dados no formado JSON, portanto devemos decodifiá-los utilizando a JSON do mootools. Logo após, a função <em>_showTweet()</em> se responsabiliza por mostrar os tweets no HTML.</p>
<pre lang="js" line="45">
	_onRequest : function (response)
	{
		//TODO
	},
</pre>
<p>O método <em>_onRequest()</em> é invocado quando a requisição de tweets é iniciada, com ela possível mostrar um gif com um aguarde para o usuário, que posteriormente pode ser removido no método <em>_onComplete()</em>.</p>
<pre lang="js" line="49">
	_onFailure : function (xhr)
	{
		//TODO
	},
</pre>
<p>O método <em>_onFailure()</em> será invocado quando ocorrer um erro na requisição.</p>
<pre lang="js" line="53">
        _showTweet : function (item, index, array)
	{
		if (!$defined(this.options.container))
			return;

		var tweet = new Element ('div').addClass('tweetItem').set('html', item.text).injectInside(this.options.container);
	}
});
</pre>
<p>Para mostrar um tweet, o método <em>_showTweet()</em> verifica a existência do container onde os tweets serão inseridos. Um elemento DIV é criado com o atributo class setado para <strong>tweetItem</strong>, dessa forma você poderá construir seu CSS para formatá-lo da forma que desejar.</p>
<pre lang="js">
Twitter.implement(new Options);
Twitter.implement(new Events);
</pre>
<p>Logo após a definição da classe os objetos da classe Options e Events utilizando o implement do mootools são instanciados.</p>
<p>Para executar a busca de tweets logo após o seu site carregar basta colocar o código ao fim do arquivo Twitter.js ou logo após a inclusão do mesmo na página HTML.</p>
<pre lang="js" line="1">
window.addEvent('domready', function()
{
	var twitter = new Twitter();

	twitter.getPublicTimeLine ();
});
</pre>
<p>O proxy PHP chamado twitter.php tem a finalidade de buscar os tweets recebendo a quantidade de tweets a serem buscados e de que usuário eles são. Para realizar essa busca será utilizado a biblioteca CURL do PHP, verifique se seu servidor Web possui esta biblioteca instalada, caso contrário deverá instalá-la.</p>
<pre lang="php" line="1">
<?php
$ch = curl_init();  

if(!isset($_GET["count"]))
	curl_setopt($ch,CURLOPT_URL,"http://twitter.com/statuses/user_timeline/".$_GET["user_timeline"].".json");
else
	curl_setopt($ch,CURLOPT_URL,"http://twitter.com/statuses/user_timeline/".$_GET["user_timeline"].".json?count=".$_GET["count"]);

curl_setopt($ch,CURLOPT_GET,1);  

curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); 

$result = curl_exec ($ch);  

curl_close($ch);

echo $result;    

?>
</pre>
<p>Um exemplo de utilização deste plugin é mostrado no código HTML abaixo:</p>
<pre lang="html">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<script type="text/javascript" src="mootools.js"></script>
<script type="text/javascript" src="Twitter.js"></script>
</head>

<body>
<div id="twitterContainer">
</div>

</body>
</html>
</pre>
<p>Pronto, com isso é possível recuperar os tweets de usuários via JS. Na parte 2 iremos definir os métodos que irão &#8216;parsear&#8217; cada tweet incluindo os links, link para perfils como @<a href="http://twitter.com/mapsiva">mapsiva</a> ou para #topics.</p>
<p><strong>Gostaria de ajudar no desenvolvimento deste plugin? Acesse http://code.google.com/p/mootwitter/ ou mande email para marcio arroba marciosilva ponto net.</strong></p>
<p><strong>Website: <a href="http://marciosilva.net/">http://marciosilva.net/</a><br />
Twitter: <a href="http://twitter.com/mapsiva" target="_blank">http://twitter.com/mapsiva</a></strong></p>
<p>Baixe os arquivos fontes deste tutorial.<br />
<a href="http://www.mxstudio.com.br/wp-content/uploads/2009/10/twitter.zip">http://www.mxstudio.com.br/wp-content/uploads/2009/10/twitter.zip</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.mxstudio.com.br/desenvolvimento/javascript/plugin-twitter-para-o-mootools-parte-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Box2D, Modo DebugDraw</title>
		<link>http://www.mxstudio.com.br/desenvolvimento/flash/box2d-modo-debugdraw/</link>
		<comments>http://www.mxstudio.com.br/desenvolvimento/flash/box2d-modo-debugdraw/#comments</comments>
		<pubDate>Sat, 06 Jun 2009 21:39:51 +0000</pubDate>
		<dc:creator>Marcio Silva</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[box2d]]></category>
		<category><![CDATA[game]]></category>

		<guid isPermaLink="false">http://www.mxstudio.com.br/?p=2511</guid>
		<description><![CDATA[Olá Pessoal, Dando continuação ao último tutorial, será mostrado como utilizar o modo de debug do Box2D chamado de DebugDraw. Com esse modo você poderá analisar visualmente como estão ocorrendo as colisões, contatos, onde estão os centros de massa, que objetos estão &#8220;dormindo&#8221;, entre outras análises. Para exemplificar esse modo será utilizado o mesmo código [...]]]></description>
			<content:encoded><![CDATA[<p>Olá Pessoal,</p>
<p>Dando continuação ao último tutorial, será mostrado como utilizar o modo de debug do Box2D chamado de <em>DebugDraw</em>. Com esse modo você poderá analisar visualmente como estão ocorrendo as colisões, contatos, onde estão os centros de massa, que objetos estão &#8220;dormindo&#8221;, entre outras análises.</p>
<p>Para exemplificar esse modo será utilizado o mesmo código do artigo anterior que pode ser visualizado em <a href="http://www.mxstudio.com.br/2009/04/box2d-primeira-simulacao/">http://www.mxstudio.com.br/2009/04/box2d-primeira-simulacao/</a>. Um preview do que será feito está logo abaixo:</p>
<p><object width="550" height="367" data="http://www.mxstudio.com.br/wp-content/uploads/2009/06/box2dmx.swf" type="application/x-shockwave-flash"><param name="src" value="http://www.mxstudio.com.br/wp-content/uploads/2009/06/box2dmx.swf" /></object></p>
<p>Algumas adaptações serão necessárias para colocar o <em>DebugDraw</em> no exemplo anteriormente visto. Primeiramente será necessário importar a classe <em>MovieClip </em> e demais modificações que podem ser vistas no código abaixo:</p>
<pre lang="actionscript">package
{
	import flash.display.Sprite;
        /*novo import*/
	import flash.display.MovieClip;

	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;

	/*importação da API Box2D*/
	import Box2D.Dynamics.*;
	import Box2D.Collision.*;
	import Box2D.Collision.Shapes.*;
	import Box2D.Common.Math.*;

	public class Box2DMX extends Sprite
	{
		/* Construtor da classe	*/
		public function Box2DMX()
		{
			init();
		}

		/* Incializa a aplicação*/
		private function init():void
		{
			createWorld();

			createListeners();

			createGround();

			debugDraw();
		}

                /*Método que realiza o DebugDraw*/
		private function debugDraw():void
		{
			var m_sprite:Sprite;
			m_sprite = new Sprite();

			addChild(m_sprite);

			debug = new b2DebugDraw();

			debug.m_sprite=m_sprite;
			/*escala padrão do Box2D 30px = 1m*/
			debug.m_drawScale=30;

			debug.m_alpha = 1;

			debug.m_fillAlpha=0.5;

			debug.m_lineThickness=1;

			debug.m_drawFlags = b2DebugDraw.e_shapeBit
				|b2DebugDraw.e_jointBit
				|b2DebugDraw.e_coreShapeBit
				|b2DebugDraw.e_aabbBit
				|b2DebugDraw.e_obbBit
				|b2DebugDraw.e_pairBit
				|b2DebugDraw.e_centerOfMassBit;

			/*aplica ao mundo o modo debug*/
			world.SetDebugDraw(debug);
		}
		/* Define os listeners da simulação/game*/
		private function createListeners():void
		{
			timer = new Timer(2000);
			timer.addEventListener(TimerEvent.TIMER, createBodies);
			timer.start();
			addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
		}

		/* Instancia o mundo onde a simulação ocorrerá*/
		private function createWorld():void
		{
			/* Definição dos limite do mundo*/
			var worldAABB:b2AABB = new b2AABB();
			worldAABB.lowerBound.Set(-100.0, -100.0);
			worldAABB.upperBound.Set(100.0, 100.0);

			/* Difinição da gravidade atuante em todos os corpos desse mundo*/
			var gravity:b2Vec2=new b2Vec2(0.0,10.0);

			/* Indica que os corpos devem permanecerem inativos	*/
			var doSleep:Boolean=true;

			/* Construção do mundo*/
			world = new b2World(worldAABB, gravity, doSleep);

		}

		/* Cria o chão onde os corpos ficarão*/
		private function createGround():void
		{
			var body:b2Body;
			var bodyDef:b2BodyDef;
			var boxDef:b2PolygonDef;

			bodyDef = new b2BodyDef();
			bodyDef.position.Set(10, 12);
			bodyDef.angle=0.0;

			boxDef = new b2PolygonDef();
			boxDef.SetAsBox(90, 3);
			boxDef.friction = 0.4;

			/* para corpos que nunca se moverão o
			* valor da densidade deve ser zero
			*/
			boxDef.density = 0;
			bodyDef.userData = new PhysGround();
			bodyDef.userData.width = physScale * 2 * 30;
			bodyDef.userData.height = physScale * 2 * 3;

			addChild(bodyDef.userData);

			body=world.CreateBody(bodyDef);
			body.CreateShape(boxDef);
			body.SetMassFromShapes();
		}
		/*cria os atores da simulação*/
		private function createBodies(e:Event):void
		{
			/* representa o corpo rígido*/
			var body:b2Body;

			/* será utilizado para representar
			* as características físicas do corpo rígido
			*/
			var bodyDef:b2BodyDef;

			/*define um polígono e suas características físicas*/
			var boxDef:b2PolygonDef;

			/*define um círculo e suas características físicas*/
			var circleDef:b2CircleDef;

			bodyDef = new b2BodyDef();
			bodyDef.position.Set(Math.random() * 15+5, 0);

			var rX:Number = Math.random() + 0.1;
			var rY:Number = Math.random() + 0.1;
			//Caixa
			if (Math.random() &lt; 0.5)
			{
				boxDef = new b2PolygonDef();
				boxDef.SetAsBox(rX, rY);
				boxDef.density = 1.0;
				boxDef.friction = 0.5;
				boxDef.restitution = 0.2;

				bodyDef.userData = new MovieClip();
				bodyDef.userData.width = rX * 2 * physScale;
				bodyDef.userData.height = rY * 2 * physScale;

				body = world.CreateBody(bodyDef);
				body.CreateShape(boxDef);
			}
			else //Círculo
			{
				circleDef = new b2CircleDef();
				circleDef.radius = rX;
				circleDef.density = 1.0;
				circleDef.friction = 0.5;
				circleDef.restitution = 0.2;

				bodyDef.userData = new MovieClip();
				bodyDef.userData.width = rX * 2 * physScale;
				bodyDef.userData.height = rX * 2 * physScale;

				body = world.CreateBody(bodyDef);
				body.CreateShape(circleDef);
			}

			bodyDef.userData.x = body.GetPosition().x *physScale ;
			body.SetMassFromShapes();
			addChild(bodyDef.userData);
		}

		/*atualiza o posicionamento dos atores*/
		private function Update(e:Event):void
		{
			world.Step(timeStep, iterations);

			// Pare cada corpo no mundo atualiza a sua posição e rotação
			for (var body:b2Body = world.GetBodyList (); body; body = body.GetNext())
			{
				if (body.GetUserData() is Sprite)
				{
					body.GetUserData().x = body.GetPosition().x * physScale;//metros para pixels
					body.GetUserData().y = body.GetPosition().y * physScale;//metros para pixels
					body.GetUserData ().rotation = body.GetAngle() * (180/Math.PI);
				}
			}
		}

		private var world:b2World;
		private var iterations:int = 10;
		private var timeStep:Number = 1.0/30.0;
		private var physScale = 30.0;
		private var timer:Timer;
                /*novo atributo para aplicar o DebugDraw*/
		private var debug:b2DebugDraw;

	}
}</pre>
<p>As modificações começaram com a adição da classe MovieClip que será usada como dado do usuário:</p>
<pre lang="actionscript">package
{
	import flash.display.Sprite;
        /*novo import*/
	import flash.display.MovieClip;</pre>
<p>Aos atributos foi adicionado um novo que serve para realizar o DebugDraw da classe b2DebugDraw:</p>
<pre lang="actionscript">		private var physScale = 30.0;
		private var timer:Timer;
                /*novo atributo para aplicar o DebugDraw*/
		private var debug:b2DebugDraw;

	}
}</pre>
<p>Tanto para criar o círculo quanto para criar os poligonos a classe de dado de usuários é a classe MovieClip, com ela fica mais fácil visualizar o comportamento dos corpos quanto ao seu estado de atividade que veremos mais à frente no texto:</p>
<pre lang="actionscript">bodyDef.userData = new MovieClip();</pre>
<p>A mudança mais importante foi a criação de um novo método chamado debugDraw():</p>
<pre lang="actionscript">private function debugDraw():void
{
	var m_sprite:Sprite;
	m_sprite = new Sprite();
	addChild(m_sprite);
	debug = new b2DebugDraw();

	debug.m_sprite=m_sprite;
	/*escala padrão do Box2D 30px = 1m*/
	debug.m_drawScale=30;
	debug.m_alpha = 1;

	debug.m_fillAlpha=0.5;

	debug.m_lineThickness=1;

	debug.m_drawFlags = b2DebugDraw.e_shapeBit
		|b2DebugDraw.e_jointBit /*mostra todos os Joints da Cena*/
		|b2DebugDraw.e_coreShapeBit /*utilizaado para observar colisões contínuas*/
		|b2DebugDraw.e_aabbBit /*mostra o eixo de coordenados dos corpos*/
		|b2DebugDraw.e_obbBit /*mostra os bouding boxes*/
		|b2DebugDraw.e_pairBit /*mostra um vetor que parte do centro dos corpos para os outros que estão em contado*/
		|b2DebugDraw.e_centerOfMassBit ;/*mostra o centro de massa dos Corpos*/
	/*aplica ao mundo o modo debug*/
	world.SetDebugDraw(debug);
}</pre>
<p>debug.m_drawFlags é um inteiro sem sinal com 7 bits que podem estar ligados ou não dependendo do OR (OU) resultante da combinação de uma mais flags unidos pelo OR bit a bit representado pelo &#8216;|&#8217;, comumente chamado de Pipe.</p>
<p>No debugdraw você também observa que alguns corpos possuem cores diferentes de outros. A cor vermelha indica que o corpo está dormindo, ou seja, o existem cálculos matemáticos/físicos sendo realizados para ele, esse fato é muito é muito importante para que haja uma maior performance reduzindo o consumo de processamento desnecessarimante. Os corpos cinzas estão em movimento, e os verdes são corpos estáticos, como por exemplo paredes e obstáculos.</p>
<div id="attachment_451" class="wp-caption alignleft" style="width: 580px"><a href="http://www.mxstudio.com.br/wp-content/uploads/2009/06/box2e1.jpg"><img class="size-full wp-image-451" title="box2e1" src="http://www.mxstudio.com.br/wp-content/uploads/2009/06/box2e1.jpg" alt="Estados" width="570" height="460" /></a><p class="wp-caption-text">Estados</p></div>
<p>Os arquivos deste tutorial podem ser baixados aqui:<br />
<a href="http://www.mxstudio.com.br/wp-content/uploads/2009/06/box2d.zip">http://www.mxstudio.com.br/wp-content/uploads/2009/06/box2d.zip</a></p>
<p>Faça diversas combinações dessas flags para você verificar visualmente como os corpos se comportam. Até a próxima.</p>
<p>Website: <strong><a href="http://marciosilva.net">www.marciosilva.net</a></strong> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.mxstudio.com.br/desenvolvimento/flash/box2d-modo-debugdraw/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Box2D, Primeira Simulação</title>
		<link>http://www.mxstudio.com.br/desenvolvimento/flash/box2d-primeira-simulacao/</link>
		<comments>http://www.mxstudio.com.br/desenvolvimento/flash/box2d-primeira-simulacao/#comments</comments>
		<pubDate>Sat, 25 Apr 2009 00:05:43 +0000</pubDate>
		<dc:creator>Marcio Silva</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[action script 3.0]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[Jogos]]></category>

		<guid isPermaLink="false">http://www.mxstudio.com.br/?p=2384</guid>
		<description><![CDATA[Olá Pessoal, Vamos agora aprender como programar com a Engine de Física para Games em Flash Box2D. Neste primeiro exemplo prático iremos mostrar como criar um Mundo e corpos que sofrerão ações e restrições desse mundo. Quem está lendo este tutorial e ainda não leu o primeiro recomendo que o leia neste link [http://www.mxstudio.com.br/flash/box2d-engine-de-fisica-para-games-em-flash/]. Pré-requisitos [...]]]></description>
			<content:encoded><![CDATA[<p>Olá Pessoal, </p>
<p>Vamos agora aprender como programar com a Engine de Física para Games em Flash Box2D. Neste primeiro exemplo prático iremos mostrar como criar um Mundo e corpos que sofrerão ações e restrições desse mundo.</p>
<p>Quem está lendo este tutorial e ainda não leu o primeiro recomendo que o leia neste link [<a href="http://www.mxstudio.com.br/flash/box2d-engine-de-fisica-para-games-em-flash/">http://www.mxstudio.com.br/flash/box2d-engine-de-fisica-para-games-em-flash/</a>]. </p>
<p><strong>Pré-requisitos e Softwares utilizados:</strong></p>
<p>Macromedia Flash CS4</p>
<p>Conhecimento em Física Básica (Cinemática pelo menos).</p>
<p>Conhecimento Intermediário em AS3.</p>
<p>API do Box2D que você pode baixar aqui [<a href="http://sourceforge.net/project/showfiles.php?group_id=210232&amp;package_id=252417&amp;release_id=642873">http://sourceforge.net/project/showfiles.php?group_id=210232&amp;package_id=252417&amp;release_id=642873</a>]</p>
<p>Faremos algo como o exemplo abaixo:</p>
<p><object width="500" height="300" data="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2dmx.swf" type="application/x-shockwave-flash"><param name="src" value="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2dmx.swf" /></object></p>
<p>Agora com os pré-requisitos estabelecidos, vamos criar nossa primeira aplicação. Baixe o arquivo ZIP contendo o código do Box2D e descompacte-o. Se por exemplo, você descompactou o box2D dentro de uma pasta chamada C<strong>:\game\, </strong>então o Box2D ficou com o seguinte caminho <strong>C:\game\Box2D\. </strong>Para que tudo funcione corretamente, todos os arquivos citados neste tutorial e nos próximos devem estar em <strong>C:\game\</strong>.  Veja o exemplo:</p>
<div id="attachment_287" class="wp-caption aligncenter" style="width: 457px"><a href="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2d31.png"><img class="size-full wp-image-287" title="box2d31" src="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2d31.png" alt="Exemplo de organização básica" width="447" height="321" /></a><p class="wp-caption-text">Exemplo de organização básica</p></div>
<p>Crie um novo arquivo chamado <strong>Box2DMX.as</strong>. Nele coloque o seguinte código:</p>
<pre lang="actionscript">package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;

	/*importação da API Box2D*/
	import Box2D.Dynamics.*;
	import Box2D.Collision.*;
	import Box2D.Collision.Shapes.*;
	import Box2D.Common.Math.*;

	public class Box2DMX extends Sprite
	{
		/* Construtor da classe	*/
		public function Box2DMX()
		{
			init();
		}

		/* Incializa a aplicação*/
		private function init():void
		{
			createWorld();

			createListeners();

			createGround();
		}

		/* Define os listeners da simulação/game*/
		private function createListeners():void
		{
			timer = new Timer(1000);
			timer.addEventListener(TimerEvent.TIMER, createBodies);
			timer.start();
			addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
		}

		/* Instancia o mundo onde a simulação ocorrerá*/
		private function createWorld():void
		{
			/* Definição dos limite do mundo*/
			var worldAABB:b2AABB = new b2AABB();
			worldAABB.lowerBound.Set(-100.0, -100.0);
			worldAABB.upperBound.Set(100.0, 100.0);

			/* Difinição da gravidade atuante em todos os corpos desse mundo*/
			var gravity:b2Vec2=new b2Vec2(0.0,10.0);

			/* Indica que os corpos devem permanecerem inativos	*/
			var doSleep:Boolean=true;

			/* Construção do mundo*/
			world = new b2World(worldAABB, gravity, doSleep);

		}

		/* Cria o chão onde os corpos ficarão*/
		private function createGround():void
		{
			var body:b2Body;
			var bodyDef:b2BodyDef;
			var boxDef:b2PolygonDef;

			bodyDef = new b2BodyDef();
			bodyDef.position.Set(10, 12);
			bodyDef.angle=0.0;

			boxDef = new b2PolygonDef();
			boxDef.SetAsBox(90, 3);
			boxDef.friction = 0.1;

			/* para corpos que nunca se moverão o
			* valor da densidade deve ser zero
			*/
			boxDef.density = 0;
			bodyDef.userData = new PhysGround();
			bodyDef.userData.width = physScale * 2 * 30;
			bodyDef.userData.height = physScale * 2 * 3;

			addChild(bodyDef.userData);

			body=world.CreateBody(bodyDef);
			body.CreateShape(boxDef);
			body.SetMassFromShapes();
		}
		/*cria os atores da simulação*/
		private function createBodies(e:Event):void
		{
			/* representa o corpo rígido*/
			var body:b2Body;

			/* será utilizado para representar
			* as características físicas do corpo rígido
			*/
			var bodyDef:b2BodyDef;

			/*define um polígono e suas características físicas*/
			var boxDef:b2PolygonDef;

			/*define um círculo e suas características físicas*/
			var circleDef:b2CircleDef;

			bodyDef = new b2BodyDef();
			bodyDef.position.Set(Math.random() * 15+5, 0);

			var rX:Number = Math.random() + 0.1;
			var rY:Number = Math.random() + 0.1;
			//Caixa
			if (Math.random() &lt; 0.5)
			{
				boxDef = new b2PolygonDef();
				boxDef.SetAsBox(rX, rY);
				boxDef.density = 1.0;
				boxDef.friction = 0.5;
				boxDef.restitution = 0.2;

				bodyDef.userData = new PhysBox();
				bodyDef.userData.width = rX * 2 * physScale;
				bodyDef.userData.height = rY * 2 * physScale; 

				body = world.CreateBody(bodyDef);
				body.CreateShape(boxDef);
			}
			else //Círculo
			{
				circleDef = new b2CircleDef();
				circleDef.radius = rX;
				circleDef.density = 1.0;
				circleDef.friction = 0.5;
				circleDef.restitution = 0.2;

				bodyDef.userData = new PhysCircle();
				bodyDef.userData.width = rX * 2 * physScale;
				bodyDef.userData.height = rX * 2 * physScale; 

				body = world.CreateBody(bodyDef);
				body.CreateShape(circleDef);
			}

			bodyDef.userData.x = body.GetPosition().x *physScale ;
			body.SetMassFromShapes();
			addChild(bodyDef.userData);
		}

		/*atualiza o posicionamento dos atores*/
		private function Update(e:Event):void
		{
			world.Step(timeStep, iterations);

			// Pare cada corpo no mundo atualiza a sua posição e rotação
			for (var body:b2Body = world.GetBodyList (); body; body = body.GetNext())
			{
				if (body.GetUserData() is Sprite)
				{
					body.GetUserData().x = body.GetPosition().x * physScale;//metros para pixels
					body.GetUserData().y = body.GetPosition().y * physScale;//metros para pixels
					body.GetUserData ().rotation = body.GetAngle() * (180/Math.PI);
				}
			}
		}

		private var world:b2World;
		private var iterations:int = 10;
		private var timeStep:Number = 1.0/30.0;
		private var physScale = 30.0;
		private var timer:Timer;

	}
}</pre>
<p>Neste primeiro código podemos destacar a criação do mundo que é realizado determinando seus limites pela classe b2AABB, além de delimitar o mundo você utilizar esta classe para determinar locais em seu game onde os personagens sofrem alguma alteração. Por exemplo, delimitar locais onde existem bombas que explodem se eles passarem por cima,  checkpoints, etc.</p>
<p>Outro ponto que deve ser destacado é a criação de corpos (bodies), a criação de um body segue uma sequência de passos bem definida e lógica:</p>
<ol>
<li>Define um body com posição;</li>
<li>Usa o obejto world para criar um body;</li>
<li>Define os shapes com geometria, atrito, densidade, etc;</li>
<li>Coloca os shapes no body;</li>
<li>E opcionalmente ajusta a massa do body;</li>
</ol>
<p>Podemos destacar também neste primeiro exemplo o atributo userData, usado por exemplo neste trecho de código:</p>
<pre lang="actionscript">bodyDef.userData = new PhysCircle();</pre>
<p>O Box2D permite que você crie suas próprias classes de atores e vincule a um body do mundo criado. Por exemplo, você está desenvolvendo um jogo de guerra e uma das suas classes se chama <strong>Tanque </strong>e dentro da classe tanque existem variáveis que você controla como life, munição, quantidade de inimigos que matou, etc. Portanto, está classe são dados controlados por você. Se você percebeu quem define as propriedades físicas é a classe <strong>b2BodyDef, </strong>é com ela que você informa ao Box2D como ele deverá tratar o ator aplicando as restrições físicas do mundo criado.</p>
<p>E por fim, temos a linha abaixo:</p>
<pre lang="actionscript">world.Step(timeStep, iterations);</pre>
<p>Esta linha deve aparecer no Main loop de seu Game, nesse momento o Box2D faz o trabalho duro de calcular colisões, prever contatos, tudo através de cálculos matemáticos. Você não precisa saber como ele faz isso, precisa apenas informar o quão preciso você quer esses cálculos através da variável <em>iterations</em>. Quanto maior o valor dessa variável mais perfeito são os cálculos físicos e matemáticos. No entanto, isso gera um <em>overhead, </em>ou seja, deixa seu jogo mais lento perdendo performance.</p>
<p>Games com Engines, ao contrário de games simples que não possuem engines de cálculos físicos e matemáticos, necessitam de um tempo adicional para que possam aplicar equações complexas para que a simulação possua um pouco de realidade. Esse tempo no Box2D é o <strong>timeStep, </strong>o <em>game loop</em> ou <em>main loop <span style="font-style: normal;">é necessário apenas para aplicar as novas posições calculadas pelo Box2D.</span></em></p>
<p><em><span style="font-style: normal;">Um fato importante que deve ser observado é o<strong> physScale </strong>que indica as escala utilizada pelo Box2D, em Box2D 1(um) metro é igual a 30px. Esse fato deve-se ao fato dos cálculos físicos serem feitos com unidades  internacionais e convencionadas pelos físicos como o metro e não com coordenadas de tela. Dessa forma, no main loop (método update)  é feita uma conversão de metros para pixel, pois após a chamada do método </span>Step() <span style="font-style: normal;">as novas coordenadas calculdas pela Engine foram determinadas, no entanto elas foram calculadas em metros. </span></em></p>
<p>Como a tela do seu munitor tem como unidade de medida e posicionamento o pixel, devemos converter o valor em metros calculado pelo Box2D para pixel como vemos abaixo. E o mesmo vale para outras medidas como altura e largura de objetos na cena.</p>
<pre lang="actionscript">body.GetUserData().x = body.GetPosition().x * physScale;//metros para pixels
body.GetUserData().y = body.GetPosition().y * physScale;//metros para pixels</pre>
<p>Agora crie um arquivo chamado <strong>Box2DMX.fla</strong> e na aba properties coloque o nome da classe que deseja linkar.</p>
<div id="attachment_279" class="wp-caption aligncenter" style="width: 513px"><a href="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2d1.png"><img class="size-full wp-image-279 " title="box2d1" src="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2d1.png" alt="Aba properties" width="503" height="399" /></a><p class="wp-caption-text">Aba properties</p></div>
<p>Agora vamos criar os atores da simulação.  Pressione <strong>CTRL + F8 </strong>para adicionar um novo símbolo, crie um quadrado de <strong>100px</strong> x<strong>100px </strong>com o nome de <strong>PhysBox</strong>. Veja figura abaixo:</p>
<div id="attachment_289" class="wp-caption alignnone" style="width: 530px"><a href="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2d4.png"><img class="size-full wp-image-289" title="box2d4" src="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2d4.png" alt="Box" width="520" height="494" /></a><p class="wp-caption-text">Box</p></div>
<p>Agora crie da mesma forma um círculo chamado <strong>PhysCircle</strong> com as dimensões e posicionamento mostrados abaixo:</p>
<div id="attachment_291" class="wp-caption alignnone" style="width: 530px"><a href="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2d5.png"><img class="size-full wp-image-291" title="box2d5" src="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2d5.png" alt="Circle" width="520" height="494" /></a><p class="wp-caption-text">Circle</p></div>
<p>E por fim crie um movieclip que será o chão de sua simulação, este se chamará <strong>PhysGround.</strong></p>
<div id="attachment_292" class="wp-caption alignnone" style="width: 530px"><a href="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2d6.png"><img class="size-full wp-image-292" title="box2d6" src="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2d6.png" alt="Ground" width="520" height="494" /></a><p class="wp-caption-text">Ground</p></div>
<p>Para que os movie clips criados acima funcionem com o código, para cada um você irá até a <em>library </em>clicar com o botão direito em cima do <strong>PhysBox </strong>por exemplo, e depois escolher a opção <strong>properties. </strong>Uma janela de diálogo se abrirá como a que está ilustrada abaixo para você exportar para o Action Script é só confirmar clicando em OK. Lembre-se de fazer o mesmo para o <strong>PhysCircle</strong> e o <strong>PhysGround</strong>.</p>
<div id="attachment_294" class="wp-caption alignnone" style="width: 434px"><a href="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2d7.png"><img class="size-full wp-image-294" title="box2d7" src="http://www.mxstudio.com.br/wp-content/uploads/2009/04/box2d7.png" alt="Exportanto para o Action Script 3.0" width="424" height="553" /></a><p class="wp-caption-text">Exportanto para o Action Script 3.0</p></div>
<p>Agora é só salvar os dois arquivos e dar <strong>CTRL + ENTER. </strong></p>
<p>Espero que tenham gostado, até a próxima. </p>
<p><strong>Meu Website: <a href="http://www.marciosilva.net">www.marciosilva.net</a></strong></p>
<p>Fontes:</p>
<p>http://www.emanueleferonato.com</p>
<p>http://www.box2d.org</p>
<p>Arquivos do tutorial:<br />
<a href="http://www.mxstudio.com.br/wp-content/uploads/2009/04/exemplo1.zip">http://www.mxstudio.com.br/wp-content/uploads/2009/04/exemplo1.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mxstudio.com.br/desenvolvimento/flash/box2d-primeira-simulacao/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Box2D, a engine de Física para Games em Flash</title>
		<link>http://www.mxstudio.com.br/desenvolvimento/flash/box2d-engine-de-fisica-para-games-em-flash/</link>
		<comments>http://www.mxstudio.com.br/desenvolvimento/flash/box2d-engine-de-fisica-para-games-em-flash/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 22:21:20 +0000</pubDate>
		<dc:creator>Marcio Silva</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[action script 3.0]]></category>
		<category><![CDATA[game]]></category>

		<guid isPermaLink="false">http://www.mxstudio.com.br/?p=2347</guid>
		<description><![CDATA[Olá Pessoal, De hoje em diante começarei um conjunto de tutoriais que explicam o funcionamento básico de uma grande ferramenta para os desenvolvedores de Games em flash. Trata-se de uma poderosa API para simulação Física de Corpos Rígidos, é de extrema importância que você tenha familiaridade com conceitos físicos como: massa, força, atrito, colisão, inércia, [...]]]></description>
			<content:encoded><![CDATA[<p>Olá Pessoal,</p>
<p>De hoje em diante começarei um conjunto de tutoriais que explicam o funcionamento básico de uma grande ferramenta para os desenvolvedores de Games em flash. Trata-se de uma poderosa API para simulação Física de Corpos Rígidos, é de extrema importância que você tenha familiaridade com conceitos físicos como: massa, força, atrito, colisão, inércia, movimento, dentre outros conceitos que estão intimamente ligados a Dinâmica de Corpos Rígidos.</p>
<p>Exemplos do que pode ser feito com o Box2D. Use as setas do teclado para fazer o objeto andar.</p>
<p style="text-align:center"><object width="400" height="200" data="http://marciosilva.net/wp-content/uploads/2009/04/game1.swf" type="application/x-shockwave-flash"><param name="src" value="http://marciosilva.net/wp-content/uploads/2009/04/game1.swf" /></object><br />
Fonte: Emanuele Feronato.</p>
<p>De forma alguma darei uma aula de física aqui, dessa forma, procure conteúdos pela internet que falem sobre os itens que citei acima. No entanto, basta pedir que indicarei links para que vocês possam estudar. De imediato posso indicar um dos melhores sites para que você possa procurar sobre esses conteúdos: </p>
<p><a title="Wikipédia" href="http://wikipedia.org/">Wikipédia</a> aqui você irá encontrar com certeza os tópicos que mencionei acima.</p>
<p>Também assumirei que você conhece muito bem Action Script 3.0 ou AS3, pois também não é o intuito aqui ensinar como criar uma classe no AS3 ou manipular o Macromédia Flash. O principlal objetivo é o mostrar o funcionamento de Engine da Física no flash, mostrar os principais conceitos de física empregados em cada linha de código.</p>
<p>Nesse primeiro artigo, apresentarei os conceitos mais básicos que você necessita saber antes de prosseguir.</p>
<p style="text-align: justify; "><span style="color: #000000;"><span style="color: #ff0000;"><span style="text-decoration: underline;"><strong>ATENÇÃO:</strong></span></span> Se não entender a definição dos termos apresentados abaixo, não adianta prosseguir nos próximos artigos, pois não entenderá nada do que estará acontecendo. Sei que provavelmente você pode fazer um CTRL + C e CTRL + V do código para testar o funcionamento. Mas e aí? Você vai aprender alguma coisa fazendo assim? E se funcionar claro, pois muita gente copia e dá um monte de erro, pois as belas Aspas &#8220;&#8221; do HTML causam esses erros.</span></p>
<p>Bom, avisos dados agora vamos ao que interessa, alguns termos eu deixarei em inglês mesmo, por que é da forma que aparecerá na API. Os conceitos iniciais são os seguintes:</p>
<p><strong>Rigid Body / Corpo Rigido: </strong>Este é um dos mais importantes conceitos, a idéia básica é que em um corpo rígido se marcarmos dois pontos neste corpo, a distância entre esses dois pontos <em>será sempre constante</em>. Exemplo: um diamente. Na API esse corpo rígido se chamará <strong>body</strong>. </p>
<p><strong>Shape/ Forma: </strong>É qualquer parte da Geometria 2D fixada ao corpo rígido. Ela pode possuir propriedades físicas como atrito e restituição.</p>
<p><strong>Constraint / Restrição: U</strong>ma restrição remove graus de liberdade de um corpo. Em 2d existem 3 graus de liberdade e em 3D existem 6. No caso de 2D um corpo pode transladar (deslocar) sobre qualquer um dos eixos (x, y) e realizar um movimento de rotação em torno do eixo perpendicular ao plano formado por x e y. Se pendurarmos um corpo numa parede como se fosse um pêndulo, estaremos retirando 2 Graus de liberdade desse corpo, pois ele conseguirá apenas realizar rotações em torno do eixo de fixação.</p>
<p><strong>Contact Constraint / Restrição de contato: </strong>Nada mais é do que não permitir que dois corpos possam penetrar um no outro, aí vem a famosa lei de Newton: &#8220;Dois corpos não podem ocupar o mesmo lugar ao mesmo tempo&#8221;. Esta restrição é implementada pelo próprio Box2D.</p>
<p><strong>Joint / Junção: </strong>É uma restrição para manter 2 ou mais corpos rígidos ligados. A Junção pode ser Limite e Motora.</p>
<p><strong>Joint Limit / Junção Limite: <span style="font-weight: normal;">Uma junção limite restringe a amplitude de movimento de uma articulação. Pode representar um braço humano por exemplo.</span></strong></p>
<p><strong>Joint Motor / Junção Motora: <span style="font-weight: normal;">Junção motora coordena o movimenta de corpos conectados conforme os graus de liberdade.</span></strong></p>
<p><strong>World / Mundo: </strong>É um conjunto de corpos, formas, e restrições que interagem entre si.</p>
<p>Espero que tenham assimilado os conceitos básicos apresentados na API, eles são importantes para que você entenda os códigos que serão estudados.</p>
<p>Até a próxima.</p>
<p><strong>Meu website: <a href="http://www.marciosilva.net">www.marciosilva.net</a></strong></p>
<p>Fontes: </p>
<p>http://www.box2d.org</p>
<p>http://www.emanueleferonato.com</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mxstudio.com.br/desenvolvimento/flash/box2d-engine-de-fisica-para-games-em-flash/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Criação de games &#8211; Conceitos Matemáticos e aplicações</title>
		<link>http://www.mxstudio.com.br/desenvolvimento/flash/criacao-de-games-conceitos-matematicos-e-aplicacoes/</link>
		<comments>http://www.mxstudio.com.br/desenvolvimento/flash/criacao-de-games-conceitos-matematicos-e-aplicacoes/#comments</comments>
		<pubDate>Sat, 17 May 2008 03:55:23 +0000</pubDate>
		<dc:creator>Marcio Silva</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[conceitos]]></category>
		<category><![CDATA[criação]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[Jogos]]></category>
		<category><![CDATA[matemática]]></category>

		<guid isPermaLink="false">http://www.mxstudio.com.br/?p=1427</guid>
		<description><![CDATA[Olá comunidade MXSTUDIO, Vamos a mais um tutorial que vai ensinar um pouco de matem&#225;tica aplicada ao mundo da cria&#231;&#227;o de games em flash. Pré-requisitos: Conhecimento básico em ActionScript 3.0 Macromedia Flash CS3 Objetivo: O objetivo principal &#233; que voc&#234; entenda teoria envolvida aplicada &#224; pr&#225;tica, n&#227;o adianta voc&#234; sair copiando e colando c&#243;digo daqui [...]]]></description>
			<content:encoded><![CDATA[<link href="http://www.mxstudio.com.br/webgerenciador/_css/PadraoCss.css" rel="stylesheet" type="text/css" />
<p><script src="http://www.mxstudio.com.br/js/ColorCode.js"></script></p>
<table cellSpacing=0 cellPadding=0 width=100% border=0>
<tbody>
<tr>
<td id=colunaTexto vAlign=top>
<p>Olá comunidade MXSTUDIO,</p>
<p style="text-align:justify">Vamos a mais um tutorial que vai ensinar um pouco de matem&aacute;tica aplicada ao mundo da cria&ccedil;&atilde;o de games em flash. </p>
<h3>Pré-requisitos:</h3>
<p style="text-align:justify">
<p>Conhecimento básico em ActionScript 3.0</p>
<p></p>
<p>Macromedia Flash CS3</p>
<h3>Objetivo:</h3>
<p style="text-align:justify">O objetivo principal &eacute; que voc&ecirc; entenda  teoria envolvida aplicada &agrave; pr&aacute;tica, n&atilde;o adianta voc&ecirc; sair copiando e colando c&oacute;digo daqui e n&atilde;o entender nada do que o c&oacute;digo faz. N&atilde;o s&oacute; a pegunta &eacute; como fazer deve ser respondida, mas tamb&eacute;m por que funciona. Recomendo que n&atilde;o pule a parte te&oacute;rica deste tutorial, pois &eacute; basicamente a explica&ccedil;&atilde;o do c&oacute;digo, demonstrando que ele realmente funciona e tem embasamento te&oacute;rico da nossa querida matem&aacute;tica: </p>
<p></p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="550" height="400" id="Megaman" align="middle"><param name="allowScriptAccess" value="sameDomain" /><param name="movie" value="http://www.mxstudio.com.br/wp-content/uploads/2008/05/cannon.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#000000" /><embed src="http://www.mxstudio.com.br/wp-content/uploads/2008/05/cannon.swf" quality="high" bgcolor="#FFF" width="550" height="400" name="cannon" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /></p>
<p></object></p>
<p></p>
<h3>Conceitos:</h3>
<p style="text-align:justify">Os conceitos que ser&atilde;o abordados s&atilde;o basicamente a utiliza&ccedil;&atilde;o de Action Script 3.0 aliado &agrave; trigonometria, para montar um exemplo simples de movimenta&ccedil;&atilde;o que pode ser a chave para a cria&ccedil;&atilde;o de games de tanque de guerra por exemplo, que atira e gira para todos os lados com seu canh&atilde;o. Existem diversos joguinhos na Internet que usam este conceito. </p>
<h3>Conteúdo</h3>
<p style="text-align:justify">
<p>Primeiro vamos criar o tanque de guerra, para isso crie um documento novo no seu Macromedia Flash CS3 (<strong>pressione CTRL + N</strong>), escolha a op&ccedil;&atilde;o <strong>flash file action script 3.0</strong>. Ap&oacute;s criado o documento, pressione <strong>CTRL + F8</strong> para inserir um novo movie clip chamado <strong>Cannon</strong>, o movie clip que dever&aacute; ser criado &eacute; igual o que &eacute; mostrado abaixo, fa&ccedil;a da cor e to tamanho que quiser. Mas aten&ccedil;&atilde;o! Certifique-se que o centro de rota&ccedil;&atilde;o do Canh&atilde;o ser&aacute; o centro do c&iacute;rculo desenhado, pois seu canh&atilde;o poder&aacute; rotacionar de forma degenarada (todo densengon&ccedil;ado). Para ficar certinho a rota&ccedil;&atilde;o posicione o c&iacute;rculo bem ao centro. No meu exemplo, criei o circulo com <strong>height de 80px e width de 80px</strong> e <strong>com X e y posicionados em -40px</strong>:</p>
<p style="text-align:center; margin:0 auto">
<p>	<img src="http://www.mxstudio.com.br/wp-content/uploads/2008/05/fig1.jpg" alt="exemplo" /></p>
<p>	<strong>Figura 1 </strong> &#8211; Posicionamento correto </p>
<p align="justify">Finalizado o Canh&atilde;o, agora chega o momento de pensar como fazer a mira do canh&atilde;o ficar seguindo o cursor do mouse. Ser&aacute; usada a trigonometria para fazer isso, voc&ecirc; pode n&atilde;o lembrar de alguma coisa de trigonometria e querer pular esta parte, mas l&aacute; vai a exeplica&ccedil;&atilde;o para n&atilde;o ter desculpa. Na <strong>figura 2 e 3</strong> o ponto <strong>P</strong> indicado pode ser interpretado como o cursor do mouse e o ponto <strong>O</strong> como o centro do canh&atilde;o. A diferen&ccedil;a entre o ponto X do mouse menos o X do canh&atilde;o &eacute; cosseno de alpha e a diferen&ccedil;a entre o ponto Y do mouse menos o Y do canh&atilde;o &eacute; o seno do ângulo alpha, esse ângulo alpha que precisamos para calcular a rota&ccedil;&atilde;o do canh&atilde;o usando a fun&ccedil;&atilde;o tangente: </p>
<p style="text-align:center; margin:0 auto"></p>
<p><img src="http://www.mxstudio.com.br/wp-content/uploads/2008/05/seno.jpg" alt="exemplo" /></p>
<p>	<strong>Figura 2 </strong> &#8211; Seno e cosseno. <em>Fonte: http://www.brasilescola.com</em></p>
<p style="text-align:center; margin:0 auto">
<p>	<img src="http://www.mxstudio.com.br/wp-content/uploads/2008/05/tang.jpg" alt="exemplo" /></p>
<p>	<strong>Figura 3 </strong> &#8211; Tangente. <em>Fonte: http://www.brasilescola.com</em></p>
<p align="justify">
<p>Lembrando que o plano catesiano nas coordenadas de v&iacute;deo o Y cresce para baixo, ao contr&aacute;tio do convencional, logo devemos tomar alguns cuidados na hora de implementar. Abaixo segue o c&oacute;digo que implementa o movimento do canh&atilde;o. Antes disso v&aacute; na <em>library</em> onde est&aacute; o movie clip <strong>Cannon </strong>e clique com o bot&atilde;o direito do mouse em cima dele, escolha <em>Linkage </em>e coloque como mostrado na figura, para que este movie clip possa ser instanciado no Action Script.</p>
<p style="text-align:center; margin:0 auto">
<p>	<img src="http://www.mxstudio.com.br/wp-content/uploads/2008/05/linkage.jpg" alt="linkage" /></p>
<p>	<strong>Figura 4 </strong> &#8211; Linkage. </p>
<p align="justify">
<p>   Finalmente o c&oacute;digo, ele simplesmente pega as coordadas do mouse e subtrai da posição do tanque, tanto na coordenada Y (seno) quanto em X (cosseno) e por fim calcula a tangente do &acirc;ngulo alpha da <strong>figura 1 e 2</strong>.</p>
<p><DIV id="codigo" title="AS"></p>
<p>/*Instância do canhão*/</p>
<p>var cannon_mc = new Cannon();</p>
<p>/*Será utilizado para posicionar o canhão*/</p>
<p>var dobj:DisplayObject = null;</p>
<p>/*adiciona o canhão ao palco e faz o correto posicionamento*/</p>
<p>dobj = addChild(cannon_mc);</p>
<p>dobj.x = 250;</p>
<p>dobj.y = 200;</p>
<p>dobj.width = 120;</p>
<p>dobj.height = 80;</p>
<p>/*adiciona evento de movimentação de mouse*/</p>
<p>parent.addEventListener(MouseEvent.MOUSE_MOVE, rotate);</p>
<p>function rotate(evt:MouseEvent):void</p>
<p>{</p>
<p>	/*Calcula o vetor em X (cosseno)(Ver figura 1)*/</p>
<p>    var mousex = evt.stageX-cannon_mc.x;</p>
<p>    /*Calcula o vetor em Y (seno)(Ver figura 1)</p>
<p>    * Multiplica por -1, coordenadas de vídeo para </p>
<p>    * coordenadas reais</p>
<p>    */</p>
<p>    var mousey = (evt.stageY-cannon_mc.y)*-1;</p>
<p></p>
<p>    /*Calcula a tangente*/</p>
<p>    var angle = Math.atan2(mousey, mousex);</p>
<p>	/*rotaciona, tranformando o angulo de radianos para graus</p>
<p>    * Pura matemática =)</p>
<p>    */</p>
<p>   cannon_mc.rotation = -angle*180/Math.PI;</p>
<p>}</p>
<p></DIV></p>
<p>&nbsp;</p>
<h3>Considera&ccedil;&otilde;es Finais </h3>
<p style="text-align:justify">Agora &eacute; s&oacute; rodar e ver o resultado, esse conceito tem uma infinidade de aplica&ccedil;&otilde;es, tudo depende da sua criatividade. Aprofundei apenas nos conceitos chaves, saber o que &eacute; um vetor ou o que &eacute; plano cartesiano fica um estudo a seu crit&eacute;rio. Recomendo um estudo nos conceitos de trigonometria para que seus joguinhos fiquem cada vez mais legais e viciantes.</p>
<p style="text-align:justify">Nas pr&oacute;ximas colunas abordarei mais conceitos matem&aacute;ticos. Fazer um jogo de tabuleiro &eacute; f&aacute;cil, agora fazer um que envolva f&iacute;sica e matem&aacute;tica demanda um pouco mais de empenho de quem o faz, e consequentemente isso trar&aacute; um impacto positivo para seus jogos. Do que seria os jogos de hoje, como Crysis ou Need For Speed Pro Street, sem a Matem&aacute;tica e a F&iacute;sica, os seus criadores possuem um intenso conhecimento sobre ambas &aacute;reas de conhecimento, n&atilde;o s&atilde;o meros programadores.</p>
<p>   <script>FormatAS(new Array('AS'))</script></p>
<p>   Espero que tenham gostado. At&eacute; a pr&oacute;xima.  </p>
<p><strong>Autor: M&aacute;rcio Silva &#8211; Colunista de Flash &amp; ActionSctipt MXSTUDIO.</strong></p>
<p><a href="http://www.mxstudio.com.br/wp-content/uploads/2008/05/cannon.zip">Download dos arquivos</a></p>
<p>Qualquer d&uacute;vida envie um e-mail para <a href="mailto:marciosilva@mxstudio.com.br" target="new">marciosilva@mxstudio.com.br</a> ou acesse nosso <a href="http://www.mxstudio.com.br/forum/index.php?showforum=127" target="forum">f&oacute;rum</a></p>
<p>&nbsp; </p>
</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.mxstudio.com.br/desenvolvimento/flash/criacao-de-games-conceitos-matematicos-e-aplicacoes/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>CriaÃ§Ã£o de games &#8211; Campo Minado em AS3</title>
		<link>http://www.mxstudio.com.br/desenvolvimento/flash/criacao_de_games___campo_minado_em_as3/</link>
		<comments>http://www.mxstudio.com.br/desenvolvimento/flash/criacao_de_games___campo_minado_em_as3/#comments</comments>
		<pubDate>Fri, 18 Jan 2008 00:00:00 +0000</pubDate>
		<dc:creator>Marcio Silva</dc:creator>
				<category><![CDATA[Flash]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Aprenda a desenvolver o Campo Minado em flash com os novos conceitos do Action Script 3.0]]></description>
			<content:encoded><![CDATA[<p><script src="http://www.mxstudio.com.br/js/ColorCode.js"></script></p>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr>
<td id="colunaTexto" valign="top">
<h1>CriaÃ§Ã£o de games &#8211; Campo Minado em AS3</h1>
<p>OlÃ¡ pessoal,</p>
<p style="text-align: justify">Vamos criar mais um joguinho,  que vai apresentar a programaÃ§Ã£o de games com o AS3.</p>
<h3>PrÃ©-requisitos:</h3>
<p style="text-align: justify">Conhecimento bÃ¡sico em ActionScript 2.0 e 3.0</p>
<p>Macromedia Flash CS3</p>
<p><a href="http://www.mxstudio.com.br/views.tutorial.php?act=view&#038;cid=3&#038;aid=554">Classe EventDispatcher</a><br />
<a href="http://www.mxstudio.com.br/views.tutorial.php?act=view&#038;cid=3&#038;aid=1129">Classe DisplayObject</a></p>
<h3>Objetivo:</h3>
<p style="text-align: justify">O objetivo deste tutorial Ã© que vocÃª, ao tÃ©rmino dele, possa entender como funciona a programaÃ§Ã£o orientada a objetos de games, criar seus prÃ³prios eventos nos jogos. Procurei selecionar um jogo simples no resultado final que todo mundo conhece (campo minado), mas que no momento do desenvolvimento vai explorar sua capacidade de resolver problemas bem relacionados a programaÃ§Ã£o. Visto em nÃ­vel de cÃ³digo este joguinho nÃ£o Ã© tÃ£o simples.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="520" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="name" value="Megaman" /><param name="bgcolor" value="#FFF" /><param name="align" value="middle" /><param name="src" value="http://www.mxstudio.com.br/imagens_artigos/htmlA9I39_marcioSilva_jan08_campominado_imagens/mines.swf" /><embed type="application/x-shockwave-flash" width="550" height="520" src="http://www.mxstudio.com.br/imagens_artigos/htmlA9I39_marcioSilva_jan08_campominado_imagens/mines.swf" align="middle" bgcolor="#FFF" name="Megaman"></embed></object></p>
<h3>Conceitos:</h3>
<p style="text-align: justify">Os conceitos que serÃ£o vistos aqui, sÃ£o a utilizaÃ§Ã£o dos <em>dispatchers</em> para resolver alguns problemas, resoluÃ§Ã£o de problemas algorÃ­tmicos simples, arganizaÃ§Ã£o dos objetos pelo AS3, duplicar movie clips com a ausÃªncia do <em><strong>duplicateMovieClip</strong></em>.</p>
<h3>ConteÃºdo</h3>
<p style="text-align: justify">Primeiro vamos preparar os movie clips principais, no fim deste tutorial tem o link dos arquivos fontes, nele eu coloquei as imagens que vamos utilizar. Crie um documento novo Adobe flash CS 3 com o nome <strong>mines.fla </strong>com o background da cor <strong>#CCCCCC</strong> . Depois vÃ¡ em <em>insert &gt; new symbol</em> ou CTRL + F8, o novo sÃ­mbolo Ã© do tipo movie clip e se chamarÃ¡ <strong>Mine</strong>. Neste novo movie clip vazio crie 11 <em>Keyframes</em>. Com exceÃ§Ã£o do primeiro <em>Keyframe</em>, todos os outros receberÃ£o um nome. A nome de cada frame a partir do 2Â° serÃ¡ a seguinte: <strong>_1</strong>,<strong> _2</strong>,<strong> _3</strong>, <strong>_4</strong>, <strong>_5</strong>, <strong>_6</strong>, <strong>_7</strong>, <strong>_8</strong>, <strong>die</strong> e <strong>clear. </strong>Dessa forma facilitarÃ¡ no momento da programaÃ§Ã£o. Agora no primeiro <em>keyframe</em> vocÃª colocarÃ¡ a figura chamada <strong>square.jpg</strong> coloque nas coordenadas mostradas na figura.</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/htmlA9I39_marcioSilva_jan08_campominado_imagens/fig1.jpg" alt="posiÃ§Ã£o do square" /><br />
<strong>Figura 1 </strong> &#8211; DimensÃµes e a posiÃ§Ã£o da imagem</p>
<p align="justify">Seguindo, clique no primeiro keyframe e aperte F9 para colocar o comando stop() no editor de script. Agora exatamente na mesma posiÃ§Ã£o, mas no keyframe 10 que tem o nome <strong>die</strong>, coloque a figura <strong>bomb.jpg</strong>, ela serÃ¡ colocada na mesma posiÃ§Ã£o e dimensÃµes mostrada na <strong>figura 1, </strong>nos outros keyframes vocÃª vai apenas colocar um nÃºmero no stage com a ferramenta text, seguindo a lÃ³gica nÃºmero 1 no keyframe <strong>_1</strong>, 2 no jeyframe <strong>_2</strong>, todos posicionados no <strong>x=2.8 e y=0 </strong>atÃ© o keyframe <strong>_8</strong>, isso representa um determinado nÃºmero de bombas que estÃ£o prÃ³ximas de um quadrado (Regra do jogo), se vocÃª jogou campo minado alguma vez jÃ¡ observou os nÃºmeros que aparecem no local que clicou  . Volte Ã  cena principal, falta um botÃ£o novo jogo, que vocÃª irÃ¡ achar em <em>window &gt; components</em> ou aperte CTRL + F7. Escolha o Button na lista que aparecerÃ¡, arraste-o para o stage e altere seu label para novo jogo como na figura abaixo, e o nome de instÃ¢ncia do botÃ£o Ã© <strong>newGame_btn</strong>:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/htmlA9I39_marcioSilva_jan08_campominado_imagens/fig2.jpg" alt="componente no stage" /><br />
<strong>Figura 2 </strong> &#8211; Componente no Stage</p>
<p align="justify">E para finalizar esta parte vamos linkar o mc <strong>Mine</strong> que acabamos de criar com o Action Script 3.0, vÃ¡ na library e clique com o botÃ£o direito no mc <strong>Mine</strong> e escolha linkage, aparecerÃ¡ esta janela de diÃ¡logo, configure como estÃ¡ mostrado.</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/htmlA9I39_marcioSilva_jan08_campominado_imagens/fig3.jpg" alt="posiÃ§Ã£o do square" /><br />
<strong>Figura 3 </strong> &#8211; Linkando o mc criado com Action Script 3.0</p>
<p align="justify">Acabamos esta fase, agora vamos a codificaÃ§Ã£o, primeiramente construiremos duas classes: a primeira Ã© que dispara eventos, recomendo ver os tutoriais mencionados nos prÃ©-requisitos para continuar este tutorial, neles vocÃª ira entender como funciona as classes que sÃ£o dispatcher e as listeners, abaixo a classe dispatcher que chamei de <strong>DispacherObject</strong>:</p>
<div id="codigo" title="AS">package<br />
{<br />
import flash.events.EventDispatcher;<br />
import flash.events.Event;	public class DispatcherObject extends EventDispatcher<br />
{<br />
private var label:String;</p>
<p>static var EXPLOSION:String = &#8216;explosion&#8217;;</p>
<p>public function DispatcherObject(label:String)<br />
{<br />
this.label = label;<br />
}</p>
<p>public override function toString():String<br />
{<br />
return &#8220;[ Dispatcher "+label+" ]&#8220;;<br />
}</p>
<p>public function dispatch()<br />
{<br />
this.dispatchEvent(new Event(DispatcherObject.EXPLOSION));<br />
}<br />
};<br />
};</p>
</div>
<p align="justify">A classe Ã© bem simples, possui um atributo para debugar e um estÃ¡tico que representa o no evento a ser disparado, chamei esse evento de <strong>explosion</strong>. Possui um construtor, um mÃ©todo para debugar que sobrescreve o mÃ©todo <em>toString()</em> da classe pai por meio da palavra reservada <em>override</em> e por fim o mÃ©todo que dispara o evento em si. Abaixo segue a classe listener que &#8216;escuta&#8217; a classe emissora de eventos que acabamos de ver:</p>
<div id="codigo" title="AS">package<br />
{<br />
import flash.events.IEventDispatcher;<br />
import flash.events.Event;	public class ListenerObject<br />
{</p>
<p>private var label:String;</p>
<p>public function ListenerObject(label:String)<br />
{<br />
this.label = label;<br />
}</p>
<p>public function addDispatcher(dispatcher:IEventDispatcher, functionHandler:Function)<br />
{<br />
dispatcher.addEventListener(DispatcherObject.EXPLOSION, functionHandler);<br />
}</p>
<p>public function toString()<br />
{<br />
return &#8220;[ Listener "+label+" ]&#8220;;<br />
}<br />
};<br />
};</div>
<p align="justify">
<p align="justify">Semelhante a classe acima tambÃ©m possui mÃ©todo e atributo para debugar, e um mÃ©todo que recebe dois parÃ¢metros: um Ã© o dispatcher que ela ficarÃ¡ &#8216;ouvindo&#8217; e o outro parÃ¢metro e a funÃ§Ã£o que serÃ¡ chamada no momento do disparo do evento.</p>
<p align="justify">A prÃ³xima classe Ã© a classe que representarÃ¡ cada quadrado do campo minado:</p>
<div id="codigo" title="AS">package<br />
{<br />
import flash.display.MovieClip;<br />
import flash.display.Sprite;<br />
import flash.display.DisplayObject;<br />
import flash.events.MouseEvent;<br />
import flash.events.Event;	public class Square extends Sprite<br />
{<br />
/*indica se Ã© bomba ou nÃ£o*/<br />
private var bomb:Boolean;<br />
/*cÃ³pia do mc que representa a bomba*/<br />
private var mc:MovieClip;</p>
<p>/*indica quantas bombas estÃ£o perto*/<br />
private var proximity: Number;</p>
<p>/*listeners e dispatchers*/<br />
private var listener:ListenerObject;</p>
<p>private var listener2:ListenerObject;</p>
<p>private var disp:DispatcherObject;</p>
<p>var disp2:DispatcherObject;</p>
<p>/*construtor, recebe o mc que representa a mina e um booleano<br />
* que indica se Ã© uma bomba<br />
*/<br />
function Square ( target_mc:MovieClip, bomb:Boolean )<br />
{</p>
<p>this.mc = target_mc;</p>
<p>this.addChild ( target_mc );</p>
<p>this.bomb = bomb;</p>
<p>this.mc.buttonMode = true;</p>
<p>listener = new ListenerObject(&#8216;CS3&#8242;);</p>
<p>listener2 = new ListenerObject(&#8216;ADOBE&#8217;);</p>
<p>disp2 = new DispatcherObject(&#8216;MINADO&#8217;);</p>
<p>doEvents();<br />
};</p>
<p>/* seta quantas bombas estÃ£o proximas desse Square*/<br />
function setProximity ( proximity:Number )<br />
{<br />
this.proximity = proximity;<br />
};<br />
/* retorna a proximidade*/<br />
function getProximity ( )<br />
{<br />
return this.proximity;<br />
};</p>
<p>/* retorna true ou false dizendo se Ã© bomba*/<br />
function isBomb()<br />
{<br />
return this.bomb;<br />
};</p>
<p>/*seta dispachador de eventos que &#8216;ouvirÃ¡&#8217; o clique em uma bomba*/<br />
function setDispatcher ( d:DispatcherObject )<br />
{<br />
this.disp = d;</p>
<p>listener.addDispatcher( d, onExplosion );<br />
};</p>
<p>/*seta quem irÃ¡ disparar o armegedon*/<br />
function setDispatcherArm ( d:DispatcherObject )<br />
{<br />
this.disp2 = d;</p>
<p>listener2.addDispatcher( d, explode );<br />
};</p>
<p>/*adiciona evento de click do mouse*/<br />
function doEvents()<br />
{<br />
this.mc.addEventListener( MouseEvent.CLICK, check );<br />
};<br />
/*remove evento de click do mouse*/<br />
function undoEvents()<br />
{<br />
this.mc.removeEventListener( MouseEvent.CLICK, check );<br />
};<br />
/*verifica em que o usuÃ¡rio clicou e dispara os eventos necessÃ¡rios*/<br />
function check (event:Event)<br />
{</p>
<p>if(this.bomb)<br />
this.disp.dispatch();<br />
else<br />
{<br />
if(this.proximity == 0)<br />
{<br />
this.proximity = 1000;<br />
this.disp2.dispatch();<br />
this.mc.gotoAndStop(&#8216;clear&#8217;);</p>
<p>}<br />
else<br />
this.mc.gotoAndStop(&#8216;_&#8217;+this.proximity);</p>
<p>}</p>
<p>};</p>
<p>/*mÃ©todo de callback que serÃ¡ invocado quando clicar numa bomba*/<br />
function onExplosion (event:Event)<br />
{<br />
this.mc.gotoAndStop(&#8216;die&#8217;);</p>
<p>};</p>
<p>/*mÃ©todo de callback que serÃ¡ invocado quando houver um armagedon*/<br />
function explode(event:Event)<br />
{<br />
if(this.proximity == 0)<br />
{<br />
this.proximity = 1000;<br />
this.mc.gotoAndStop(&#8216;clear&#8217;);<br />
this.disp2.dispatch();<br />
}<br />
else if (this.proximity == 1000)<br />
return;<br />
else<br />
this.mc.gotoAndStop(&#8216;_&#8217;+this.proximity );<br />
};<br />
};<br />
};</div>
<p align="justify">
<p align="justify">Agora vamos a classe controladora do jogo, optei por chamÃ¡-la de <strong>Game, </strong>ela  possui como um dos mÃ©todos principais um para posicionar bombas aleatoriamente no campo (mÃ©todo <em>prepare</em>()), tambÃ©m mÃ©todo para computar a proximidade de um quadrado (Square) de uma bomba (mÃ©todo <em>computeProximity()</em>). E um para criar o efeito de explosÃ£o em cadeia que Ã© visto no jogo de campo minado, ele ocorre quando vocÃª clica em uma posiÃ§Ã£o que nÃ£o estÃ¡ proximo de nunhuma bomba, este quadrado por sua vez explode todos os seus quadrados vizinhos num raio de um quadrado.</p>
<p align="justify">Se ele explodir um quadrado vizinho que tambÃ©m tem proximity igual a Zero, esse tambÃ©m realiza uma explosÃ£o em cadeia. Chamei este mÃ©todo de <em>armagedon()</em>. Podem abservar que todas as explosÃµes sÃ£o ativadas por eventos, e nÃ£o preciso varrer o campo para ir explodindo as bombas, elas se explodem &#8216;sozinhas&#8217;. Ã‰ como se eu fosse ligando um fio em cada uma e precisasse apertar apenas um botÃ£o para disparÃ¡-las, esse tipo de conceito ajuda em muitos tipos de jogos que existem diversos objetos para manipular. Veja a implementaÃ§Ã£o abaixo:</p>
<div id="codigo" title="AS">package<br />
{<br />
import flash.display.MovieClip;<br />
import flash.events.Event;<br />
import flash.events.MouseEvent;	public class Game extends MovieClip<br />
{<br />
/*armazena as bombas e suas informaÃ§Ãµes*/<br />
private var field:Array;</p>
<p>/*nÃºmero de bombas*/<br />
private var nBombs:Number;</p>
<p>/*dispachador de eventos*/<br />
private static var dispatcher:DispatcherObject;</p>
<p>private var listener:ListenerObject;</p>
<p>/*construtor da classe Game<br />
@param largura e altura do campo e nÃºmero de bombas<br />
*/<br />
function Game ( width:Number, height:Number, nBombs:Number )<br />
{<br />
this.nBombs 	= nBombs;</p>
<p>field = new Array(width);<br />
for (var i=0; i &lt; field.length; i++)<br />
field[i] = new Array(height);</p>
<p>dispatcher = new DispatcherObject(&#8216;MX&#8217;);</p>
<p>this.listener = new ListenerObject(&#8216;MX&#8217;);</p>
<p>this.listener.addDispatcher( Game.dispatcher, gameOver );<br />
}</p>
<p>function gameOver(event:Event)<br />
{<br />
for (var i =0; i &lt; field.length; i++)<br />
{<br />
for(var j=0; j &lt; field[i].length; j++)<br />
field[i][j].undoEvents();<br />
}<br />
}<br />
/*MÃ©todo responsÃ¡vel por mostrar um nÃºmero aleatÃ³rrio<br />
* entre min e max<br />
*/<br />
private function randRange(min:Number, max:Number)<br />
{<br />
return Math.floor(Math.random() * (max &#8211; min + 1)) + min;<br />
}</p>
<p>/* prepara o ambiente do jogo*<br />
* colocando bombas em locais aleatÃ³rios<br />
*/<br />
private function prepare()<br />
{<br />
var i = 0;<br />
var iAux = 0;<br />
var jAux = 0;</p>
<p>while ( i &lt; this.nBombs )<br />
{<br />
iAux = randRange(0, field.length-1);<br />
jAux = randRange(0, field[0].length-1);</p>
<p>if (!field[iAux][jAux])<br />
{<br />
field[iAux][jAux] = new Square ( new Mine(), true );<br />
i++;<br />
field[iAux][jAux].setDispatcher ( Game.dispatcher );<br />
this.addChild(field[iAux][jAux]);<br />
}</p>
<p>}</p>
<p>for (i =0; i &lt; field.length; i++)<br />
{<br />
for (var j = 0; j &lt; field[i].length; j++)<br />
{<br />
if ( !field[i][j] )<br />
{<br />
field[i][j] = new Square (new Mine(), false);<br />
this.addChild(field[i][j]);</p>
<p>}<br />
}<br />
}</p>
<p>}</p>
<p>/*inicia o jogo, prepara depois mostra na tela*/<br />
public function init()<br />
{<br />
prepare();<br />
display();</p>
<p>}<br />
/*MÃ©todo responsÃ¡vel mostar na tela*/<br />
private function display()<br />
{<br />
for (var i =0; i &lt; field.length; i++)<br />
{<br />
for(var j=0; j &lt; field[i].length; j++)<br />
{<br />
field[i][j].x = j*16;<br />
field[i][j].y = i*16;<br />
computeProximity(field, i , j);<br />
}<br />
}<br />
/* Aqui Ã© muito importante, pois Ã© aqui que sabemos<br />
* se o quadrado na posiÃ§Ã£o [i ,j] tem proximidade igual a 0<br />
* se tiver, fazemos todos os seus vizinhos escutar sua explosÃ£o<br />
* e se explodirem tambÃ©m<br />
*/<br />
for ( i =0; i &lt; field.length; i++)<br />
{<br />
for( j=0; j &lt; field[i].length; j++)<br />
armagedon(field, i , j);<br />
}<br />
}</p>
<p>/* MÃ©todo responsÃ¡vel por computar a proximidade de cada Square de uma bomba<br />
* o nÃºmero que aparece no campo minado quando vocÃª clica numa casa sem bomba<br />
*/<br />
private function computeProximity( arr:Array, i:Number, j:Number)<br />
{<br />
var proximity:Number = 0;</p>
<p>if( i-1 &gt;= 0 &#038;&#038; arr[i-1][j].isBomb())<br />
proximity++;<br />
if (i+1 &lt; arr.length &#038;&#038; arr[i+1][j].isBomb())<br />
proximity++;<br />
if (j-1 &gt;= 0 &#038;&#038; arr[i][j-1].isBomb())<br />
proximity++;<br />
if (j+1 &lt; arr[0].length &#038;&#038; arr[i][j+1].isBomb())<br />
proximity++;<br />
if (i-1 &gt;= 0 &#038;&#038; j-1 &gt;= 0 &#038;&#038; arr[i-1][j-1].isBomb())<br />
proximity++;<br />
if (i+1 &lt; arr.length &#038;&#038; j+1 &lt; arr[0].length &#038;&#038; arr[i+1][j+1].isBomb())<br />
proximity++;<br />
if (i+1 &lt; arr.length &#038;&#038; j-1 &gt;= 0 &#038;&#038; arr[i+1][j-1].isBomb())<br />
proximity++;<br />
if (i-1 &gt;= 0 &#038;&#038; j+1 &lt; arr[0].length &#038;&#038; arr[i-1][j+1].isBomb())<br />
proximity++;</p>
<p>arr[i][j].setProximity( proximity );<br />
}</p>
<p>/* Este mÃ©todo Ã© responsÃ¡vel por criar um espÃ©cie de explosÃ£o em cadeia<br />
*  Quando um quadrado nÃ£o estÃ¡ prÃ³ximo de nenhuma bomba ele explode todas<br />
* as bombas vizinhas, e estas por sua vez se tiverem proximity = 0 tambÃ©m<br />
* criam a mesma reaÃ§Ã£o em cadeia =)<br />
* @param arr =&gt; array de array (Matriz) analizada<br />
* @param i e j indÃ­ces da matriz<br />
*/<br />
private function armagedon( arr:Array, i:Number, j:Number)<br />
{<br />
if(arr[i][j].getProximity() == 0)<br />
{<br />
if( i-1 &gt;= 0 )<br />
arr[i-1][j].setDispatcherArm ( arr[i][j].disp2 );</p>
<p>if (i+1 &lt; arr.length )<br />
arr[i+1][j].setDispatcherArm ( arr[i][j].disp2 );</p>
<p>if (j-1 &gt;= 0 )<br />
arr[i][j-1].setDispatcherArm ( arr[i][j].disp2 );</p>
<p>if (j+1 &lt; arr[0].length )<br />
arr[i][j+1].setDispatcherArm ( arr[i][j].disp2 );</p>
<p>if (i-1 &gt;= 0 &#038;&#038; j-1 &gt;= 0 )<br />
arr[i-1][j-1].setDispatcherArm ( arr[i][j].disp2 );</p>
<p>if (i+1 &lt; arr.length &#038;&#038; j+1 &lt; arr[0].length )<br />
arr[i+1][j+1].setDispatcherArm ( arr[i][j].disp2 );</p>
<p>if (i+1 &lt; arr.length &#038;&#038; j-1 &gt;= 0 )<br />
arr[i+1][j-1].setDispatcherArm ( arr[i][j].disp2 );</p>
<p>if (i-1 &gt;= 0 &#038;&#038; j+1 &lt; arr[0].length )<br />
arr[i-1][j+1].setDispatcherArm ( arr[i][j].disp2 );</p>
<p>}<br />
}</p>
<p>};<br />
};</div>
<p align="justify">
<p align="justify">Agora Vamos ao cÃ³digo que realmente irÃ¡ instanciar a classe <strong>Game</strong> para fazer nosso jogo funcionar:</p>
<div id="codigo" title="AS">var game:Game;/* Novo jogo*/<br />
function newGame( event:MouseEvent)<br />
{</p>
<p>/* aqui removemos o jogo atual e inciamos um novo<br />
* e deixamos o resto do trabalho com a ActionScript<br />
* Virtual Machine, que Ã© o compilador do ECMA script usado<br />
* pelo flash e que possui um Ã³timo coletor de lixo<br />
*/<br />
if(event)<br />
removeChild(game);<br />
/* game de 25 linhas e 25 colunas, com 100 bombas*/<br />
game = new Game(25, 25, 100);</p>
<p>var isk:DisplayObject = null;</p>
<p>game.init();</p>
<p>/*adiciona o game a lista do root<br />
* posicionando no local adequado<br />
*/<br />
isk = addChild(game);<br />
isk.x = 0;<br />
isk.y = 48;</p>
<p>isk.width = 400;<br />
isk.height = 400;<br />
}</p>
<p>newGame(null);</p>
<p>/* aqui adicionamos o evento de clique do mouse no botÃ£o novo jogo*/<br />
newGame_btn.addEventListener(MouseEvent.CLICK, newGame);</div>
<p style="text-align: justify">Veja que eu quando inicio um novo jogo e descubro que acabou de ser realizado um outro simplesmente crio um novo, mas e os objetos criados no jogo anterior?? Para onde vÃ£o? Para quem nÃ£o sabe a mÃ¡quina virtual do flash 9 foi reimplementada e possui um Ã³timo coletor de lixo, que se encarrega de limpar esses espaÃ§os deixados sem referÃªncia.</p>
<h3>ConsideraÃ§Ãµes Finais</h3>
<p style="text-align: justify">Este Ã© o jogo, sÃ³ rodar e ver o resultado, aconselho estudar as classes de manipulaÃ§Ã£o de eventos elas ajudam bastante na hora de resolver um poblema. Usando esta idÃ©ia vocÃª poderÃ¡ criar outros jogos, use sua criatividade. NÃ£o pule etapas, se vocÃª estiver comeÃ§ando Ã© melhor comeÃ§ar a programar os jogos dos tutoriais iniciais de games. Tivemos que nos adptar a ausÃªncia do <strong>duplicateMovieClip</strong>, mas que foi suprida pela forma ainda mais fÃ¡cil de linkar o nome do mc como classe e apenas instanciar com o operador <em>new</em> o mc que se deseja duplicar, no nosso caso o mc <strong>Mine.</strong></p>
<p style="text-align: justify">NÃ£o tente criar jogos antes de saber programar vocÃª pode acabar se frustrando por nÃ£o conseguir, nos tutoriais mostro apenas como utilizar o que vocÃª sabe de Action Script 3.0  em jogos. Aqui apresentei uma forma de criar o game. VocÃª pode colocar novas funcionalidaes nele como timer, contador de acertos entre outros. Apenas fiz nÃºcleo do jogo, as inovaÃ§Ãµes ficam de desafio para vocÃªs. Depois postem no fÃ³rum as suas inovaÃ§Ãµes se vocÃªs quiserem para que possamos avaliar e jogar um pouco.</p>
<p><script type="text/javascript"><!--
FormatAS(new Array('AS'))
// --></script><br />
Espero que tenham gostado. AtÃ© a prÃ³xima.</p>
<p><strong>Autor: MÃ¡rcio Silva &#8211; Colunista de Flash &#038; ActionSctipt MXSTUDIO.</strong></p>
<p><a href="http://www.mxstudio.com.br/apoio/upload/campo_minado.zip">Download dos arquivos</a></p>
<p>Qualquer dÃºvida envie um e-mail para <a href="mailto:marciosilva@mxstudio.com.br" target="new">marciosilva@mxstudio.com.br</a> ou acesse nosso <a href="http://www.mxstudio.com.br/forum/index.php?showforum=127" target="forum">fÃ³rum</a></p>
<p><a href="http://www.marciosilva.net">www.marciosilva.net</a></p>
</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.mxstudio.com.br/desenvolvimento/flash/criacao_de_games___campo_minado_em_as3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Criação de Games &#8211; Simulação Física (Gravidade)</title>
		<link>http://www.mxstudio.com.br/desenvolvimento/flash/criacao_de_games___simulacao_fisica__gravidade_/</link>
		<comments>http://www.mxstudio.com.br/desenvolvimento/flash/criacao_de_games___simulacao_fisica__gravidade_/#comments</comments>
		<pubDate>Sun, 30 Sep 2007 00:00:00 +0000</pubDate>
		<dc:creator>Marcio Silva</dc:creator>
				<category><![CDATA[Flash]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Aprenda a fazer simula&#231;&#245;es em seus games deixando-os mais reais. C&#243;digo totalmente comentado.]]></description>
			<content:encoded><![CDATA[<p><script src="http://www.mxstudio.com.br/js/ColorCode.js"></script></p>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr>
<td id="colunaTexto" valign="top">
<h1>Criação de games &#8211; Simulação física (Gravidade)</h1>
<p>Olá comunidade MXSTUDIO,</p>
<p style="text-align: justify">Estou de volta com um tutorial que mostrar para você como utilizar a física na simulação de movimentos realísticos em seu game. Apresentarei o efeito em si, fica a seu cargo modificar o código para se adequar a seu jogo.</p>
<h3>Pré-requisitos:</h3>
<p style="text-align: justify">Conhecimento básico em ActionScript 2.0</p>
<p>Macromedia Flash 8</p>
<h3>Objetivo:</h3>
<p style="text-align: justify">O objetivo deste tutorial é que você, ao término dele possa entender como criar efeitos reais em seu game. O efeito que veremos é o da gravidade, a colisão inelástica e elástica de uma bola quando esta colide com uma parede, solo ou qualquer outra superfície. Todas neste tutorial podem ser acionadas apenas clicando na bolinha arrastando para jogá-la onde quiser. Veja abaixo o produto final de nosso tutorial:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="320" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="name" value="Megaman" /><param name="bgcolor" value="#FFF" /><param name="align" value="middle" /><param name="src" value="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_out07_gravidade_imagens/swf1.swf" /><embed type="application/x-shockwave-flash" width="550" height="320" src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_out07_gravidade_imagens/swf1.swf" align="middle" bgcolor="#FFF" name="Megaman"></embed></object></p>
<h3>Conceitos:</h3>
<p style="text-align: justify">Os conceitos que serão vistos aqui, são mais de aplicação da física em simulações que podem ser usadas para tornar seu game ainda mais legal e viciante. Dentre os conceitos que serão apresentados podemos destacar o da gravidade, coeficiente de restituição, colisão elástica e ineláslitca.</p>
<h3>Conteúdo</h3>
<p style="text-align: justify">Inicialmente baixe os arquivos que disponibilizei no final deste tutorial. Abra o Macromedia Flash 8 e crie um documento flash novo apertando CTRL + N. Agora crie um novo símbolo do tipo button apertando CTRL + F8, coloque o nome de <strong>bola_drag</strong>. Com o botão no modo de edição vá em <em>file -&gt; import -&gt; import to library. </em>Importe a imagem a imagem que está nos arquivos que você baixou, o arquivo se chama <strong>bola_golf.jpg</strong>. Quando importar a imagem irá aparecer na sua <em>library</em>, portanto arraste essa imagem para o centro do stage de edição do botão e posicione nos valores mostrados na figura abaixo::</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_out07_gravidade_imagens/img1.jpg" alt="ajustes" /><br />
<strong>Figura 1 </strong> &#8211; Dimensões e a posição da imagem</p>
<p align="justify">Pronto, insira novamente um novo símbolo do tipo <em>movie clip</em> e dê o nome <strong>bola</strong>. Com esse <strong>movie clip</strong> vazio aberto coloque ao centro o botão que acabamos de fazer, coloque o mesmo tamanho e posição que está na imagem acima. Depois de posicionar, dê um clique nesse botão <strong>bola_drag</strong> e coloque o seguinte código:</p>
<div id="codigo" title="AS">on (press)<br />
{<br />
arrastando = true;<br />
startDrag(this, true);<br />
}<br />
on (release, releaseOutside)<br />
{<br />
arrastando = false;<br />
stopDrag();<br />
}</div>
<p align="justify">Volte à cena principal e crie duas layers: uma chamada <strong>Action</strong> e outra chamada <strong>Bola, </strong>na layer chamada <strong>Bola</strong> você irá até a library e arrastar  o mc chamado <strong>bola</strong> que acabamos de fazer para o centro do stage, caso tenha dúvida olhe só como ficou a disposição das layers:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_out07_gravidade_imagens/img2.jpg" alt="layers" /><br />
<strong>Figura 2 </strong> &#8211; Layers da simulação .</p>
<p align="justify">Note também que na figura acima vc irá ver o <em>frame rate</em> que utilizei nesta simulação, coloquei 36 fps, quanto maior melhor fica a simulação. No frame 1 da layer <strong>Action</strong> coloque o seguinte código:</p>
<div id="codigo" title="AS">maxWidth = Stage.width-5;<br />
maxHeight = Stage.height-5;<br />
stop();</p>
<p align="justify"></div>
<p align="justify">Agora Vamos ao código que realmente faz a simulação física que implementaremos, o código mostrado a seguir implementa uma teoria vista em física, pretendo apenas mostrar um breve conceito do que o código faz, fica a seu cargo estudar mais a fundo essa teoria.</p>
<div id="codigo" title="AS">onClipEvent (load)</p>
<p>{<br />
gravidade = 10; // valor da gravidade<br />
restituicao = 0.89; //coeficiente de restituição<br />
raio = this._width/2; //raio da bolinha<br />
vx = 140; //valor inicial da velocidade em X<br />
vy = 140; //valor da velocidade inicial em Y<br />
}<br />
onClipEvent (enterFrame)<br />
{<br />
/*pega a ultima posição ocupada pela bolinha<br />
* no instante anterior ao corrente<br />
*/<br />
oldx = x;<br />
oldy = y;	/* armazena a atual posição da bolinha na tela*/<br />
x = this._x;<br />
y = this._y;</p>
<p>/* Verifica se o usuário está arrastanto a bolinha*/<br />
if (arrastando)<br />
{<br />
/*pega a variação de posição da bolinha*/<br />
vx = (x-oldx);<br />
vy = (y-oldy);<br />
}<br />
else<br />
{<br />
vy += gravidade; //aplica o efeito de gravidade<br />
x += (vx/10); //aplica a velocidade em X<br />
y += (vy/10); //aplica a velocidade em Y</p>
<p>/*Verificação de colisão com as bordas do Stage*/<br />
if (y &lt; raio) //SUPERIOR<br />
{<br />
y = raio;<br />
vx *= restituicao;<br />
vy *= -restituicao;//muda o sentido da velocidade em Y<br />
}<br />
if (y &gt; (_root.maxHeight-raio)) //INFERIOR<br />
{<br />
y = _root.maxHeight-raio;<br />
vx *= restituicao;<br />
vy *= -restituicao;<br />
}<br />
if (x &lt; raio) //ESQUERDA<br />
{<br />
x = raio;<br />
vx *= -restituicao;<br />
vy *= restituicao;<br />
}<br />
if (x &gt; (_root.maxWidth-raio)) //DIREITA<br />
{<br />
x = _root.maxWidth-raio;<br />
vx *= -restituicao;<br />
vy *= restituicao;<br />
}<br />
/* atualiza a posição da bolinha*/<br />
this._x = x;<br />
this._y = y;<br />
}<br />
}//adaptado flashGuru
</p></div>
<h4>Entendo o código</h4>
<p style="text-align: justify">As variáveis que o código utiliza são todas variáveis de expressões físicas. A <em><strong>gravidade</strong> </em>dispensa explicações; <em><strong>vx</strong></em> e <em><strong>vy </strong></em>são respectivamente velocidade no eixo x e y; <em><strong>raio</strong></em> é o raio da bolinha e por fim a <em><strong>restituicao</strong> </em>responsável pelo efeito &#8216;quicar&#8217; da bolinha. Formalizando essa variável restituição ela é obtida fazendo a divisão entre a velocidade <strong>v2</strong> depois da colisão com a velocidade <strong>v1</strong> antes da colisão. Veja abaixo várias formas de se obter o valor do coeficiente de restituição:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_out07_gravidade_imagens/img3.jpg" alt="ajustes" /><br />
<strong>Figura 3 </strong> &#8211; Formalização matemática</p>
<p style="text-align: justify">Minhas desculpas aos que não gostam de física ou matemática, mas é preciso dessa formalização para entender por que o código foi implemementado daquela forma. A diferença entre o código e a formalização é que já temos de antemão o valor do coeficiente de restituição e o valor da velocidade <strong>v1</strong> logo para obtermos a velocidade v2 que é após a colisão basta multiplicarmos a velocidade atual pelo coeficiente de restituição. As linhas 35, 36, 41, 42, 47, 48, 53 e 54 fazem exatamente o cálculo de v2 baseado na velocidade v1. E veja que o coeficiente somente é utilizado no cálculo da velocidade quando há uma colisão. O coeficiente é um número sem unidade, ou seja, é adimensional, variando entre 0 e 1.</p>
<p style="text-align: justify">Vejamos agora algumas curiosidades:</p>
<p style="text-align: justify">Com coeficiente de restituição igual a 1 temos que a bolinha nunca irá parar de bater nos limites da simulação. Pois a bolinha ao bater nos limites não irá perder sua velocidade.</p>
<p style="text-align: justify">
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="320" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="name" value="Megaman" /><param name="bgcolor" value="#FFF" /><param name="align" value="middle" /><param name="src" value="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_out07_gravidade_imagens/swf4.swf" /><embed type="application/x-shockwave-flash" width="550" height="320" src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_out07_gravidade_imagens/swf4.swf" align="middle" bgcolor="#FFF" name="Megaman"></embed></object></p>
<p style="text-align: justify">Agora coeficiente maior que 1, a bolinha ganha velocidade.</p>
<p style="text-align: justify">
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="320" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="name" value="Megaman" /><param name="bgcolor" value="#FFF" /><param name="align" value="middle" /><param name="src" value="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_out07_gravidade_imagens/swf2.swf" /><embed type="application/x-shockwave-flash" width="550" height="320" src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_out07_gravidade_imagens/swf2.swf" align="middle" bgcolor="#FFF" name="Megaman"></embed></object></p>
<p style="text-align: justify">Gravidade com sinal modificado, ou seja, as coisas agora caem pra cima.</p>
<p style="text-align: justify">
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="320" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="name" value="Megaman" /><param name="bgcolor" value="#FFF" /><param name="align" value="middle" /><param name="src" value="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_out07_gravidade_imagens/swf3.swf" /><embed type="application/x-shockwave-flash" width="550" height="320" src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_out07_gravidade_imagens/swf3.swf" align="middle" bgcolor="#FFF" name="Megaman"></embed></object></p>
<p style="text-align: justify">E por fim sem gravidade. A bolinha vai batendo nos limites até parar sem cair.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="320" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="name" value="Megaman" /><param name="bgcolor" value="#FFF" /><param name="align" value="middle" /><param name="src" value="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_out07_gravidade_imagens/swf5.swf" /><embed type="application/x-shockwave-flash" width="550" height="320" src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_out07_gravidade_imagens/swf5.swf" align="middle" bgcolor="#FFF" name="Megaman"></embed></object></p>
<h3>Considerações Finais</h3>
<p style="text-align: justify">Bom espero que tenham entendido um pouco dessa aula de física, pois para programar um efeito desse é preciso que se entenda pelo menos o básico, com certeza com o que foi mostrado aqui neste tutorial somado a sua criatividade muitos games legais podem ser feitos. Modifique os valores das variáveis do problema e observe os resultados como eu fiz acima.</p>
<p><script type="text/javascript"><!--
FormatAS(new Array('AS'))
// --></script><br />
Espero que tenham gostado. Até a próxima.</p>
<p><strong>Autor: Márcio Silva &#8211; Colunista de Flash &amp; ActionSctipt MXSTUDIO.</strong></p>
<p><a href="http://www.mxstudio.com.br/apoio/upload/gravidade.zip">Download dos arquivos</a></p>
<p>Qualquer dúvida envie um e-mail para <a href="mailto:marciosilva@mxstudio.com.br" target="new">marciosilva@mxstudio.com.br</a> ou acesse nosso <a href="http://www.mxstudio.com.br/forum/index.php?showforum=127" target="forum">fórum</a></td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.mxstudio.com.br/desenvolvimento/flash/criacao_de_games___simulacao_fisica__gravidade_/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Criação de Games &#8211; Megaman Parte 2</title>
		<link>http://www.mxstudio.com.br/desenvolvimento/flash/criacao_de_games___megaman_parte_2/</link>
		<comments>http://www.mxstudio.com.br/desenvolvimento/flash/criacao_de_games___megaman_parte_2/#comments</comments>
		<pubDate>Sat, 28 Jul 2007 00:00:00 +0000</pubDate>
		<dc:creator>Marcio Silva</dc:creator>
				<category><![CDATA[Flash]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Continua&#231;&#227;o da desenvolvimento do game Megaman, abordagem de novos conceitos em jogos de plataforma.]]></description>
			<content:encoded><![CDATA[<p><script src="http://www.mxstudio.com.br/js/ColorCode.js"></script></p>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr>
<td id="colunaTexto" valign="top">
<h1>Criação de games &#8211; Megaman Parte 2</h1>
<p>Olá comunidade,</p>
<p style="text-align: justify">Estou de volta trazendo a continuação do tutorial de criação de games &#8211; Megaman, tendo como foco a criação de um game de plataforma. Na primeira parte do tutorial, <a href="http://www.mxstudio.com.br/views.tutorial.php?act=view&amp;cid=3&amp;aid=1128">Criação de Games &#8211; Megaman parte 1</a>, aprendemos algumas técnicas como a utilização de sprites, fizemos uma simulação do pulo do personagem, o tão prucurado scrolling da tela que cuja a idéia é bem tranquila e os princípios básicos de construção de jogos de plataforma. Portanto, assumo desde de já que você já possui os pré-requisitos listados abaixo.</p>
<h3>Pré-requisitos:</h3>
<p style="text-align: justify">Conhecimento básico em ActionScript<br />
Macromedia Fireworks 8<br />
Macromedia Flash 8<br />
Recomenda-se que você tenha visto a coluna de movimentação básica de personagens e princípios básicos de games de plataforma, caso não tenha acesse:</p>
<p><a href="http://www.mxstudio.com.br/views.tutorial.php?act=view&amp;cid=3&amp;aid=1070">Criação de Games</a><br />
<a href="http://www.mxstudio.com.br/views.tutorial.php?act=view&amp;cid=3&amp;aid=1128">Criação de Games &#8211; Megaman parte 1</a></p>
<h3>Objetivo:</h3>
<p style="text-align: justify">O abjetivo desta segunda parte é a inclusão de novos elementos dentro do nosso joguinho, lembrando que é o básico, use sua imaginação para deixar o joguinho ainda mais interessante. Como o interesse aqui é puramente o aprendizado, não estamos desenvolvendo um jogo comercial que necessita de mais otimizações. No entanto, uma vez que assimilado todos os conceitos apresentados, conseguirá facilmente desenvolver seus jogos de forma comercial. A construção das animações é feita ação a ação do personagem, para cada ação um movie clip diferente, é claro que é possivel criar um único mc que pode ser controladoo via <em>Action Script</em>, mas vamos aprender uma coisa de cada vez. Veja o jogo pronto:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="320" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="name" value="Megaman" /><param name="bgcolor" value="#000000" /><param name="align" value="middle" /><param name="src" value="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/Megaman.swf" /><embed type="application/x-shockwave-flash" width="550" height="320" src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/Megaman.swf" align="middle" bgcolor="#000000" name="Megaman"></embed></object></p>
<h3>Conceitos:</h3>
<p style="text-align: justify">Apresentarei neste artigo noções legais como como fazer o tiro que o Megaman vai disparar, a temporização destes tiros, um timer para marcar o tempo de jogo, a inclusão de inimigos no cenário e um pouquinho sobre IA em games. Logo nosso jogo estará completo com os itens básicos para este tipo de game.</p>
<h3>Conteúdo</h3>
<p style="text-align: justify">Já vou supor que você tenha visto o artigo anterior caso não tenha acesse (<a href="http://www.mxstudio.com.br/views.tutorial.php?act=view&amp;cid=3&amp;aid=1128">Criação de Games &#8211; Megaman parte 1</a>), agora iremos adicionar ao projeto anterior, os elementos mencionados acima (tiro, timer, inimigos&#8230;). Para isso, abra o arquivo do jogo que fizemos no último artigo e vamos lá!</p>
<p align="justify">Primeiramente, vamos construir os tiros que serão dados tanto pelo megaman quanto pelos seus inimigos. Insira um novo símbolo do tipo <em>movie clip</em>, chame-o de <strong>tiro_mega</strong>, ao fim deste tutorial segue um link para que baixem as imagens que utilizei ou <a href="http://www.mxstudio.com.br/apoio/upload/files_megaman.zip">clique aqui para baixar</a>. Da mesma forma que o outro artigo monte a animação do tiro baseado na folha de sprites abaixo:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/img1.gif" alt="entrada do jogo" /><br />
<strong>Figura 1 </strong> &#8211; Folha de sprites para o <strong>tiro_mega</strong>.</p>
<p align="justify">Depois do <em>movie clip</em> pronto, volte para a cena e arraste-o da <em>library, </em>se ela não estiver aparecendo aperte CTRL + L. Iremos implementar as ações do tiro semelhante ao que eu fiz no meu primeiro turorial, aquele da nave. Então, devemos posicionar esse tiro fora do stage, redimensione o seu tamanho para 15px de altura e 15px de largura, chame essa instância de <strong>tiro_mc</strong>. Veja abaixo como posicionei no stage.</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/img2.gif" alt="entrada do jogo" /><br />
<strong>Figura 2 </strong> &#8211; Posição inicla adequada para o <strong>tiro_mega</strong>.</p>
<p align="justify">Agora vamos programar as ações desse tiro. Selecione o <em>movie clip</em> <strong>tiro_mc</strong> e aperte F9 para editar seu <em>Action Script </em>onde os inimigos que estão sendo referenciados no código serão criados nos passos seguintes<em>, </em>o código segue abaixo:</p>
<div id="codigo" title="AS">onClipEvent( enterFrame )<br />
{<br />
if(_name != &#8220;tiro_mc&#8221;)<br />
{<br />
//verifica colisão com inimigo 1<br />
if(this.hitTest(_root.terreno_mc.inimigo_1_mc))<br />
{<br />
_root.terreno_mc.inimigo_1_mc.barra_mc._xscale -= 5;<br />
this.removeMovieClip();<br />
}<br />
else<br />
{<br />
if(direcao == &#8220;direita&#8221;)<br />
this._x += 25;<br />
else<br />
this._x -= 25;			if(this._x &gt;2000 || this._x &lt; -5)<br />
this.removeMovieClip();<br />
}<br />
}<br />
}</div>
<p align="justify">Também precisaremos de um tiro que será dado por um dos inimigos do megaman que será feito mais a frente. O processo é o mesmo, pegue a folha de sprites, insira um novo movie clip vazio e chame-o de <strong>tiro_2</strong>, depois da animação pronta, volte à cena e arraste-o da <em>library</em> para o stage e dê o nome de instância de <strong>tiro_fogo_mc. </strong>Veja abaixo como ficou:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/img9.gif" alt="entrada do jogo" /><br />
<strong>Figura 3 </strong> &#8211; Folha de sprites para <strong>tiro_2</strong>.</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/img10.gif" alt="entrada do jogo" /><br />
<strong>Figura 4 </strong> &#8211; Veja o posicionamento na cena.</p>
<p align="justify">O código para este tiro segue abaixo com algumas modificações para testar a colisão com o megaman em vez do inimigo, claro. E se o life do megaman chegar ao fim vai para frame 3 ou frame de Game Over. Eu chamei de <strong>gameOver</strong> o último frame da layer terreno.</p>
<div id="codigo" title="AS">onClipEvent( enterFrame )<br />
{<br />
if(_name != &#8220;tiro_fogo_mc&#8221;)<br />
{<br />
if(_root.life_mc._xscale &lt;= 0)<br />
{<br />
_root.gotoAndStop(&#8220;gameOver&#8221;);		}<br />
if(this.hitTest(_root.megaman_mc))<br />
{<br />
_root.life_mc._xscale -= 5;<br />
this.removeMovieClip();<br />
}<br />
else<br />
{<br />
if(direcao == &#8220;direita&#8221;)<br />
this._x += 25;<br />
else<br />
this._x -= 25;</p>
<p>if(this._x &gt;2000 || this._x &lt; -5)<br />
this.removeMovieClip();<br />
}<br />
}<br />
}
</p></div>
<p align="justify">
<p align="justify">Note que existe uma variável direcao que não foi declarada em lugar nenhum e está sendo usada em nosso AS dos dois tiros, ela foi criada no arquivo <strong>Megaman.as. </strong>Portanto, abra-o e insira o seguinte código nas linhas iniciais onde são declaradas as variáveis utilizadas no nosso game, aproveite e declare variáveis de controle que servirão para controlar o número de tiros e o tempo de intervalo entre cado tiro, veja abaixo como ficou.</p>
<div id="codigo" title="AS">stop();<br />
/* Variáveis globais<br />
* Aqui estão presentes as variáveis que fazem o<br />
* controle dos estados<br />
* em que o jogo se encontra<br />
*/<br />
var velSaltar:Number = 20;<br />
var velAndar:Number = 0;<br />
var pulando:Boolean = false;<br />
var caindo:Boolean = false;<br />
var morreu:Boolean = false;<br />
var velMax:Number = 10;<br />
var direcao:String = &#8220;&#8221;;<br />
var entrada:Boolean = true;<br />
var contTiros:Number = 0; /*Contador de tiros*/<br />
var tiroInterval:Number = getTimer(); /*utilizada para calcular o intervalo dos tiros*/<br />
/*adiciona à classe MovieClip um atributo que indica a direção para onde está indo*/<br />
MovieClip.prototype.direcao = &#8220;esquerda&#8221;;<br />
.<br />
.<br />
.</div>
<p align="justify">Agora vamos construir um timer que ficará contando o tempo, vai ser um timer bem simples em termos de beleza, mas que você poderá facilmente customizá-lo a seu gosto. Primeiramente insira um campo texto na parte superior central do nosso stage, sinta-se à vontade em colocar onde achar mais adequado dentro do stage a localização não vai influenciar, e mude suas propriedades para que seja um campo texto do tipo dinâmico. Mais algumas linhas serão adicionadas no arquivos Megaman.as, como já temos o tiro em mãos e uma variável que controla o intervalo de tempo dos tiros, podemos implementar a ação de disparar tiros. Abaixo está o código que implementa o disparo.</p>
<div id="codigo" title="AS">.<br />
.<br />
.<br />
//só pula se não tiver pulando, claro<br />
if ( Key.isDown(Key.SPACE) &amp;&amp; !pulando )<br />
{<br />
pulando = true;		/*mostra a animação pulando para direita se o personagem<br />
* está indo para a direita, caso contrário para a esquerda<br />
*/</p>
<p>if(direcao == &#8220;direita&#8221;)<br />
megaman_mc.gotoAndStop(&#8220;pulando_dir&#8221;);<br />
else<br />
megaman_mc.gotoAndStop(&#8220;pulando_esq&#8221;);<br />
}<br />
/*########### Novas Linhas adicionadas ##########*/<br />
tempo = Math.round(getTimer()/1000);<br />
_root.tempo_txt.text = tempo;</p>
<p>if( Key.isDown( Key.CONTROL) &amp;&amp; (getTimer() &#8211; tiroInterval) &gt; 200 )<br />
{<br />
_root.contTiros++;<br />
_root.tiro_mc.duplicateMovieClip(&#8220;tiro&#8221;+_root.contTiros,_root.contTiros,_root.contTiros); //duplicamos o tiro<br />
if(direcao == &#8220;direita&#8221;)<br />
{<br />
if(!Key.isDown( Key.RIGHT) )<br />
this.gotoAndStop(&#8220;atirando_dir&#8221;);<br />
_root["tiro"+_root.contTiros]._y = this._y+35;<br />
_root["tiro"+_root.contTiros]._x = this._x+50;</p>
<p>}<br />
else<br />
{<br />
if(!Key.isDown( Key.LEFT) )<br />
this.gotoAndStop(&#8220;atirando_esq&#8221;);<br />
_root["tiro"+_root.contTiros]._y = this._y+35;<br />
_root["tiro"+_root.contTiros]._x = this._x-10;<br />
}</p>
<p>tiroInterval = getTimer();</p>
<p>/*atribuindo direcao para o tiro*/<br />
_root["tiro"+_root.contTiros].direcao = direcao;<br />
atirando = true;</p>
<p>}<br />
/*#################################################*/<br />
if( Key.isDown( Key.LEFT) )</p>
<p>.<br />
.<br />
.
</p></div>
<p>Agora vamos adicionar os inimigos. Neste artigo vou adicionar apenas 2 inimigos para que você tenha uma noção de como implementar uma pequena Inteligência Artificial (IA) nos seus inimigos, a implementação de IA em games pode ser feita de diversas formas, aqui apresentarei uma idéia bem simples onde você poerá usar sua criatividade e implementá-la de uma forma mais rebuscada.</p>
<p>O primeiro Inimigo está representado no gif abaixo:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/img3.gif" alt="entrada do jogo" /><br />
<strong>Figura 5 </strong> &#8211; Primeiro inimigo.</p>
<p align="justify">Uma forma de utilizar sprites foi visto na último artigo, era baseada na folha de sprites onde tinhamos que colocar um a um os sprites em cada frame. Agora veremos outra forma de usar sprites a partir de gif&#8217;s animados. Com uma imagem gif pronta é fácil obter seus sprites pelo flash que fará sozinho o processo da passagem da animação para o <em>timeline</em>. Primeiro vamos criar um <em>movie clip</em> vazio e chame-o de <strong>inimigo1. </strong>Agora vá no menu <em>arquivo -&gt;import</em> -&gt;<em>import to stage</em> ou simplesmente CTRL + R e selecione o arquivo <strong>img3.gif</strong> que forneci no link ao fim deste artigo. Clique em abrir e automaticamente o flash fará o milagre de colocar cada quadro da animação no seu respectivo frame. Que bacana hein!.</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/img4.gif" alt="Timeline e o stage depois do import." /><br />
<strong>Figura 6 </strong> &#8211; Timeline e o stage depois do import.</p>
<p align="justify">Vamos criar agora o outro inimigo, volte ao <em>stage</em> e insira um novo <em>movie clip</em> chamado <strong>inimigo2, </strong>abaixo segue a imagem do nosso inimigo número 2:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/img5.gif" alt="inimigo número 2" /><br />
<strong>Figura 7 </strong> &#8211; Segundo inimigo.<strong>img5.gif</strong></p>
<p>Depois que ocoreu o import seu time e stage devem ficar assim:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/img6.gif" alt="Timeline e o stage depois do import." /><br />
<strong>Figura 8 </strong> &#8211; Timeline e o stage depois do import da segunda imagem.</p>
<p align="justify">Agora com as animações bases prontas iremos criar o mc que iremos controlar via <em>Action Script. </em>Portanto, na cena principal insira um novo mc chamado <strong>inimigo_1</strong><strong>. </strong>Neste mc,  crie duas <em>layers</em> uma chamada <strong>barra</strong> e outra chamada <strong>imagem</strong>. Na <em>layer</em> <strong>imagem</strong>, no primeiro frame desta <em>layer</em> coloque o mc que fizemos agora pouco chamado <strong>inimigo1</strong> chame este primeiro frame de<strong> esquerda </strong>(aperte F9 neste frame e coloque um stop(); no Action Script) e o segundo desta mesma layer de <strong>direita</strong> e o terceiro frame chame de <strong>morto, </strong>este último indica o estado de quando sua barra de força chegar ao fim<strong>. </strong>O mc <strong>inimigo1</strong> já está direcionado para a esquerda, como foi visto no artigo anterior basta usar a ferramenta <em>Free Transform Tool</em> para inverter a direção. Para mais detalhes veja o artigo anterior, e no frame <strong>morto</strong> não coloque nada deixe-o em branco sem nada no stage. Fica aqui como um teste criar uma animação de explosão ou qualquer coisa que pareça que o inimgo explodiu.</p>
<p>Agora  vamos construir a barra de life do <strong>inimigo_1, </strong>na sua layer <strong>barra, </strong>usando a ferramenta <em>Rectangle Tool</em> desenhe um retângulo acima da cabeça do personagem de forma que esse desenho pertença à layer <strong>barra</strong>, transforme essa barra em mc apenas selecionando e apertando F8 chamando-a de <strong>barra_life. </strong>Por fim dê o nome de instância de <strong>barra_mc. </strong>Depois de todo esse processo com o primeiro frame selecione aperte F6 para criar um <em>key Frame</em> cópia do primeiro.  Após todo esse processo veja como ficou:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/img7.gif" alt="Inimigo 1 no stage." /><br />
<strong>Figura 9 </strong> &#8211; Inimigo 1 no stage e seus respectivos frames.</p>
<p>Para fazer o outro inimigo você vai aplicar o mesmo processo, volte à cena principal e crie um movie clip chamado <strong>inimigo_2</strong>, crie as mesma layers e dê o mesmo nome pra elas. Utilize o mc <strong>inimigo2</strong> para fazer a animação para a esquerda e inverta o mc para fazer a animação para direita. Coloque também o <em>stop()</em> no primeiro frame da <em>layer</em> imagem e barra de life não precisa fazer por que ela já está pronta na <em>library. </em>Basta arrastá-la para o primeiro frame da <em>layer</em> barra e dar o nome novamente de intância de <strong>barra_mc</strong> e apertar F6 com o primeiro frame selecionado para fazer uma cópia para o segund<em>o</em>.</p>
<p align="justify">Depois de criado esses dois mc&#8217;s volte para a cena principal e dê um duplo clique no mc <strong>terreno_mc</strong>, assim ele será aberto para edição e é aqui que vamos colocar nossos inimigos. Mas você poderia ter imaginado colocá-los diretamente na cena criando uma nova layer, por exemplo chamada de inimigos; isso sim é possível mas é inviável dependendo do número de inimigos no cenário por que será complicado aplicar o <em>scrolling</em> em todos esses objetos. Continuando, com o <strong>terreno_mc</strong> aberto para edição arraste o mc <strong>inimigo_1</strong> da <em>library</em> para o stage. Dê o nome de instância de <strong>inimigo_1_mc</strong>. A posição onde vai ficar o seu inimigo depende de como você vai programar seu <strong>Action Script</strong> de modo que ele não ultrapasse barreiras que ele não possa ou estipular limites até onde possa ir, eu estipulei um valor máximo e um valor mínimo para que o personagem possa andar no eixo x. Dê um clique seu <strong>inimigo_1_mc</strong> e com ele selecionado aperte F9 para programá-lo com o código abaixo:</p>
<div id="codigo" title="AS">onClipEvent(load)<br />
{<br />
/*velocidade inicial do inimigo_1_mc*/<br />
var speed = 2;<br />
}onClipEvent(enterFrame)<br />
{<br />
/*não tem mais barra de life, então morreu*/<br />
if(this.barra_mc._xscale &lt;=0)<br />
this.gotoAndStop(&#8220;morto&#8221;);<br />
else<br />
{<br />
/*pequena simulação de inteligência artificial*/<br />
atack = Math.random();<br />
if(this.hitTest(_root.megaman_mc))<br />
_root.life_mc._xscale -= .5;<br />
/*realiza um ataque se o número randômico for divisível por 15*/<br />
if(Math.round(atack*10000) % 15 == 0)<br />
speed = 10;<br />
/*persegue o megaman*/<br />
if(_root.megaman_mc._x &gt; _root.terreno_mc._x+this._x)<br />
{<br />
this.gotoAndStop(&#8220;direita&#8221;);<br />
this._x +=speed;<br />
}<br />
else<br />
{<br />
this.gotoAndStop(&#8220;esquerda&#8221;);<br />
this._x -=speed;<br />
}<br />
if(this._x &lt; 100)<br />
this._x +=speed;<br />
else if(this._x &gt; 600)<br />
this._x -=speed;<br />
speed = 2;</p>
<p>if(speed &gt; 100)<br />
speed = 0;<br />
}<br />
}
</p></div>
<p align="justify">No código acima fiz com que o inimigo fique fazendo umas aceleradas para frente como se fosse um ataque e o código também faz com o inimigo fique sempre andando atrás do megaman se este estiver na sua linha de ataque. Cada vez que o <strong>inimigo_1_mc</strong> encosta no megaman ele tira 0.5 do life.</p>
<p align="justify">Para o <strong>inimigo_2_mc</strong> algumas adaptações  são necessárias no código acima, primeiro eu admiti que não vou diminuir o life do megaman quando encostar neste inimigo só o tiro que este dará que vai diminuir, o intervalo x que o <strong>inimigo_2_mc</strong> pode andar também é diferente eu o coloquei na parte final da fase. E também atualizo a variável <strong>direcao</strong> para eu saber para onde este inimigo vai atirar. A imagem de como fica no stage  depois desse processo de montagem das animações do personagem e o código seguem abaixo:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/img8.gif" alt="Inimigo 2 no stage." /><br />
<strong>Figura 10 </strong> &#8211; Inimigo 2 no stage e seus respectivos frames.</p>
<div id="codigo" title="AS">onClipEvent(load)<br />
{<br />
/*velocidade inicial do inimigo_2_mc*/<br />
var speed = 2;<br />
}onClipEvent(enterFrame)<br />
{<br />
/*não tem mais barra de life, então morreu*/<br />
if(this.barra_mc._xscale &lt;=0)<br />
this.gotoAndStop(&#8220;morto&#8221;);<br />
else<br />
{<br />
/*pequena simulação de inteligência artificial*/<br />
atack = Math.random();<br />
if(this.hitTest(_root.megaman_mc))<br />
_root.life_mc._xscale -= .5;<br />
/*realiza um ataque se o número randômico for divisível por 15*/<br />
if(Math.round(atack*10000) % 15 == 0)<br />
speed = 10;<br />
/*persegue o megaman*/<br />
if(_root.megaman_mc._x &gt; _root.terreno_mc._x+this._x)<br />
{<br />
this.gotoAndStop(&#8220;direita&#8221;);<br />
direcao = &#8220;direita&#8221;;<br />
this._x +=speed;<br />
}<br />
else<br />
{<br />
this.gotoAndStop(&#8220;esquerda&#8221;);<br />
direcao = &#8220;esquerda&#8221;;<br />
this._x -=speed;<br />
}<br />
if(this._x &lt; 1446)<br />
this._x +=speed;<br />
else if(this._x &gt; 2040)<br />
this._x -=speed;<br />
speed = 2;</p>
<p>if(speed &gt; 100)<br />
speed = 0;<br />
}<br />
}
</p></div>
<p align="justify">
<p align="justify">Vale ressaltar que o código das ações desses inimigos são os que podem mais serem implementados de forma diferente, eu optei para as ações da forma que está acima codificada, o <strong>inimigo_1_mc</strong> com o corpo e <strong>inimigo_2_mc</strong> ataca com um tiro de fogo. Lembre-se que ambos estão no mc <strong>terreno_mc</strong>.</p>
<p align="justify">Por fim vamos fazer a personagem que voa disparar o tiro de fogo que fizemos acima, vá a sua library e procure pelo mc <strong>inimigo2</strong> que está na <strong>figura 8. </strong>Insira o código abaixo no <em>frame</em> 25, mas por que no frame 25? Se você observar a animação é nesse frame que a personagem sofre uma espécie de solavanco devido a um tiro que de forma imaginária ela tenha dado.</p>
<div id="codigo" title="AS">_root.contTiros++;	_root.tiro_fogo_mc.duplicateMovieClip(&#8220;tiro&#8221;+_root.contTiros,_root.contTiros,_root.contTiros); //duplicamos o tiro</p>
<p>x_terreno = _root.terreno_mc._x;<br />
x_inimigo = _root.terreno_mc.inimigo_2_mc._x;</p>
<p>/*Verifica para onde ela está olhando e atira*/<br />
if(_root.terreno_mc.inimigo_2_mc.direcao == &#8220;direita&#8221;)<br />
{<br />
_root["tiro"+_root.contTiros].direcao = &#8220;direita&#8221;;<br />
_root["tiro"+_root.contTiros]._y = _root.terreno_mc.inimigo_2_mc._y+58;<br />
_root["tiro"+_root.contTiros]._x = x_terreno + x_inimigo+90;<br />
}<br />
else<br />
{<br />
_root["tiro"+_root.contTiros].direcao = &#8220;esquerda&#8221;;<br />
_root["tiro"+_root.contTiros]._y = _root.terreno_mc.inimigo_2_mc._y+58;<br />
_root["tiro"+_root.contTiros]._x = x_terreno + x_inimigo+10;<br />
_root["tiro"+_root.contTiros]._xscale = &#8211; 2*_root["tiro"+_root.contTiros]._width;<br />
}
</p></div>
<p>Você conseguiu entender a linha 17 deste código? Sim? Não? O que ela faz? Até agora quando a gente desejava que um personagem ficasse virado para os dois sentidos criávamos duas frames e depois utilizando a ferramenta <em>Free Transform Tool</em> invertia o sentido da figura da esquerda para a direita ou vice e versa. Agora fizemos essa inversão via <em>Action Script</em> com uma linha de código, o mais impressionante é que funciona.</p>
<p>Falei muito de uma tal barra de life do megaman mais ainda não fizemos. Então, vá ao stage da cena e cria um retângulo da cor que quiser parecido com o que foi feito para os inimigos, transforme em movie clip chamando-o de <strong>barra</strong> dê o nome de instância de <strong>life_mc</strong>. Posicione no topo um pouco à direita perto do timer e se prefeir coloque uma imagem do megaman que você desejar ao lado do life só pra ficar claro que aquele life é do megaman. Veja como ficou:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/img11.gif" alt="entrada do jogo" /><br />
<strong>Figura 11 </strong> -Posição do life e o primeiro inimigo.</p>
<p align="justify">Por último só falta fazer as animação do megaman atirando e o código que fará ele disparar os tiros. Para fazer a animação vamos usar o arquivo de imagens que segue logo ao fim desse artigo. Lá tem várias imagens do megaman atirando correndo e tudo mais. Acredito que você já está ficando bom nesse processo de copiar e colar para montar animações. Use a folha de sprite abaixo, OBS: eu não usei toda a sequência de animação para fazer ele atirando, usei apenas os prites que estão abaixo.</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/img12.gif" alt="entrada do jogo" /><br />
<strong>Figura 12 </strong> &#8211; Folha de sprites para atirando parado.</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart2_imagens/img13.gif" alt="entrada do jogo" /><br />
<strong>Figura 13 </strong> &#8211; Folha de sprites para atirando correndo.</p>
<p align="justify">Os dois mc&#8217;s vazios que você irá criar para fazer as animações vão se chamar respectivamente <strong>atirando</strong> e <strong>atirando_correndo. </strong>Agora iremos incorporar esses mc&#8217;s ao megaman propriamente dito que é aquele que está no stage e que estamos controlando via <em>Action Script</em> e que se chama <strong>megaman_mc</strong>. Portanto, vá à cena principal e dê um duplo clique no <strong>megaman_mc</strong> e adicione mais 4 <em>frames </em>aos frames existentes e chame-os respectivamente de: <strong>atirando_dir</strong>, <strong>atirando_esq</strong>, <strong>correndo_atirando_dir</strong> e <strong>correndo_atirando_esq. </strong>Cuidado com esses nomes sempre utilizo para referenciá-los no <em>Action Script</em>. As animações para os frames <strong>atirando_dir</strong> e <strong>correndo_atirando_dir</strong> já estão pronta (<strong>atirando</strong> e <strong>atirando_correndo</strong>), ou seja, a direção em que o personagem está olhando já está correta. Para fazer as animações para esquerda será usada a mesma técnica que consistia em usar a ferramenta <em>Free Transform Tool</em> para inverter o sentido da animação que já está pronta, se tiver ainda dúvidas quanto a esta parte consulte novamente a parte 1 deste artigo.</p>
<p align="justify">Depois de cada coisa no seu lugar, você agora precisa apenas colocar o seguinte código no último frame do mc <strong>atirando </strong>para que quando você atirar saiba para que lado deva parar e de tirar <strong>:</strong></p>
<div id="codigo" title="AS">_root.atirando = false;<br />
if(_root.direcao == &#8220;direita&#8221;)<br />
_parent.gotoAndStop(&#8220;parado_dir&#8221;);<br />
else<br />
_parent.gotoAndStop(&#8220;parado_esq&#8221;);
</div>
<p>E para o mc <strong>atirando_correndo</strong> coloque no último frame:</p>
<div id="codigo" title="AS">_root.atirando = false;<br />
É moçada, agora falta apenas o código do coração do nosso game com as novas modificações e com a parte de tiros, com a possibilidade de correr atirando e pular atirando todas já incorporadas no código, então aí está:</p>
<div id="codigo" title="AS">stop();<br />
/* Variáveis globais<br />
* Aqui estão presentes as variáveis que fazem o<br />
* controle dos estados<br />
* em que o jogo se encontra<br />
*/<br />
var velSaltar:Number = 20;<br />
var velAndar:Number = 0;<br />
var pulando:Boolean = false;<br />
var caindo:Boolean = false;<br />
var morreu:Boolean = false;<br />
var atirando:Boolean = false;<br />
var velMax:Number = 10;<br />
var direcao:String = &#8220;&#8221;;<br />
var entrada:Boolean = true;<br />
var contTiros:Number = 0; /*Contador de tiros*/<br />
var tiroInterval:Number = getTimer(); /*utilizada para calcular o intervalo dos tiros*/<br />
/*adiciona à classe MovieClip um atributo que indica a direção para onde está indo*/<br />
MovieClip.prototype.direcao = &#8220;esquerda&#8221;; /*fazemos com que as layers que representam as paredes<br />
* e a plataforma não apareçam na hora que<br />
* o jogo for executado<br />
*/<br />
plataforma_mc._visible = false;<br />
paredes_mc._visible = false;</p>
<p>/* Todo o controle do personagem Megaman*/<br />
megaman_mc.onEnterFrame = function()<br />
{<br />
//verifica se ainda não acabou a entrada do Megaman<br />
if(entrada)<br />
return;</p>
<p>if(this._y &gt; 350)<br />
_root.gotoAndStop(&#8220;gameOver&#8221;);<br />
/*verifica colisão com alguma parede do lado direito ou esquerdo<br />
* Se houve colisão faz uma anulação do passo que ele deu para frente<br />
*/<br />
if( colisao_paredes(_root.paredes_mc, this, velAndar))<br />
this._x-=velAndar;<br />
/* simples simulação de gravidade<br />
* Se ele não tiver em cima da plataforma então ele vai caindo<br />
* sem aceleração<br />
*/</p>
<p>if ( !colisao_plataforma(_root.plataforma_mc, this) &amp;&amp; !pulando)<br />
this._y += 6;</p>
<p>//se velocidade positiva estou andando para a<br />
//direita senão estou indo para esquerda<br />
if (velAndar&gt;0)<br />
direcao = &#8220;direita&#8221;;<br />
else if (velAndar&lt;0)<br />
direcao = &#8220;esquerda&#8221;;</p>
<p>//só pula se não tiver pulando, claro<br />
if ( Key.isDown(Key.SPACE) &amp;&amp; !pulando )<br />
{<br />
pulando = true;</p>
<p>/*mostra a animação pulando para direita se o personagem<br />
* está indo para a direita, caso contrário para a esquerda<br />
*/</p>
<p>if(direcao == &#8220;direita&#8221;)<br />
megaman_mc.gotoAndStop(&#8220;pulando_dir&#8221;);<br />
else<br />
megaman_mc.gotoAndStop(&#8220;pulando_esq&#8221;);<br />
}</p>
<p>if( Key.isDown( Key.CONTROL) &amp;&amp; (getTimer() &#8211; tiroInterval) &gt; 200 )<br />
{<br />
_root.contTiros++;<br />
_root.tiro_mc.duplicateMovieClip(&#8220;tiro&#8221;+_root.contTiros,_root.contTiros,_root.contTiros); //duplicamos o tiro<br />
if(direcao == &#8220;direita&#8221;)<br />
{<br />
if(!Key.isDown( Key.RIGHT) )<br />
this.gotoAndStop(&#8220;atirando_dir&#8221;);<br />
_root["tiro"+_root.contTiros]._y = this._y+35;<br />
_root["tiro"+_root.contTiros]._x = this._x+50;</p>
<p>}<br />
else<br />
{<br />
if(!Key.isDown( Key.LEFT) )<br />
this.gotoAndStop(&#8220;atirando_esq&#8221;);<br />
_root["tiro"+_root.contTiros]._y = this._y+35;<br />
_root["tiro"+_root.contTiros]._x = this._x-10;<br />
}</p>
<p>tiroInterval = getTimer();</p>
<p>/*atribuindo direcao para o tiro*/<br />
_root["tiro"+_root.contTiros].direcao = direcao;<br />
atirando = true;</p>
<p>}</p>
<p>if( Key.isDown( Key.RIGHT) &amp;&amp; atirando)<br />
{<br />
if( velAndar &lt; velMax )<br />
velAndar++;<br />
if(!pulando)<br />
megaman_mc.gotoAndStop(&#8220;correndo_atirando_dir&#8221;);<br />
}<br />
else if( Key.isDown( Key.LEFT) &amp;&amp; atirando)<br />
{<br />
if ( velAndar &gt; -velMax ) //não deixa o personagem acelerar muito<br />
velAndar&#8211;;<br />
if(!pulando)<br />
megaman_mc.gotoAndStop(&#8220;correndo_atirando_esq&#8221;);<br />
}<br />
else if( Key.isDown( Key.RIGHT))<br />
{<br />
if( velAndar &lt; velMax )<br />
velAndar++;<br />
if(!pulando)<br />
megaman_mc.gotoAndStop(&#8220;correndo_dir&#8221;);<br />
}<br />
else if( Key.isDown( Key.LEFT) )<br />
{<br />
if ( velAndar &gt; -velMax ) //não deixa o personagem acelerar muito<br />
velAndar&#8211;;<br />
if(!pulando)<br />
megaman_mc.gotoAndStop(&#8220;correndo_esq&#8221;);<br />
}<br />
else if(!pulando &amp;&amp; !entrada &amp;&amp; !atirando)</p>
<p>{<br />
//se não tiver acontecendo nada ele fica parado<br />
if(direcao == &#8220;direita&#8221;)<br />
megaman_mc.gotoAndStop(&#8220;parado_dir&#8221;);<br />
else<br />
megaman_mc.gotoAndStop(&#8220;parado_esq&#8221;);<br />
velAndar = 0;<br />
}</p>
<p>/* nosso personagem não é carro mas tem aceleração, que é .85<br />
* mude para um valor alto e veja o resultado<br />
*/<br />
velAndar *= .85;</p>
<p>/*esta função faz o bendito scrolling*/<br />
movimento(this, terreno_mc, plataforma_mc, paredes_mc, velAndar);</p>
<p>if( pulando )<br />
{<br />
/* mais física aqui, veja na figura 9 o que acontece aqui*/<br />
this._y -= velSaltar;<br />
velSaltar -= 1.8;<br />
if (velSaltar&lt;0)<br />
caindo = true;<br />
if (velSaltar &lt;-15)<br />
velSaltar = -15;<br />
}</p>
<p>/* indica que o personagem emcima da plataforma, logo ele não está<br />
* caindo e nem pulando é claro! E setamos novamente<br />
*/<br />
if ( colisao_plataforma( _root.plataforma_mc, this) &amp;&amp; caindo)<br />
{<br />
velSaltar = 20;<br />
pulando = false;<br />
caindo = false;<br />
}<br />
};</p>
<p>function colisao_plataforma(obj1:Object, obj2:Object)<br />
{<br />
return obj1.hitTest(obj2._x, obj2._y+60, true);<br />
}</p>
<p>function colisao_paredes(obj1:Object, obj2:Object, vel:Number)<br />
{<br />
return (obj1.hitTest(obj2._x-5, obj2._y+60, true) or obj1.hitTest(obj2._x+40, obj2._y+60, true))<br />
}</p>
<p>function movimento(personagem_obj:Object, terreno_obj:Object,</p>
<p>limite_obj:Object,paredes_obj:Object, velocidade:Number)<br />
{<br />
if(direcao == &#8220;direita&#8221;)<br />
{<br />
/*se obedecer a condição abaixo, quem anda é o cenário*/<br />
if(personagem_obj._x &gt; 200 and terreno_obj._x &gt;=-1853)<br />
{<br />
terreno_obj._x -= velocidade;<br />
limite_obj._x -= velocidade;<br />
paredes_obj._x -= velocidade;<br />
}<br />
else<br />
personagem_obj._x += velocidade;<br />
}</p>
<p>if(direcao == &#8220;esquerda&#8221;)<br />
{<br />
if(personagem_obj._x &lt; 100 and terreno_obj._x &lt; 0)<br />
{<br />
terreno_obj._x -= velocidade;<br />
limite_obj._x -= velocidade;<br />
paredes_obj._x -= velocidade;</p>
<p>}<br />
else<br />
personagem_obj._x += velocidade;<br />
}<br />
}
</p></div>
<p style="text-align: justify">
<h3>Considerações Finais</h3>
<p style="text-align: justify">Bom pessoal, então isso. espero que tenham gostado fiz o máximo par ser claro e objetivo, dificilmente vocês encontraram um tutorial completo e comentado passo-a-passo de como contruir uma fase inteira de um game. Claro que poderiam ser abordados ainda mais assuntos, mas seria muito trabalho repetido e estenderia muito este artigo. Procurei abordar o que é necessário para se criar um game deste gênero. Agora coloque sua imaginação e criatividade e modfique o quanto quiser e aperfeiçoe para fique ainda melhor, como havia dito antes quero que entendam a técnica e não apenas aprender a fazer o jogo do &#8220;Megaman&#8221;, o meu intuito é que possam criar qualquer jogo com uma folha de sprites na mão e muita criatividade.</p>
<p style="text-align: justify">O Frame <strong>gameover</strong> eu não fiz por que fica a seu cargo decidir o que acontecer depois que o jogo acaba, no meu caso mostrei apenas meu nome e enderço de email com o título do artigo. O barulho que você ouve no início do jogo é apenas um arquivo <strong>inicio.wav</strong> que coloquei no primeiro frame do <strong>megaman_mc</strong> só pra dar mais emoção. Pra utilizá-lo basta importá-lo para a biblioteca via menu <em>file-&gt;import-&gt;to library</em>.</p>
<p style="text-align: justify">Se encontrarem problemas, vocês terão em mãos o mesmo código que usei para o exemplo funcional que está no início deste artigo. Olhe com cuidado cada etapa pois são muitos detalhes onde a falta de um causará um erro no game. Creio que não seja facil para quem está começando, mas estude bem os artigos anteriores para que se familiarize com a forma de como se programa um game. Fáça várias vezes se possível, a prática estimula a compreensão.</p>
<p><script type="text/javascript"><!--
FormatAS(new Array('AS'))
// --></script><br />
Espero que tenham gostado. Até a próxima.</p>
<p><strong>Autor: Márcio Silva &#8211; Colunista de Flash &amp; ActionSctipt MXSTUDIO.</strong></p>
<p><a href="http://www.mxstudio.com.br/apoio/upload/files_megaman.zip">Download dos arquivos</a></p>
<p>Qualquer dúvida envie um e-mail para <a href="mailto:marciosilva@mxstudio.com.br" target="new">marciosilva@mxstudio.com.br</a> ou acesse nosso <a href="http://www.mxstudio.com.br/forum/index.php?showforum=127" target="forum">fórum</a></td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.mxstudio.com.br/desenvolvimento/flash/criacao_de_games___megaman_parte_2/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Criação de Games &#8211; Megaman Parte 1</title>
		<link>http://www.mxstudio.com.br/desenvolvimento/flash/criacao_de_games___megaman_parte_1/</link>
		<comments>http://www.mxstudio.com.br/desenvolvimento/flash/criacao_de_games___megaman_parte_1/#comments</comments>
		<pubDate>Sun, 15 Jul 2007 00:00:00 +0000</pubDate>
		<dc:creator>Marcio Silva</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[criação]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[jogo]]></category>
		<category><![CDATA[plataforma]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Aprenda a construir games de plataforma.V&#225;rias t&#233;cnicas e conceitos mais utilizados.]]></description>
			<content:encoded><![CDATA[<p><script src="http://www.mxstudio.com.br/js/ColorCode.js"></script></p>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr>
<td id="colunaTexto" valign="top"></td>
<td id="colunaTexto" valign="top">
<h1>Criação de games &#8211; Megaman Parte 1</h1>
<p>Olá comunidade,</p>
<p style="text-align: justify">Estou de volta com novas colunas sobre criação de games, destacando os que usam conceitos de física, matemática e outras áreas que estão intimamente ligadas a esta área tão fascinante. No meu último tutorial mostrei a criação de um simples joguinho que tratava de colisão e movimentação de um modelo na tela e que disparava tiros contra inimigos. O objetivo era apenas dar um pontapé inicial para quem não sabia nada sobre games, dessa forma propiciando uma pequena base para aqueles mais iniciantes. Neste tutorial, tratarei de conceitos um pouco mais elaborados, mas que são de fácil compreensão</p>
<h3>Pré-requisitos:</h3>
<p style="text-align: justify">Conhecimento básico em ActionScript<br />
Macromedia Fireworks 8<br />
Macromedia Flash 8<br />
Recomenda-se que você tenha visto a coluna de movimentação básica de personagens, caso não tenha acesse:<br />
<a href="http://www.mxstudio.com.br/views.tutorial.php?act=view&amp;cid=3&amp;aid=1070">Criação de Games</a></p>
<h3>Objetivo:</h3>
<p style="text-align: justify">Propiciar ao leitor o conhecimento necessário para que este possa desenvolver seus próprios jogos de plataforma. Ao logo da construção do game serão mostrados e comentados cada conceito novo que for mostrado, preocupando-se em não só mostrar como faz, mas também por que funciona, dúvida que fica geralmente na cabeça de quem está no início do aprendizado ou até mesmo quem já tem algum conhecimento na área. O objetivo aqui é desenvolver uma fase completa de um game que segue o formato de plataforma, estilo Super Mário.</p>
<p style="text-align: justify">
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="320" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="name" value="Megaman" /><param name="bgcolor" value="#000000" /><param name="align" value="middle" /><param name="src" value="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart1_imagens/Megaman.swf" /><embed type="application/x-shockwave-flash" width="550" height="320" src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart1_imagens/Megaman.swf" align="middle" bgcolor="#000000" name="Megaman"></embed></object></p>
<h3>Conceitos:</h3>
<p style="text-align: justify">Nesta primeira parte iremos abordar a técnica de animação de personagens utilizando sprites, criar interação do usuário com um modelo baseado em sprites, o famoso scrolling, simulação de gravidade e técnicas de tratamento de colisão em jogos de plataforma.</p>
<p style="text-align: justify">Os sprites nada mais são do que vários quadros de uma animação nos games 2D, a animação de personagens é feita quadro a quadro, como o Macromedia Flash trabalha com quadros é muito prático manipular sprites de uma animação na ferramenta.</p>
<h3>Conteúdo</h3>
<p>Então, mão na massa!</p>
<h4>O Personagem</h4>
<p style="text-align: justify">Antes de mais nada devemos obter as figuras para o tutorial, existem vários sites pela internet que fornecem sprites para download gratuitamente, é claro que se você é bom em designer de personagens pode fazer os seus próprios. Mas muitos games em flash disponíveis na internet são adaptações de games já existentes e consagrados, que é nosso caso, onde iremos utilizar sprites do jogo do Megaman. Recomendo o <a href="http://www.spritekingdom.com/sheet/megaman/32bit.gif">Sprite Kingdom</a>, de onde tirei os sprites para esta coluna. Salve o arquivo com os sprites do link acima e abra no Macromedia Fireworks. Os passos seguintes serão repetidos para cada estado do personagem, você deve ter percebido no arquivo que você baixou que cada linha trata-se de uma ação do Megaman, com exceção das duas primeiras, vejamos a figura abaixo:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart1_imagens/img1.gif" alt="entrada do jogo" /><br />
<strong>Figura 1 </strong> &#8211; Representa a chegada do Megaman</p>
<p style="text-align: justify">Na <strong>Figura 1</strong> podemos observar que seguindo a numeração indicada obtemos uma animação do Megaman quando ele entra no cenário de jogo. Então para ver essa animação funcionando basta contruir um movieclip com 26 <em>frames</em>, note que cada quadro da animação será mapeado para um frame do <em>timeline</em> do flash . Para fazer isso devemos seguir os seguintes passos:</p>
<ul>
<li>Com a imagem que você baixou do <a href="http://www.spritekingdom.com/sheet/megaman/32bit.gif">Sprite Kingdom</a> aberta no Macromedia Fireworks selecione o quadro 1 utilizando a ferramenta <em>Marquee Tool</em>, cuide para que apenas o primeiro quadro seja selecionado;</li>
<li>Com o primeiro quadro selecionado aperte CTRL + C para copiar;</li>
<li>Abra um documento em branco no Macromedia Flash 8 e vá em <em>Insert » new Symbol</em> ou CTRL + F8, chame-o de <strong>entrada</strong>;</li>
<li>transforme o 1° primeiro frame em <em>Key Frame</em> apertando F6;</li>
<li>Agora CTRL + V na área do <em>stage</em>, pronto o primeiro quadro agora está no primeiro frame, todos os outros que viram terão como base este primeiro frame para que a animação fique perfeita;</li>
<li>Repita o processo de copiar e colar agora para o segundo quadro da figura aberta no fireworks e cole agora no segundo frame no flash, esse processo deve ser feito até que os 26 sprites estejam na animação. Serão 26 <em>Key Frames</em></li>
<li>No decorrer deste processo se quiser visualizar como está ficando, clique no primeiro frame do <em>timeline</em> aperte ENTER, assim você poderá ver que ajustes deverão ser feitos para que animação fique perfeita. Por que pode ser que uma figura de um frame anterior tenha ficado mais baixa que a atual que você está colocando e outros probleminhas de alinhamento podem aparecer.</li>
</ul>
<p style="text-align: justify">Depois desse processo você já deve ter percebido que o Macromédia Flash é muito bom para fazer animação de personages 2D. Bom, agora devemos fazer as animações para o Megaman correndo e pulando, vai seguir a mesmo processo descrito acima, criando um novo movieclip vazio, o estadocorrendo eu chamei de <strong>correndo_dir</strong> e o pulando de <strong>pulando_dir</strong>, o dir no final indica direita para facilitar na hora de escrever o Action Script.</p>
<p style="text-align: justify">Só para vocês conferirem, as seqüências de imagens para <strong>correndo_dir</strong> e <strong>pulando_dir</strong> seguem abaixo:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart1_imagens/img2.gif" alt="entrada do jogo" /><br />
<strong>Figura 2 </strong> &#8211; Sprites para <strong>correndo_dir</strong>.</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart1_imagens/img3.gif" alt="entrada do jogo" /><br />
<strong>Figura 3 </strong> &#8211; Sprites para <strong>pulando_dir</strong>.</p>
<p style="text-align: justify">Até agora construímos apenas as principais ações que o Megaman terá, agora vamos contruir o Movieclip que será realmente o Megaman e que nós iremos manipular via Action Script, no mundo dos games podemos chamá-lo de Modelo. Para isto aperte CTRL + F8 e chame esse movie clip vazio de <strong>megaman</strong>. Como este será o movieclip principal ele terá todos estados possíveis do Megaman dentro do jogo: correr para esquerda e direita, pular para esquerda e direita, e ficar parado olhando para esquerda e para direita e o estado de entrada que construímos anteriormente. Portanto devemos ter 7 <em>Key Frames</em> no timeline. Veja abaixo:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart1_imagens/img4.gif" alt="entrada do jogo" /><br />
<strong>Figura 4 </strong> -Timeline com os <em>Key Frames</em>.</p>
<p style="text-align: justify">Coloque em cada frame o seu respectivo nome.</p>
<ul>
<li><strong>Frame 1</strong> chame de <strong>entrada</strong></li>
<li><strong>Frame 2</strong> chame de <strong>correndo_dir</strong></li>
<li><strong>Frame 3</strong> chame de <strong>correndo_esq</strong></li>
<li><strong>Frame 4</strong> chame de <strong>pulando_dir</strong></li>
<li><strong>Frame 5</strong> chame de <strong>pulando_esq</strong></li>
<li><strong>Frame 6</strong> chame de <strong>parado_dir</strong></li>
<li><strong>Frame 7</strong> chame de <strong>parado_esq</strong></li>
</ul>
<p style="text-align: justify">Vamos agora associar as animações para cada ação, quase parecido com o processo de copiar e colar para montar as animações mas agora você irá usar as animações que criou anteriormente. Com o frame <strong>entrada</strong> selecionado pegue da <em>Library</em> a animação que também se chama <strong>entrada</strong> e coloque no centro do <em>stage</em>, como nas animações este primeiro servirá como base para o alinhamento das demais animações. A animação <strong>correndo_dir</strong> também já está pronta, foi feita nos passos anteriores basta colocar no seu respectivo frame, da mesma forma a <strong>pulando_dir</strong>.</p>
<p style="text-align: justify">Para fazer a <strong>correndo_esq</strong> e a <strong>pulando_esq</strong>, você vai utilizar uma instância das versões para direita, mas como o personagem nas outras versões está virado para a direita basta usar a ferramenta <em>Free Transform Tool</em> e usar o mouse para inverter o sentido do movieclip. Para isto basta clicar no movieclip e acionar a ferramenta <em>Free Transform Tool</em>, clique no lado esquerdo da figura e arraste para o lado direito, isso faz com que a figura inverta de direção. Por fim, para fazer o <strong>parado_dir</strong> e o <strong>parado_esq</strong> basta copiar o último sprite do movieclip <strong>entrada</strong> para o frame <strong>parado_dir</strong>, copie este mesmo sprite para o <strong>parado_esq</strong> só que neste invertendo sua direção com a ferramenta <em>Free Transform Tool</em> do flash como feito anteriormente.</p>
<p style="text-align: justify">A menos dos devidos ajustes que você possa fazer para deixar as animações bem alinhadas, o nosso personagem está praticamente pronto, só mecheremos nele na etapa de codificação.</p>
<h4>O Cenário</h4>
<p style="text-align: justify">Da mesma forma que os sprites, os cenários podem ser encontrados em sites na especializados na internet, eu utilizei um que está no site <a href="http://www.bghq.com/bgs.php?system=psx&amp;game=m/mmx6&amp;mode=commander">Background HQ</a>. A montagem do cenário é mais fácil que o personagem, para fazer este tutorial usei apenas parte do cenário, pois ele é muito grande, por isso eu disponibilizei a versão que vou utilizar <a href="http://www.mxstudio.com.br/apoio/upload/Megaman.zip"> neste link</a>. Na verdade o cenário nada mais é do que uma imagem de plano de fundo, que servirá como molde para desenhar os obstáculos e a plataforma.</p>
<p>Volte para a cena principal do nosso documento flash, agora vamos colocar todas a layers que precisaremos para manipular o jogo, cada layer vai ter 3 <em>Key Frames</em>. Faça como a imagem abaixo:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart1_imagens/img5.gif" alt="entrada do jogo" /><br />
<strong>Figura 5 </strong> &#8211; Nome de cada <em>layer</em> com seus <em>Key Frames</em>.</p>
<p style="text-align: justify">Por enquanto o primeiro <em>frame</em> de cada <em>layer</em> não iremos utilizar, Para começar a montagem do jogo. Supondo que você já baixou o cenário no fim deste tutorial, insira um novo símbolo do tipo mocieclip e cole a imagem do cenário que você baixou.</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart1_imagens/img6.gif" alt="entrada do jogo" /><br />
<strong>Figura 6 </strong> &#8211; Movieclip <strong>terreno</strong>.</p>
<p style="text-align: justify">Veja que a figura ficou no movieclip que acabei de criar, certifique-se que você fez exatamente igual. Volte à cena e agora apenas arraste-o da biblioteca para o <em>stage. </em>Alinhe na posição <em>x</em>=0 e <em>y</em>=0 e certifique-se que este mc está na layer Terreno e no seu segundo <em>frame</em>. Dê o nome para esta intância de terreno de <strong>terreno_mc</strong>. Pronto, o terreno já está no lugar certo. Agora teremos uma a plataforma onde o personagem vai ficar durante todo o jogo, essa plataforma vai simular o piso do terreno. Para isto crie um novo movieclip vazio chamado de <strong>plataforma</strong>.</p>
<p style="text-align: justify">Agora preste muita atenção! O segredo do jogo funcionar corretamente está como você faz os próximos passos. Nesse movieclip vazio faço um quadrado qualquer, isso mesmo, um quadrado qualquer. Volte à cena e arraste para o <em>stage </em>este novo movieclip chamado de <strong>plataforma </strong>que ficará no segundo frame da <em>layer</em> Plataforma, dê o nome para esta nova instância da plataforma de <strong>plataforma_mc</strong>. Se você der dois cliques no mc <strong>plataforma_mc </strong>o terreno vai ficar como se fosse marcada d&#8217;agua, assim o terreno será seu molde para desenhar sobre ele a plataforma, agora você não vai utilizar aquele quadrado qualquer. Utilizando a ferramenta <em>Rectangle Tool</em> desenhe sobre as superfícies que o Magaman irá ficar apoiado, esses retângulos simularam a base onde o personagem pode caminhar. Veja abaixo:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart1_imagens/img7.gif" alt="entrada do jogo" /><br />
<strong>Figura 7 </strong> &#8211; Movieclip <strong>plataforma_mc </strong>(cor banca) sobre o <strong>terreno_mc</strong>.</p>
<p style="margin: 0pt auto; text-align: center">
<p style="text-align: justify">Veja que eu coloquei a plataforma na altura que o personagem pode caminhar, a parte de cima de cada retângulo é onde vai ficar os pés do Megaman. Pra terminar essa brincadeira com as imagens, vamos agora fazer o mc que vai representar as paredes do cenário. O processo para a construção das paredes &#8220;fictícias&#8221;, ou seja, retângulos que representarão as paredes e onde o personagem vai colidir, será feito como foi feito com a <strong>plataforma. </strong>Crie de novo um mc vazio chamado <strong>paredes</strong> e coloque um quadrado qualquer, volte à cena e arraste-o para o <em>stage </em>de modo que fique no segundo <em>frame</em> da <em>layer</em> Paredes  , dê novamente dois cliques nesse novo mc, o que muda agora que você não mais vai colocar retângulos onde o Magaman pisa, e sim onde ele pode colidir de frente simulando uma parede. Chame essa instancia de <strong>paredes</strong> que você acabou de arrastar para o stage de <strong>paredes_mc</strong>. Veja como ficou:</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart1_imagens/img8.gif" alt="entrada do jogo" /><br />
<strong>Figura 8 </strong> &#8211; Em branco <strong>plataforma_mc </strong>e em azul <strong>paredes_mc</strong>.</p>
<p style="margin: 0pt auto; text-align: center">
<p style="text-align: justify">Quando começar a testar as colisões algumas modificações devem ser feitas na largura na altura desses quadrados. Note que a idéia para simular paredes é cobrir de retângulos azuis tudo obstáculo que o Megaman pode colidir, não importa que esses retângulos fiquem bonitinhos por cima do terreno, o que importa é que eles não deixem o Megaman passar pelas paredes e nem sumir chão a dentro (Os ajustes são feitos quando começar a etapa de teste do game).. Onde ele não consegue colidir de frente não é necessário colocar paredes.</p>
<p style="text-align: justify">Agora falta colocar o Megaman no cenário. Vá a sua biblioteca e coloque no <em>stage</em> o movieclip <strong>megaman, </strong>ele foi feito em etapas anteriores. Chame essa instância de <strong>magaman_mc</strong>. Se você der dois cliques nesse mc, você vai entrar no modo de edição, veja que ele é composto de de 7 <em>frames. </em>Devemos colocar um <em>stop</em>() no primeiro frame para que a animação começe a executar quando o game começar. Ainda com o megaman aberto para edição, vá no <em>frame</em> <strong>pulando_dir</strong> que por sua vez possui o mc <strong>pulando_dir</strong> dê dois cliques nesse mc para edição. Já este mc, se você o construiu corretamente, tem 19 <em>frames</em> que é a quantidade de quadros da ação de pular. No último frame colque o seguinte código:</p>
<div id="codigo" title="AS">if(_root.direcao == &#8220;direita&#8221;)<br />
_parent.gotoAndStop(&#8220;parado_dir&#8221;);<br />
else<br />
_parent.gotoAndStop(&#8220;parado_esq&#8221;);</div>
<p style="text-align: justify">Isso fará com que quando animação de pular saiba em que direção ficar parada depois que acabar, não precisa fazer para o <strong>pulando_esq, </strong>já que ele é uma instância de <strong>parado_dir</strong>.</p>
<h4>O Código</h4>
<p style="text-align: justify">Esta etapa que passamos agora no desenvolvimento de jogos é chamada de <strong>MODELAGEM, </strong>todo jogo, não importa em que plataforma você o faça, tem essa etapa, principalmente os games 3D. Assim você pode passar essa etapa para um colega seu que sabe muito de design de cenários e personagens, depois você  dá vida ao jogo com a codificação.</p>
<p style="text-align: justify">Para codificar o jogo só usei uma arquivo de <em>Action Script </em>(AS)<em>, </em>logo crie um arquivo de AS e chame-o de <strong>Megaman.as</strong>. Seu código está logo abaixo:</p>
<p style="text-align: justify">
<div id="codigo" title="AS">stop();<br />
/* Variáveis globais<br />
* Aqui estão presentes as variáveis que fazem o<br />
* controle dos estados<br />
* em que o jogo se encontra<br />
*/<br />
var velSaltar:Number = 20;<br />
var velAndar:Number = 0;<br />
var pulando:Boolean = false;<br />
var caindo:Boolean = false;<br />
var morreu:Boolean = false;<br />
var velMax:Number = 10;<br />
var direcao:String = &#8220;&#8221;;<br />
var entrada:Boolean = true; /*fazemos com que as layers que representam as paredes<br />
* e a plataforma não apareçam na hora que<br />
* o jogo for executado<br />
*/<br />
plataforma_mc._visible = false;<br />
paredes_mc._visible = false;</p>
<p>/* Todo o controle do personagem Megaman*/<br />
megaman_mc.onEnterFrame = function()<br />
{<br />
//verifica se ainda não acabou a entrada do Megaman<br />
if(entrada)<br />
return;<br />
/*verifica colisão com alguma parede do lado direito ou esquerdo<br />
* Se houve colisão faz uma anulação do passo que ele deu para frente<br />
*/<br />
if( colisao_paredes(_root.paredes_mc, this, velAndar))<br />
this._x-=velAndar;<br />
/* simples simulação de gravidade<br />
* Se ele não tiver em cima da plataforma então ele vai caindo<br />
* sem aceleração<br />
*/</p>
<p>if ( !colisao_plataforma(_root.plataforma_mc, this) &amp;&amp; !pulando)<br />
this._y += 6;</p>
<p>//se velocidade positiva estou andando para a<br />
//direita senão estou indo para esquerda<br />
if (velAndar&gt;0)<br />
direcao = &#8220;direita&#8221;;<br />
else if (velAndar&lt;0)<br />
direcao = &#8220;esquerda&#8221;;</p>
<p>//só pula se não tiver pulando, claro<br />
if ( Key.isDown(Key.SPACE) &amp;&amp; !pulando )<br />
{<br />
pulando = true;</p>
<p>/*mostra a animação pulando para direita se o personagem<br />
* está indo para a direita, caso contrário para a esquerda<br />
*/</p>
<p>if(direcao == &#8220;direita&#8221;)<br />
megaman_mc.gotoAndStop(&#8220;pulando_dir&#8221;);<br />
else<br />
megaman_mc.gotoAndStop(&#8220;pulando_esq&#8221;);<br />
}<br />
if( Key.isDown( Key.LEFT) )<br />
{<br />
if ( velAndar &gt; -velMax ) //não deixa o personagem acelerar muito<br />
velAndar&#8211;;<br />
if(!pulando)<br />
megaman_mc.gotoAndStop(&#8220;correndo_esq&#8221;);<br />
}<br />
else if( Key.isDown( Key.RIGHT) )<br />
{<br />
if( velAndar &lt; velMax )<br />
velAndar++;<br />
if(!pulando)<br />
megaman_mc.gotoAndStop(&#8220;correndo_dir&#8221;);<br />
}<br />
else if(!pulando and !entrada )<br />
{<br />
//se não tiver acontecendo nada ele fica parado<br />
if(direcao == &#8220;direita&#8221;)<br />
megaman_mc.gotoAndStop(&#8220;parado_dir&#8221;);<br />
else<br />
megaman_mc.gotoAndStop(&#8220;parado_esq&#8221;);<br />
velAndar = 0;<br />
}</p>
<p>/* nosso personagem não é carro mas tem aceleração, que é .85<br />
* mude para um valor alto e veja o resultado<br />
*/<br />
velAndar *= .85;</p>
<p>/*esta função faz o bendito scrolling*/<br />
movimento(this, terreno_mc, plataforma_mc, paredes_mc, velAndar);</p>
<p>if( pulando )<br />
{<br />
/* mais física aqui, veja na figura 9 o que acontece aqui*/<br />
this._y -= velSaltar;<br />
velSaltar -= 1.8;<br />
if (velSaltar&lt;0)<br />
caindo = true;<br />
if (velSaltar &lt;-15)<br />
velSaltar = -15;<br />
}</p>
<p>/* indica que o personagem emcima da plataforma, logo ele não está<br />
* caindo e nem pulando é claro! E setamos novamente<br />
*/<br />
if ( colisao_plataforma( _root.plataforma_mc, this) &amp;&amp; caindo)<br />
{<br />
velSaltar = 20;<br />
pulando = false;<br />
caindo = false;<br />
}<br />
};</p>
<p>function colisao_plataforma(obj1:Object, obj2:Object)<br />
{<br />
return obj1.hitTest(obj2._x, obj2._y+60, true);<br />
}</p>
<p>function colisao_paredes(obj1:Object, obj2:Object, vel:Number)<br />
{<br />
return (obj1.hitTest(obj2._x-5, obj2._y+60, true) or obj1.hitTest(obj2._x+40, obj2._y+60, true))<br />
}</p>
<p>function movimento(personagem_obj:Object, terreno_obj:Object,</p>
<p>limite_obj:Object,paredes_obj:Object, velocidade:Number)<br />
{<br />
if(direcao == &#8220;direita&#8221;)<br />
{<br />
/*se obedecer a condição abaixo, quem anda é o cenário*/<br />
if(personagem_obj._x &gt; 200 and terreno_obj._x &gt;=-1853)<br />
{<br />
terreno_obj._x -= velocidade;<br />
limite_obj._x -= velocidade;<br />
paredes_obj._x -= velocidade;<br />
}<br />
else<br />
personagem_obj._x += velocidade;<br />
}</p>
<p>if(direcao == &#8220;esquerda&#8221;)<br />
{<br />
if(personagem_obj._x &lt; 100 and terreno_obj._x &lt; 0)<br />
{<br />
terreno_obj._x -= velocidade;<br />
limite_obj._x -= velocidade;<br />
paredes_obj._x -= velocidade;</p>
<p>}<br />
else<br />
personagem_obj._x += velocidade;<br />
}<br />
}
</p></div>
<p style="text-align: justify">Agora para funcionar o jogo, vá à <em>layer</em> Action no segundo <em>frame</em> da cena principal  e coloque como segue abaixo:</p>
<div id="codigo" title="AS">stop();<br />
/*inclusão do código do game*/<br />
#include &#8220;Megaman.as&#8221;</div>
<p style="text-align: justify">Àqueles que mataram essa aula de física a figura abaixo mostra uma parte da física que diz: &#8220;Tudo que sobe tem que descer&#8221;, a idéia que o código das linhas 91 à 97 é simular desaceleração de um corpo quando este é lançado de baixo para cima, que nada mais é do que a gravidade atuando sobre o corpo que sobe, chega um momento que a velocidade chega a zero e depois inverte o sinal fazendo com que o corpo mude direção e comece a cair, o que foi codificado é uma aproximação desse efeito bem superficial , veja na figura abaixo como a magnitude da velocidade vai diminuindo, isto é, a cada passo de tempo seu valor vai se reduzindo até zerar e mudar de sentido (sinal). Esse moviemnto é chamado de Movimento Uniformemente Variado (MUV).</p>
<p style="margin: 0pt auto; text-align: center"><img src="http://www.mxstudio.com.br/imagens_artigos/marcioSilva_jul07_megamanPart1_imagens/img9.gif" alt="entrada do jogo" /><br />
<strong>Figura 9 </strong> &#8211; Velocidade no decorrer do pulo.</p>
<p style="margin: 0pt auto; text-align: center">
<h3>Considerações Finais</h3>
<p style="text-align: justify">Vimos durante o texto diversos conceitos referentes ao desenvolvimento de games de plataforma, é claro que o modo de fazer não é único, você pode achar várias formas de fazer, mas os conceitos sempre serão o mesmos. Você viu como fazer scrolling, uma pequena simulação física, que permite mais suavidade ao pulo do personagem, é claro que quanto mais detalhes nessa simulação fica mais próximo da realidade.</p>
<p style="text-align: justify">Espero que você tenha assimilado os conceitos mais básicos e mais importantes desse tipo de game. Calma que tem mais, você percebe que ainda falta os inimigos, fazer o Megaman atirar colocar um timer entre outros, para ficar bem parecido com o game real. Mas isso fica para uma próxima, nas próximas semanas estarei postando a constinuação deste artigo.</p>
<p><script type="text/javascript"><!--
FormatAS(new Array('AS'))
// --></script><br />
Espero que tenham gostado. Até a próxima.</p>
<p><strong>Autor: Márcio Silva &#8211; Colunista de Flash &amp; ActionSctipt MXSTUDIO.</strong></p>
<p><a href="http://www.mxstudio.com.br/apoio/upload/Megaman.zip">Download dos arquivos</a></p>
<p>Qualquer dúvida envie um e-mail para <a href="http://mce_host/mx_novo/wp-admin/maito:marciosilva@mxstudio.com.br" target="new">marciosilva@mxstudio.com.br</a> ou acesse nosso <a href="http://forum.mxstudio.com.br" target="forum">fórum</a></td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.mxstudio.com.br/desenvolvimento/flash/criacao_de_games___megaman_parte_1/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
	</channel>
</rss>

