0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

processingとfisicaでアクションゲームのベースを作る

Posted at

はじめに

 Processingでゲームを作る場合、自分でいちから書く方法と、なんらかのライブラリを使う方法があります。宇宙空間を漂うシューティングゲームとかであれば、動きと衝突判定だけなので、自力でも楽ですが、アクションゲームとなると、衝突時の動きを計算するのがとてもに大変です。
 なのでfisicaライブラリを使った場合、アクションゲームはどう書けばいいのか、というサンプルを示します。

環境

MacOS 13.4.1
Processing 4.2
Fisica

物理でうごかす

 fisicaを使ってカーソルキーでキャラクタを動かそうとする場合、キャラクタの位置を直接操作するのではなくて、「力を加えて」、加速度->速度->位置、とfisicaの物理計算に合わせる必要があります。直接、位置を指定すると、予期せず、壁にめり込んだりすることが生じます。より具体的には、次の命令を使って操作します。(細かな違いはわかりませんでした)
addForce()
addImpulse()

サンプル

白い正方形をカーソルキーとスペースキーで操作して、のぼったりするサンプルです。
物理パラメータは、いい感じに調整済みです。

image.png

コード

気づき:
 getMassはあるけど、setMassはなく、サイズで質量が決まる。質量を変えたいときはどうするのかというと、setDensityで濃度調整によって実現する。

 キー入力は「key」と「keycode」の変数の中身は、最後に押された一つしか保持されないようで、カーソル移動しながらジャンプ(スペース)すると、カーソル移動ができなくなり、押し続けているのに、押されてない判定になってしまう。
 なので、各キーに対し、boolean変数を用意して、keyPressedとkeyReleasedでtrue,falseを制御している。

import fisica.*;

FWorld world;
FBox me;  //自分

boolean L_key, R_key;//キャラクタ左右操作用、trueのときは押されてる

void setup() {
  size(1280, 720);//16:9(HD)

  Fisica.init(this);
  world = new FWorld();
  world.setEdges();

  // blockを作成(x,y,w,h)
  addBlock( 400, 600, 200, 20);
  addBlock( 700, 500, 200, 20);
  addBlock(1000, 400, 200, 20);
  addBlock( 800, 300, 100, 20);
  addBlock( 600, 200,  50, 20);

  //自分(x,y)
  me = me(200, 500);

  //重力
  world.setGravity(0, 100);
}

void draw() {
  background(255);
  
  if(L_key){
    me.addForce(-200, 0);
  }
  if(R_key){
    me.addForce(200, 0);
  }

  //5回進めて、1回描画
  world.step();
  world.step();
  world.step();
  world.step();
  world.step();
  world.draw();
}

void keyPressed() {
  //速度Yが0のときだけジャンプ
  if ( key == ' ') {
    if (me.getVelocityY()==0) {
      me.addImpulse(0, -200);  //me.addForce(0, -10000);
    }
  }
  
  //左右移動準備
  if (key == CODED) {
    if (keyCode == LEFT) {
      L_key = true;
    }
    if (keyCode == RIGHT) {
      R_key = true;
    }
  }
}

void keyReleased(){
  if (key == CODED) {
    if (keyCode == LEFT) {
      L_key = false;
    }
    if (keyCode == RIGHT) {
      R_key = false;
    }
  }
}

void addBlock(int x, int y, int w, int h) {
  FBox b = new FBox(w, h);  //サイズ
  b.setPosition(x, y);      //位置
  b.setFill(212, 72, 32);   //色
  b.setStatic(true);        //固定
  b.setFriction(0.2);       //摩擦抵抗
  b.setRestitution(0);      //反発係数
  b.setName("block");       //名前
  world.add(b);
}

FBox me(int x, int y) {
  FBox c = new FBox(40, 40); //サイズ
  c.setDensity(0.25);        //サイズが20x20のときdensity=1なので、40x40のときdensity=0.25にします。
  c.setPosition(x, y);       //位置
  c.setFill(255, 255, 255);  //色
  c.setVelocity(0, 0);       //速度
  c.setDamping(0.3);         //減衰(空気抵抗)
  c.setFriction(0.2);        //摩擦抵抗
  c.setRestitution(0);       //反発係数
  c.setName("me");           //名前
  c.setRotatable(false);     //回転させない
  world.add(c);
  return(c);
}

画像を貼りたいとき

FBoxのattachImageメソッドを使います。
画像が伸びるのを避けるには、細かくブロックを分ける必要があります。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?