*
* This file is part of Pixel Wheels.
*
* Pixel 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 .
*/
package com.agateau.pixelwheels.screens;
import static com.agateau.translations.Translator.tr;
import com.agateau.pixelwheels.PwGame;
import com.agateau.pixelwheels.PwRefreshHelper;
import com.agateau.ui.CreditsScrollPane;
import com.agateau.ui.anchor.AnchorGroup;
import com.agateau.ui.menu.Menu;
import com.agateau.ui.uibuilder.UiBuilder;
import com.agateau.utils.FileUtils;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.XmlReader;
class CreditsScreen extends PwStageScreen {
private final PwGame mGame;
CreditsScreen(PwGame game) {
super(game.getAssets().ui);
mGame = game;
setupUi();
new PwRefreshHelper(mGame, getStage()) {
@Override
protected void refresh() {
mGame.replaceScreen(new CreditsScreen(mGame));
}
};
}
private void setupUi() {
Skin skin = mGame.getAssets().ui.skin;
UiBuilder builder = new UiBuilder(mGame.getAssets().atlas, skin);
builder.registerActorFactory(
"CreditsScrollPane",
(uiBuilder, element) -> {
ScrollPane pane = new CreditsScrollPane();
Actor child = uiBuilder.buildChildren(element, null);
if (child != null) {
pane.setActor(child);
}
return pane;
});
AnchorGroup root = (AnchorGroup) builder.build(loadCreditsXml());
root.setFillParent(true);
getStage().addActor(root);
final CreditsScrollPane pane = builder.getActor("creditsScrollPane");
float stageHeight = getStage().getHeight();
VerticalGroup group = pane.getGroup();
group.addActorAt(0, createSpacer(stageHeight));
addSpacer(group, stageHeight * 2 / 3);
group.addActor(new Label(tr("Thank you for playing!"), mGame.getAssets().ui.skin));
addSpacer(group, stageHeight / 2);
Menu menu = builder.getActor("menu");
menu.addBackButton()
.addListener(
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
onBackPressed();
}
});
for (Actor actor : group.getChildren()) {
if (actor instanceof Label) {
Label label = (Label) actor;
label.setAlignment(Align.center);
label.setWrap(true);
label.setWidth(group.getWidth());
label.setHeight(label.getPrefHeight());
}
}
}
/**
* Post-process the gdxui XML to add some fancy ascii-art decorations around the text of the
* section headers.
*
* Doing it this way reduces duplication and, more importantly, ensures translators do not
* have to care about the decorations.
*/
private XmlReader.Element loadCreditsXml() {
FileHandle handle = FileUtils.assets("screens/credits.gdxui");
XmlReader.Element root = FileUtils.parseXml(handle);
for (XmlReader.Element element : root.getChildrenByNameRecursively("Label")) {
if (element.getAttribute("style", "").equals("creditsSection")) {
element.setText(String.format("-= %s =-", tr(element.getText())));
}
}
return root;
}
private void addSpacer(VerticalGroup group, float height) {
group.addActor(createSpacer(height));
}
private Actor createSpacer(float height) {
Actor spacer = new Actor();
spacer.setSize(1, height);
return spacer;
}
@Override
public void onBackPressed() {
mGame.popScreen();
}
}
FILE: com.agateau.tinywheels.android_33_src.tar.gz/core/src/com/agateau/ui/CreditsScrollPane.java
/*
* Copyright 2020 Aurélien Gâteau
*
* This file is part of Pixel Wheels.
*
* 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.
*/
package com.agateau.ui;
import com.agateau.utils.Assert;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.scenes.scene2d.Action;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
/** A scroll pane to show credits */
public class CreditsScrollPane extends ScrollPane {
private static final float AUTO_SCROLL_PX_PER_S = 45;
private VerticalGroup mGroup;
public CreditsScrollPane() {
super(null);
setupAutoScroll();
}
public VerticalGroup getGroup() {
return mGroup;
}
@Override
public void setActor(Actor actor) {
super.setActor(actor);
if (actor != null) {
Assert.check(actor instanceof VerticalGroup, "Child must be a VerticalGroup");
mGroup = (VerticalGroup) actor;
}
}
@Override
protected void sizeChanged() {
if (mGroup != null) {
mGroup.setWidth(getWidth());
}
}
@Override
public void act(float delta) {
super.act(delta);
UiInputMapper inputMapper = UiInputMapper.getInstance();
if (inputMapper.isKeyJustPressed(VirtualKey.DOWN)) {
scroll(1);
} else if (inputMapper.isKeyJustPressed(VirtualKey.UP)) {
scroll(-1);
}
}
private void scroll(int dy) {
float scrollAmount = getHeight() / 2;
float y = MathUtils.clamp(getScrollY() + scrollAmount * dy, 0, getMaxY());
setScrollY(y);
}
private void setupAutoScroll() {
addAction(
new Action() {
@Override
public boolean act(float delta) {
float maxY = getMaxY();
float y = Math.min(getScrollY() + AUTO_SCROLL_PX_PER_S * delta, maxY);
setScrollY(y);
return false;
}
});
}
}
FILE: com.agateau.tinywheels.android_33_src.tar.gz/docs/credits.md
## Music
### Menu
Lightspeed by Thomas Tripon
### Victory
Core Descent (16-bit) v0.9 by FoxSynergy,
### Country Life championship
Cosmo Blast v1.0 by FoxSynergy,
### Square Mountains championship
Lunar Harvest v1.0 by FoxSynergy,
### Pix Cities championship
Bouncing Baal v0.95 by FoxSynergy,
## Sound effects
"Car tire squeal skid loop" by Tom Haigh,
"Racing car engine sound loops" by domasx2,
## Fonts
Xolonium by Severin Meyer,
Kwajong by Tup Wanders,
Noto by Google,
(This file must be kept in sync with ../android/assets/screens/credits.gdxui, for in-game credits)
FILE: com.agateau.tinywheels.android_33_src.tar.gz/README.md
# Pixel Wheels

