Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Daniel o rei

jogo de canhão com box2D 2.1a

Recommended Posts

É possível fazer bastante coisa com a API box2d.

 

Neste exemplo faremos um "carro" com um canhão em cima.

 

 

Um resumo:

O XML na variavel xmlmap está contido todos os objetos do mundo, dos 3 "mapas".

 

Como os objetos são criados?

 

Os circulos:

 

A função create_circles tem um for que cria os circulos um por um com a função create_circle.

 

A função create_circle recebe um xml e cria um circulo de acordo com os parâmetros e retorna um b2Body

 

Os "boxes":

 

A função create_boxies(desculpe o erro de ortografia) tem um for que cria as caixas um por um com a função create_box.

 

A função create_box recebe um xml e cria uma caixa de acordo com os parâmetros e retorna um b2Body

 

 

 

O carro é criado atravéz da função create_car, que faz o carro com as funções: create_circle , create_box , create_weldjoint e create_rvjoint

As "partes do carro"(b2Body e b2Joint) são gravadas no array carparts

 

 

Como o canhão atira?

 

 

Ao soltar a barra de espaço cria um circulo e grava no array projeteis.

Depois com o Math.sin e Math.cos e atravez da força calcula o impulso x e y

Depois aplica esse impulso no circulo e a força contraria no carro.

 

 

Eu tentei comentar bem o script

