Newer
Older
Cactus / app / src / main / java / org / ntlab / radishforandroidstudio / cactusClient / models / OwnPlayerModel.java
package org.ntlab.radishforandroidstudio.cactusClient.models;

import android.content.res.Resources;
import android.view.MotionEvent;
import android.view.View;

import net.arnx.jsonic.JSON;

import org.ntlab.radishforandroidstudio.cactusClient.connections.CharacterConnection;
import org.ntlab.radishforandroidstudio.framework.animation.Animation3D;
import org.ntlab.radishforandroidstudio.framework.event.PadEvent;
import org.ntlab.radishforandroidstudio.framework.gameMain.OnlineModel;
import org.ntlab.radishforandroidstudio.framework.gameMain.OvergroundActor;
import org.ntlab.radishforandroidstudio.framework.listener.PadListener;
import org.ntlab.radishforandroidstudio.framework.model3D.ModelFactory;
import org.ntlab.radishforandroidstudio.framework.model3D.Object3D;
import org.ntlab.radishforandroidstudio.framework.model3D.Position3D;
import org.ntlab.radishforandroidstudio.framework.model3D.Quaternion3D;
import org.ntlab.radishforandroidstudio.framework.model3D.Universe;
import org.ntlab.radishforandroidstudio.framework.physics.Solid3D;
import org.ntlab.radishforandroidstudio.framework.physics.Velocity3D;
import org.ntlab.radishforandroidstudio.framework.view3D.Camera3D;
import org.ntlab.radishforandroidstudio.java3d.Appearance;
import org.ntlab.radishforandroidstudio.java3d.Material;
import org.ntlab.radishforandroidstudio.java3d.Vector3d;

import java.util.ArrayList;

public class OwnPlayerModel implements PadListener, OnlineModel {
    private boolean isPadTouched = false; //Padのタッチ判定
    private float touchPadX = 0.0f;
    private float touchPadY = 0.0f;
    double n = 1.0;

    private OvergroundActor actor;
    private Camera3D camera;
    private Player player;
    private CharacterConnection con;
    private int nextConnectRenaimdTime = 0;
    private int connectInterval = 300;
    private String playerId;
    private OwnBulletsModel bullets;

    public OwnPlayerModel(Player player, Resources resources, Universe universe, Camera3D camera, String playerId, String instanceId) {
        this.player = player;
        setPlayerId(playerId);
        setInstanceId(instanceId);
        bullets = new OwnBulletsModel(resources, universe, instanceId, playerId);

        // キャラクタの作成
        Appearance ap1 = new Appearance();
        Material m = new Material();
        m.setDiffuseColor(0.0f, 0.3f, 1.0f);
        m.setAmbientColor(0.0f, 0.0f, 0.0f);
        m.setEmissiveColor(0.0f, 0.0f, 0.0f);
        m.setSpecularColor(0.0f, 0.0f, 0.0f);
        m.setShininess(5.0f);
        ap1.setMaterial(m);
        Object3D pochaBody = null;
        try {
            pochaBody = ModelFactory.loadModel(resources, "pocha.stl", ap1).createObject();
            Animation3D pochaAnimation = null;    //AnimationFactory.loadAnimation("data\\pocha\\walk.wrl");
            actor = new OvergroundActor(pochaBody, pochaAnimation);
            actor.setPosition(new Position3D(0.0, 1.0, 0.0));
            universe.place(actor);
        } catch (Exception e) {
            e.printStackTrace();
        }

        this.camera = camera;
        camera.setViewPoint(actor.getPosition().add(0.0, 1.5, 0.0));
        camera.setViewLine(actor.getDirection());
        camera.setFieldOfView(1.5);
        camera.setBackClipDistance(10000.0);
        updateCamera(n);
    }

    public void setPlayerId(String id) {
        playerId = id;
    }

    public void updateCamera(double n) {
        Vector3d charaVector3d = actor.getDirection();
        charaVector3d.normalize();//キャラの向きを単位ベクトルに
        camera.setViewPoint(actor.getPosition().add(5.0 * charaVector3d.getX(), charaVector3d.getY() + 5.5 - n, 5.0 * charaVector3d.getZ()));//視点
        camera.setViewLine(new Vector3d(-5.0 * charaVector3d.getX(), charaVector3d.getY() - 2.5 + n, -5.0 * charaVector3d.getZ()));//視線
    }

