如何从菜单画面切换到实际游戏?

问题描述 投票:0回答:1

所以我尝试在 p5.js 中的菜单屏幕(当前只是带有一行文本的空白画布)和实际游戏屏幕之间切换。我目前尝试的是使用一个名为“state”的变量,该变量根据其值在菜单代码和实际游戏代码之间进行分支(菜单的状态 = 1,游戏的状态 = 2)。当状态从1变为2时,确实会切换到游戏画面,但只是静止的一帧,无法玩。

正如我上面所说,我尝试使用名为“state”的变量在不同的游戏状态之间进行分支。我编写的代码如下,不包括类。

  var state;
  var character;
  var platform;

  function setup() {
    state = 1;
    createCanvas(800, 400);
  }

  function draw() {
    background(220);
    if(state == 1){
      text("press enter to start",20,20);
    }
    else if(state == 2){
      enemy = new Enemy(50, 0)
      character = new Player(200, 200);
      platform = new Platform(0, 350, width, 50);
      
      character.update();
      platform.update();
      enemy.update();

      enemy.show();
      character.show();
      platform.show();
    }
    if (keyIsDown(UP_ARROW)) 
    {
      if (!character.jumping && character.grounded) {
        character.jumping = true;
        character.grounded = false;
        character.velY = -character.speed * 3;
      }
    }
    if (keyIsDown(LEFT_ARROW)) {
      character.velX = -character.speed;
    }
    if (keyIsDown(RIGHT_ARROW)) {
      character.velX = character.speed;
    }
  }
  
  function keyPressed(){
  if(keyCode === ENTER)
    state = 2
  }

我认为问题在于,每次重复绘制循环时,它都会创建所有类的新实例,使得游戏看起来像静止的帧,因为每个循环都替换了对象。虽然我认为这就是问题所在,但我不知道如何解决它。任何帮助将不胜感激,不仅针对这个问题,而且针对我的代码。

Image of still frame 附:该图像显示了静止帧的样子。由于存在“重力”,因此两个方块都应该下落。

javascript loops class menu p5.js
1个回答
0
投票

draw()
函数中根据场景编号切换的分支应该只更新和绘制,而不是初始化该场景的状态。只有从菜单转换到游戏屏幕的代码才应该创建与游戏相关的实体。否则,您每秒会创建一个新的
Enemy
Player
Platform
大约 60 次,始终处于其初始位置,因此它们看起来是不动的。

换句话说,将像

enemy =
这样的任务移动到
if(keyCode === ENTER)
分支中,这应该被视为特定于游戏场景的
setup()
函数(以及可选的菜单场景拆卸)。

另请参阅 使用 p5.js 从一个场景过渡到下一个场景,它展示了一种更稳健的设计,可以处理具有复杂过渡的许多场景,每个场景都具有特定的输入和渲染行为。该答案中的方法还在每个场景的变量周围添加了闭包,从而更容易防止状态意外从一个场景泄漏到另一个场景。

除此之外,

1
2
是神奇的数字,并且可以改进为至少是描述性字符串或符号,或者可能是布尔值
let menuActive = true; // or false
。或者您可以将
draw()
函数替换为
draw()
的游戏版本并删除分支:

function setup() {
  createCanvas(800, 400);
}

function draw() {
  background(220);
  text("press enter to start", 20, 20);
}

function gameLoop(t) {
  background(150);
  text("you're in the game loop!", sin(frameCount / 2) + 10, 20);
}

function initializeGameLoop() {
  // one-time set up gameLoop here
  print("switching scenes");
  draw = gameLoop;
}

function keyPressed() {
                        // you can check which state you're in like this,
                        // or alternatively, override/redefine keyPressed
                        // the same way as done with draw()
                        // v---------------v
  if (keyCode === ENTER && draw !== gameLoop) {
    /* optionally tear down state for the menu screen here */

    initializeGameLoop();
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.js"></script>

这种方法具有更少的状态、更少的幻数和更少的分支,所有这些都增加了程序的复杂性,使它们更难以理解和维护。

© www.soinside.com 2019 - 2024. All rights reserved.