private void setCurrent(int index, TrackEntry entry) { TrackEntry current = expandToIndex(index); if (current != null) { TrackEntry previous = current.previous; current.previous = null; if (current.listener != null) current.listener.end(index); for (int i = 0, n = listeners.size; i < n; i++) listeners.get(i).end(index); entry.mixDuration = data.getMix(current.animation, entry.animation); if (entry.mixDuration > 0) { entry.mixTime = 0; // If a mix is in progress, mix from the closest animation. if (previous != null && current.mixTime / current.mixDuration < 0.5f) { entry.previous = previous; previous = current; } else entry.previous = current; } else trackEntryPool.free(current); if (previous != null) trackEntryPool.free(previous); } tracks.set(index, entry); if (entry.listener != null) entry.listener.start(index); for (int i = 0, n = listeners.size; i < n; i++) listeners.get(i).start(index); }
public void defineSnapperViews() { if (logic.level == null) return; SnapperView view; int i; int j; int state; synchronized (activeSnappers) { for (i = 0; i < activeSnappers.size; i++) removeActor(activeSnappers.get(i)); snapperViewPool.free(activeSnappers); activeSnappers.clear(); int w = logic.width; int h = logic.height; for (i = 0; i < Snappers.WIDTH; i++) for (j = 0; j < Snappers.HEIGHT; j++) if ((state = logic.snappers.getSnapper(i, j)) > 0) { view = snapperViewPool.obtain(); view.set(i, j, state); view.setRandomStart(0, 0, w, h, SNAPPER_WARM_TIME); activeSnappers.add(view); addActor(view); view.setListener(snapperAnimationListener); view.setAnimFn(snapperAnimFn); } } }
public boolean remove() { if (super.remove()) { pool.free(this); return true; } return false; }
/** @param last May be null. */ private TrackEntry trackEntry( int trackIndex, Animation animation, boolean loop, TrackEntry last) { TrackEntry entry = trackEntryPool.obtain(); entry.trackIndex = trackIndex; entry.animation = animation; entry.loop = loop; entry.eventThreshold = 0; entry.attachmentThreshold = 0; entry.drawOrderThreshold = 0; entry.animationStart = 0; entry.animationEnd = animation.getDuration(); entry.animationLast = -1; entry.nextAnimationLast = -1; entry.delay = 0; entry.trackTime = 0; entry.trackLast = -1; entry.nextTrackLast = -1; entry.trackEnd = Float.MAX_VALUE; entry.timeScale = 1; entry.alpha = 1; entry.mixAlpha = 1; entry.mixTime = 0; entry.mixDuration = last == null ? 0 : data.getMix(last.animation, animation); return entry; }
@Override public void draw(SpriteBatch spriteBatch) { delta = Math.min(0.06f, Gdx.graphics.getDeltaTime()); this.setOrigin(0, 0); for (int i = particles.size - 1; i >= 0; i--) { Particle particle = particles.get(i); if (particle.life > 0) { updateParticle(particle); float dx = this.getWidth() / 2 * particle.scale; float dy = this.getHeight() / 2 * particle.scale; this.setColor(1, 1, 1, Math.max(particle.life / this.life, 0)); this.setScale(particle.scale); this.setPosition(particle.position.x - dx, particle.position.y - dy); if (!(particle.position.y - dy >= -10 && particle.position.y - dy <= 10) && !(particle.position.x - dx >= -10 && particle.position.x - dx <= 10)) { super.draw(spriteBatch); } else { particle.life = 0; } } else { particles.removeIndex(i); freeParticles.free(particle); } } }
private void freeAll(TrackEntry entry) { while (entry != null) { TrackEntry next = entry.next; trackEntryPool.free(entry); entry = next; } }
private void drawRecursive(Actor actor) { if (!invisibleActors && !actor.isVisible()) return; if (allActors) actor.debug(); if (actor.getDebug()) { actor.getDebugRects(debugRects); for (DebugRect debugRect : debugRects) drawRect(actor, debugRect); debugRects.clear(); debugRectPool.freeAll(usedRects); usedRects.clear(); } boolean draw = true; Rectangle scissorBounds = null; if (actor instanceof Group) scissorBounds = ((Group) actor).getScissorBounds(); if (scissorBounds != null) { shapes.flush(); draw = ScissorStack.pushScissors(scissorBounds); } if (draw) { // Children are still rendered, even if the group has no debugging enabled. if (actor instanceof Group) { Group group = (Group) actor; for (Actor child : group.getChildren()) drawRecursive(child); } if (scissorBounds != null) { shapes.flush(); ScissorStack.popScissors(); } } }
@Override public boolean handleMessage(Telegram telegram) { switch (telegram.message) { case PF_RESPONSE: // PathFinderQueue will call us directly, no need to register for this // message if (PathFinderRequestControl.DEBUG) { @SuppressWarnings("unchecked") PathFinderQueue<HierarchicalTiledNode> pfQueue = (PathFinderQueue<HierarchicalTiledNode>) telegram.sender; System.out.println("pfQueue.size = " + pfQueue.size()); } MyPathFinderRequest pfr = (MyPathFinderRequest) telegram.extraInfo; TiledSmoothableGraphPath<HierarchicalTiledNode> path = paths[pfr.pathIndex]; int n = path.getCount(); if (n > 0 && pfr.pathFound && pfr.endNode != path.get(n - 1)) { pfr.startNode = path.get(n - 1); if (pfr.pathIndex + 1 < paths.length) { pfr.pathIndex++; } pfr.resultPath = paths[pfr.pathIndex]; pfr.changeStatus(PathFinderRequest.SEARCH_NEW); numPaths = pfr.pathIndex; } else { requestPool.free(pfr); numPaths = pfr.pathIndex + 1; } break; } return true; }
/** * Obtain a {@link btCollisionShape} based on the specified nodes, which can be used for a static * body but not for a dynamic body. Depending on the specified nodes the result will be either a * {@link btBvhTriangleMeshShape} or a {@link btCompoundShape} of multiple * btBvhTriangleMeshShape's. Where possible, the same btBvhTriangleMeshShape will be reused if * multiple nodes use the same (mesh) part. The node transformation (translation and rotation) * will be included, but scaling will be ignored. * * @param nodes The nodes for which to obtain a node, typically this would be: `model.nodes`. * @return The obtained shape, if you're using reference counting then you can release the shape * when no longer needed. */ public static btCollisionShape obtainStaticNodeShape(final Array<Node> nodes) { getShapeParts(nodes, shapePartArray, 0, shapePartPool); btCollisionShape result = obtainStaticShape(shapePartArray); shapePartPool.freeAll(shapePartArray); shapePartArray.clear(); return result; }
public void addParticle(Vector2 position, Vector2 velocity, float life, float scale) { if (particles.size > maxParticle) return; if (Gdx.graphics.getFramesPerSecond() < 25 && !(this instanceof ExplosionParticleEmitter)) return; Particle particle = freeParticles.obtain(); particle.setup(position, velocity, life, scale); particles.add(particle); }
public static btCollisionShape obtainStaticNodeShape( final Node node, final boolean applyTransform) { getShapeParts(node, applyTransform, shapePartArray, 0, shapePartPool); btCollisionShape result = obtainStaticShape(shapePartArray); shapePartPool.freeAll(shapePartArray); shapePartArray.clear(); return result; }
/** End applying multiple animations to the instance and update it to reflect the changes. */ protected void end() { if (!applying) throw new GdxRuntimeException("You must call begin() first"); for (Entry<Node, Transform> entry : transforms.entries()) { entry.value.toMatrix4(entry.key.localTransform); transformPool.free(entry.value); } transforms.clear(); target.calculateTransforms(); applying = false; }
@Override public void onGamepadUpdated(int index) { Gamepad gamepad = Gamepad.getGamepad(index); GwtController controller = controllerMap.get(index); if (gamepad != null && controller != null) { // Determine what changed JsArrayNumber axes = gamepad.getAxes(); JsArrayNumber buttons = gamepad.getButtons(); synchronized (eventQueue) { for (int i = 0, j = axes.length(); i < j; i++) { float oldAxis = controller.getAxis(i); float newAxis = (float) axes.get(i); if (oldAxis != newAxis) { GwtControllerEvent event = eventPool.obtain(); event.type = GwtControllerEvent.AXIS; event.controller = controller; event.code = i; event.amount = newAxis; eventQueue.add(event); } } for (int i = 0, j = buttons.length(); i < j; i++) { float oldButton = controller.getButtonAmount(i); float newButton = (float) buttons.get(i); if (oldButton != newButton) { if ((oldButton < 0.5f && newButton < 0.5f) || (oldButton >= 0.5f && newButton >= 0.5f)) { controller.buttons.put(i, newButton); continue; } GwtControllerEvent event = eventPool.obtain(); event.type = newButton >= 0.5f ? GwtControllerEvent.BUTTON_DOWN : GwtControllerEvent.BUTTON_UP; event.controller = controller; event.code = i; event.amount = newButton; eventQueue.add(event); } } } } }
/** Set the current animation. Any queued animations are cleared. */ public TrackEntry setAnimation(int trackIndex, Animation animation, boolean loop) { TrackEntry current = expandToIndex(trackIndex); if (current != null) freeAll(current.next); TrackEntry entry = trackEntryPool.obtain(); entry.animation = animation; entry.loop = loop; entry.endTime = animation.getDuration(); setCurrent(trackIndex, entry); return entry; }
protected void postTap(int x, int y) { synchronized (this) { TouchEvent event = usedTouchEvents.obtain(); event.timeStamp = System.nanoTime(); event.pointer = 0; event.x = x; event.y = y; event.type = TouchEvent.TOUCH_DOWN; touchEvents.add(event); event = usedTouchEvents.obtain(); event.timeStamp = System.nanoTime(); event.pointer = 0; event.x = x; event.y = y; event.type = TouchEvent.TOUCH_UP; touchEvents.add(event); } Gdx.app.getGraphics().requestRendering(); }
@Override public void onGamepadDisconnected(int index) { GwtController controller = controllerMap.remove(index); if (controller != null) { synchronized (eventQueue) { GwtControllerEvent event = eventPool.obtain(); event.type = GwtControllerEvent.DISCONNECTED; event.controller = controller; eventQueue.add(event); } } }
@Override public void onGamepadConnected(int index) { Gamepad gamepad = Gamepad.getGamepad(index); GwtController controller = new GwtController(gamepad.getIndex(), gamepad.getId()); controllerMap.put(index, controller); synchronized (eventQueue) { GwtControllerEvent event = eventPool.obtain(); event.type = GwtControllerEvent.CONNECTED; event.controller = controller; eventQueue.add(event); } }
private void requestNewPathFinding( HierarchicalTiledNode startNode, HierarchicalTiledNode endNode, int pathIndex) { TiledSmoothableGraphPath<HierarchicalTiledNode> path = paths[pathIndex]; MyPathFinderRequest pfRequest = requestPool.obtain(); pfRequest.startNode = startNode; pfRequest.endNode = endNode; pfRequest.heuristic = heuristic; pfRequest.resultPath = path; pfRequest.pathIndex = pathIndex; pfRequest.responseMessageCode = PF_RESPONSE; MessageManager.getInstance().dispatchMessage(this, PF_REQUEST, pfRequest); }
public void clearTrack(int trackIndex) { if (trackIndex >= tracks.size) return; TrackEntry current = tracks.get(trackIndex); if (current == null) return; if (current.listener != null) current.listener.end(trackIndex); for (int i = 0, n = listeners.size; i < n; i++) listeners.get(i).end(trackIndex); tracks.set(trackIndex, null); freeAll(current); if (current.previous != null) trackEntryPool.free(current.previous); }
public void apply(Skeleton skeleton) { Array<Event> events = this.events; int listenerCount = listeners.size; for (int i = 0; i < tracks.size; i++) { TrackEntry current = tracks.get(i); if (current == null) continue; events.size = 0; float time = current.time; float lastTime = current.lastTime; float endTime = current.endTime; boolean loop = current.loop; if (!loop && time > endTime) time = endTime; TrackEntry previous = current.previous; if (previous == null) current.animation.mix(skeleton, lastTime, time, loop, events, current.mix); else { float previousTime = previous.time; if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime; previous.animation.apply(skeleton, previousTime, previousTime, previous.loop, null); float alpha = current.mixTime / current.mixDuration * current.mix; if (alpha >= 1) { alpha = 1; trackEntryPool.free(previous); current.previous = null; } current.animation.mix(skeleton, lastTime, time, loop, events, alpha); } for (int ii = 0, nn = events.size; ii < nn; ii++) { Event event = events.get(ii); if (current.listener != null) current.listener.event(i, event); for (int iii = 0; iii < listenerCount; iii++) listeners.get(iii).event(i, event); } // Check if completed the animation or a loop iteration. if (loop ? (lastTime % endTime > time % endTime) : (lastTime < endTime && time >= endTime)) { int count = (int) (time / endTime); if (current.listener != null) current.listener.complete(i, count); for (int ii = 0, nn = listeners.size; ii < nn; ii++) listeners.get(ii).complete(i, count); } current.lastTime = current.time; } }
public static <T extends GameObject> void removeOutOfBounds( Pool<T> pool, Array<T> gos, Rectangle bounds) { float minX = bounds.x; float maxX = minX + bounds.width; float minY = bounds.y; float maxY = minY + bounds.height; for (int i = gos.size - 1; i >= 0; i--) { T go = gos.get(i); if (go.getX() >= maxX || go.getX() + go.width <= minX || go.getY() >= maxY || go.getY() + go.getHeight() <= minY) { gos.removeIndex(i); pool.free(go); } } }
public void remove(Array<RobotNinjas> robotNinjases) { if (body.getUserData() == Constants.deadID) { robotNinjases.removeValue(this, true); robotNinjasPool.free(this); } if (body.getPosition().x < 0 - width) { body.setUserData(Constants.deadID); if (!dead) { Constants.currentScoreValue++; Constants.standardVelocity.x += Constants.globalAcceleration; Constants.ninjaVelocity.x += Constants.globalAcceleration; Constants.globalAcceleration -= Constants.globalAccelerationDecline; } dead = true; } }
/** * Helper method to apply one animation to either an objectmap for blending or directly to the * bones. */ protected static void applyAnimation( final ObjectMap<Node, Transform> out, final Pool<Transform> pool, final float alpha, final Animation animation, final float time) { for (final NodeAnimation nodeAnim : animation.nodeAnimations) { final Node node = nodeAnim.node; node.isAnimated = true; // Find the keyframe(s) final int n = nodeAnim.keyframes.size - 1; int first = 0, second = -1; for (int i = 0; i < n; i++) { if (time >= nodeAnim.keyframes.get(i).keytime && time <= nodeAnim.keyframes.get(i + 1).keytime) { first = i; second = i + 1; break; } } // Apply the first keyframe: final Transform transform = tmpT; final NodeKeyframe firstKeyframe = nodeAnim.keyframes.get(first); transform.set(firstKeyframe.translation, firstKeyframe.rotation, firstKeyframe.scale); // Lerp the second keyframe if (second > first) { final NodeKeyframe secondKeyframe = nodeAnim.keyframes.get(second); final float t = (time - firstKeyframe.keytime) / (secondKeyframe.keytime - firstKeyframe.keytime); transform.lerp( secondKeyframe.translation, secondKeyframe.rotation, secondKeyframe.scale, t); } // Apply the transform, either directly to the bone or to out when blending if (out == null) transform.toMatrix4(node.localTransform); else { if (out.containsKey(node)) { if (alpha == 1.f) out.get(node).set(transform); else out.get(node).lerp(transform, alpha); } else { out.put(node, pool.obtain().set(transform)); } } } }
/** * Adds an animation to be played delay seconds after the current or last queued animation. * * @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the * negative delay. */ public TrackEntry addAnimation(int trackIndex, Animation animation, boolean loop, float delay) { TrackEntry entry = trackEntryPool.obtain(); entry.animation = animation; entry.loop = loop; entry.endTime = animation.getDuration(); TrackEntry last = expandToIndex(trackIndex); if (last != null) { while (last.next != null) last = last.next; last.next = entry; } else tracks.set(trackIndex, entry); if (delay <= 0) { if (last != null) delay += last.endTime - data.getMix(last.animation, animation); else delay = 0; } entry.delay = delay; return entry; }
public void end() { sorter.sort(camera, renderables); context.begin(); Shader currentShader = null; for (int i = 0; i < renderables.size; i++) { final Renderable renderable = renderables.get(i); if (currentShader != renderable.shader) { if (currentShader != null) currentShader.end(); currentShader = renderable.shader; currentShader.begin(camera, context); } currentShader.render(renderable); } if (currentShader != null) currentShader.end(); context.end(); renderablesPool.freeAll(reuseableRenderables); reuseableRenderables.clear(); renderables.clear(); camera = null; }
public static void getShapeParts( final Node node, final boolean applyTransform, final Array<ShapePart> out, final int offset, final Pool<ShapePart> pool) { final Matrix4 transform = applyTransform ? node.localTransform : idt; if (node.parts.size > 0) { ShapePart part = null; for (int i = offset, n = out.size; i < n; i++) { final ShapePart p = out.get(i); if (Arrays.equals(p.transform.val, transform.val)) { part = p; break; } } if (part == null) { part = pool.obtain(); part.parts.clear(); part.transform.set(transform); out.add(part); } for (int i = 0, n = node.parts.size; i < n; i++) part.parts.add(node.parts.get(i).meshPart); } if (node.hasChildren()) { final boolean transformed = applyTransform && !Arrays.equals(transform.val, idt.val); final int o = transformed ? out.size : offset; getShapeParts(node.getChildren(), out, o, pool); if (transformed) { for (int i = o, n = out.size; i < n; i++) { final ShapePart part = out.get(i); tmpM.set(part.transform); part.transform.set(transform).mul(tmpM); } } } }
@Override public boolean onKey(View v, int keyCode, android.view.KeyEvent e) { for (int i = 0, n = keyListeners.size(); i < n; i++) if (keyListeners.get(i).onKey(v, keyCode, e)) return true; synchronized (this) { KeyEvent event = null; if (e.getKeyCode() == android.view.KeyEvent.KEYCODE_UNKNOWN && e.getAction() == android.view.KeyEvent.ACTION_MULTIPLE) { String chars = e.getCharacters(); for (int i = 0; i < chars.length(); i++) { event = usedKeyEvents.obtain(); event.keyCode = 0; event.keyChar = chars.charAt(i); event.type = KeyEvent.KEY_TYPED; keyEvents.add(event); } return false; } char character = (char) e.getUnicodeChar(); // Android doesn't report a unicode char for back space. hrm... if (keyCode == 67) character = '\b'; switch (e.getAction()) { case android.view.KeyEvent.ACTION_DOWN: event = usedKeyEvents.obtain(); event.keyChar = 0; event.keyCode = e.getKeyCode(); event.type = KeyEvent.KEY_DOWN; // Xperia hack for circle key. gah... if (keyCode == android.view.KeyEvent.KEYCODE_BACK && e.isAltPressed()) { keyCode = Keys.BUTTON_CIRCLE; event.keyCode = keyCode; } keyEvents.add(event); keys.put(event.keyCode, null); break; case android.view.KeyEvent.ACTION_UP: event = usedKeyEvents.obtain(); event.keyChar = 0; event.keyCode = e.getKeyCode(); event.type = KeyEvent.KEY_UP; // Xperia hack for circle key. gah... if (keyCode == android.view.KeyEvent.KEYCODE_BACK && e.isAltPressed()) { keyCode = Keys.BUTTON_CIRCLE; event.keyCode = keyCode; } keyEvents.add(event); event = usedKeyEvents.obtain(); event.keyChar = character; event.keyCode = 0; event.type = KeyEvent.KEY_TYPED; keyEvents.add(event); if (keyCode == Keys.BUTTON_CIRCLE) keys.remove(Keys.BUTTON_CIRCLE); else keys.remove(e.getKeyCode()); } app.getGraphics().requestRendering(); } // circle button on Xperia Play shouldn't need catchBack == true if (keyCode == Keys.BUTTON_CIRCLE) return true; if (catchBack && keyCode == android.view.KeyEvent.KEYCODE_BACK) return true; if (catchMenu && keyCode == android.view.KeyEvent.KEYCODE_MENU) return true; return false; }
void processEvents() { synchronized (this) { justTouched = false; if (processor != null) { final InputProcessor processor = this.processor; int len = keyEvents.size(); for (int i = 0; i < len; i++) { KeyEvent e = keyEvents.get(i); currentEventTimeStamp = e.timeStamp; switch (e.type) { case KeyEvent.KEY_DOWN: processor.keyDown(e.keyCode); break; case KeyEvent.KEY_UP: processor.keyUp(e.keyCode); break; case KeyEvent.KEY_TYPED: processor.keyTyped(e.keyChar); } usedKeyEvents.free(e); } len = touchEvents.size(); for (int i = 0; i < len; i++) { TouchEvent e = touchEvents.get(i); currentEventTimeStamp = e.timeStamp; switch (e.type) { case TouchEvent.TOUCH_DOWN: processor.touchDown(e.x, e.y, e.pointer, Buttons.LEFT); justTouched = true; break; case TouchEvent.TOUCH_UP: processor.touchUp(e.x, e.y, e.pointer, Buttons.LEFT); break; case TouchEvent.TOUCH_DRAGGED: processor.touchDragged(e.x, e.y, e.pointer); } usedTouchEvents.free(e); } } else { int len = touchEvents.size(); for (int i = 0; i < len; i++) { TouchEvent e = touchEvents.get(i); if (e.type == TouchEvent.TOUCH_DOWN) justTouched = true; usedTouchEvents.free(e); } len = keyEvents.size(); for (int i = 0; i < len; i++) { usedKeyEvents.free(keyEvents.get(i)); } } if (touchEvents.size() == 0) { for (int i = 0; i < deltaX.length; i++) { deltaX[0] = 0; deltaY[0] = 0; } } keyEvents.clear(); touchEvents.clear(); } }
public void dispose() { particles.clear(); freeParticles.clear(); }
public static SmallFish obtainSmallFish(TextureRegion region) { SmallFish fish = pool.obtain(); fish.setRegion(region); fish.setPosition(0, 0); return fish; }