0

我正在使用 Android“Javascript”IDE——AndroidScript(太棒了!)开发一个功能齐全的基本经典 RPG (JRPG)。这里有几个问题要开始:(我将在单独的问题中提出以获得更多声誉 - 一开始很难获得。哈)

问题:我正在创建战斗文本(即“你攻击 8。\n地精攻击 2。”)。我正在尝试使用一个字符串并添加文本,具体取决于谁先行,并用换行符分隔。但是,在 canvas.DrawText(string, x, y) 中,它似乎不允许“\n”,而且我无法在我的(因此任何)手机上的一行中放置那么多文本。因此,如果不使用带有换行符的字符串,就需要进行大量不必要的条件测试。可以在图像的 DrawText() 方法中插入换行符吗?

这太过分了,但这是迄今为止的所有代码:

/*
 * My first JavaScript RPG
 * @author I don't care...please steal this.
 */

var enemyArray = [];

function Enemy( type, level, str, hp, totalhp, x, y, speed )
{
  this.type = type; 
  this.level = level;
  this.str = str;
  this.hp = hp;
  this.totalhp = totalhp;
  this.exp = level * 3;
  this.gold = level;
  this.x = x;
  this.y = y;
  this.isAlive = true;
  this.speed = speed;
}

var STATE = {
  MAINMENU : {value: 0, name: "Main Menu", code: "M"}, 
  WORLDMAP : {value: 1, name: "World Map", code: "W"}, 
  BATTLE : {value: 2, name: "Battle", code: "B"},
  STATUS : {value: 3, name: "Status", code: "S"},
  INVENTORY : {value: 4, name: "Inventory", code: "I"},
  DEAD : {value: 5, name: "Dead", code: "D"},
};

var player = {
    yourTurn: true,
    name : "",
    x : 0.5,
    y : 0.9,
    level : 1,
    strength : 2,
    intel : 2,
    totalhp : 10,
    hp : 10,
    totalmp : 3,
    mp : 3,
    level : 1,
    exp : 0,
    gold : 0,
    inventory : [],
    speed : 0.002,
    playerSpeedMultiplier : 20 // it's low so that the run decision uses even sides
}

var game = {
    timer : null,
    isPaused : false,
    quit : false,
    state : STATE.MAINMENU,
    level : 0,
    enemies : enemyArray,
    currentEnemy : null
}

