DreamerDreamのブログ

夢想家の夢です。〜揚げたてのモヤっとしたものをラフレシアと共に〜

なぜゲームにハマるのか?

僕は基本的にあまりゲームというものをしない。

町中でスマホゲームなんてしている人を「他にすることないんかい?」と白い目で見ている方だ(だった)。だが、不覚にも先日ハマってしまったゲームがある。

何度かお誘いは受けていたので内容は知っていた。

そしてゲームの内容より動きが面白いので最初はほんの少し動作の検証をしてみるつもり・・・だった...

  • 重力エンジンっぽい動きをしている
  • キャラクタが数種類で使い回ししている
  • 画面上でキャラクタの遠近判断をしている
  • 他アプリと連携している

 

 

 

 

その名は

 

 

 

 

 

 

 

ツムツム

 

 

なぜだ???

 

なぜ今頃???

 

いや

 

 

そうではなく、ツムツムというゲームというものにハマるのか?ということを検証してみることにした。

 

①操作が単純

②時間制限

③ミッションが明確

④貸し借り

 

①について

3つ以上の同じキャラ「ツム」を結ぶだけ。

これなら片手で操作できる、つまり「ながら」が可能だ。

「難しそうだから」という心のリミットが外れる。

「やってもいいかな?」と許可してしまう。

 

②について

時間無制限なら「いま時間無いしな」とゲームから遠のく理由になるが、短時間(ツムツムの場合基本的に1分)だと「時間がない」というリミットが外れる。

これも「やってもいいかな?」と許可してしまう。

 

③について

「今日のミッション」として明確なポイントが標示される。

これをクリアすることに夢中になりついつい自分に課せた制限時間を外してしまう。

これは「やらなければ」というノルマを課している。

 

④について

友達に♥をプレゼントしたり♥を貰ったりすることでゲーム出来る回数が増える。

友達から♥をプレゼントされると貰った分しなくてはいけないというノルマを感じる。

そして♥を貰ったら自分が♥をプレゼント出来る状態になるとついつい友達にあげたくなる。借りを返すという心情をうまく利用している。

これも「やらなければ」というノルマを課している。

 

 

つまり

「やってもいいかな」という許可を与え、「やらなければならない」というノルマを感じさせているのだ。

実にうまい戦略だ。

f:id:DreamerDream:20180608123411p:plain

LINEスタンプの売上げの実際

2月あたりから新たな趣味の一つとしてLINEスタンプを作っているのですが、「LINEスタンプ 売り上げ」等で検索するとネガティブな記事ばかりが目に留まるものです。

 

実際、他人の不幸は蜜の味と言うように「わわわ、、売り上げ0になっちゃったwなんじゃそりゃーwwwちゃんちゃん♪」という記事の方がおもしろおかしくて良いのだろうけれど、それではこれからスタンプを作ろうという人が読んだ時に夢が無さ過ぎて熱が冷めてしまうだろうと思うんですよね。

で、分配額が確定したので以前にLINEスタンプの売り上げを伸ばす方法でまとめたように実際にシリーズ化した結果を公表しようと思ったのです。

dreamerdream.hateblo.jp

 

「すくなっ」って思うか「おおっ」って思うかは人それぞれなのですが、僕的には趣味で得られるお小遣いとしては大満足です。

 

ということで分配額公開!

f:id:DreamerDream:20160512090345p:plain

初めての月の4千円弱からスタートして徐々に売り上げを伸ばして先月は3万円弱になりました。

※(実際にはこの金額から源泉所得税が引かれ、銀行振込の手数料が引かれます^^;)

 

まあ、このまま売り上げが伸びれば万歳なのですが、やはり売り上げがかなり落ち込んでしまったスタンプもあります。

毎月1つづつでも新たに追加すれば2万円前後をキープ出来るのではないかな?というところです。

 

尚、こちらのブログではスタンプの宣伝、公開しません。

なぜなら「スタンプ 売り上げ」等でこの記事が検索ヒットする人ってスタンプを買ってくれる人ではなく作る側の人だからです。

共に頑張ってまいりましょうw

 

 

↓ペンタブ、スタンプのデザインするなら必須です!

RaspberryPiでモニタースリープ時にHDMIの出力をOFFにする(HDMI出力先によるらしい)

