I have some trouble with my enum in my touchDown method from InputProcessor. When I try to use it it generates all the possible enums...
public class Memoration implements ApplicationListener, InputProcessor {
public static enum Screen {GAME, MENU}
Screen screen;
#Override
public void create() {
screen = Screen.MENU;
Gdx.app.log("onCreate", "works");
Gdx.input.setInputProcessor(this);
}
#Override
public void dispose() {
}
#Override
public void render() {
// bla bla bla
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
Gdx.app.log("touch", "down");
if(screen == null)
Gdx.app.log("screen", "null");
if(screen == Screen.MENU)
Gdx.app.log("screen", "menu");
if(screen == Screen.GAME)
Gdx.app.log("screen", "game");
return false;
}
}
The log show us "onCreate: workds", "touch: down", "screen: null", "screen: menu" and "screen: game"
Your class is called Memoration and implements InputProcessor. However, in your create() callback, you are creating another instance of Memoration and setting that as the input processor, so it's that instance that is getting the callbacks. And, because create() isn't being called for that instance, screen is never initialized.
Try this instead...
#Override
public void create() {
screen = Screen.MENU;
Gdx.app.log("onCreate", "works");
Gdx.input.setInputProcessor(this);
}
Related
I am making a game in android like flappy bird and I am able to go from the menu state to the playState but when the game is over and when I try to get the menu state back it just gives me the background or sometimes a white screen.
public class FlappyDemo extends ApplicationAdapter {//ApplicatoonListener
public static final int width=480;
public static final int height=800;
public static final String title="Flappy Bird";
public GameStateManager gsm;
/*private*/public SpriteBatch spriteBatch;
public void create () {
spriteBatch=new SpriteBatch();
gsm=new GameStateManager();
gsm.push(new MenuState(gsm));
Gdx.gl.glClearColor(1,1,1,1);
}
#Override
public void render () {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
gsm.update(Gdx.graphics.getDeltaTime());
gsm.render(spriteBatch);
}
}
public abstract class State {
OrthographicCamera cam;
Vector3 mouse;
GameStateManager gsm;
public State(GameStateManager gsm){
this.gsm=gsm;
mouse=new Vector3();
cam = new OrthographicCamera();
}
public abstract void handleInput();
public abstract void update(float dt);
public abstract void render(SpriteBatch sb);
public abstract void dispose();
}
public class GameStateManager {
private Stack<State> states;
public GameStateManager(){
states=new Stack<State>();
}
public void push(State state){
states.push(state);
}
public void pop(){
states.pop();
}
public void set(State state){
states.pop().dispose();
states.push(state);
}
public void update(float dt){
states.peek().update(dt);
}
public void render(SpriteBatch sb){
states.peek().render(sb);
}
}
public class MenuState extends State {
Texture background;
Texture playBtn;
public MenuState(GameStateManager gsm) {
super(gsm);
background=new Texture("bg.png");
playBtn=new Texture("buttonflappy.jpg");
}
#Override
public void handleInput() {
if(Gdx.input.isTouched()) {
gsm.push(new PlayState(gsm));
}
}
#Override
public void update(float dt) {
handleInput();
}
#Override
public void render(SpriteBatch sb) {
sb.begin();
sb.draw(background,0,0, 1100,1800);
sb.draw(playBtn,1100/2, 1800/2);
sb.end();
}
#Override
public void dispose() {
playBtn.dispose();
background.dispose();
}
}
so first I call the push method and pass it the MENUSTATE and than in the menustate I call the push method and pass it the PlayState to start the game and in the PLayState I have got the gameplay, cameras,viewports. Now when I say that if the bird hits the tube or the ground the menustate should be called again all I get is a green screen which is the background of the playstate.
if (tube.collide(bird.getBirdBound())) {
gsm.set(new MenuState(gsm));
}
if (bird.getPosition().y <= ground.getHeight() + offset) {
gsm.set(new MenuState(gsm));
}
this is the calling method to the gamestate manager when the game ends and the menustate should be called.
So can anyone tell me how can I get the menustate back instead of getting the background color i.e green.
Really appreciate if anyone could help.
You do not clear the previously rendered color to the framebuffer. I see you only call glClearColor on create. Try this render method:
#Override
public void render () {
Gdx.gl.glClearColor(1,1,1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
gsm.update(Gdx.graphics.getDeltaTime());
gsm.render(spriteBatch);
}
I finally got it the problem was that I was not changing the camera position. SO what I did was that in the menustate I used the camera and set its position cam.setToOrtho(false,1100,1800) the position where I had drawn the background and updated the camera so now when in the playstate I poped the current state and went back to to the menustate my camera was pointing at the menustate insted of the green color.
I made an app, that works good, but something strange happens. When you install the app for the 1st time, open it and put onPause, lock your phone and then you resume it clicking on icon, when it is loaded, click on BACK button (Gdx.app.exit();), It gives me the following exception:
E/AndroidRuntime: FATAL EXCEPTION: GLThread 1723
java.lang.NullPointerException
at com.badlogic.gdx.Game.render(Game.java:46)
at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(AndroidGraphics.java:459)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1524)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
After you launch the app again, and it works properly.
So, trying to figure out this error, I made a new project with gdx-setup.jar. I didn't change AndroidLauncher, neither gradle. Only in manifest I changed landscape to portrait. And I have only 4 classes with almost no code and the problem is still there. May be somebody know what happens. I will appreciate any help. Thanks!
My code:
Main class.
public class TenPuzzle extends Game {
#Override
public void create () {
setScreen(new SplashScreen(this));
}
}
SpalashScreen.java
public class SplashScreen extends Screens{
public SplashScreen(TenPuzzle ten) {
super(ten);
Gdx.app.log("1010", "SPLASH");
}
#Override
public void draw(float delta) {
game.setScreen(new MainMenuScreen(game));
}
#Override
public void update(float delta) {
}
}
MainMenuScreen.java
public class MainMenuScreen extends Screens {
public MainMenuScreen(TenPuzzle ten) {
super(ten);
Gdx.app.log("1010", "Main menu screen");
}
#Override
public void draw(float delta) {}
#Override
public void update(float delta) {}
public boolean keyDown(int keycode) {
if(keycode == Input.Keys.BACK){
Gdx.app.exit();
}
return false;
}
}
and Screens.java
public abstract class Screens extends InputAdapter implements Screen {
public static float SCREEN_WIDTH = 575;
public static float SCREEN_HEIGHT = 1024;
public TenPuzzle game;
public OrthographicCamera oCam;
public SpriteBatch batcher;
public Stage stage;
public static float diffViewportStage;
public Screens(TenPuzzle game) {
this.game = game;
stage = new Stage(new ExtendViewport(Screens.SCREEN_WIDTH,
Screens.SCREEN_HEIGHT, 768, 1224));
oCam = new OrthographicCamera(stage.getWidth(), stage.getHeight());
oCam.position.set(stage.getWidth()/ 2,stage.getHeight()/2f, 0);
InputMultiplexer input = new InputMultiplexer(this, stage);
Gdx.input.setInputProcessor(input);
Gdx.input.setCatchBackKey(true);
}
#Override
public void render(float delta) {
update(delta);
oCam.update();
stage.act(delta);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
draw(delta);
stage.draw();
}
public abstract void draw(float delta);
public abstract void update(float delta);
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
}
#Override
public void show() {
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
stage.dispose();
}
#Override
public boolean keyDown(int keycode) {
return super.keyDown(keycode);
}
}
Ok, I found the solution. I have no problem in my code, the problem was the Android bug described here: Re-launch of Activity on Home button, but...only the first time
I am making a game. There is a MainActivity with several layout over the mainscreen. One of the layout involves Google user login / logout / leaderboard / achievement.
The code are as follows:
MainActivity.class
public class MainActivity extends Activity
{
public static MainActivity main;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
main=this;
setContentView(R.layout.activity_main);
GameAdapter.StartGame();
....
}
The GameAdapter which then invoke MainLayout to inflates the different layout over the main screen.
MainLayout.class
public class MainLayout
{
public static double FloorY,Gravity,WalkSpeed;
public static void Inicial()
{
....
SoundAdapter.init();
FrontLayout.init();
....
}
FrontLayout.class (extending BaseGameActivity so as for Google Game Services)
public class FrontLayout extends BaseGameActivity
{
public static Urect LoginHolder;
public static Uimage Btn_lb, Btn_achieve, Btn_login, Btn_logout;
public static Uimage Info, info_intro;
public static void init()
{
Holder = Urect.CreateHolder(true);
LoginHolder=new Urect(0, 0, Screen.Width/2, Screen.Width/2);
Holder.AddChild(LoginHolder);
Btn_login =new Uimage(0, 0, Screen.Width/6.5, Screen.Width/6.5, Media.btn_login);
Btn_logout =new Uimage(0, 0, Screen.Width/6.5, Screen.Width/6.5, Media.btn_logout);
LoginHolder.AddChild(Btn_login);
LoginHolder.AddChild(Btn_logout);
Btn_login.addOnClickDownListner(new ClickDownListner()
{
#Override
public void OnClickDownDo(Urect curentRect, double X, double Y)
{
beginUserInitiatedSignIn(); ###1
}
});
Btn_logout.addOnClickDownListner(new ClickDownListner()
{
#Override
public void OnClickDownDo(Urect curentRect, double X, double Y)
{
signOut(); ###2
Btn_login.setAlpha(0); // visible
Btn_logout.setAlpha(255); //gone
}
});
Btn_lb.addOnClickDownListner(new ClickDownListner()
{
#Override
public void OnClickDownDo(Urect curentRect, double X, double Y)
{
if(isSignedIn()) ###3
{
MainActivity.main.startActivityForResult(Games.Leaderboards.getLeaderboardIntent(getApiClient(), MainActivity.main.getString(R.string.leaderboard_highest_mark)), 2); ###4
}
else
{
Utilities.custom_toast(MainActivity.main, "Not yet signed in", "gone", "short", "center");
}
}
});
Btn_achieve.addOnClickDownListner(new ClickDownListner()
{
#Override
public void OnClickDownDo(Urect curentRect, double X, double Y)
{
if(isSignedIn()) ###3A
{
MainActivity.main.startActivityForResult(Games.Achievements.getAchievementsIntent(getApiClient()), 1); ###4A
}
else
{
Utilities.custom_toast(MainActivity.main, "Not yet signed in", "gone", "short", "center");
}
}
});
}
#Override
public void onSignInFailed()
{
Btn_login.setAlpha(0); // visible
Btn_logout.setAlpha(255); // gone
}
#Override
public void onSignInSucceeded()
{
Btn_login.setAlpha(255); // gone
Btn_logout.setAlpha(0); // visible
}
}
Questions:
Referring to the locations marked in the above code:
###1: Cannot make a static reference to the non-static method beginUserInitiatedSignIn() from the type BaseGameActivity
###2: Cannot make a static reference to the non-static method signOut() from the type BaseGameActivity
###3, 3A: Cannot make a static reference to the non-static method isSignedIn() from the type BaseGameActivity
###4, 4A: Cannot make a static reference to the non-static method getApiClient() from the type BaseGameActivity
The error marked are basically the raised from the same error...but how could such be solved? Many thanks in advance!
In my Android app, I have a custom View that receives touch events. However, it doesn't react every time I touch it - only sometimes. From what I can tell, if I touch the screen, move my finger, and then let go - even if I move only a little - the event is picked up, but if I tap the screen too quickly for my finger to slide across it, nothing happens. How can I fix this?
Here is the View's code:
public class SpeedShooterGameView extends GameActivity.GameView {
public SpeedShooterGameView(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
}
#Override
protected GameThread getNewThread(SurfaceHolder holder, Context context) {
return new SpeedShooterGameThread(holder, context);
}
// Program is driven by screen touches
public boolean onTouchEvent(MotionEvent event) {
SpeedShooterGameThread thread = (SpeedShooterGameThread) getThread();
if (thread.isRunning()) {
return thread.recieveTouch(event);
} else {
return false;
}
}
}
I am pretty confident that the object returned in the line SpeedShooterGameThread thread = (SpeedShooterGameThread) getThread(); is working as I expect it to, but if the code above looks fine, I'll post the relevant code from that class as well. When thread.recieveTouch(event); is called, the MotionEvent is being sent to another thread.
EDIT: I'll go ahead and post the code for SpeedShooterGameThread:
public class SpeedShooterGameThread extends GameActivity.GameView.GameThread {
//... snip ...
private Queue<MotionEvent> touchEventQueue;
//... snip ...
public synchronized final void newGame() { //called from the constructor, used to go to a known stable state
//... snip ...
touchEventQueue = new LinkedList<MotionEvent>();
//... snip ...
}
//...snip...
public synchronized boolean recieveTouch(MotionEvent event) {
return touchEventQueue.offer(event);
}
private synchronized void processTouchEvents() {
synchronized (touchEventQueue) {
while (!touchEventQueue.isEmpty()) {
MotionEvent event = touchEventQueue.poll();
if (event == null) {
continue;
}
//... snip ....
}
}
}
//... snip ...
}
I fixed the bug by taking the Queue<MotionEvent> out entirely. My code now looks something like this:
The thread no longer uses a Queue, and MotionEvents are immediately processed when recieveTouch() is called:
public class SpeedShooterGameThread extends GameActivity.GameView.GameThread {
//The touchEvent member has been removed.
//... snip ...
public synchronized final void newGame() { //called from the constructor, used to go to a known stable state
// touchEvents is no longer initialized.
//...snip...
}
//...snip...
public synchronized boolean recieveTouch(MotionEvent event) {
//Immediately handle the MotionEvent here,
//or return false if the event isn't processed
}
// The processTouchEvents() method is removed.
//... snip ...
}
The view is unchanged:
public class SpeedShooterGameView extends GameActivity.GameView {
public SpeedShooterGameView(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
}
#Override
protected GameThread getNewThread(SurfaceHolder holder, Context context) {
return new SpeedShooterGameThread(holder, context);
}
// Program is driven by screen touches
public boolean onTouchEvent(MotionEvent event) {
SpeedShooterGameThread thread = (SpeedShooterGameThread) getThread();
if (thread.isRunning()) {
return thread.recieveTouch(event);
} else {
return false;
}
}
}
I'm trying to get a simple libgdx project running on Android. Everything is fine, but my InputProcessor does not fire its events.
I implemented everything according to this tutorial:
http://code.google.com/p/libgdx-users/wiki/IntegratingAndroidNativeUiElements3TierProjectSetup#Code_Example
The first call of "showToast" works fine and is shown on my screen => The showToast-Method does work. Unfortunately, I can't fire any of the InputProcessor events. Even the debugger does not stop there, so they are definitely not called.
Edit: Here is the complete code. I only omitted the Calculator Class, since it works fine and should not be of any conern here. If anyone disagrees with that I can always add it, of course.
Surface Class in libgdx main project (Main class so to say)
public class Surface implements ApplicationListener {
ActionResolver actionResolver;
SpriteBatch spriteBatch;
Texture texture;
Calculator calculator;
public Surface(ActionResolver actionResolver) {
this.actionResolver = actionResolver;
}
#Override
public void create() {
spriteBatch = new SpriteBatch();
texture = new Texture(Gdx.files.internal("ship.png"));
calculator = new Calculator(texture);
actionResolver.showToast("Tap screen to open Activity");
Gdx.input.setInputProcessor(new InputProcessor() {
#Override
public boolean touchDown(int x, int y, int pointer, int button) {
actionResolver.showToast("touchDown");
actionResolver.showMyList();
return true;
}
// overriding all other interface-methods the same way
});
}
#Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
calculator.update();
spriteBatch.begin();
calculator.draw(spriteBatch);
spriteBatch.end();
}
// Overriding resize, pause, resume, dispose without functionality
}
ActionResolver interface in libgdx main project
public interface ActionResolver {
public void showMyList();
public void showToast(String toastMessage);
}
Implementation of the ActionResolver interface within my Android project
public class ActionResolverImpl implements ActionResolver {
Handler uiThread;
Context appContext;
public ActionResolverImpl(Context appContext) {
uiThread = new Handler();
this.appContext = appContext;
}
#Override
public void showMyList() {
appContext.startActivity(new Intent(this.appContext, MyListActivity.class));
}
#Override
public void showToast(final String toastMessage) {
uiThread.post(new Runnable() {
#Override
public void run() {
Toast.makeText(appContext, toastMessage, Toast.LENGTH_SHORT).show();
}
});
}
}
Android Activity for inizializing the Suface-Class
public class AndroidActivity extends AndroidApplication {
ActionResolverImpl actionResolver;
#Override
public void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
actionResolver = new ActionResolverImpl(this);
initialize(new Surface(actionResolver), false);
}
}
I also implemented the InputProcessor in my Surface-class, but this should not (and did not) make any difference. Any ideas, what I'm missing?