var ui =
{
    battleText : "",
    init : function(){
         //Lock screen orientation to Portrait.
        app.SetOrientation( "Portrait" );

        //Stop screen turning off.
        app.PreventScreenLock( true );

        //Create a layout with objects vertically centered.
        lay = app.CreateLayout( "linear", "Vertical,FillXY" );    
        lay.SetBackColor( "#000000" );

        //Set canvas size
        var canvasHeight = 0.75;
        var canvasWidth = 1.0;

        //Create an blank image to act as our drawing 'canvas'.
        //(For performance reasons, we limit the internal bitmap to 
        //480x800 and set screen updating to manual mode).    
        canvas = app.CreateImage( null, canvasWidth, canvasHeight, "fix", 480, 800 );
        canvas.SetAutoUpdate( false );
        lay.AddChild( canvas );

        //Create menu button.
        btnStart = app.CreateButton( "Start", 0.4 );
        btnStart.SetMargins( 0, 0.02, 0, 0 );
        btnStart.SetOnTouch( btn_start );
        lay.AddChild( btnStart );

        moveButtons = app.CreateLayout( "Linear", "Horizontal" );
        lay.AddChild( moveButtons );

        btnLeft = app.CreateButton( "Left", 0.2, 0.16 );
        btnLeft.SetOnTouch( btn_left );
        moveButtons.AddChild( btnLeft );

        layVert = app.CreateLayout( "Linear", "Vertical" );

        btnUp = app.CreateButton( "Up", 0.3, 0.08 );
        btnUp.SetOnTouch( btn_up );
        layVert.AddChild( btnUp );
        btnDown = app.CreateButton( "Down", 0.3, 0.08 );
        btnDown.SetOnTouch( btn_down );
        layVert.AddChild( btnDown );

        moveButtons.AddChild( layVert );

        btnRight = app.CreateButton( "Right", 0.2, 0.16 );
        btnRight.SetOnTouch( btn_right );
        moveButtons.AddChild( btnRight );

        btnLeft.SetVisibility( "hide" );
        btnUp.SetVisibility( "hide" );
        btnDown.SetVisibility( "hide" );
        btnRight.SetVisibility( "hide" ); 

        battleButtons = app.CreateLayout( "Linear", "Horizontal" );
        lay.AddChild( battleButtons );

        btnAttack = app.CreateButton( "Attack", 0.2, 0.16 );
        btnAttack.SetOnTouch( btn_attack );
        battleButtons.AddChild( btnAttack );

        layMid = app.CreateLayout( "Linear", "Vertical" );

        btnItem = app.CreateButton( "Item", 0.3, 0.08 );
        btnItem.SetOnTouch( btn_item );
        layMid.AddChild( btnItem );
        btnRun = app.CreateButton( "Run", 0.3, 0.08 );
        btnRun.SetOnTouch( btn_run );
        layMid.AddChild( btnRun );

        battleButtons.AddChild( layMid );

        btnMagic = app.CreateButton( "Magic", 0.2, 0.16 );
        btnMagic.SetOnTouch( btn_magic );
        battleButtons.AddChild( btnMagic );

           //Status button
          btnStatus = app.CreateButton( "Status", 0.9, 0.025, "blue" ); 
          btnStatus.SetOnTouch( btn_status ); 
          lay.AddChild( btnStatus );

        btnAttack.SetVisibility( "gone" );
        btnItem.SetVisibility( "gone" );
        btnRun.SetVisibility( "gone" );
        btnMagic.SetVisibility( "gone" );


         //Status slider
         //Create a layout we can slide over the main layout. 
         laySlide = app.CreateLayout( "Linear", "FillXY" ); 
         laySlide.SetPadding( 0, 0.1, 0, 0 );  
         laySlide.SetBackground( "/Sys/Img/GreenBack.png" ); 
         laySlide.SetVisibility( "Hide" ); 

         //Create tabs.
         var tabs = app.CreateTabs( "STATUS,EQUIP,INVENTORY", 0.8, 0.8, "VCenter" );
         tabs.SetOnChange( tabs_OnChange ); 
         laySlide.AddChild( tabs ); 

         //Create button and add to main layout. 
         btnBack = app.CreateButton( "Back", 0.3, 0.06, "gray" ); 
         btnBack.SetOnTouch( btnBack_OnTouch ); 
         laySlide.AddChild( btnBack ); 

         btnStatus.SetVisibility( "gone" );

        //Add layouts to app.    
        app.AddLayout( lay );
        app.AddLayout( laySlide );

        //Switch off debugging for max speed.
        app.SetDebugEnabled( false );
    },
    write : function(){},
    update: function(){}
}


//STATUS SLIDER
//Called when user touches our 'slide' button. 
function btn_status() 
{ 
    laySlide.Animate( "SlideFromRight" ); 
    game.isPaused = true;
} 

//Called when user touches our 'back' button. 
function btnBack_OnTouch() 
{ 
    laySlide.Animate( "SlideToLeft" );
    game.isPaused = false;     
} 

//Handle tab selection.
function tabs_OnChange( name )
{
    app.ShowPopup( name );
}



//Called when application is started.
function OnStart()
{    
    ui.init();

    //Call DrawFrame function 30x a second.
    game.timer = setInterval( drawFrame, 1000/30 ); // 30 default    
}

