2017-10-28 90 views
0

这是我的触摸板。 enter image description here制作可触摸的触摸板bg [LibGdx]

我想要的是:当我触摸触摸板的背景(不是旋钮)时,旋钮移动到这个位置。代码,这是我使用触摸板从GitHub/libgdx/GDX/src目录/ COM/badlogic/GDX /场景/ scene2d/UI/Touchpad.java

package com.liketurbo.funnyGame; 
 

 
/******************************************************************************* 
 
* Copyright 2011 See AUTHORS file. 
 
* 
 
* Licensed under the Apache License, Version 2.0 (the "License"); 
 
* you may not use this file except in compliance with the License. 
 
* You may obtain a copy of the License at 
 
* 
 
* http://www.apache.org/licenses/LICENSE-2.0 
 
* 
 
* Unless required by applicable law or agreed to in writing, software 
 
* distributed under the License is distributed on an "AS IS" BASIS, 
 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 
* See the License for the specific language governing permissions and 
 
* limitations under the License. 
 
******************************************************************************/ 
 

 
import com.badlogic.gdx.scenes.scene2d.Event; 
 
import com.badlogic.gdx.scenes.scene2d.EventListener; 
 
import com.badlogic.gdx.scenes.scene2d.ui.Widget; 
 
import com.badlogic.gdx.scenes.scene2d.ui.Skin; 
 

 
     import com.badlogic.gdx.graphics.Color; 
 
     import com.badlogic.gdx.graphics.g2d.Batch; 
 
     import com.badlogic.gdx.math.Circle; 
 
     import com.badlogic.gdx.math.Vector2; 
 
     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.utils.ChangeListener.ChangeEvent; 
 
     import com.badlogic.gdx.scenes.scene2d.utils.Drawable; 
 
     import com.badlogic.gdx.utils.Pools; 
 

 
/** An on-screen joystick. The movement area of the joystick is circular, centered on the touchpad, and its size determined by the 
 
* smaller touchpad dimension. 
 
* <p> 
 
* The preferred size of the touchpad is determined by the background. 
 
* <p> 
 
* {@link ChangeEvent} is fired when the touchpad knob is moved. Cancelling the event will move the knob to where it was 
 
* previously. 
 
* @author Josh Street */ 
 
public class Touchpad extends Widget { 
 
    private TouchpadStyle style; 
 
    boolean touched; 
 
    boolean resetOnTouchUp = true; 
 
    private float deadzoneRadius; 
 
    private final Circle knobBounds = new Circle(0, 0, 0); 
 
    private final Circle touchBounds = new Circle(0, 0, 0); 
 
    private final Circle deadzoneBounds = new Circle(0, 0, 0); 
 
    private final Vector2 knobPosition = new Vector2(); 
 
    private final Vector2 knobPercent = new Vector2(); 
 

 
    /** @param deadzoneRadius The distance in pixels from the center of the touchpad required for the knob to be moved. */ 
 
    public Touchpad (float deadzoneRadius, Skin skin) { 
 
     this(deadzoneRadius, skin.get(TouchpadStyle.class)); 
 
    } 
 

 
    /** @param deadzoneRadius The distance in pixels from the center of the touchpad required for the knob to be moved. */ 
 
    public Touchpad (float deadzoneRadius, Skin skin, String styleName) { 
 
     this(deadzoneRadius, skin.get(styleName, TouchpadStyle.class)); 
 
    } 
 

 
    /** @param deadzoneRadius The distance in pixels from the center of the touchpad required for the knob to be moved. */ 
 