Pixel Wheels is a retro top-down racing game for Linux, macOS, Windows and Android.

It features multiple tracks and vehicles as well as various bonuses and weapons to help you get to the finish line first!
On PC, you can play Pixel Wheels alone or with a friend.
## I want to try it!
Great! For Linux, macOS and Windows, you can get binaries from [Pixel Wheels page on itch.io][itch].
*ARM-based Mac users: Note that Pixel Wheels does not run on ARM-based Macs for now. This will be added when the game is updated to use [libGDX 1.11.0][libgdx-arm-mac].*
[libgdx-arm-mac]: https://github.com/libgdx/libgdx/releases/tag/1.11.0
For Android, you can install Pixel Wheels from [F-Droid][fd], [Google Play][gplay] or from [itch.io][itch] too.
[itch]: https://agateau.itch.io/pixelwheels
[fd]: https://f-droid.org/packages/com.agateau.tinywheels.android/
[gplay]: https://play.google.com/store/apps/details?id=com.agateau.tinywheels.android
### master builds
If you feel adventurous, you can also try binaries from the master branch. These are available from [builds.agateau.com][builds-agateau].
[builds-agateau]: https://builds.agateau.com/pixelwheels
## I think it would be much better if it did X, Y or Z...
I have a reasonably well defined vision of what I want Pixel Wheels to be. Your feedback and suggestions are welcome, and I will look into them, but I reserve the right to decide if your ideas fit with the game I am trying to create.
## Contributing
The [docs](docs/) directory contains documentation to work on Pixel Wheels.
In particular:
- [Adding or updating a translation](docs/translations.md)
- [Building instructions](docs/building.md)
## License
- The game logic is licensed under GPL 3.0 or later. This is all the code in [core/src/com/agateau/pixelwheels](core/src/com/agateau/pixelwheels) directory.
- The rest of the code is licensed under Apache 2.0.
- Assets are licensed under Creative Commons BY-SA 4.0.
The rationale behind this combination of licenses is to:
- Allow reuse of all the code and assets by free software projects.
- Allow reuse of utility code in proprietary projects.
- Prevent appearance of ad-based, malicious, proprietary clones of the game.
Put another way, if you are a game developer and find some of the code interesting, feel free to use it to build your *own* original project. If you are interested in some of the GPL code, get in touch, I am open to relicensing.
On the other hand, if your plan is to take the game, slap some ads on it, and release it without releasing the sources of your changes: the license forbids you to do so, go find another prey.
## Why is the Java package called "tinywheels"?
The game used to be called Tiny Wheels, but I found out there is already a Tiny Wheels game on Steam, so I had to rename it. I did not change the Java package name however because Google Play does not allow changing the package name of an existing app or game.
## Support development of the game
Want to support the development of the game? Awesome! My [support page][support] is waiting for you :)
[support]: https://agateau.com/support/