//Update and redraw all game graphics.
function drawFrame()
{
    //Clear the canvas.
    canvas.Clear();

    if(game.state == STATE.MAINMENU) {
        drawMenu();
    }
    if(game.state == STATE.WORLDMAP) {
        drawWorld();
        drawChar();
        drawEnemies();
        areAllEnemiesDead();
    }
    if(game.state == STATE.BATTLE) {
        drawBattleScreen();
    }
    if(game.state == STATE.STATUS) {
        drawStatusScreen();
    }
    if(game.state == STATE.INVENTORY) {
        drawInventory();
    }
    if(game.state == STATE.DEAD) {
        drawDead();
    }

    //Update the canvas.
    canvas.Update();

    //Quit game if required.
    if( game.quit ) return;
}

function goToNextLevel(){
    game.level += 1;

    player.hp = player.totalhp;
    player.mp = player.totalmp;

    app.ShowPopup( "Level " + game.level );
    btnStart.SetVisibility("gone");
    btnLeft.SetVisibility( "show" );
    btnUp.SetVisibility( "show" );
    btnDown.SetVisibility( "show" );
    btnRight.SetVisibility( "show" );
    btnAttack.SetVisibility( "gone" );
    btnItem.SetVisibility( "gone" );
    btnRun.SetVisibility( "gone" );
    btnMagic.SetVisibility( "gone" );
    canvas.SetBackColor( "#008200"  );

   for (var i = 0; i < game.enemies.length; i++) {
       game.enemies.pop();
    }
    player.x = 0.5;
    player.y = 0.9;
    createEnemies();
    game.state=STATE.WORLDMAP;
}

//Draw the Menu
function drawMenu()
{
    //Draw header
    canvas.SetTextSize( 14 );
    canvas.SetPaintColor( "#ff0088ff"  );
    canvas.DrawText( "Super Best RPG,", 0.1, 0.1 );

    //Draw info
    canvas.SetTextSize( 16 );
    canvas.SetPaintColor( "#ffff0000"  );
    canvas.DrawText( "Battle great moon", 0.1, 0.3 );
}

//Called when user presses 'Start' button.
function btn_start()
{
    goToNextLevel();
    btnStatus.SetVisibility( "show" );
}

function createEnemies(){
 app.ShowPopup( "Level " + game.level );
    for(var i = 0; i < game.level; i++) {
        game.enemies.push(
            new Enemy("Goblin", 
                                  1,
                                  Math.pow(1.2, game.level),
                                  5,
                                  game.level * 5,
                                  (Math.random() * 0.58) + 0.22,
                                  (Math.random() * 0.89),
                                  0.002
                                  )
        );
    }

}

//Called when user presses 'up'
function btn_up()
{
    if(player.y > 0.06) {
        player.y -= player.speed * player.playerSpeedMultiplier;
        app.Vibrate( "0,30" );
    }
}

//Called when user presses 'down'
function btn_down()
{
    if(player.y < 0.90) {
        player.y += player.speed * player.playerSpeedMultiplier;
        app.Vibrate( "0,30" );
    }
}

//Called when user presses 'left'
function btn_left()
{
    if(player.x > 0.23) {
        player.x -= player.speed * player.playerSpeedMultiplier;
        app.Vibrate( "0,30" );
    }
}

//Called when user presses 'right'
function btn_right()
{
    if(player.x < 0.77) {
        player.x += player.speed * player.playerSpeedMultiplier;
        app.Vibrate( "0,30" );
    }
}

//Called when user presses 'Attack'
function btn_attack()
{
    ui.battleText = "";
    if(player.speed >= game.currentEnemy.speed) {
        youAttack();
        player.yourTurn = false;
        enemyAttack();
        player.yourTurn = true;
    }
    else {
        player.yourTurn = false;
        enemyAttack();
        player.yourTurn = true;
        youAttack();
    }
}

//Called when user presses 'Item'
function btn_item()
{
    ui.battleText = "";
    if(player.yourTurn) {

    }
}

