본문 바로가기

Cocos2d

Cocos2d Android : 7장. Box2d DynamicBody

//아직 공부가 덜 되었지만 물리엔진에 대해서 포스팅 해볼려고 합니다
//하늘에서 알이 떨어지는 간단한 예제입니다
//lib폴더 안에  box2d-gdxwrap.jar , libgdx.so 파일을 넣어주시고 라이브러리 등록 하셔야 됩니다(첨부했습니다)
  ->에러가 난다면 lib폴더 안에 armeabi 폴더를 만들어서 libgdx.so을 복사해서 넣어주세요~ 
//asset 폴더에 ball.png 파일도 넣어주셔야 합니다^^



DropBall.java
=========================================================================================================

import java.util.Iterator;
import java.util.Random;

import org.cocos2d.actions.UpdateCallback;
import org.cocos2d.layers.CCColorLayer;
import org.cocos2d.layers.CCLayer;
import org.cocos2d.layers.CCScene;
import org.cocos2d.nodes.CCDirector;
import org.cocos2d.nodes.CCSprite;
import org.cocos2d.types.CGPoint;
import org.cocos2d.types.CGSize;
import org.cocos2d.types.ccColor4B;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;


public class DropBall extends CCColorLayer{
protected World mworld;
private Vector2 vec;
protected static final float FPS = (float) CCDirector.sharedDirector()
.getAnimationInterval();
protected  float PTM_RATIO = 32.0f;
float scaledWidth;
float scaledHeight;
CGSize s;
private static float rdelta = 0;
  

static {
        System.loadLibrary("gdx"); 
 
protected DropBall(ccColor4B color) {
super(color);
this.vec = new Vector2(0, -9.8f);
s = CCDirector.sharedDirector().winSize();
mworld = new World(vec, true);
mworld.setContinuousPhysics(true);
scaledWidth = s.width/PTM_RATIO;
scaledHeight = s.height/PTM_RATIO;
setGround();
startTickBody();
schedule("addBall",1f);
}
public  void addBall(float dt){//랜덤 위치에 볼 애드
Random r = new Random();
int xPos = r.nextInt(480);
CGPoint dropPos= CGPoint.ccp(xPos, 700f);
dropBall(dropPos);
}
public static CCScene scene() {
CCScene scene = CCScene.node();
CCLayer layer = new DropBall(ccColor4B.ccc4(255, 255, 255, 255));
scene.addChild(layer);
return scene;
}
private void setGround() {//물리세계 세팅
Vector2 bottomLeft = new Vector2(0f, 2.4f);
Vector2 topLeft = new Vector2(0.0f, scaledHeight);
Vector2 topRight = new Vector2(scaledWidth, scaledHeight);
Vector2 bottomRight = new Vector2(scaledWidth,  2.4f);

BodyDef bodyDef = new BodyDef();
bodyDef.position.set(0f, 0f);
PolygonShape box;
Body body;
box = new PolygonShape(); 
body = mworld.createBody(bodyDef);

box.setAsEdge(bottomLeft, bottomRight);
body.createFixture(box, 0);

box.setAsEdge(topLeft, topRight);
body.createFixture(box, 0);

box.setAsEdge(topLeft, bottomLeft);
body.createFixture(box, 0);

box.setAsEdge(topRight, bottomRight);
body.createFixture(box, 0);
}
private void dropBall(CGPoint pos) {//알 DynamicBody설정
CCSprite dball = CCSprite.sprite("ball.png");
this.addChild(dball);
BodyDef bodyDef = new BodyDef();//바디의 타입과 위치 지정
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(pos.x / PTM_RATIO, pos.y / PTM_RATIO);

CircleShape bCircle = new CircleShape();// 물체의 형태 지정
bCircle.setRadius(.5f);// 
Body body = mworld.createBody(bodyDef);// 세계에 바디 생성
synchronized (mworld) {
body.setUserData(dball);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = bCircle;
fixtureDef.density = 1.0f;// 밀도
fixtureDef.friction = 0.2f;// 마찰
fixtureDef.restitution = 0.2f;// 탄성
body.createFixture(fixtureDef);// 바디에서 물체 생성
}
}
protected void startTickBody(){
this.schedule(tickCallback);
}
protected void tickBodies(Body b){
Object userData = b.getUserData();
if (userData != null && userData instanceof CCSprite){
final CCSprite sprite = (CCSprite) userData;
final Vector2 pos = b.getPosition();
sprite.setPosition(pos.x * PTM_RATIO, pos.y * PTM_RATIO);
}
}
public UpdateCallback tickCallback = new UpdateCallback() {
@Override
public void update(float d) {
tick(d);
}
};

public synchronized void tick(float delta) {
if ((rdelta += delta) < FPS)
return;

synchronized (mworld) {
mworld.step(FPS, 8, 1);
}
rdelta = 0;
Iterator<Body> it1 = mworld.getBodies();
while (it1.hasNext()){
Body b = it1.next();
tickBodies(b); 
}
}
@Override
public void onEnter() {
super.onEnter();
}
@Override
public void onExit() {
super.onExit();
}

}
=======================================================================================================