以前、モニタースリープ時に/dev/shm/へモニタースリープ状態を書き出す方法を紹介した。 

<過去記事>

dreamerdream.hateblo.jp

 

PiTFTでスリープ時にバックライトが消えないがHDMI出力も同じように画面が真っ暗になるだけでモニタの電源は消えない。

なので今回はHDMIへの出力をOFFにするようにする。

HDMIへの出力ON/OFFはコンソールから扱えるそうだ。

参考にさせてもらったサイト

Raspberry Piで、HDMI出力をON/OFFする | Soramimi Vox

Raspberry PiでHDMIで接続したディスプレイの制御 - Qiita

 

ということは以前のコードを改造したらON/OFF制御できるんじゃないか?と思いモニタースリープを検知するコードと置き換えることにした。

-- dodpms.cpp --

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <unistd.h>

extern "C" {
#include <X11/Xlib.h>
#include <X11/Xproto.h>
#include <X11/extensions/dpms.h>
}

Display *dpy = NULL;
CARD16 standby, suspend, off;

int main(int argc, const char **argv)
{
dpy = XOpenDisplay(NULL);
if (! dpy) {
fprintf(stderr, "XOpenDisplay failed.\n");
exit(1);
}

CARD16 state;
BOOL onoff = False;
for(;;){
usleep(300000);
DPMSInfo(dpy, &state, &onoff);
if(state != 0 && access("/usr/local/bin/sleep_hdmi",0)==0 && access("/usr/local/bin/active_hdmi",0)==0 ){
system("/usr/local/bin/sleep_hdmi");
for(;;){
usleep(300000);
DPMSInfo(dpy, &state, &onoff);
if(state == 0) break;
}
system("/usr/local/bin/active_hdmi");
}
}
}

 

つまり、スリープ時には/usr/local/bin/sleep_hdmiに書いたスクリプトが呼ばれ、復帰時には/usr/local/bin/active_hdmiに書いたスクリプトが呼ばれるようにした。

(なぜか/usr/local/bin/sleepにすると起動時にスリープになってしまった。何か違うプログラムから呼ばれているのだろう)

 

コレを過去記事と同様にコンパイルして保存してスタート時に呼ばれるよう設定すると完了。

 

HDMI 出力OFFスクリプト

-- /usr/lcoal/bin/sleep_hdmi --

#!/bin/sh
tvservice -o
exit 0

 

HDMI 出力再開スクリプト

-- /usr/local/bin/active_hdmi --

#!/bin/sh
tvservice -p
fbset -depth 8
fbset -depth 16 #8/16/24等環境によるらしい
exit 0

 

・・・しかし僕の環境ではOFFはできるもののONがうまくいかない。。ONまでは出来るけどどうやらfbsetあたりでつまづいているらしい。

なんでだろ? HDMI→DVI変換しているからかもしれない。

PiTFTのバックライトを画面スリープと同時に消す

 以前に書いたPiTFTのバックライトがスリープ時にも消えない。

dreamerdream.hateblo.jp

 

 

 このままでも使えるんだけどもLEDの寿命と発熱の問題が出てきそうなのでスリープと同時にバックライトを消すスクリプトを書いた。

 

Raspbianで画面スリープを検知する方法が見当たらなかったので前回書いた画面スリープ時に書き出される/dev/shm/sleep_displayファイルを参照するという方法を利用することにした。

dreamerdream.hateblo.jp

 

 

 

-- /usr/local/lib/pitft_backlightd.py --

#!/usr/bin/python

import RPi.GPIO as GPIO
import time, sys, os, atexit
import file_mng

LED = 18

Hz = 100.0
DUTY = 100.0

DUTY_etc = "/etc/pitft_backlight"
SLEEP = '/dev/shm/sleep_display'


def end():
    GPIO.cleanup()

def init():
    atexit.register(end)
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(LED, GPIO.OUT)

def pwm():
    global DUTY
    dt = DUTY
    init()
    p = GPIO.PWM(LED,Hz)
    p.start(0)
    p.ChangeFrequency(Hz)
    while 1:
        data = file_mng.load_line(DUTY_etc, 1)
        if('not Load' != data):
            try:
                dt = float(data)
                if(dt < 0):
                    dt = 0.0
                if(100 < dt):
                    dt = 100.0
            except:
                dt = 100.0
        data = file_mng.load_line(SLEEP, 1)

        if("1" == data):
            p.ChangeDutyCycle(0.0)
        else:
            p.ChangeDutyCycle(dt)

            time.sleep(0.3)

    p.stop()