//Called when user presses 'Run'
function btn_run()
{
    ui.battleText = "";
    if(player.yourTurn) {
        if(player.speed >= game.currentEnemy.speed) {
            game.currentEnemy.isAlive = false;
            battleExit();
            game.state = STATE.WORLDMAP;
        }
        else {
            player.yourTurn = false;
            enemyAttack();
            player.yourTurn = true;
        }
    }
}

//Called when user presses 'Magic'
function btn_magic()
{
    ui.battleText = "";
    if(player.yourTurn) {

    }
}

function drawWorld() 
{
    canvas.SetPaintStyle( "Fill" ); 
    canvas.SetPaintColor( "#555500" );
    canvas.DrawRectangle(0.2, 0.0, 0.8, 1.0);   

    //HUD
    //level
    canvas.SetTextSize( 24 );
    canvas.SetPaintColor( "#ff22aaaa"  );
    canvas.DrawText( "" + game.level, 0.05, 0.1 );

    //health/magic text
    canvas.SetTextSize( 6 );
    canvas.SetPaintColor( "#ff000000"  );
    canvas.DrawText( "HP: " + player.hp + "\\" + player.totalhp, 0.01, 0.95 );
    canvas.DrawText( "MP: " + player.mp + "\\" + player.totalmp, 0.82, 0.95 );

    //health/magic bars
    canvas.SetPaintColor( "#ffff0000"  );    
    var hpsize = (player.hp/player.totalhp) * 0.6;
    canvas.DrawRectangle( 0.066, 0.9 - hpsize, 0.133 , 0.9);

    canvas.SetPaintColor( "#ff0000ff"  );
    var mpsize = (player.mp/player.totalmp) * 0.6;
    canvas.DrawRectangle( 0.866, 0.9 - mpsize, 0.933 , 0.9);
}



function drawChar() 
{   
    //Stick man
    //Head 
    canvas.SetPaintStyle( "Line" ); 
    canvas.SetPaintColor( "#ff000000" ); 
    canvas.DrawCircle( player.x, player.y, 0.02 );

    //Body
    canvas.SetLineWidth( 4.0 ); 
    canvas.DrawLine( player.x, player.y + 0.01, player.x, player.y + 0.05 ); 

    //Legs
    canvas.SetLineWidth( 2.5 ); 
    canvas.DrawLine( player.x, player.y + 0.05, player.x - 0.03, player.y + 0.08 ); 
    canvas.DrawLine( player.x, player.y + 0.05, player.x + 0.03, player.y + 0.08 ); 

    //Arms
    canvas.DrawLine( player.x - 0.04, player.y + 0.025, player.x + 0.04, player.y + 0.025 );
}



function drawEnemies(){
    canvas.SetPaintStyle( "Line" ); 
    canvas.SetPaintColor( "#000000" ); 
    for (var i = 0; i < game.enemies.length; i++) {
       if(game.enemies[i].isAlive){
           moveEnemyTowardsPlayer(game.enemies[i]);
           checkEnemy(game.enemies[i]);
           canvas.DrawCircle(game.enemies[i].x ,game.enemies[i].y ,0.01);     
       }
    }
}


function moveEnemyTowardsPlayer(enemy)
{
       if (game.isPaused) return;
       if (enemy.x < player.x) {
           enemy.x += enemy.speed;
       }
       if (enemy.x > player.x) {
           enemy.x -= enemy.speed;
       }
       if (enemy.y < player.y) {
           enemy.y += enemy.speed;
       }
       if (enemy.y > player.y) {
           enemy.y -= enemy.speed;
       }
}

function checkEnemy(enemy) 
{
       if (enemy.hp <= 0) return;
       if (enemy.x > player.x - 0.03 && enemy.x < player.x + 0.03 &&
           enemy.y > player.y - 0.02 && enemy.y < player.y + 0.08) {
               enemy.speed = 0;
               game.currentEnemy = enemy;     
               app.ShowPopup( game.currentEnemy.type + " Attacks!");
               if(Math.random() > 0.5) yourTurn = false;
               battleSetup();
               game.state = STATE.BATTLE;
       }
}







