我一直在寻找一种简单的方法,可以在实现Screen
的游戏画面之间进行简单的淡出过渡。在执行某个操作后,我正在调用game.setScreen
方法,但我希望在两者之间进行转换。
我不使用舞台和演员。
我应该stages
并使用actions
进行转换,还是使用TweenEngine更简单?
如果我应该使用阶段,如何将我的常规渲染方法转换为stage.draw
?使用stage
将所有渲染方法转换为actors
是否很难?您是否可以将整个渲染方法变为stage.draw
以使用actions
以淡出Screen
?只要有效,解决方案是否愚蠢或低效无关紧要。
由于
修改:我的完整Game class
。这里可能有成千上万的怪异事物。原谅我,因为这是我的第一个libGDX项目。
package com.samuel.kiwi;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.utils.viewport.ExtendViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.samuel.kiwi.states.MenuState;
public class Kiwi extends Game {
private Sound point;
private Sound select;
private Sound die;
private Music chirp;
private Actor fadeActor = new Actor();
private ShapeRenderer fadeRenderer;
public SpriteBatch batch;
public static BitmapFont font;
public static final int WIDTH = 480;
public static final int HEIGHT = 800;
private int currentHighscore;
private Preferences highscore;
private int currentTotalScore;
private Preferences totalScore;
private int currentDeaths;
private Preferences deaths;
private boolean soundOn;
private Preferences sound;
Viewport viewport;
Viewport viewportFont;
private boolean currentTutMode;
private Preferences tut;
public static final String TITLE = "Kiwi";
private OrthographicCamera cam;
public static OrthographicCamera fontCam;
private float aspectRatio;
@Override
public void create() {
batch = new SpriteBatch();
fontCam = new OrthographicCamera();
aspectRatio = (float) Gdx.graphics.getHeight() / Gdx.graphics.getWidth();
cam = new OrthographicCamera();
viewport = new ExtendViewport((WIDTH / 4) * aspectRatio, HEIGHT / 2, cam);
viewportFont = new ExtendViewport((WIDTH) * aspectRatio, HEIGHT * 2, fontCam);
viewport.apply();
viewportFont.apply();
cam.position.set(WIDTH / 4, HEIGHT / 4, 0);
fontCam.position.set(WIDTH, HEIGHT, 0);
initFonts();
highscore = Gdx.app.getPreferences("highscore"); //highscore preferencen
currentHighscore = highscore.getInteger("currentHighscore", 0);
totalScore = Gdx.app.getPreferences("total_score"); //total score
currentTotalScore = totalScore.getInteger("totalScore", 0);
deaths = Gdx.app.getPreferences("deaths");
currentDeaths = deaths.getInteger("currentDeaths", 0);
tut = Gdx.app.getPreferences("is tutorial on");
currentTutMode = tut.getBoolean("currentTutMode", true);
sound = Gdx.app.getPreferences("sound");
soundOn = sound.getBoolean("currentSoundMode", true);
point = Gdx.audio.newSound(Gdx.files.internal("sounds/point.wav"));
select = Gdx.audio.newSound(Gdx.files.internal("sounds/select.wav"));
die = Gdx.audio.newSound(Gdx.files.internal("sounds/die.wav"));
Gdx.gl.glClearColor(0, 0, 0, 1);
fadeRenderer = new ShapeRenderer(8);
chirp = Gdx.audio.newMusic(Gdx.files.internal("sounds/chirp.wav"));
chirp.setLooping(true);
chirp.setVolume(0);
chirp.play();
setScreen(new MenuState(this, cam)); //ändra till splash
}
@Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
super.render();
cam.update();
fontCam.update();
fadeActor.act(Gdx.graphics.getDeltaTime());
float alpha = fadeActor.getColor().a;
if (alpha != 0) {
fadeRenderer.begin(ShapeRenderer.ShapeType.Filled);
fadeRenderer.setColor(0, 0, 0, alpha);
System.out.println("alpha: " + alpha); //shows the alpha becoming less and less and then more an more
fadeRenderer.rect(-1, -1, 2, 2); //full screen rect w/ identity matrix
fadeRenderer.end();
}
}
@Override
public void resize(int width, int height) {
viewport.update(width, height);
viewportFont.update(width, height);
cam.position.set(WIDTH / 4, HEIGHT / 4, 0);
fontCam.position.set(WIDTH, HEIGHT, 0);
}
public void initFonts() {
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/Minecraft.ttf"));
FreeTypeFontGenerator.FreeTypeFontParameter params = new FreeTypeFontGenerator.FreeTypeFontParameter();
params.characters = "0123456789-.";
params.size = 80;
params.color.set(254f / 255f, 208f / 255f, 0, 1f);
params.shadowColor.set(0 / 255f, 0 / 255f, 0, 0.5f);
params.shadowOffsetY = 8;
font = generator.generateFont(params);
generator.dispose();
}
@Override
public void dispose() {
super.dispose();
batch.dispose();
font.dispose();
select.dispose();
point.dispose();
chirp.dispose();
die.dispose();
fadeRenderer.dispose();
}
public void setScreenWithFade(final Screen screen, float duration) {
fadeActor.clearActions();
fadeActor.setColor(Color.CLEAR);
fadeActor.addAction(Actions.sequence(
Actions.color(Color.BLACK, duration / 2f, Interpolation.fade),
Actions.run(new Runnable() {
public void run() {
setScreen(screen);
}
}),
Actions.color(Color.CLEAR, duration / 2f, Interpolation.fade)
));
}
public void setCurrentHighscore(int currentHighscore) {
this.currentHighscore = currentHighscore;
}
public Preferences getHighscore() {
return highscore;
}
public void setCurrentTotalScore(int currentTotalScore) {
this.currentTotalScore = currentTotalScore;
}
public Preferences getTotalScore() {
return totalScore;
}
public boolean isCurrentTutMode() {
return currentTutMode;
}
public void setCurrentTutMode(boolean currentTutMode) {
this.currentTutMode = currentTutMode;
}
public Preferences getTut() {
return tut;
}
public Sound getPoint() {
return point;
}
public Sound getSelect() {
return select;
}
public Sound getDie() {
return die;
}
public Music getChirp() {
return chirp;
}
public Preferences getDeaths() {
return deaths;
}
public void setSoundOn(boolean soundOn) {
sound.putBoolean("currentSoundMode", soundOn);
sound.putBoolean("soundOn", soundOn);
sound.flush();
}
public Preferences getSound() {
return sound;
}
public boolean isSoundOn() {
return sound.getBoolean("currentSoundMode", true);
}
public void setCurrentDeaths(int currentDeaths) {
this.currentDeaths = currentDeaths;
}
}
编辑2:我的MenuState Screen
package com.samuel.kiwi.states;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.Vector3;
import com.samuel.kiwi.Kiwi;
/**
* Created by Samuel on 10/2/2016.
*/
public class MenuState extends InputAdapter implements Screen {
private Texture bg;
private Texture playBtn;
private Texture playBtnDown;
private Texture gPlayBtn;
private Texture gPlayBtnDown;
private Texture settingsBtn;
private Texture settingsBtnDown;
private boolean updatePos;
private Kiwi game;
private Texture kiwiLogo;
private Vector3 kiwiLogoPos;
private Vector3 kiwiLogoVel;
private Vector3 touchPos;
private boolean isTouchPlay;
private boolean isTouchReleased;
private boolean isGDown;
private boolean isGReleased;
private boolean isSettingsDown;
private boolean isSettingsReleased;
private OrthographicCamera cam;
private boolean handleInput;
public MenuState(final Kiwi game, OrthographicCamera cam) {
this.game = game;
this.cam = cam;
kiwiLogo = new Texture("pics/menu/kiwiLogo.png");
bg = new Texture("pics/bg.png");
playBtn = new Texture("pics/menu/play_button.png");
playBtnDown = new Texture("pics/menu/play_button_down.png");
gPlayBtn = new Texture("pics/menu/g_play_button.png");
gPlayBtnDown = new Texture("pics/menu/g_play_button_down.png");
settingsBtn = new Texture("pics/menu/settings_button.png");
settingsBtnDown = new Texture("pics/menu/settings_button_down.png");
}
public void handleInput() {
if (isTouchReleased && isTouchPlay) {
Gdx.input.setInputProcessor(null);
game.setScreenWithFade(new PlayState(game, cam), 5);
handleInput = false;
}
if (isGReleased) {
//glöm inte disposa... eller?
//google playa dude
}
if (isSettingsReleased && isSettingsDown) {
Gdx.input.setInputProcessor(null);
game.setScreenWithFade(new SettingsState(game, cam), 5);
handleInput = false;
}
}
public void update(float delta) {
if (handleInput)
handleInput();
if (updatePos) {
if (kiwiLogoPos.y < cam.position.y + 30)
kiwiLogoVel.add(0, 3, 0);
else
kiwiLogoVel.add(0, -3, 0);
kiwiLogoVel.scl(delta);
kiwiLogoPos.add(0, kiwiLogoVel.y, 0);
kiwiLogoVel.scl(1 / delta);
}
}
@Override
public void show() {
handleInput = true;
updatePos = true;
if (game.isSoundOn())
game.getChirp().setVolume(1);
else
game.getChirp().setVolume(0);
Gdx.input.setInputProcessor(this);
kiwiLogoPos = new Vector3(cam.position.x - kiwiLogo.getWidth(), cam.position.y + 25, 0);
kiwiLogoVel = new Vector3(0, 0, 0);
isTouchPlay = false;
touchPos = new Vector3();
}
@Override
public void render(float delta) {
update(delta);
game.batch.begin();
game.batch.setProjectionMatrix(cam.combined);
game.batch.draw(bg, cam.position.x - cam.viewportWidth / 2, cam.position.y - cam.viewportHeight / 2, cam.viewportWidth, cam.viewportHeight);
game.batch.draw(kiwiLogo, kiwiLogoPos.x, kiwiLogoPos.y, kiwiLogo.getWidth() * 2, kiwiLogo.getHeight() * 2);
if (!isTouchPlay) {
game.batch.draw(playBtn, cam.position.x - playBtn.getWidth(), cam.position.y - 100, playBtn.getWidth() * 2, playBtn.getHeight() * 2);
} else {
game.batch.draw(playBtnDown, cam.position.x - playBtn.getWidth(), cam.position.y - 100, playBtn.getWidth() * 2, playBtn.getHeight() * 2);
}
if (!isGDown) {
game.batch.draw(gPlayBtn, cam.position.x - playBtn.getWidth(), cam.position.y - gPlayBtn.getHeight() * 2 - 112, gPlayBtn.getWidth() * 2, gPlayBtn.getHeight() * 2);
} else {
game.batch.draw(gPlayBtnDown, cam.position.x - playBtn.getWidth(), cam.position.y - gPlayBtn.getHeight() * 2 - 112, gPlayBtn.getWidth() * 2, gPlayBtn.getHeight() * 2);
}
if (!isSettingsDown) {
game.batch.draw(settingsBtn, cam.position.x + playBtn.getWidth() - settingsBtn.getWidth() * 2, cam.position.y - gPlayBtn.getHeight() * 2 - 112, gPlayBtn.getWidth() * 2, gPlayBtn.getHeight() * 2);
} else {
game.batch.draw(settingsBtnDown, cam.position.x + playBtn.getWidth() - settingsBtn.getWidth() * 2, cam.position.y - gPlayBtn.getHeight() * 2 - 112, gPlayBtn.getWidth() * 2, gPlayBtn.getHeight() * 2);
}
game.batch.end();
}
@Override
public void resize(int width, int height) {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void hide() {
dispose();
}
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
cam.unproject(touchPos.set(screenX, screenY, 0));
//gobutton
if (touchPos.x > cam.position.x - playBtn.getWidth() && touchPos.x < cam.position.x + playBtn.getWidth()
&& touchPos.y < cam.position.y - 100 + playBtn.getHeight() * 2 && touchPos.y > cam.position.y - 100) {
isTouchPlay = true;
if (game.isSoundOn())
game.getSelect().play();
}
//gplay
if (touchPos.x > cam.position.x - playBtn.getWidth() && touchPos.x < cam.position.x - playBtn.getWidth() + gPlayBtn.getWidth() * 2
&& touchPos.y < cam.position.y - 112 && touchPos.y > cam.position.y - gPlayBtn.getHeight() * 2 - 112) {
isGDown = true;
if (game.isSoundOn())
game.getSelect().play();
}
//settings
if (touchPos.x > cam.position.x + playBtn.getWidth() - settingsBtn.getWidth() * 2 && touchPos.x < cam.position.x + playBtn.getWidth()
&& touchPos.y < cam.position.y - 112 && touchPos.y > cam.position.y - gPlayBtn.getHeight() * 2 - 112) {
isSettingsDown = true;
if (game.isSoundOn())
game.getSelect().play();
}
return true;
}
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
cam.unproject(touchPos.set(screenX, screenY, 0));
//gobutton
if (touchPos.x > cam.position.x - playBtn.getWidth() && touchPos.x < cam.position.x + playBtn.getWidth()
&& touchPos.y < cam.position.y - 100 + playBtn.getHeight() * 2 && touchPos.y > cam.position.y - 100 && isTouchPlay)
isTouchReleased = true;
else
isTouchPlay = false;
//gplay
if (touchPos.x > cam.position.x - playBtn.getWidth() && touchPos.x < cam.position.x - playBtn.getWidth() + gPlayBtn.getWidth() * 2
&& touchPos.y < cam.position.y - 112 && touchPos.y > cam.position.y - gPlayBtn.getHeight() * 2 - 112)
isGReleased = true;
else
isGDown = false;
//settings
if (touchPos.x > cam.position.x + playBtn.getWidth() - settingsBtn.getWidth() * 2 && touchPos.x < cam.position.x + playBtn.getWidth()
&& touchPos.y < cam.position.y - 112 && touchPos.y > cam.position.y - gPlayBtn.getHeight() * 2 - 112)
isSettingsReleased = true;
else
isSettingsDown = false;
return true;
}
@Override
public void dispose() {
bg.dispose();
playBtn.dispose();
playBtnDown.dispose();
gPlayBtn.dispose();
gPlayBtnDown.dispose();
settingsBtn.dispose();
settingsBtnDown.dispose();
kiwiLogo.dispose();
}
}
答案 0 :(得分:3)
You can use an Actor as a tween engine by placing a ColorAction (or any subclass of TemporalAction) on it. Then you don't have to fool with a Stage and the overhead that entails. Something like this:
public class GameWithTransitions extends Game {
private Actor fadeActor = new Actor();
private ShapeRenderer fadeRenderer;
public void create (){
//...your create() code
fadeRenderer = new ShapeRenderer(8);
}
public void setScreenWithFade (final Screen screen, float duration) {
fadeActor.clearActions();
fadeActor.setColor(Color.CLEAR);
fadeActor.addAction(Actions.sequence(
Actions.color(Color.BLACK, duration/2f, Interpolation.fade),
Actions.run(new Runnable(){public void run(){setScreen(screen);}}),
Actions.color(Color.CLEAR, duration/2f, Interpolation.fade)
));
}
@Override
public void render (){
super.render();
fadeActor.act(Gdx.graphics.getDeltaTime());
float alpha = fadeActor.getColor().a;
if (alpha != 0){
fadeRenderer.begin(ShapeType.Filled);
fadeRenderer.setColor(0, 0, 0, alpha);
fadeRenderer.rect(-1, -1, 2, 2); //full screen rect w/ identity matrix
fadeRenderer.end();
}
}
}
Note: I haven't tested the above code.