happasukeの覚書

私がググらなくてもいいよう記事にします。またそのほかにも感じたことも書き綴りたいと思います。

スネークゲームをスマホの加速度センサーで動かす

先日書いたスネークゲームをパソコンだけでなくスマホ用にも書き換えてみました。

書き換えた点は以下の2点です。

  1. サイズをスマホ用に対応させる
  2. 蛇を動かすのに加速度センサーを使う

順にみていきます。

 

1.サイズをスマホ用に対応させる。

html内のhead部分を書き換えました。

metaとしてviewportを指定しました。

表示する幅をこれで固定できます。

 

<head>
    <title>snakegame</title>
    <meta charset="UTF-8"></meta>
    <meta name="keywords" content="snakegame">
    <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximumscale=1.0,user-scalable=no">
</head>

 

2.蛇を動かすのに加速度センサをー使う

せっかくなので加速度センサーで操作できるようにします。

傾けた方向に蛇の頭が向くようにしただけです。

 

まず、htmlに加速度センサーのイベントを追加します。

 最初に割り込みが入ったときだけ元の位置として保存して、そのあとはその値との差分を見てどの方向に傾いているかを判断させます。

 tibanmeflgはセンスがないですね。

window.addEventListener("devicemotion", function(event1){

        x = event1.accelerationIncludingGravity.x;
        y = event1.accelerationIncludingGravity.y;

        if(itibanmeflg==0){
            itibanmeflg = 1;
            basex = x;
            basey = y;
        }

}, true);

 そしてintervalの中で以下の関数を毎回読み込ませます。これでどの方向に進むべきかがわかります。

 body=onLoad()で以下の関数を読み込ませ、

function setScript(){
    init();
    timerId = setInterval("snakeScript()",300);
}

 snakeScript()の中で以下の関数を実行させます。

function readVector(){
    if(basex-x>1){
        if(mike.v!=3)mike.v = 4;
    }else if(basex-x<-1){
        if(mike.v!=4)mike.v = 3;
    }else if(basey-y>1){
        if(mike.v!=2)mike.v = 1;
    }else if(basey-y<-1){
        if(mike.v!=1)mike.v = 2;
    }
}

 こんなところでできます。いい時代になったものです。

 

 

スネークゲームをcanvasで動かしてみる

 先日Processingでスネークゲームを作成しました。

 後輩が課題で作っていたので便乗しました。

 

 それをHTML5canvasに書き換えて動かしてみます。

 

 とりあえずパソコン向けにキーボード操作で動かせるようにしてみます。

 作成したコードがこちら。

<!DOCTYPE html>
<html>
<head>
    <title>snakegame</title>
    <meta charset="UTF-8"></meta>
</head>

<script type="text/javascript">

<!--
var canvas;
var context;

var mouse;    //food's name
var mike;    //snake's name
var c;
var timerId;
var sub=0;

document.addEventListener("keydown",readKey);


var foodClass = (function(){
    //constructor
    var foodClass = function(){
        this.x;
        this.y;
    };

    //method
    var t = foodClass.prototype;

    t.makefood = function(){
        this.x = Math.ceil(Math.random()*24);
        this.y = Math.ceil(Math.random()*24);
    };

    t.drawfood = function(){
        context.fillStyle = 'rgb(0,0,255)';
        context.fillRect(this.x*20,this.y*20,20,20);
    };

    return foodClass;
})();


var snakeClass = (function(){
    //constructor
    var snakeClass = function(){
        this.out = 0;
        this.x = 12;
        this.y = 12;
        this.l = 1;
        this.v = 2;//1:upper 2:down 3:left 4:right
        this.xelm = new Array(300);
        this.yelm = new Array(300);
    };

    //method

    var t = snakeClass.prototype;

    t.falldown = function(){
//         context.clearRect(0,0,500,500);//screen reset
    };

    t.drawSnake = function(){
        if(this.x<25 && this.y<25 && this.x>0 && this.y>0 && this.out==0){

              switch(this.v){
                case 1:this.y--;break;
                case 2:this.y++;break;
                case 3:this.x--;break;
                case 4:this.x++;break;
              }

              this.update();


            context.fillStyle = 'rgb(255,0,0)';

            for(var i=0;i<this.l;i++){
                context.fillRect(this.xelm[i]*20,this.yelm[i]*20,20,20);
            }

        }else{
            clearInterval(timerId);
            alert("game over!  score:" + (this.l-1));

            console.log("elements:")
            for(var i=0;i<this.l;i++){
                console.log(this.xelm[i] + ',' + this.yelm[i]);
            }
            console.log("cul:x" + this.x +' y'+this.y);
        }
    };

    t.eaten = function(){
        console.log("");
        console.log(this.l + ','  + this.x + ',' + this.y);

        this.xelm[this.l] = this.x;
        this.yelm[this.l] = this.y;
        this.l++;

        for(var i=0;i<this.l;i++){
            console.log(this.xelm[i] + ',' + this.yelm[i]);
        }
    };

    t.update = function(){
        for(var i=this.l-1;i>0;i--){
            this.xelm[i] = this.xelm[i-1];
            this.yelm[i] = this.yelm[i-1];
            if(this.yelm[i]==this.y&&this.xelm[i]==this.x){
                this.out = 1;
            }
        }

        this.xelm[0] = this.x;
          this.yelm[0] = this.y;

    };

    return snakeClass;
})();