//BATTLE

//Hide moveButtons
//Show battleButtons
function battleSetup() {
                btnLeft.SetVisibility( "gone" );
                btnUp.SetVisibility( "gone" );
                btnDown.SetVisibility( "gone" );
                btnRight.SetVisibility( "gone" );
                btnAttack.SetVisibility( "show" );
                btnItem.SetVisibility( "show" );
                btnRun.SetVisibility( "show" );
                btnMagic.SetVisibility( "show" );
                canvas.SetLineWidth(10);
                canvas.SetPaintColor( "#ff777777"  );
                canvas.DrawLine(0, 1, 1, 1);
}

//Show moveButtons
//Hide battleButtons
function battleExit() {
               btnLeft.SetVisibility( "show" );
               btnUp.SetVisibility( "show" );
               btnDown.SetVisibility( "show" );
               btnRight.SetVisibility( "show" );
               btnAttack.SetVisibility( "gone" );
               btnItem.SetVisibility( "gone" );
               btnRun.SetVisibility( "gone" );
               btnMagic.SetVisibility( "gone" );
}

//Draw the Battle Screen
function drawBattleScreen()
{
    //Draw Enemy Stats
    canvas.SetLineWidth(1);
    canvas.SetTextSize( 9 );
    canvas.SetPaintColor( "#ff000000"  );
    canvas.DrawText( "" + game.currentEnemy.type + 
        "  HP: " + game.currentEnemy.hp + "\\" + game.currentEnemy.totalhp, 0.04, 0.07 );
    //Lines under enemy stats
    canvas.SetLineWidth(2.5);
    canvas.SetPaintColor( "#ff000000"  );
    canvas.DrawLine(0, 0.09, 0.25, 0.09);
    canvas.SetLineWidth(2.0);
    canvas.DrawLine(0, 0.10, 0.20, 0.10);
    canvas.SetLineWidth(1.5);
    canvas.DrawLine(0, 0.11, 0.15, 0.11);
    canvas.SetLineWidth(1.0);
    canvas.DrawLine(0, 0.12, 0.10, 0.12);
    canvas.SetLineWidth(0.5);
    canvas.DrawLine(0, 0.13, 0.05, 0.13);

    //Draw Player Stats
    canvas.SetLineWidth(1);
    canvas.SetTextSize( 9 );
    canvas.SetPaintColor( "#ff000000"  );
    canvas.DrawText( "HP: " + player.hp + "\\" + player.totalhp, 0.7, 0.87 );
    canvas.DrawText( "MP: " + player.mp + "\\" + player.totalmp, 0.7, 0.93 );

    //Draw Enemy
    //Head
    canvas.SetLineWidth(5);
    canvas.SetPaintColor( "#ff884400"  );
    canvas.DrawCircle( 0.7, 0.25, 0.2 );
    //Eyes
    canvas.SetPaintColor( "#ff222200"  );
    canvas.SetLineWidth(7);
    canvas.DrawLine( 0.55, 0.2, 0.64, 0.24);
    canvas.DrawLine( 0.79, 0.2, 0.70, 0.24);
    //Mouth
    canvas.SetPaintColor( "#ff000000"  );
    canvas.SetLineWidth(7);
    canvas.DrawLine( 0.59, 0.31, 0.75, 0.31);
    canvas.DrawLine( 0.61, 0.32, 0.73, 0.32);

    //Draw Player
    //Head
    canvas.SetLineWidth(10);
    canvas.SetPaintColor( "#ff000000"  );
    canvas.DrawCircle( 0, 0.5, 0.25 );
    //Body
    canvas.SetLineWidth(20);
    canvas.DrawLine(0, 0.65, 0, 1);
    //Arm
    canvas.DrawLine(0, 0.8, 0.4, 0.8);
    //Sword
    canvas.SetLineWidth(12);
    canvas.DrawLine(0.35, 0.88, 0.5, 0.5);
    canvas.SetLineWidth(7);
    canvas.DrawLine(0.3, 0.73, 0.5, 0.78);

    //BattleText
    canvas.SetLineWidth(1);
    canvas.DrawText(ui.battleText, 0.6, 0.7);

    showOrHideButtons();
}