package {
import flash.ui.Keyboard;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.display.Sprite;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
import Box2D.Dynamics.*;
import 	Box2D.Dynamics.Joints.*;
import flash.events.*;
public class c_box2d extends Sprite {
	var boxarray:Array = new Array(); // array onde estarão contidos os boxies
	var circlearray:Array = new Array();//array onde estarão contidos os circulos

	var left:Boolean = false;//se a seta esquerda estiver pressionada será true
	var up:Boolean = false;		//se a seta de cima estiver pressionada será true
	var right:Boolean = false;//se a seta direita estiver pressionada será true
	var down:Boolean = false;//se a seta de baixo estiver pressionada será true
	var space:Boolean = false;//se a barra de espaço estiver pressionada será true

	var carparts:Array = new Array() ;//array onde estarão contidos as partes do carro(joints,circles,boxies)

	var force:int = 0;//inteiro com a forca do tiro do canhão
	var force_a:Boolean ;// se true a barra de força almenta ,false diminui
	var projeteis:Array = new Array(); //array onde estarão contidos os projeteis que serão disparados pelo canhão
	public var world:b2World;//o mundo
	//abaixo o xml com os mapas
	var xmlmap:XML = 

	            	<xmlmap><mapa num="1">

	            	<box id="0" width="2447" height="32" x="169"  y="174"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="-5"/>
	            	<box id="1" width="2447" height="32" x="2604"  y="196"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="5"/>
	            	<box id="2" width="5" height="132" x="3700"  y="180"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="5"/>

					<circulo id="0" size="15" x="107"y="133" obj="1" type="1" />
	            	<objeffect id="0" type="gravity" x="50" y="50" />
	            	</mapa>
	            	<mapa num="2">
	            	<box id="0" width="488" height="32" x="-34"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="5"/>
	            	<box id="1" width="488" height="32" x="412"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="-5"/>
	            	<box id="2" width="488" height="32" x="885"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="5"/>
					<box id="3" width="488" height="32" x="1304"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="-5"/>
	            	<box id="4" width="488" height="32" x="1785"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="5"/>
	            	<box id="5" width="488" height="32" x="2232"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="-5"/>
	            	<box id="6" width="488" height="32" x="2710"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="5"/>
					<box id="7" width="488" height="32" x="3150"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="-5"/>
	            	<circulo id="0" size="15" x="107"y="133" obj="1" type="1" />

					</mapa>
	            	<mapa num="3">
	             	<box id="0" width="488" height="32" x="-34"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="5"/>
	            	<box id="1" width="488" height="32" x="412"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="-5"/>
	            	<box id="2" width="488" height="32" x="885"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="5"/>
					<box id="3" width="488" height="32" x="1304"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="-5"/>
	            	<box id="4" width="488" height="32" x="1785"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="5"/>
	            	<box id="5" width="488" height="32" x="2232"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="-5"/>
	            	<box id="6" width="488" height="32" x="2710"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="5"/>
					<box id="7" width="488" height="32" x="3150"  y="243"  obj="1" type="0" friction2="on"friction="0.4" angle2="on" angle="-5"/>

					<box id="8" width="100" height="32" x="3400"  y="243"  obj="1" type="0" friction2="on"friction="0.4" />
	            	<box id="9" width="15" height="500" x="3650"  y="110" obj="3" type="0" friction2="on"friction="0.025"  angle2="on" angle="55" />

					<box id="10" width="300" height="32" x="4000"  y="-30"  obj="1" type="0" friction2="on"friction="0.4" />
	           	<circulo id="0" size="15" x="107"y="133" obj="1" type="1" />
				   </mapa>

	            	</xmlmap>;

	public function c_box2d() {
		var grav=new b2Vec2(00,10);//b2Vec2 onde estarão contida o valor da gravidade
		world=new b2World(grav,true);//cria o mundo
		stage.addEventListener(Event.ENTER_FRAME,update);//enter frame
		stage.addEventListener(KeyboardEvent.KEY_DOWN,kdown);
		stage.addEventListener(KeyboardEvent.KEY_UP,kup);
		create_boxies(1);//cria os boxies do primeiro mapa
		create_circles(1);//cria os circulos do primeiro mapa
		create_car(-1090 , 0);//cria o carro na posição x:3000 e y 0

		//as três linhas abaixo cria o evendo para os botões de criar mapa
		painel.mapa1.addEventListener(MouseEvent.CLICK, mp1);//bt mapa 1
		painel.mapa2.addEventListener(MouseEvent.CLICK, mp2);//bt mapa 2
		painel.mapa3.addEventListener(MouseEvent.CLICK, mp3);//bt mapa 3


	}
	function update(e:Event):void {			
		x = carparts[6].GetPosition().x * -30 + 225; //atualiza a posição do stage
		y = carparts[6].GetPosition().y * -30 + 225; //atualiza a posição do stage
		painel.x = (x) * -1+ 278;//atualiza a posição do mc painel
		painel.y = (y) * -1+ 50;//atualiza a posição do mc painel
		if(space){//verifica se a barra de espaço está precionada
		if(force == 0){
			force_a = true;// se force for 0 force_a vai ser true e a barra vai almentar
			}
		if(force == 300){
			force_a = false; // se force for 300 que é o limite force_a vai ser false e vai diminuir a barra
			}
		if(force_a == true){
			force +=10; //almenta a força
		}
		if(force_a == false){
			force -=10; // diminui a força caso já tenha batido nos 300
		}

		}else{
		if(force > 0){
		var valorx = Math.cos(carparts[11].GetAngle()) ; // calcula o seno do angulo do canhão
		var valory = Math.sin(carparts[11].GetAngle()) ;// calcula o cosseno do angulo do canhão
			var fx:Number = (force/ (Math.abs(valorx) + Math.abs(valory))) * valorx / 10;// faz um pequeno calculo de proporção e calcula o impulso na posicao x
			var fy:Number = (force/ (Math.abs(valorx) + Math.abs(valory))) * valory / 10;// faz um pequeno calculo de proporção e calcula o impulso na posicao y

			//abaixo cria o projetil
			projeteis[projeteis.length] = create_circle(<circulo size="10" x={valorx * 45 + carparts[11].GetPosition().x*30} y={valory * 45 + carparts[11].GetPosition().y*30} obj="1" type="1" density="5"/>);
			//abaixo aplica o impulso ao projetil
			projeteis[projeteis.length-1].ApplyImpulse(new b2Vec2(fx , fy),carparts[11].GetPosition());
			//abaixo alica a força contraria ao impulso do projetil
			carparts[11].ApplyImpulse(new b2Vec2(fx*-1, fy*-1),carparts[11].GetPosition());


		}
		force = 0 ; //zera a variavel force


		}
		painel.forcebar.width = force; //atualiza o tamanho da barra de acondo com a var force
		if(right){
		carparts[4].SetMaxMotorTorque(350);//o máximo de torque do motor
		carparts[4].SetMotorSpeed(-25);	 // a velocidade
		carparts[5].SetMaxMotorTorque(350); 
		carparts[5].SetMotorSpeed(-15);
		}
		if(left){
		carparts[4].SetMaxMotorTorque(350);
		carparts[4].SetMotorSpeed(25);			
		carparts[5].SetMaxMotorTorque(350);
		carparts[5].SetMotorSpeed(15);			
		}
		if(!left && !right){
		//caso não esteja pressionado nenhuma tecla
		carparts[4].SetMaxMotorTorque(0);
		carparts[4].SetMotorSpeed(0);			
		carparts[5].SetMaxMotorTorque(0);
		carparts[5].SetMotorSpeed(0);
		}

		if(up){
		carparts[12].EnableLimit(false); // desabilita o limite
			//carparts[12].EnableMotor(true);	
		carparts[12].SetMaxMotorTorque(10000000); // o torque do motor do canhão
		carparts[12].SetMotorSpeed(-2);	 // a velocidade
		carparts[12].SetLimits(carparts[12].GetJointAngle(), carparts[12].GetJointAngle());
		}
		if(down){
		carparts[12].EnableLimit(false);
		carparts[12].SetMaxMotorTorque(10000000);
		carparts[12].SetMotorSpeed(2);
		carparts[12].SetLimits(carparts[12].GetJointAngle(), carparts[12].GetJointAngle());
		}
		if(!up && !down){			
		carparts[12].EnableLimit(true); // trava o eixo do canhão de acordo com o limite setado em cima
		}
		// abaixo atualiza a posição e rotação dos objetos
		for (var bb:b2Body = world.GetBodyList(); bb; bb = bb.GetNext()) {
			if (bb.GetUserData() is Sprite) {
				var sprite:Sprite=bb.GetUserData() as Sprite;
				sprite.x=bb.GetPosition().x*30;//atualiza a posição x e multiplica por 30(a escala)
				sprite.y=bb.GetPosition().y*30;//atualiza a posição y e multiplica por 30(a escala)
				sprite.rotation = bb.GetAngle() * (180/Math.PI); // atualiza a rotação, transformando bb.GetAngle que é em radianos para graus
			}
		}
		world.Step(1/30 , 10, 10); // atualiza o mundo


	}
	function kdown(e:KeyboardEvent){	 //quando a tecla for pressionada
		switch(e.keyCode){
			case 37:
			left = true;
			break;
			case 39:
			right = true;
			break;

			case 38:
			up = true;
			break;
			case 40:
			down = true;
			break;
			case Keyboard.SPACE:
			space = true;

			break;

		}
	}
	function kup(e:KeyboardEvent){	// quando a tecla for solta
		switch(e.keyCode){
			case 37:
			left = false;
			break;
			case 39:
			right = false;
			break;

			case 38:
			up = false;
			break;
			case 40:
			down = false;
			break;
			case Keyboard.SPACE:
			space = false;

			break;
		}
	}


	function create_car(_x, _y):void {

	var xx = _x; //posição do carro
	var yy = _y;//posição do carro

	/*quadrado esquerdo*/carparts[2] = create_box(<box width="8"  height="35" x={ xx + 31} y={ yy +62} obj="4" type="2"/>);
	/*quadrado direito*/carparts[3] = create_box(<box width="8"  height="35" x={ xx + 178} y={ yy +62} obj="4" type="2"/>);

	/*pneu esquerdo*/carparts[0] = create_circle(<circulo size="33" x={ xx + 31} y={ yy +71} obj="1" type="1" friction2="on" friction="10"/>);
	/*pneu direito*/carparts[1] = create_circle(<circulo  size="33" x={ xx + 178} y={ yy +71} obj="1" type="1" friction2="on" friction="0.5"/>);

	/*joint do pneu esquerdo*/carparts[4] = create_rvjoint(carparts[0],carparts[2], carparts[0].GetWorldCenter());
	/*joint do pneu esquerdo*/carparts[5] = create_rvjoint(carparts[1],carparts[3], carparts[1].GetWorldCenter());
	/*BASE*/carparts[6] = create_box(<box width="206"  height="16" x={ xx + 103} y={ yy +42} obj="1" type="2" density="10"/>);
	/*joint pneu-base left*/carparts[7] = create_weldjoint(carparts[6],carparts[2], carparts[2].GetWorldCenter());
	/*joint pneu-base left*/carparts[8] = create_weldjoint(carparts[6],carparts[3], carparts[3].GetWorldCenter());
	/*base canhão*/carparts[9] = create_box(<box width="8.7"  height="24" x={ xx + 84} y={ yy + 24.2} obj="4" type="2"/>);
	/*joint base-base_canhão*/carparts[10] = create_weldjoint(carparts[6],carparts[9], carparts[9].GetWorldCenter());
	/*circ_canhão*/carparts[11] = create_circle(<circulo  size="21.5" x={ xx + 84.5} y={ yy + 12} obj="1" type="1"/>);
	/*joint canhão*/carparts[12] = create_rvjoint(carparts[9],carparts[11], carparts[11].GetWorldCenter());
	/*canhão_lado1*/carparts[13] = create_box(<box width="33.9"  height="3.2" x={ xx + 109.6} y={ yy +6.7} obj="1" type="2"  />);
	/*canhão_lado2*/carparts[14] = create_box(<box width="33.9"  height="3.2" x={ xx + 109.6} y={ yy +16.1} obj="1" type="2" />);
	/*joint canhão_lado1*/carparts[15] = create_weldjoint(carparts[11],carparts[13], carparts[13].GetWorldCenter());
	/*joint canhão_lado2*/carparts[16] = create_weldjoint(carparts[11],carparts[14], carparts[14].GetWorldCenter());

	}



	public function create_weldjoint(body1, body2, local):b2WeldJoint{ //declara uma função que retorna um b2WeldJoint
		// joint fixo

		var weldJointDef:b2WeldJointDef = new b2WeldJointDef(); //cria a definição do weldjoint
weldJointDef.Initialize(body1, body2, local); // essa função recebe 2 b2Bodys e o local onde vai ficar preso ( b2Vec2 )
var r = world.CreateJoint(weldJointDef); // esse método do world cria o joint e coloca ele no mundo. Esse método além de criar o mundo retorna  um b2WeldJoint
return r; // retorna a variavel r(b2WeldJoint)
	}
	public function create_rvjoint(body1, body2, local,motor:Boolean = true):b2RevoluteJoint{
		// joint que pode rotacionar
		var revoluteJointDef:b2RevoluteJointDef = new  b2RevoluteJointDef();// cria a definição
		revoluteJointDef.Initialize(body1,body2 , local); // junta os dois b2Body onde local é o eixo
		revoluteJointDef.enableMotor=motor; // se a variavel motor for true vai habilitar o motor

		var r = world.CreateJoint(revoluteJointDef); // cria o joint de acordo com a definição



		return r ; // retorna o joint
	}
	function create_boxies(number:Number):void {


		number-=1;
		for (var i = 0; i <= xmlmap.mapa[number].box.length() - 1; i++) {
			boxarray[i]=create_box(xmlmap.mapa[number].box[i]);


		}


	}



	function create_box( xml:XML):b2Body {
		var xxboxShape:b2PolygonShape = new b2PolygonShape();

		var body; // declara uma variavel
		var xfixtureDef:b2FixtureDef = new b2FixtureDef(); 
		var xbodyDef:b2BodyDef = new b2BodyDef();
		xxboxShape = new b2PolygonShape();
		xxboxShape.SetAsBox((xml.@width / 30)/2 , (xml.@height / 30) / 2 );
		xfixtureDef.shape=xxboxShape;
		xfixtureDef.density=2.7;
		if(xml.@density > 0){
			xfixtureDef.density= xml.@density ;//
		}else{
		}

		if (xml.@friction2=="on") {
			xfixtureDef.friction=xml.@friction;
		} else {
			xfixtureDef.friction=0.5;
		}
		if (xml.@restitution2=="on") {
			xfixtureDef.restitution=xml.@restitution;
		} else {
			xfixtureDef.restitution=0.2;
		}
		if (xml.@obj==3) {
			xbodyDef.userData = new ice();
		} else if(xml.@obj==1){
			xbodyDef.userData = new quadra();
		}else
		{
			xbodyDef.userData = new quadra2();
		}
		xbodyDef.userData.width=xml.@width;
		xbodyDef.userData.height=xml.@height;
		if (xml.@angle2=="on") {
			xbodyDef.angle = (xml.@angle * Math.PI) / 180 ;
			xbodyDef.userData.rotation=xml.@angle;
		}
		xbodyDef.type=0;
		if (xml.@type==2) {
			xbodyDef.type=2;
		}
		addChildAt(xbodyDef.userData,0);
		xbodyDef.position.Set(xml.@x / 30 ,xml.@y / 30);
		body=world.CreateBody(xbodyDef);
		body.CreateFixture(xfixtureDef);
		return body;
	}

	function create_circle(xml:XML):b2Body{
		//declara as variaveis
		var xcircleShape:b2CircleShape;
		var body;
		var xfixtureDef:b2FixtureDef = new b2FixtureDef();			
		var xbodyDef:b2BodyDef = new b2BodyDef();

		xcircleShape=new b2CircleShape(xml.@size/30/2);			//cria a forma do circulo
		xfixtureDef.shape=xcircleShape; 
		xfixtureDef.density=1.0;//densidade
		xfixtureDef.friction=0.5;//fricção
		xfixtureDef.restitution=0.2;//restituição 1 = 100%
		xbodyDef.userData = new circle(); // circle() é um movieclip
		xbodyDef.userData.width=xml.@size;//muda o tamanho do displayobject
		xbodyDef.userData.height=xml.@size;
		if (xml.@friction2=="on") {
			xfixtureDef.friction=xml.@friction;
		} else {
			xfixtureDef.friction=0.5;
		}
		if (xml.@type=="1") {
			xbodyDef.type=b2Body.b2_dynamicBody;// dynamicBody não é fixo
		}
		if(xml.@density > 0){
			xfixtureDef.density= xml.@density ; //xml.@density				
		}else{				
		}
		addChildAt(xbodyDef.userData,0);
		xbodyDef.position.Set(xml.@x / 30 ,xml.@y / 30);
		body=world.CreateBody(xbodyDef);
		body.CreateFixture(xfixtureDef);
		return body ;
	}
	function create_circles(number:Number) {
		number-=1;
		for (var i:Number = 0; i <= xmlmap.mapa[number].circulo.length() - 1; i++) {

			circlearray[i]=create_circle(xmlmap.mapa[number].circulo[i]);
		}
	}
	function detonatudo() {
		for (var i:Number = 0; i <= boxarray.length; i++) {
			removeChild(boxarray[i].GetUserData());
			world.DestroyBody(boxarray[i]);
			if (i==boxarray.length-1) {
				i=boxarray.length;
			}
		}
		for (i = 0; i <= circlearray.length; i++) {
			removeChild(circlearray[i].GetUserData());
			world.DestroyBody(circlearray[i]);
			if (i==circlearray.length-1) {
				i=circlearray.length;
			}
		}
		circlearray=[];
		boxarray=[];
		destroy_car();
	}
	function destroy_car(){
		for(var i:Number = 0 ; i  <= 16; i++){
			if(carparts[i] is b2Body){ // se carparts[i] é um b2Body vai retornar true
			carparts[i].GetUserData().parent.removeChild(carparts[i].GetUserData()); // aqui remove o DisplayObject
			world.DestroyBody(carparts[i]); // aqui destroi o b2Body
			}
			if(carparts[i] is b2Joint){ // se carparts[i] for um joint retorna true
				world.DestroyJoint( carparts[i]) ;
				}
		}
		carparts =[]; //zera o array
	}
	function mp1(e:MouseEvent) { // mapa 1
		detonatudo();
		create_circles(1);
		create_boxies(1);
		create_car(-1090 , 0);
	}
	function mp2(e:MouseEvent) {// mapa 2
		detonatudo();
		create_circles(2);
		create_boxies(2);
		create_car(50 , 0);
	}
	function mp3(e:MouseEvent) {// mapa 3
		detonatudo();
		create_circles(3);
		create_boxies(3);			
		create_car(50 , 0);
	}

}
}

 

 

Resultado:

 

http://megaswf.com/serve/1961944/

 

download:

 

arquivo: c_box2d.as e canhao_box2d.fla

https://rapidshare.com/files/1183835285/c.zip

 

arquivo: c_box2d.as e canhao_box2d.fla + o box2d (pasta source)

https://rapidshare.com/files/176347342/Source.zip

 

Se tiverem problemas é só postar

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.