function setScript(){
    init();
    timerId = setInterval("snakeScript()",200-sub);
}

function figurePropatiesInit(){
    var context = canvas.getContext('2d');

    context.strokeStyle = 'rgb(0,255,0)';
    context.fillStyle   = 'rgb(0,0,255)';
}

function init(){
    canvas = document.getElementById('sketch');
    context = canvas.getContext('2d');
    figurePropatiesInit();

    mouse = new foodClass();
    mouse.makefood();

    mike = new snakeClass();
    c=0;
}


function snakeScript(){

    if(canvas.getContext==null){
        alert("not support");
    }else{

        context.clearRect(0,0,500,500);//screen reset

        mike.drawSnake();
        mouse.drawfood();

        if(mike.x==mouse.x && mike.y==mouse.y){
            mike.eaten();
            mouse.makefood();
        }

        sub += 5;
    }
}


function readKey(e){
    var key = e.keyCode;

    switch(key){
        case 65://a
            if(mike.v!=4)mike.v = 3;
            break;
        case 68://d
            if(mike.v!=3)mike.v = 4;
            break;
        case 87://w
            if(mike.v!=2)mike.v = 1;
            break;
        case 83://s
            if(mike.v!=1)mike.v = 2;
            break;
    }
}

//-->
</script>

<style type="text/css">
    body{
        width:1000px;
    }

    #sketch{
        background-color: #000000;
    }
</style>

<body onLoad="setScript()">

<canvas id="sketch" width="500" height="500">

</canvas>

</body>
</html>

 canvasは初めて使いましたが本当に簡単にものが作れてしまいますね。すごいです。

 

 html5ではスマホの加速度センサーを使えるようなので次はスマホでも動かせるようにしてみようかと思います。

 

 

GY-521をlpcxpresso1768で使ってみる

 6軸加速度センサーのGY-521をlpcxpresso1768で使ってみました。

 xpressoはmbedと互換があるので、ベースとなるプログラムはmbedのデベロッパーのページから拾ってきました。

https://developer.mbed.org/users/onehorse/code/MPU6050IMU/

 便利な時代です。

 これをmbedのオンラインコンパイラで読み込んでそのままxpresso用にエクスポートします。

 デバッグとしてxpressoからシリアルに出力します。

f:id:happasuke:20150120185203j:plain

 mbedでは

 Serial pc(USBTX,USBRX);

 でしたがXpressoにはminiBはついていないので

 Serial pc(p13, p14);

 とします。

 

 よし動かそうとxpressoで読み込んで使おうとしたところここで問題が。

 MPU6050というセンサーのアドレスの値を以下のコードで読み取るのですが

  uint8_t whoami = mpu6050.readByte(MPU6050_ADDRESS, WHO_AM_I_MPU6050);  // Read WHO_AM_I register for MPU-6050

 whoamiの戻り値が0x68になるべきところ0x7aとなっていました。

 

 ヘッダファイルやデータシートを見てもわからない。

 

 ということで

  // Read the WHO_AM_I register, this is a good test of communication
  uint8_t whoami = mpu6050.readByte(MPU6050_ADDRESS, WHO_AM_I_MPU6050);  // Read WHO_AM_I register for MPU-6050
  pc.printf("I AM 0x%x\n\r", whoami); pc.printf("I SHOULD BE 0x68\n\r");
 
if (whoami == 0x68) // WHO_AM_I should always be 0x68
  {  
    pc.printf("MPU6050 is online...");
    wait(1);

   

 これを

  // Read the WHO_AM_I register, this is a good test of communication
  uint8_t whoami = mpu6050.readByte(MPU6050_ADDRESS, WHO_AM_I_MPU6050);  // Read WHO_AM_I register for MPU-6050
  pc.printf("I AM 0x%x\n\r", whoami); pc.printf("I SHOULD BE 0x68\n\r");
 
if(whoami){  
    pc.printf("MPU6050 is online...");
    wait(1);
   

 このようにしました。そうしたら値が返ってきました。

 モジュールのアドレスはあまり関係ないのですかね。

 

 

php導入

さくらインターネットから借りているサーバーにphpを導入しました。

apt-cache search php5でapt-getでパッケージがあるかどうかを調べたところ

php5 - server-side, HTML-embedded scripting language (metapackage)

ありました。phpのインストールはapt-get install php5でできました。