function showOrHideButtons() {
    if(player.yourTurn) {
        btnAttack.SetVisibility("Show");
        btnItem.SetVisibility("Show");
        btnRun.SetVisibility("Show");
        btnMagic.SetVisibility("Show");
    }
    else {
        btnAttack.SetVisibility("Hide");
        btnItem.SetVisibility("Hide");
        btnRun.SetVisibility("Hide");
        btnMagic.SetVisibility("Hide");
    }
}



function youAttack(){
  if(player.hp <= 0) return;
  var tempRandom = (Math.random() > 0.3);
  app.ShowPopup( "str:" + player.strength + tempRandom);
  if(tempRandom) {  
      game.currentEnemy.hp -= player.strength;
      ui.battleText += "Hit for " + player.strength;      
   } else {
      ui.battleText += "You missed";      
   }
   checkEnemyDeath();
}

function enemyAttack(){ 
   if(game.currentEnemy.hp <= 0) return;
   if(Math.random() > 0.5) {  
      player.hp -= Math.floor(game.currentEnemy.str);
   } 
   checkPlayerDeath();

}

function checkEnemyDeath() {
    if(game.currentEnemy.hp <= 0) {
        game.currentEnemy.isAlive == false;
        player.exp += game.currentEnemy.exp;
        ui.battleText = "You defeated the " + game.currentEnemy.type + "! " +
                      "You gained " + game.currentEnemy.exp + " exp.";
        player.y += 0.01;
        battleExit();
        game.currentEnemy.x = 1000;
        game.state = STATE.WORLDMAP;
        areAllEnemiesDead();
    }
}

function areAllEnemiesDead(){
   var allDead = true;
   for (var i = 0; i < game.enemies.length; i++) {
       if(game.enemies[i].hp > 0){
           allDead = false;     
       }
    }
    if (allDead) {
       goToNextLevel();
    }
}

function checkPlayerDeath() {
    if(player.hp <= 0) {
        player.isAlive == false;
        player.hp = 0;
        app.ShowPopup( "Died on level " + game.level );
        btnStart.SetVisibility("gone");
        btnLeft.SetVisibility( "gone" );
        btnUp.SetVisibility( "gone" );
        btnDown.SetVisibility( "gone" );
        btnRight.SetVisibility( "gone" );
        btnAttack.SetVisibility( "gone" );
        btnItem.SetVisibility( "gone" );
        btnRun.SetVisibility( "gone" );
        btnMagic.SetVisibility( "gone" );
        btnStatus.SetVisibility( "gone" );
        canvas.SetBackColor( "#000000"  );
        drawFrame();
    }
}

谢谢!

4

2 回答 2

1

不幸的是,不能将 '\n' 与 DrawText 一起使用。您可以偏移 Y 以模拟另一条线。

于 2014-04-21T04:50:16.647 回答
0

恐怕塞巴斯蒂安是正确的。AndroidScript 中的 DrawText 方法内部调用了标准的 Android SDK Canvas.DrawText() 方法,该方法不支持多行输出(可能出于性能原因)。

您可以从其他人关于 Android 的问题中看到这一点:-

将多行文本绘制到 Canvas

但是您可以尝试通过使用 JavaScript split() 方法拆分字符串来编写自己的小多行输出函数 :)

顺便说一句,我喜欢你的应用程序……它看起来很有趣!

于 2014-04-21T07:48:34.397 回答