
この記事の最初のパート「 Appcelerator TitaniumでのQuickTiGame2dのプレイ。パート1 」では、エンジンの操作のいくつかの側面について説明しました。 ここで、Appcelerator Titaniumで最もシンプルなゲームの作成を検討することを提案します。
ゲームの本質は、表示される文字から「TITANIUM」という単語を収集する必要があることです。その後、対応する勝利メッセージが表示され、ゲームが終了します。
まず、pathsToFiles.jsファイルを作成します。このファイルでは、使用可能なリソースにパスを割り当てます。
//menuScene var pngMenuBackground = "pictures/menu/background.png"; var pngButtonNewGame = "pictures/menu/newGame.png"; var pngButtonHelp = "pictures/menu/help.png"; //helpScene var pngHelp = "pictures/help/help.png"; var pngBackFromHelp = "pictures/help/back.png"; //mainLoadingScene var pngMainBackground = "pictures/game/background.png"; var pngBackToMenu = "pictures/game/back.png"; var pngVictory = "pictures/game/victory.png"; var xmlCharactersPosition = "pictures/game/charactersPosition.xml"; //sound var soundClick = "sound/click.wav";
まず最初に、app.jsを見てみましょう。 ゲーム画面を作成し、使用するjsファイルを接続し、AndroidとiOSの画面レイアウトについても説明します。
var window = Ti.UI.createWindow({ backgroundColor : 'black' }); var quicktigame2d = require('com.googlecode.quicktigame2d'); var game = quicktigame2d.createGameView(); if (Titanium.Platform.osname === 'android') { game.orientation = Ti.UI.LANDSCAPE_LEFT; window.orientationModes = [Titanium.UI.LANDSCAPE_LEFT]; } else { game.orientation = Ti.UI.LANDSCAPE_RIGHT; window.orientationModes = [Titanium.UI.LANDSCAPE_RIGHT]; } Ti.include('pathsToFiles.js'); Ti.include('helpScene.js'); Ti.include('menuScene.js'); Ti.include('mainScene.js');
次に、デバイスに必要なゲームのスケールを計算し、ロードされたシーンを初期化します。これについては以下で説明し、ゲーム画面をアプリケーションウィンドウに追加して開き、MenuSceneを起動します。
var WINDOW_SCALE_FACTOR_X = 1; var WINDOW_SCALE_FACTOR_Y = 1; game.addEventListener('onload', function(e) { var screenScale = game.size.height / 640; game.screen = { width : game.size.width / screenScale, height : game.size.height / screenScale }; WINDOW_SCALE_FACTOR_X = game.screen.width / game.size.width; WINDOW_SCALE_FACTOR_Y = game.screen.height / game.size.height; MenuScene.init(); HelpScene.init(); MainScene.init(); game.pushScene(MenuScene.scene); game.start(); }); window.add(game); window.open({ fullscreen : true, navBarHidden : true });
次に、ゲームのMenuSceneを作成しましょう。 開始するには、直接作成します。
var buttonMargin = 20; var clickSound = null; var MenuScene = { scene : null, background : null, buttonNewGame : null, buttonHelp : null, init : function() { this.scene = quicktigame2d.createScene(); ... }, };
ここで、buttonMarginは後で使用されるインデントで、clickSoundはサウンドを保存するための変数です。
今、いくつかのアクションを追加する価値があります。 スプライトを読み込むときに現在のシーンを実行します。
var onloadsprite = (function(self) { return function(e) { if (e.name == pngButtonHelp) { game.startCurrentScene(); } }; })(this);
「新しいゲーム」ボタンと「ヘルプ」ボタンをクリックしたときのイベントについて説明しましょう。 ボタンを押すとボタンを放すと、画像が変化します。また、押すと短い音が鳴り、「押す」とゲームシーンが選択したシーンに変わります。
var touchstart = (function(self) { return function(e) { var x = ex * WINDOW_SCALE_FACTOR_X; var y = ey * WINDOW_SCALE_FACTOR_Y; if (self.buttonNewGame.contains(x, y)) { self.buttonNewGame.frame = 0; clickSound.play(); } if (self.buttonHelp.contains(x, y)) { self.buttonHelp.frame = 0; clickSound.play(); } } })(this); var touchend = (function(self) { return function(e) { var x = ex * WINDOW_SCALE_FACTOR_X; var y = ey * WINDOW_SCALE_FACTOR_Y; self.buttonNewGame.frame = 1; self.buttonHelp.frame = 1; if (self.buttonNewGame.contains(x, y)) { game.pushScene(MainScene.scene); } if (self.buttonHelp.contains(x, y)) { game.pushScene(HelpScene.scene); } }; })(this);
次に、変数を初期化し、ボタンの座標とゲームメニューの背景を設定します。 シーンに適切な要素とイベントリスナーを追加します。
var activated = (function(self) { return function(e) { if (clickSound == null) { clickSound = Ti.Media.createSound({ url : soundClick }); } if (self.background == null) { self.background = quicktigame2d.createSprite({ image : pngMenuBackground }); } if (self.buttonNewGame == null) { self.buttonNewGame = quicktigame2d.createSpriteSheet({ image : pngButtonNewGame, width : 275, height : 100 }); } if (self.buttonHelp == null) { self.buttonHelp = quicktigame2d.createSpriteSheet({ image : pngButtonHelp, width : 275, height : 100 }); } self.background.x = (game.screen.width * 0.5) - (self.background.width * 0.5); self.background.y = (game.screen.height * 0.5) - (self.background.height * 0.5); self.buttonNewGame.x = (game.screen.width - self.buttonNewGame.width) / 4; self.buttonNewGame.y = (game.screen.height * 0.8); self.buttonHelp.x = (game.screen.width - self.buttonNewGame.width) / 4*3; self.buttonHelp.y = self.buttonNewGame.y; self.buttonNewGame.frame = 1; self.buttonHelp.frame = 1; self.scene.add(self.background); self.scene.add(self.buttonNewGame); self.scene.add(self.buttonHelp); game.addEventListener('touchstart', touchstart); game.addEventListener('touchend', touchend); self.scene.addEventListener('enterframe', enterframe); }; })(this);
作成したすべての要素を削除する機能について説明します(テクスチャのアンロード、イベントリスナーの削除)
var deactivated = (function dea(self) { return function(e) { self.scene.remove(self.background); self.background = null; self.scene.remove(self.buttonNewGame); self.scene.remove(self.buttonHelp); self.buttonNewGame = null; self.buttonHelp = null; game.unloadTexture(pngButtonNewGame); game.unloadTexture(pngButtonHelp); game.removeEventListener('touchstart', touchstart); game.removeEventListener('touchend', touchend); }; })(this);
シーンのアクティブ化/非アクティブ化およびスプライトのロードのイベントのリスナーを追加することのみが残ります。
this.scene.addEventListener('activated', activated); this.scene.addEventListener('deactivated', deactivated); this.scene.addEventListener('onloadsprite', onloadsprite);
メニューシーンの準備ができました。 ヘルプシーンに移りましょう。 原則として、要素のロードおよびアンロードのプロセスはすべて非常に類似しているため、繰り返さないで、最も関心のある要素を検討しません。 それらの1つは、ヘルプの背景を作成することです。
if (self.background == null) { self.background = quicktigame2d.createSprite({ image : pngMenuBackground }); } if (self.menuLayer == null) { self.menuLayer = quicktigame2d.createSprite({ width : self.background.width, height : self.background.height }); self.menuLayer.color(0.5, 0.5, 0.5); self.menuLayer.alpha = 0.78; } if (self.foreground == null) { self.foreground = quicktigame2d.createSpriteSheet({ image : pngHelp, width : 960, height : 640 }); }
ここでは、3層の背景をロードします。 それらの1つはメニュー内のレイヤーで、一番下になります。 2番目の背景を上部に設定します(色と透明度があります)。 3番目はテキストレイヤーです。 複数の画像を使用するには、SpriteSheetとして定義します。
画面の隅にあるボタンの位置とそのサイズを説明します。
if (game.screen.width > self.background.width) { self.okButton.x = self.background.x + self.background.width - self.okButton.width - buttonMargin; self.okButton.y = self.background.y + self.background.height - self.okButton.height - buttonMargin; } else { self.okButton.x = game.screen.width - self.okButton.width - buttonMargin; self.okButton.y = game.screen.height - self.okButton.height - buttonMargin; }
そして、背景のテキストアニメーションを追加します。
self.foreground.animate(0, 2, 2000, -1);
それでは、ゲームのシーンを作成しましょう。 いくつかの変数を作成する価値があります。
var COUNT_OF_CHARACTERS = 9; var word = ""; var wordTitanium = "titanium";
COUNT_OF_CHARACTERSは文字が表示されるフィールド上の場所の数、wordは収集された単語、wordTitaniumは収集される単語です。
アクティブ化された関数に、文字画像を使用して要素の配列を作成するプロセスを追加します。
var xCoef = self.background.width / 4; var yCoef = self.background.height / 4; var xParam = 1; var yParam = 1; for (var i = 0; i < COUNT_OF_CHARACTERS; i++) { self.characters[i] = quicktigame2d.createSpriteSheet({ image : xmlCharactersPosition }); self.characters[i].x = self.background.x + xCoef * xParam; self.characters[i].y = self.background.x + yCoef * yParam; xParam++; if (xParam > 3) { xParam = 1; yParam++; } self.characters[i].z = 3; self.characters[i].hide(); self.characters[i].index = i; self.characters[i].status = "waiting"; self.characters[i].selectFrame("character0"); self.scene.add(self.characters[i]); if (self.charactersTransforms[i] == null) { self.charactersTransforms[i] = quicktigame2d.createTransform(); self.charactersTransforms[i].addEventListener('complete', oncharactersCompleted); self.charactersTransforms[i].index = i; } }
ここでは、各要素の場所を設定し、非表示にし、ステータス、現在の画像を設定します。 また、各要素に独自のイベントリスナーを設定します。 イベントリスナーは次のようになります。
var oncharactersCompleted = (function(self) { return function(e) { var transform = e.source; var choosenCharacter = self.characters[transform.index]; if (choosenCharacter != null) { if (choosenCharacter.status == "moving") { choosenCharacter.show(); choosenCharacter = changeStatus(choosenCharacter, transform, "living"); } else if (choosenCharacter.status == "living") { choosenCharacter = changeStatus(choosenCharacter, transform, "dying"); } else if (choosenCharacter.status == "dying") { choosenCharacter = changeStatus(choosenCharacter, transform, "hiding"); } else if (choosenCharacter.status == "hiding") { transform.scale(0, 0); choosenCharacter = changeStatus(choosenCharacter, transform, "queue_waiting"); } else if (choosenCharacter.status == "queue_waiting") { choosenCharacter.hide(); choosenCharacter.status = "waiting"; transform.duration = 1000; choosenCharacter.transform(transform); } else if (choosenCharacter.status == "killed") { transform.rotate(-360); transform.scale(0, 0); choosenCharacter = changeStatus(choosenCharacter, transform, "queue_waiting"); } } }; })(this); function changeStatus(choosenCharacter, transform, statuscharacter) { transform.duration = 2000; choosenCharacter.status = statuscharacter; choosenCharacter.transform(transform); return choosenCharacter; }
ここでは、要素のステータスに応じて、さまざまなアクションが実行されます:回転、ズーム、非表示、画面上に表示されます。
ゲームを終了するメソッドを追加します。このメソッドでは、既に入力した単語のテキストを削除し、プレイヤーが勝ったシーンに情報を追加します。これにより、victoryTextイベントのリスナーが呼び出されます。
function finishActivity(self) { word = ""; self.scene.add(self.victoryText); self.victoryTextTransform.duration = 1000; self.victoryText.transform(self.victoryTextTransform); } var onVictoryTextCompleted = (function(self) { return function(e) { if (self.victoryTextTransform.completed) { self.scene.remove(self.victoryText); closeGame(self); } else { self.victoryTextTransform.y = game.screen.height; self.victoryTextTransform.completed = true; self.victoryText.transform(self.victoryTextTransform); } }; })(this);
enterframeでは、対応する要素の文字を変更するプロセスを追加する必要があります。 これは、ステータスが待機中のときに発生します。要素は、ランダムに作成された文字とともに画面に表示されます。
self.charactersTransforms[i].show(); self.charactersTransforms[i].scale(1, 1); self.charactersTransforms[i].duration = 500; self.charactersTransforms[i].delay = 0; self.charactersTransforms[i].easing = quicktigame2d.ANIMATION_CURVE_CUBIC_IN; var face = Math.floor((randomNumber * 100) % 8); for (var count = 0; count < wordTitanium.length; count++) { if (face == count) { self.characters[i] = addDataToWord(self.characters[i], self.charactersTransforms[i], "character"+count, wordTitanium[count]); self.characters[i].transform(self.charactersTransforms[i]); break; } }
addDataToWord関数は次のとおりです。
function addDataToWord(choosenCharacter, choosenCharacterTransform, frame, symbol) { choosenCharacter.isMoving = false; choosenCharacter.faceName = frame; choosenCharacter.symbol = symbol; choosenCharacter.status = "moving"; choosenCharacter.selectFrame(frame); choosenCharacterTransform.duration = 0; choosenCharacter.transform(choosenCharacterTransform); return choosenCharacter; }
最後にやることは、要素をクリックする機能を登録することです:
var dblclick = (function(self) { return function(e) { var x = ex * WINDOW_SCALE_FACTOR_X; var y = ey * WINDOW_SCALE_FACTOR_Y; if (!self.loaded) return; if (!self.started) return; for (var i = 0; i < COUNT_OF_CHARACTERS; i++) { if (self.characters[i].status != "killed") { if (self.characters[i].contains(x, y)) { clickSound.play(); self.charactersTransforms[i].rotate(360); self.charactersTransforms[i].duration = 2000; self.characters[i].transform(self.charactersTransforms[i]); self.characters[i].status = "killed"; word += self.characters[i].symbol; Ti.API.info(word); if (wordTitanium.indexOf(word) == 0) { Ti.API.info(word + " " + wordTitanium); if(wordTitanium.length == word.length){ finishActivity(self); } } else { word = ""; } } } } }; })(this);
同時に、ステータスを変更し、アニメーションを追加して、対応する単語の文字順にこの文字の出現をチェックします。
結果は次のとおりです。




