2015-07-28 2 views
1

Я только начинаю разработку Android-игр с помощью рамки LibGdx. До сих пор я читал много онлайн-уроков, и чем больше я читал, тем больше меня путали: ApplicationListener, ApplicationAdapter, Stages, Game, Screens, Actors, Sprites, Images ... не говоря уже о слушателях ввода и жестов всего короля).LibGDX Stage и Actor, Events и Actor properties

Я наконец понял, какую «модель» я должен использовать для игры, которую я имею в виду (своего рода игра-головоломка): игра, экраны, сцена и актер.

Итак, вот мой первый код.

Это основное приложение (Игра):

package com.my.game1; 
import com.badlogic.gdx.Game; 

public class MyGame extends Game { 

    @Override 
    public void create() { 
     setScreen(new StarterScreen()); 
    } 
} 

Это основной класс экрана:

package com.my.game1; 

import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.Screen; 
import com.badlogic.gdx.graphics.GL20; 
import com.badlogic.gdx.scenes.scene2d.Stage; 

public class StarterScreen implements Screen { 

    private Stage stage; 
    private float screenW, screenH; 
    private Tess tessera; 

    @Override 
    public void show() { 
     tessera = new Tess("image.png"); 
     stage = new Stage(); 
     screenW = stage.getViewport().getWorldWidth(); 
     screenH = stage.getViewport().getWorldHeight(); 
     Gdx.input.setInputProcessor(stage); 
     stage.addActor(tessera); 
    } 

    @Override 
    public void render(float delta) { 
     Gdx.gl.glClearColor(0,0,0,1); 
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 
     stage.act(); 
     stage.draw(); 
    } 

