Java tutorial
/* * Copyright 2017 Aurlien Gteau <mail@agateau.com> * * This file is part of Pixel Wheels. * * Tiny Wheels is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ package com.agateau.pixelwheels.racer; import com.agateau.pixelwheels.Assets; import com.agateau.pixelwheels.ZLevel; import com.agateau.pixelwheels.utils.BodyRegionDrawer; import com.agateau.pixelwheels.Constants; import com.agateau.pixelwheels.Renderer; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.physics.box2d.Body; import com.badlogic.gdx.utils.Array; /** * Renders a vehicle */ public class VehicleRenderer implements Renderer { private static final Color IMMERSED_COLOR = new Color(0, 0.5f, 1, 0.2f); private final Assets mAssets; private final Vehicle mVehicle; private final Array<Renderer> mRenderers = new Array<Renderer>(); private final SkidmarksRenderer mSkidmarksRenderer; private float mTime = 0; private final BodyRegionDrawer mBodyRegionDrawer = new BodyRegionDrawer(); public VehicleRenderer(Assets assets, Vehicle vehicle) { mAssets = assets; mVehicle = vehicle; mSkidmarksRenderer = new SkidmarksRenderer(mAssets); } public void addRenderer(Renderer renderer) { mRenderers.add(renderer); } public void removeRenderer(Renderer renderer) { mRenderers.removeValue(renderer, true); } private final Color mBatchColor = new Color(); @Override public void draw(Batch batch, ZLevel zLevel) { mBodyRegionDrawer.setBatch(batch); mBodyRegionDrawer.setScale(mVehicle.getZ() + 1); mTime += Gdx.app.getGraphics().getDeltaTime(); if (zLevel == ZLevel.GROUND) { for (Vehicle.WheelInfo info : mVehicle.getWheelInfos()) { mSkidmarksRenderer.draw(batch, info.wheel.getSkidmarks()); } // Only draw splash and shadow if we are not falling if (!mVehicle.isFalling()) { for (Vehicle.WheelInfo info : mVehicle.getWheelInfos()) { if (info.wheel.getMaterial().isWater()) { mBodyRegionDrawer.draw(info.wheel.getBody(), mAssets.splash.getKeyFrame(mTime, true)); } } mBodyRegionDrawer.drawShadow(mVehicle.getBody(), mVehicle.getRegion()); } return; } ZLevel wantedZIndex = mVehicle.isFlying() ? ZLevel.FLYING : ZLevel.VEHICLES; if (zLevel != wantedZIndex) { return; } if (mVehicle.isFalling()) { float k = MathUtils.clamp(1 + mVehicle.getZ() * 10, 0, 1); // k = 0 fully immersed, k = 1 not immersed mBatchColor.set(IMMERSED_COLOR); mBatchColor.lerp(Color.WHITE, k); batch.setColor(mBatchColor); } else { // Do not draw the wheels when falling: when the body is painted with alpha < 1 the wheels are visible // through it and it looks ugly for (Vehicle.WheelInfo info : mVehicle.getWheelInfos()) { mBodyRegionDrawer.draw(info.wheel.getBody(), info.wheel.getRegion()); } } mBodyRegionDrawer.draw(mVehicle.getBody(), mVehicle.getRegion()); if (mVehicle.getTurboTime() >= 0) { drawTurbo(batch); } for (Renderer renderer : mRenderers) { renderer.draw(batch, zLevel); } if (mVehicle.isFalling()) { batch.setColor(Color.WHITE); } } private void drawTurbo(Batch batch) { TextureRegion region = mAssets.turboFlame.getKeyFrame(mVehicle.getTurboTime(), true); Body body = mVehicle.getBody(); Vector2 center = body.getPosition(); float angle = body.getAngle() * MathUtils.radiansToDegrees; float w = Constants.UNIT_FOR_PIXEL * region.getRegionWidth(); float h = Constants.UNIT_FOR_PIXEL * region.getRegionHeight(); float refH = -mVehicle.getWidth() / 2; float x = center.x + refH * MathUtils.cosDeg(angle); float y = center.y + refH * MathUtils.sinDeg(angle); batch.draw(region, x - w / 2, y - h, // pos w / 2, h, // origin w, h, // size 1, 1, // scale angle - 90); } }