def fork():
    pid = os.fork()

    if pid > 0:
        f = open('/var/run/pitft_backlightd','w')
        f.write(str(pid)+"\n")
        f.close()
        sys.exit()

    if pid == 0:
        pwm()

    if __name__=='__main__': 
        pwm()

 

100HzでPWMを出力、/dev/shm/sleep_displayを参照して1ならGPIO18にDuty0を、0、もしくはファイルが無いならDuty100を出力するという単純な動作。

Duty0って出力OFFじゃないの?って思ったが違うらしい。よくわからないがPWM出力しないとOFFにならなかった。また、ラズパイをOFFにするとPWM出力されないのでバックライト点灯しっぱなしになる。この辺りはマイコンとかで主電源を制御する必要がありそう。

 

また/etc/pitft_backlightにDuty値を設定することでアクティブ時の照度を設定出来るようにした。しかしPythonでのPWMはあまり正確ではないらしく、チラチラするので100か0で使うのがベターだと感じた。

file_mngは以前に書いたものを利用

dreamerdream.hateblo.jp

 

 

これをデーモンとして動作させることでPiTFTのバックライトLEDを制御できるようになった。

 

Raspbianでモニタースリープ状態を出力する

RaspbianでHDMI出力をしていると操作をしないとモニタがスリープ状態(真っ黒画面)になる。

そこまでは良いのだがモニタのバックライトは点灯しっぱなしだ。

 

PiTFTというモニタを手に入れたのでこのスリープ時にバックライトを何とか消したいと思った。

dreamerdream.hateblo.jp

 

 

しかし、どういうわけかモニタのスリープ状態を読み込むための参考資料が見当たらなかった。

 

ということでまずモニタのスリープ状態を/dev/shm/sleep_displayにスリープなら1、アクティブなら0と書き出すコードを書いた。

 

参考にさせてもらったのはこちら

http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11157837996

C++のコードだ。

僕はC++はわからないが見た限りXorgのライブラリを読んで300000us(300ms)ごとにXorgの状態を取得し、スリープになれば「/usr/local/bin/blankevent」が存在すれば実行し、モニターが復帰すればループを抜けるというコードだと見える。

なのでこれを改造してファイルを書き出すようにした。

-- /usr/local/lib/dodpsm.cpp --

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <unistd.h>

extern "C" {
#include <X11/Xlib.h>
#include <X11/Xproto.h>
#include <X11/extensions/dpms.h>
}

Display *dpy = NULL;
CARD16 standby, suspend, off;

int main(int argc, const char **argv)
{
dpy = XOpenDisplay(NULL);
if (! dpy) {
fprintf(stderr, "XOpenDisplay failed.\n");
exit(1);
}

CARD16 state;
BOOL onoff = False;
for(;;){
usleep(300000);
DPMSInfo(dpy, &state, &onoff);
if(state != 0 && access("/dev/shm",0)==0){
system("echo 1 > /dev/shm/sleep_display");
for(;;){
usleep(300000);
DPMSInfo(dpy, &state, &onoff);
if(state == 0) break;
}
system("echo 0 > /dev/shm/sleep_display");
}
}
}

 

 

モニタスリープ時に/dev/shmディレクトリがあれば

"echo 1 > /dev/shm/sleep_display"

が実行され、

アクティブになれば

"echo 0 > /dev/shm/sleep_display"

が実行される。

 

これをコンパイルして実行ファイルを/usr/local/binに保存する

sudo gcc -o dodpms dodpms.cpp -lXext -lX11
sudo cp dodpms /usr/local/bin

実行権限の忘れずに付ける

sudo chmod 755 /usr/local/bin/dodpms

 

X起動時にこのプログラムが実行されるように

/etc/lightdm/lightdm.conf

の内容を変更する。

#session-setup-script=

session-setup-script=/usr/bin/startscript

と設定して、
ーーー!注ーーーー
[LightDM]以下の
Seat defaults内にある
# session-setup-script =
ではなく、
[SeatDefaults]以下の
session-setup-script=

