この記事はいろふ Advent Calendar 2013の11日目の記事です。
昨日は@pocketberserkerさんの「いろふさんとの遭遇記」 でした。
明日は@akuraruさんです。
http://atnd.org/events/44814
「いろふさんを探せ!」ゲーム
こんなゲーム(?といえるのか)を10分くらいで作りました。細かい解説は後ほど。
いろふAdvent Calendarとは…
謎でした。書いてる今も謎です…w
数日前まで参加する気も全然なかったのですが、以下、鬼のような行為によって参加に至ります…。
@bitter_foxさんが「動くirofさんに会いたい!!」を書いていて、面白いなぁと何気なく、以下つぶやきました。
そこから
既に登録されてました…鬼に出会いました orz
いろふさんを探せ!解説編
気を取り直して、私のネタは、NetBeansとJava EEが入っていればすぐ作れる簡単なゲーム紹介です。
ウォーリーを探せ!のいろふさん版的な。。。
本当はNetBeans7.4とGlassFish4.0のJava EE7でやる予定でしたが、かくかくしかじかで、NetBeans7.3.1、GlassFish3.1.2.2のJava EE6で作りました(^^;
先に流れから
まずは、Webアプリを起動すると以下画面が表示されます。
![f:id:kikutaro777:20131211191131j:plain f:id:kikutaro777:20131211191131j:plain](http://cdn-ak.f.st-hatena.com/images/fotolife/k/kikutaro777/20131211/20131211191131.jpg)
デスクトップに、いろふさんがいます。
![f:id:kikutaro777:20131211191205j:plain f:id:kikutaro777:20131211191205j:plain](http://cdn-ak.f.st-hatena.com/images/fotolife/k/kikutaro777/20131211/20131211191205.jpg)
ドラッグ&ドロップしましょう。(ちなみに召喚ボタン押すとファイル選択ダイアログ)
![f:id:kikutaro777:20131211191227j:plain f:id:kikutaro777:20131211191227j:plain](http://cdn-ak.f.st-hatena.com/images/fotolife/k/kikutaro777/20131211/20131211191227.jpg)
召喚されました。
![f:id:kikutaro777:20131211191453j:plain f:id:kikutaro777:20131211191453j:plain](http://cdn-ak.f.st-hatena.com/images/fotolife/k/kikutaro777/20131211/20131211191453.jpg)
ゲームの世界に連れ込みます(単なるアップロードボタン)
成功すると、消え去ります。
![f:id:kikutaro777:20131211191517j:plain f:id:kikutaro777:20131211191517j:plain](http://cdn-ak.f.st-hatena.com/images/fotolife/k/kikutaro777/20131211/20131211191517.jpg)
ゲーム画面へボタンで次のページにいきます。
こんな画面です。
![f:id:kikutaro777:20131211191549j:plain f:id:kikutaro777:20131211191549j:plain](http://cdn-ak.f.st-hatena.com/images/fotolife/k/kikutaro777/20131211/20131211191549.jpg)
召喚されたいろふさんを触ると、スライドしていろふさんが出てきます。
![f:id:kikutaro777:20131211191654j:plain f:id:kikutaro777:20131211191654j:plain](http://cdn-ak.f.st-hatena.com/images/fotolife/k/kikutaro777/20131211/20131211191654.jpg)
![f:id:kikutaro777:20131211191646j:plain f:id:kikutaro777:20131211191646j:plain](http://cdn-ak.f.st-hatena.com/images/fotolife/k/kikutaro777/20131211/20131211191646.jpg)
画像からマウスポイントを離すと崩れ去ります。
![f:id:kikutaro777:20131211191718j:plain f:id:kikutaro777:20131211191718j:plain](http://cdn-ak.f.st-hatena.com/images/fotolife/k/kikutaro777/20131211/20131211191718.jpg)
これが本物のいろふさんです。
では次に、増殖ボタンを押します。すると、偽物のいろふさんをいくらでも発生することができます。
![f:id:kikutaro777:20131211191746j:plain f:id:kikutaro777:20131211191746j:plain](http://cdn-ak.f.st-hatena.com/images/fotolife/k/kikutaro777/20131211/20131211191746.jpg)
本物のいろふさんも、偽物のいろふさんもドラッグで自由に移動できるので、ごちゃまぜにして準備完了です。
いろふさんを愛するプレイヤーに、どこに本当のいろふさんがいるか探してもらいましょう!
みつけると
![f:id:kikutaro777:20131211191839j:plain f:id:kikutaro777:20131211191839j:plain](http://cdn-ak.f.st-hatena.com/images/fotolife/k/kikutaro777/20131211/20131211191839.jpg)
いいことあるかも!
コード
ドラッグ&ドロップとか、画像にマウスオーバーしてエフェクト(画像がスライドイン、コラスプしたり)、画像を移動したり…10分はうそでしょ!と思われるかもしれませんが、JSFのPrimeFacesというコンポーネントを使っていて、簡単に実現しています。
- ドラッグ&ドロップのアップロードやアップ画像のサムネイル表示はFileUploadコンポーネント
http://www.primefaces.org/showcase/ui/tooltip.jsf
http://www.primefaces.org/showcase/ui/draggableBasic.jsf
を使ってます。
なので、ほとんどビュー定義のみで
最初のアップロードするページビューはこんな感じ。
<h:body>
<h:form>
<p:fileUpload mode="advanced"
label="召喚する"
uploadLabel="ゲームの世界に連れ込む"
cancelLabel="現実世界に戻してあげる"
fileUploadListener="#{irofSanUploadBean.handleFileUpload}" />
<p:commandButton value="ゲーム画面へ" ajax="false" action="irofSanCooking.xhtml" />
</h:form>
</h:body>
次のゲームページはこんな感じ。
<h:body>
<h:form id="frm">
<p:commandButton value="増殖" actionListener="#{irofSanCookingBean.incrementIrofSan()}" update="@form"/>
<p:graphicImage id="irofSan" url="/images/irof.jpeg" />
<p:draggable for="frm:irofSan" />
<p:tooltip for="frm:irofSan" showEffect="slide" hideEffect="explode">
<p:graphicImage id="tooltipIrofSan1" url="/images/irof.jpeg" />
</p:tooltip>
</h:form>
</h:body>
コンポーネント置いてID指定するだけ…(^^;
増殖ボタンでコンポーネントが増える部分はプログラム側でコンポーネントを生成しています。
package jp.co.hoge.irofsanwebapp;
import java.io.Serializable;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.context.FacesContext;
import org.primefaces.component.dnd.Draggable;
import org.primefaces.component.graphicimage.GraphicImage;
@Named
@SessionScoped
public class IrofSanCookingBean implements Serializable{
private int cnt;
public void incrementIrofSan(){
cnt++;
UIForm form = (UIForm) findComponent(":frm");
GraphicImage img = new GraphicImage();
img.setId("irofSan" + cnt);
img.setUrl("/images/irof.jpeg");
img.setStyle(randomPosition());
form.getChildren().add(img);
Draggable dra = new Draggable();
dra.setFor(img.getId());
form.getChildren().add(dra);
}
private String randomPosition(){
StringBuilder posStr = new StringBuilder();
posStr.append("position:absolute;left:");
posStr.append(Math.round(Math.random() * 1280));
posStr.append("px;top:");
posStr.append(Math.round(Math.random() * 640));
posStr.append("px;");
return posStr.toString();
}
private UIComponent findComponent(String componentId){
return FacesContext.getCurrentInstance().getViewRoot().findComponent(componentId);
}
}
ちなみに昨日の時点では、アップロードした画像をImageCropperコンポーネントでバラバラにするという残酷なネタだったのですが、ImageCropperが動かなくて、デバッグしてもわからなかったので断念しました(^^;
http://www.primefaces.org/showcase/ui/imageCropper.jsf
うーん、なぜ動かない。。。