    public Touchpad (float deadzoneRadius, TouchpadStyle style) { 
 
     if (deadzoneRadius < 0) throw new IllegalArgumentException("deadzoneRadius must be > 0"); 
 
     this.deadzoneRadius = deadzoneRadius; 
 

 
     knobPosition.set(getWidth()/2f, getHeight()/2f); 
 

 
     setStyle(style); 
 
     setSize(getPrefWidth(), getPrefHeight()); 
 

 
     addListener(new InputListener() { 
 
      @Override 
 
      public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) { 
 
       if (touched) return false; 
 
       touched = true; 
 
       calculatePositionAndValue(x, y, false); 
 
       return true; 
 
      } 
 

 
      @Override 
 
      public void touchDragged (InputEvent event, float x, float y, int pointer) { 
 
       calculatePositionAndValue(x, y, false); 
 
      } 
 

 
      @Override 
 
      public void touchUp (InputEvent event, float x, float y, int pointer, int button) { 
 
       touched = false; 
 
       calculatePositionAndValue(x, y, resetOnTouchUp); 
 
      } 
 
     }); 
 
    } 
 

 
    void calculatePositionAndValue (float x, float y, boolean isTouchUp) { 
 
     float oldPositionX = knobPosition.x; 
 
     float oldPositionY = knobPosition.y; 
 
     float oldPercentX = knobPercent.x; 
 
     float oldPercentY = knobPercent.y; 
 
     float centerX = knobBounds.x; 
 
     float centerY = knobBounds.y; 
 
     y = centerY; 
 

 
     knobPosition.set(centerX, centerY); 
 
     knobPercent.set(0f, 0f); 
 
     if (!isTouchUp) { 
 
      if (!deadzoneBounds.contains(x, y)) { 
 
       knobPercent.set((x - centerX)/knobBounds.radius*3.5f, 0); 
 
       float length = knobPercent.len(); 
 
       if (length > 1) knobPercent.scl(1/length); 
 
       if (knobBounds.contains(x, y)) { 
 
        knobPosition.set(x, y); 
 
       } else { 
 
        knobPosition.set(knobPercent).nor().scl(knobBounds.radius*3.5f).add(knobBounds.x, knobBounds.y); 
 
       } 
 
      } 
 
     } 
 
     if (oldPercentX != knobPercent.x || oldPercentY != knobPercent.y) { 
 
      ChangeEvent changeEvent = Pools.obtain(ChangeEvent.class); 
 
      if (fire(changeEvent)) { 
 
       knobPercent.set(oldPercentX, oldPercentY); 
 
       knobPosition.set(oldPositionX, oldPositionY); 
 
      } 
 
      Pools.free(changeEvent); 
 
     } 
 
    } 
 

 
    public void setStyle (TouchpadStyle style) { 
 
     if (style == null) throw new IllegalArgumentException("style cannot be null"); 
 
     this.style = style; 
 
     invalidateHierarchy(); 
 
    } 
 

 
    /** Returns the touchpad's style. Modifying the returned style may not have an effect until {@link #setStyle(TouchpadStyle)} is 
 
    * called. */ 
 
    public TouchpadStyle getStyle() { 
 
     return style; 
 
    } 
 

 
    @Override 
 
    public Actor hit (float x, float y, boolean touchable) { 
 
     return touchBounds.contains(x, y) ? this : null; 
 
    } 
 

 
    @Override 
 
    public void layout() { 
 
     // Recalc pad and deadzone bounds 
 
     float halfWidth = getWidth()/2; 
 
     float halfHeight = getHeight()/2; 
 
     float radius = Math.min(halfWidth, halfHeight); 
 
     touchBounds.set(halfWidth, halfHeight, radius); 
 
     if (style.knob != null) radius -= Math.max(style.knob.getMinWidth(), style.knob.getMinHeight())/2; 
 
     knobBounds.set(halfWidth, halfHeight, radius); 
 
     deadzoneBounds.set(halfWidth, halfHeight, deadzoneRadius); 
 
     // Recalc pad values and knob position 
 
     knobPosition.set(halfWidth, halfHeight); 
 
     knobPercent.set(0, 0); 
 
    } 
 

 
    @Override 
 
    public void draw (Batch batch, float parentAlpha) { 
 
     validate(); 
 

 
     Color c = getColor(); 
 
     batch.setColor(c.r, c.g, c.b, c.a * parentAlpha); 
 

 
     float x = getX(); 
 
     float y = getY(); 
 
     float w = getWidth(); 
 
     float h = getHeight(); 
 

 
     final Drawable bg = style.background; 
 
     if (bg != null) bg.draw(batch, x, y, w, h); 
 

 
     final Drawable knob = style.knob; 
 
     if (knob != null) { 
 
      x += knobPosition.x - (knob.getMinWidth()*2)/2f; 
 
      y += knobPosition.y - (knob.getMinHeight()*2)/2f; 
 
      knob.draw(batch, x, y, knob.getMinWidth()*2, knob.getMinHeight()*2); 
 
     } 
 
    } 
 

 
    @Override 
 
    public float getPrefWidth() { 
 
     return style.background != null ? style.background.getMinWidth() : 0; 
 
    } 
 

 
    @Override 
 
    public float getPrefHeight() { 
 
     return style.background != null ? style.background.getMinHeight() : 0; 
 
    } 
 

 
    public boolean isTouched() { 
 
     return touched; 
 
    } 
 

 
    public boolean getResetOnTouchUp() { 
 
     return resetOnTouchUp; 
 
    } 
 

 
    /** @param reset Whether to reset the knob to the center on touch up. */ 
 
    public void setResetOnTouchUp (boolean reset) { 
 
     this.resetOnTouchUp = reset; 
 
    } 
 

 
    /** @param deadzoneRadius The distance in pixels from the center of the touchpad required for the knob to be moved. */ 
 
    public void setDeadzone (float deadzoneRadius) { 
 
     if (deadzoneRadius < 0) throw new IllegalArgumentException("deadzoneRadius must be > 0"); 
 
     this.deadzoneRadius = deadzoneRadius; 
 
     invalidate(); 
 
    } 
 

 
    /** Returns the x-position of the knob relative to the center of the widget. The positive direction is right. */ 
 
    public float getKnobX() { 
 
     return knobPosition.x; 
 
    } 
 

 
    /** Returns the y-position of the knob relative to the center of the widget. The positive direction is up. */ 
 
    public float getKnobY() { 
 
     return knobPosition.y; 
 
    } 
 

 
    /** Returns the x-position of the knob as a percentage from the center of the touchpad to the edge of the circular movement 
 
    * area. The positive direction is right. */ 
 
    public float getKnobPercentX() { 
 
     return knobPercent.x; 
 
    } 
 

 
    /** Returns the y-position of the knob as a percentage from the center of the touchpad to the edge of the circular movement 
 
    * area. The positive direction is up. */ 
 
    public float getKnobPercentY() { 
 
     return knobPercent.y; 
 
    } 
 

 
    /** The style for a {@link Touchpad}. 
 
    * @author Josh Street */ 
 
    public static class TouchpadStyle { 
 
     /** Stretched in both directions. Optional. */ 
 
     public Drawable background; 
 

 
     /** Optional. */ 
 
     public Drawable knob; 
 

 
     public TouchpadStyle() { 
 
     } 
 

 
     public TouchpadStyle (Drawable background, Drawable knob) { 
 
      this.background = background; 
 
      this.knob = knob; 
 
     } 
 

 
     public TouchpadStyle (TouchpadStyle style) { 
 
      this.background = style.background; 
 
      this.knob = style.knob; 
 
     } 
 
    } 
 
}