    /**
     * パッドを動かしたときのイベント処理
     *
     * @param event イベントの情報
     * @return
     */
    @Override
    public boolean onEvent(PadEvent event) {
        Vector3d charaVector3d = actor.getDirection();
        charaVector3d.normalize();//キャラの向きを単位ベクトルに
        MotionEvent motionEvent = event.getMotionEvent();

        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN || motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
            isPadTouched = true;
            touchPadX = (float) (Math.cos(event.getAngle()) * event.getLength());
            touchPadY = (float) (Math.sin(event.getAngle()) * event.getLength());
        } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
            Velocity3D vel = actor.getVelocity();
            vel.setX(0);
            vel.setY(0);
            actor.setVelocity(vel);
            isPadTouched = false;
        }
        return false;
    }

    @Override
    public void update(double interval) {
        updateCamera(n);
        Velocity3D vel = actor.getVelocity();
        Vector3d actorVec = actor.getDirection();
        bullets.setPosition(actor.getPosition());
        bullets.setAngle(((Solid3D) (actor.getBody())).getQuaternion());

        if (isPadTouched) {
            Vector3d up = new Vector3d(0, 1, 0);
            Vector3d total = new Vector3d();
            Vector3d right = new Vector3d();

            right.cross(actorVec, up);

            Vector3d touchXVec = right.clone();
            Vector3d touchYVec = actorVec.clone();

            touchXVec.scale(touchPadX * -5);
            touchYVec.scale(touchPadY * 5);

            total.add(touchXVec);
            total.add(touchYVec);
            total.y = vel.getY();

            vel.setVector3d(total);
            actor.setVelocity(vel);

        } else {
            vel.setX(0.0);
            vel.setZ(0.0);
            actor.setVelocity(vel);
        }

        nextConnectRenaimdTime -= interval;
        if (nextConnectRenaimdTime <= 0) {
            nextConnectRenaimdTime = connectInterval;
            sendPlayerInfo();
        }
    }

    public void sendPlayerInfo() {
        con = new CharacterConnection(playerId);
        con.setCallBack(this);

        Quaternion3D q = ((Solid3D) (actor.getBody())).getQuaternion();
        player.setPosition(actor.getPosition());
        player.setAngle(q);

        JSON json = new JSON();
        con.addFormParam("characterID", player.getCharacterID());
        con.addFormParam("cameraState", json.encode(player.getCameraState()));
        con.addFormParam("position", json.encode(player.getPosition()));
        con.addFormParam("animationClassToStart", json.encode(player.getEmoteState()));
        con.addFormParam("angle", "{ \"x\":" + q.getX() + ", \"y\":" + q.getY() + ", \"z\":" + q.getZ() + ", \"w\":" + q.getW() + "}");
        con.doPut();
    }

    @Override
    public void setInstanceId(String id) {
        player.setInstanceID(id);
    }

    @Override
    public void onResponse(String response) {

    }

    public void jump() {
        if (actor.isOnGround()) {
            Velocity3D vel = actor.getVelocity();
            vel.setY(vel.getY() + 5);
            actor.setVelocity(vel);
            System.out.print("Jumpしました。");
        } else {
            System.out.print("地に足がついてない。");
        }
        System.out.print("onClick押されましたよ。");
    }

    public void changeViewpoint(float eyeX, float eyeY) {
        actor.rotY(0.1 * (0.5f - eyeX));
        if (n <= 5 && n >= 0) {
            n += (0.5f - eyeY);
        } else if (n > 5) {
            n = 5;
        } else if (n < 0) {
            n = 0;
        }
    }

    public OwnBulletsModel getBulletsModel() {
        return bullets;
    }

    public boolean onTouch(View v, MotionEvent event) {
        System.out.println("RWTUIFragment touch");
        return false;
    }

    public void logout() {
        con = new CharacterConnection(playerId);
        con.setCallBack(this);
        con.doDelete();
    }

    public void deleteBullets(ArrayList<String> bullets) {
        this.bullets.deleteBullets(bullets);
    }
}