    @Override 
    public void resize(int width, int height) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void pause() { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void resume() { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void hide() { 
     dispose(); 
    } 

    @Override 
    public void dispose() { 
     stage.dispose(); 
    } 

} 

А следующий класс, который расширяет актер:

package com.my.game1; 

import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.graphics.Texture; 
import com.badlogic.gdx.graphics.g2d.Batch; 
import com.badlogic.gdx.scenes.scene2d.Actor; 
import com.badlogic.gdx.scenes.scene2d.InputEvent; 
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener; 

public class Tess extends Actor { 

    private Texture texture; 
    private boolean selected = false; 

    public Tess (String img) { 
     this.texture = new Texture(Gdx.files.internal(img)); 
     this.setBounds(0f, 0f, this.texture.getWidth(), this.texture.getHeight()); 
     this.setOrigin(this.texture.getWidth()/2, this.texture.getHeight()/2); 
     this.setScale(0.25f); 
     this.addListener(new ActorGestureListener() { 
      public void tap(InputEvent event, float x, float y, int pointer, int button) { 
       ((Tess)event.getTarget()).toggleSelect(); 
       ((Tess)event.getTarget()).setColor(0.5f, 0f, 0.5f, 1f); 
      } 
     }); 
    } 

    @Override 
    public void draw(Batch batch, float alpha){ 
     batch.draw(texture, 0, 0); 
    } 

    public void finalize() { 
     this.texture.dispose(); 
    } 

    public void toggleSelect(){ 
     this.selected = !this.selected; 
     if (this.selected == true) 
      this.setColor(0.5f, 0f, 0.5f, 1f); 
     else 
      this.setColor(0f, 0f, 0f, 0f);   
    } 
} 

Экран правильно отображает актера, но я не могу установить положение Актера или его масштаб, ни «нажмите» e вентиляционное отверстие, как представляется, обнаруживается; и цвет не меняется.

Что я сделал не так?

ответ

0

Несколько вещей были неправильными. Во-первых, просто на стороне, вы не хотите звонить dispose() с экрана hide(). hide() можно вызвать просто, когда экран выключен или когда приложение переключено на задний план, и удаление Screen во время этого приведет к серьезным проблемам при возобновлении.

С этим из пути, вот что ваш актер должен был выглядеть так:

package com.my.game1; 

import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.graphics.Texture; 
import com.badlogic.gdx.graphics.g2d.Batch; 
import com.badlogic.gdx.graphics.g2d.Sprite; 
import com.badlogic.gdx.scenes.scene2d.Actor; 
import com.badlogic.gdx.scenes.scene2d.InputEvent; 
import com.badlogic.gdx.scenes.scene2d.InputListener; 
import com.badlogic.gdx.scenes.scene2d.Touchable; 

public class Tess extends Actor { 

    private Sprite sprite; 
    private boolean selected = false; 

    public Tess (String img) { 
     this.sprite = new Sprite(new Texture(Gdx.files.internal(img))); 
     this.setTouchable(Touchable.enabled); 
     this.setBounds(this.sprite.getX(), this.sprite.getY(), this.sprite.getWidth(), this.sprite.getHeight()); 
     this.setOrigin(this.sprite.getWidth()/2, this.sprite.getHeight()/2); 
     this.setScale(0.25f); 
     this.addListener(new ActorGestureListener() { 
      @Override 
      public void tap (InputEvent event, float x, float y, int pointer, int button) { 
       ((Tess)event.getTarget()).toggleSelect(); 
      } 
     }); 
    } 

    @Override 
    public void draw(Batch batch, float alpha){ 
     sprite.draw(batch); 
    } 

    @Override 
    public void positionChanged(){ 
     sprite.setPosition(getX(), getY()); 
    } 

    public void toggleSelect(){ 
     this.selected = !this.selected; 
     if (this.selected == true) 
      sprite.setColor(0.5f, 0f, 0.5f, 1f); 
     else 
      sprite.setColor(0f, 0f, 0f, 0f);   
    } 
} 

Первое изменилось: вы должны использовать Sprite, не Texture, обрабатывать цвет, рисунок и преобразования легко. Texture возможен, но не такой простой, как Sprite есть.

Далее необходимо набрать setTouchable(Touchable.enabled) внутри актера, чтобы фактически включить обнаружение попадания. Без этого никакие события касания не передаются в Actor.

После этого, с setBounds(), вам нужно использовать sprite.getX() и sprite.getY(), чтобы использовать значения позиционных Sprite «s. Установка их на любое произвольное число, по-видимому, отключает любую сенсорную емкость для этого Actor.

Другое дело, если все это было в порядке, это то, что вы устанавливали цвет дважды для каждого касания, когда-то на основании поля selected, а затем сразу же после прямого на темно-фиолетовый, поэтому я удалил второй набор и просто использовал ваш метод переключения.

Далее, так как у нас есть Sprite теперь мы можем использовать метод draw() прикрепленного к Sprite самим и кормить его в Batch, вместо вызова Изобразите Batch «s.

Наконец, если вы хотите изменить положение изображения, называют на самом актере, и использовать переопределение метода positionChanged() установить «положение s, основанное на Actor» Sprite нового положения s.

+0

Спасибо. Вы дали мне хорошие советы. Я удалил вызов dispose() из метода hide(); вначале это был заставка, поэтому я решил уничтожить его сразу после того, как скрыть это ... потому что не более полезно. Об авторе Аккаунт, я уверяю вас, у него есть метод tap(). Не знаю еще много событий о событиях и событиях, поэтому я скопировал код из учебника. Возможно, это было только потому, что я использовал Texture вместо Sprite, и я устанавливал границы 0,0 и размер текстуры. Мне до сих пор нужно уточнить некоторые аспекты, но теперь это работает, и я думаю, что я на правильном пути. Спасибо. –

+0

А теперь я вижу 'tap()'. Должно быть, я неправильно понял. Я обновил свой ответ, чтобы отразить это (и тот факт, что у ActorGestureListener также есть методы touchUp и touchDown). Если бы это сработало для вас, можно ли принять ответ? – Malkierian

+0

Я не вижу, чтобы «Спрайт» был расположен где угодно. Как избавиться от «спрайта»? – spierce7

Смежные вопросы