线addListener(new InputListener() {...}仅供旋钮工作,如果我能弄清楚它是如何为触摸板的背景工作的,它解决了我的问题。有人知道如何解决这个问题吗?先谢谢你。

+0

请告诉我,如果你需要JavaClass,我在那里进口Touchpad.java –

回答

1

您不应该将监听器添加到触控板。只需限制触摸板可以使用的屏幕触摸区域即可。

下面是代码来激活仅在屏幕的右半部分:

private Touchpad touchpad; 
private Vector2 screenPos = new Vector2(); // position where touch occurs 
private Vector2 localPos = new Vector2(); // position in local coordinates 
private InputEvent fakeTouchDownEvent = new InputEvent(); // fake touch for correct work 
private Vector2 stagePos; // position to fire touch event 

private void getDirection() { 
    if (Gdx.input.justTouched()) { 

     // Get the touch point in screen coordinates. 
     screenPos.set(Gdx.input.getX(), Gdx.input.getY()); 

     if (screenPos.x > Gdx.graphics.getWidth()/2) { // right half of a screen 

      // Convert the touch point into local coordinates, place the touchpad and show it. 
      localPos.set(screenPos); 
      localPos = touchpad.getParent().screenToLocalCoordinates(localPos); 
      touchpad.setPosition(localPos.x - touchpad.getWidth()/2, localPos.y - touchpad.getHeight()/2); 

      // Fire a touch down event to get the touchpad working. 
      Vector2 stagePos = touchpad.getStage().screenToStageCoordinates(screenPos); 
      fakeTouchDownEvent.setStageX(stagePos.x); 
      fakeTouchDownEvent.setStageY(stagePos.y); 
      touchpad.fire(fakeTouchDownEvent); 
     } 
    } 

} 
+0

fakeTouchDownEvent()的代码崩溃的应用程序 –

+0

@RamzanChasygov这例外? – icarumbas

+0

没关系,想通了 –