ーーーーーーーーー

 

/usr/bin/startscriptを作成する

--- /usr/bin/startscript ---
#!/bin/sh
/usr/local/bin/dodpms &
exit 0

 

実行権限も忘れないように付ける。

これで再起動でX起動時にstartscriptの内容が実行される。

ファイルにスリープで1、アクティブで0が保存されてたら成功だ。

 

X起動ににユーザー、パスワードが問われたら今まで作ったファイルの所有者情報が間違っているかもしれないので要確認。

PiTFTをインストールして必要な線だけ取り出して延長する

f:id:DreamerDream:20160402084842j:plain

 

PiTFTを入手した。

ラズベリーパイの調理法 大きくなった PiTFT 3.5" 480x320

3.5インチの抵抗被膜型タッチパネル液晶モニタだ。

使用ハードウェアピンは、SPIピン(SCK, MOSI, MISO, CE0, CE1)、GPIOピン(#24, #25, #18)。

と書かれているが情報が少なく苦労したので備忘録として残すことにする。

 

f:id:DreamerDream:20160402084905j:plain

 

 

<追記 2020年>

以下の方法でのインストールは情報が古く出来なくなっていたためインストール方法の情報を更新しました↓

dreamerdream.hateblo.jp

 

 

 

ーー インストール ーー

単純にGPIOピンに刺して電源ONすると最初は真っ白の画面が表示される。

PiTFTを設定したカーネルイメージを利用するという方法もあるが、僕は現環境をそのまま使いたかったので、まずSDカードのバックアップをとり現環境に追加インストールすることにした

 

インストール前に自作のGPIOを利用しているアプリケーションは全部無効にする必要がある。

自分用メモ(sudo systemctl disable gpio_fan_controld)

アップデートもしておく

sudo apt-get update

sudo apt-get upgrade

 

 

まずコチラの簡易インストールという方法を試してみた。

テックシェアストア(TechShareStore)

ダメだった。OSのバージョンの違いなのか原因はわからないがHDMIで「startx」とすると一度だけ映ったのだがその後エラーを吐いて映らなかった。

 

コチラの方法でインストール成功した。

apt-getからブートローダーをインストールする方法

Adafruit PiTFT 3.5" Touch Screen for Raspberry Pi - IT LinesIT Lines

curl –SLs https://apt.adafruit.com/add | sudo bash
sudo apt–get install raspberrypi–bootloader

(↑かなり時間がかかる)

sudo apt–get install adafruit–pitft–helper
sudo adafruit–pitft–helper –t 35r

再起動でディスプレイが有効になった。

真っ白画面がしばらくすると黒くなってモニタにコンソールが表示されるようになる。

 

ーー インストール終了 ーー

 

ここからが本題

で、直接GPIOに刺したらモニタ裏の端子を使って他の信号をやりとりできるらしいがどの端子をモニタが使ってどの端子がフリーなのか?という情報が少なかった

 

結局必要な端子は

・SPIピン(SCK, MOSI, MISO, CE0, CE1)

・GPIOピン(#24, #25, #18)

・電源5V

GND

の計10本だった。

f:id:DreamerDream:20160402084923p:plain

 

参考にしたのはこのページ一番したの回路図と配線図

Adafruit PiTFT 3.5" Touch Screen for Raspberry Pi - IT LinesIT Lines

それを元に使われている端子を図に起こしたのがコチラ

RPi1 B+ 側の端子

赤四角がPiTFTの端子が重なる部分

赤●がPiTFTで使われている部分

黒○はGND

青●が空き端子

f:id:DreamerDream:20160402084942p:plain

赤●端子(電源5Vは2つだから1つにする)+GNDで接続するとちゃんと表示された。

f:id:DreamerDream:20160402084842j:plain

 

作業に当たって、お互いの基盤を裏返すと端子オス側とメス側で反対向きになるので刺し間違えないように刺さない端子はセロテープでマスクした。

f:id:DreamerDream:20160402085000p:plain

 

表示速度があまり早くないが何か設定があるのかもしれない。そのままでも用途を割りきれば十分実用に耐えると思われる。

しかしRPiの電源オフでも画面スリープでもバックライトが点灯したままなのが不満ではある。

kampa.me