我正在使用 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();
}
}
谢谢!