Initial commit

This commit is contained in:
2026-06-16 11:02:07 +03:00
commit 273f4a90f4
72 changed files with 1924 additions and 0 deletions
+114
View File
@@ -0,0 +1,114 @@
## Java
*.class
*.war
*.ear
hs_err_pid*
## Robovm
/ios/robovm-build/
## GWT
/html/war/
/html/gwt-unitCache/
.apt_generated/
.gwt/
gwt-unitCache/
www-test/
.gwt-tmp/
## Android Studio and Intellij and Android in general
/android/libs/armeabi-v7a/
/android/libs/arm64-v8a/
/android/libs/x86/
/android/libs/x86_64/
/android/gen/
.idea/
*.ipr
*.iws
*.iml
/android/out/
com_crashlytics_export_strings.xml
## Eclipse
.classpath
.project
.metadata/
/android/bin/
/core/bin/
/desktop/bin/
/html/bin/
/ios/bin/
*.tmp
*.bak
*.swp
*~.nib
.settings/
.loadpath
.externalToolBuilders/
*.launch
## NetBeans
/nbproject/private/
/android/nbproject/private/
/core/nbproject/private/
/desktop/nbproject/private/
/html/nbproject/private/
/ios/nbproject/private/
/build/
/android/build/
/core/build/
/desktop/build/
/html/build/
/ios/build/
/nbbuild/
/android/nbbuild/
/core/nbbuild/
/desktop/nbbuild/
/html/nbbuild/
/ios/nbbuild/
/dist/
/android/dist/
/core/dist/
/desktop/dist/
/html/dist/
/ios/dist/
/nbdist/
/android/nbdist/
/core/nbdist/
/desktop/nbdist/
/html/nbdist/
/ios/nbdist/
nbactions.xml
nb-configuration.xml
## Gradle
/local.properties
.gradle/
gradle-app.setting
/build/
/android/build/
/core/build/
/desktop/build/
/html/build/
/ios/build/
## OS Specific
.DS_Store
Thumbs.db
## iOS
/ios/xcode/*.xcodeproj/*
!/ios/xcode/*.xcodeproj/xcshareddata
!/ios/xcode/*.xcodeproj/project.pbxproj
/ios/xcode/native/
/ios/IOSLauncher.app
/ios/IOSLauncher.app.dSYM
+29
View File
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<application
android:allowBackup="true"
android:fullBackupContent="true"
android:icon="@drawable/ic_launcher"
android:isGame="true"
android:appCategory="game"
android:label="@string/app_name"
android:theme="@style/AppTheme"
tools:ignore="UnusedAttribute">
<activity
android:name="com.mygdx.game.AndroidLauncher"
android:label="@string/app_name"
android:screenOrientation="landscape"
android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenSize|screenLayout"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Binary file not shown.
+105
View File
@@ -0,0 +1,105 @@
android {
namespace "com.mygdx.game"
buildToolsVersion '33.0.0'
compileSdk 33
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['../assets']
jniLibs.srcDirs = ['libs']
}
}
packagingOptions {
exclude 'META-INF/robovm/ios/robovm.xml'
}
defaultConfig {
applicationId "com.mygdx.game"
minSdkVersion 14
targetSdkVersion 33
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
// called every time gradle gets executed, takes the native dependencies of
// the natives configuration, and extracts them to the proper libs/ folders
// so they get packed with the APK.
tasks.register('copyAndroidNatives') {
doFirst {
file("libs/armeabi-v7a/").mkdirs()
file("libs/arm64-v8a/").mkdirs()
file("libs/x86_64/").mkdirs()
file("libs/x86/").mkdirs()
configurations.natives.copy().files.each { jar ->
def outputDir = null
if (jar.name.endsWith("natives-arm64-v8a.jar")) outputDir = file("libs/arm64-v8a")
if (jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a")
if (jar.name.endsWith("natives-x86_64.jar")) outputDir = file("libs/x86_64")
if (jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86")
if (outputDir != null) {
copy {
from zipTree(jar)
into outputDir
include "*.so"
}
}
}
}
}
tasks.matching { it.name.contains("merge") && it.name.contains("JniLibFolders") }.configureEach { packageTask ->
packageTask.dependsOn 'copyAndroidNatives'
}
tasks.register('run', Exec) {
def path
def localProperties = project.file("../local.properties")
if (localProperties.exists()) {
Properties properties = new Properties()
localProperties.withInputStream { instr ->
properties.load(instr)
}
def sdkDir = properties.getProperty('sdk.dir')
if (sdkDir) {
path = sdkDir
} else {
path = "$System.env.ANDROID_HOME"
}
} else {
path = "$System.env.ANDROID_HOME"
}
def adb = path + "/platform-tools/adb"
commandLine "$adb", 'shell', 'am', 'start', '-n', 'com.mygdx.game/com.mygdx.game.AndroidLauncher'
// Внутри модуля android
dependencies {
implementation project(":core")
api "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
// Нативные библиотеки для Android
configurations.natives {
implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a"
implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-arm64-v8a"
implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86"
implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64"
}
}
}
eclipse.project.name = appName + "-android"
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

+38
View File
@@ -0,0 +1,38 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-verbose
-dontwarn com.badlogic.gdx.backends.android.AndroidFragmentApplication
# Required if using Gdx-Controllers extension
-keep class com.badlogic.gdx.controllers.android.AndroidControllers
# Required if using Box2D extension
-keepclassmembers class com.badlogic.gdx.physics.box2d.World {
boolean contactFilter(long, long);
void beginContact(long);
void endContact(long);
void preSolve(long, long);
void postSolve(long, long);
boolean reportFixture(long);
float reportRayFixture(long, float, float, float, float, float);
}
+9
View File
@@ -0,0 +1,9 @@
# This file is used by the Eclipse ADT plugin. It is unnecessary for IDEA and Android Studio projects, which
# configure Proguard and the Android target via the build.gradle file.
# To enable ProGuard to work with Eclipse ADT, uncomment this (available properties: sdk.dir, user.home)
# and ensure proguard.jar in the Android SDK is up to date (or alternately reduce the android target to 23 or lower):
# proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-rules.pro
# Project target.
target=android-19
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon
xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_background_color"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
@@ -0,0 +1,40 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:pathData="M22,48.667l2.987,0l0,10.667l-2.987,0z"
android:fillColor="#000000"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="M26.907,52.72l2.987,0l0,6.613l-2.987,0z"
android:fillColor="#000000"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="M26.907,48.667l2.987,0l0,2.56l-2.987,0z"
android:fillColor="#000000"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="M31.813,48.667L31.813,52.72 31.813,55.067 31.813,56.767 31.813,59.333l2.992,0 2.117,0c1.654,0 2.998,-1.481 2.998,-3.307 0,-1.826 -1.344,-3.307 -2.998,-3.307l-2.117,0L34.805,48.667ZM34.805,55.067l1.269,0c0.469,0 0.848,0.384 0.848,0.853 0,0.469 -0.379,0.847 -0.848,0.847l-1.269,0z"
android:fillColor="#000000"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="m44.192,48.667c-1.65,0 -2.992,1.481 -2.992,3.307 0,0.023 -0,0.044 0,0.067 0,0.004 -0,0.009 0,0.013l0,3.893c-0.001,0.027 0,0.053 0,0.08 0,1.826 1.341,3.307 2.992,3.307l2.112,0 0.247,0 2.739,0 0.247,0 2.112,0c1.651,0 2.992,-1.481 2.992,-3.307 0,-1.826 -1.341,-3.307 -2.992,-3.307l-1.199,0 -0.48,0 -2.372,0l0,2.347l2.372,0 0.48,0 0.353,0c0.468,0 0.846,0.384 0.846,0.853 0,0.469 -0.378,0.847 -0.846,0.847l-0.833,0 -0.433,0 -0.247,0 -2.739,0 -0.247,0 -0.433,0 -0.833,0c-0.459,0 -0.832,-0.363 -0.846,-0.82l0,-3.893 0,-0.013c0.021,-0.45 0.391,-0.807 0.846,-0.807l0.833,0 0.433,0 1.293,0l0,0.007L54.207,51.24L54.207,48.667l-4.917,0 -1.692,0 -1.293,0 -2.112,0z"
android:fillColor="#e74a45"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="M56.133,48.667L56.133,51.238l5.406,0 1.859,0 1.105,0 0.43,0 0.827,0c0.452,0 0.82,0.356 0.84,0.806l0,0.013 0,3.891c-0.014,0.456 -0.384,0.819 -0.84,0.819l-0.827,0 -0.43,0 -1.899,0 -1.065,0 -2.442,0L59.098,52.724L56.133,52.724l0,4.044 0,1.752 0,0.813l5.406,0 1.065,0 1.899,0 2.098,0c1.639,0 2.971,-1.48 2.971,-3.305 0,-0.027 0.001,-0.053 0,-0.08L69.573,52.058c0,-0.004 -0,-0.009 0,-0.013 0,-0.022 0,-0.044 0,-0.067 0,-1.825 -1.332,-3.305 -2.971,-3.305l-2.098,0 -1.105,0l0,-0.007L56.133,48.667Z"
android:fillColor="#e74a45"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="M69.572,48.667L73.72,48.667L77.787,52.733 81.853,48.667l4.147,0l-5.333,5.333 5.333,5.333L81.853,59.333L77.787,55.267 73.72,59.333l-4.147,0l5.333,-5.333z"
android:fillColor="#e74a45"
android:strokeColor="#00000000"/>
</vector>
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="android:Theme.Material.Light.NoActionBar.Fullscreen">
<item name="android:colorBackground">@color/ic_background_color</item>
</style>
</resources>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_background_color">#FFFFFFFF</color>
</resources>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">My GDX Game</string>
</resources>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="android:Theme.Holo.Light.NoActionBar.Fullscreen">
<item name="android:windowBackground">@color/ic_background_color</item>
</style>
</resources>
@@ -0,0 +1,15 @@
package com.mygdx.game;
import android.os.Bundle;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
public class AndroidLauncher extends AndroidApplication {
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
initialize(new MyGdxGame(), config);
}
}
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

+93
View File
@@ -0,0 +1,93 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
gradlePluginPortal()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.1.4'
}
}
allprojects {
apply plugin: "eclipse"
version = '1.0'
ext {
appName = "My GDX Game"
gdxVersion = '1.12.1'
roboVMVersion = '2.3.19'
box2DLightsVersion = '1.5'
ashleyVersion = '1.7.4'
aiVersion = '1.8.2'
gdxControllersVersion = '2.2.1'
}
repositories {
mavenLocal()
mavenCentral()
google()
gradlePluginPortal()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
maven { url "https://oss.sonatype.org/content/repositories/releases/" }
maven { url "https://jitpack.io" }
}
}
project(":desktop") {
apply plugin: "java-library"
dependencies {
implementation project(":core")
api "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion"
api "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
api "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop"
api "com.badlogicgames.gdx:gdx-bullet-platform:$gdxVersion:natives-desktop"
}
}
project(":android") {
apply plugin: "com.android.application"
configurations { natives }
dependencies {
implementation project(":core")
api "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-arm64-v8a"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64"
api "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-arm64-v8a"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86_64"
api "com.badlogicgames.gdx:gdx-bullet:$gdxVersion"
natives "com.badlogicgames.gdx:gdx-bullet-platform:$gdxVersion:natives-armeabi-v7a"
natives "com.badlogicgames.gdx:gdx-bullet-platform:$gdxVersion:natives-arm64-v8a"
natives "com.badlogicgames.gdx:gdx-bullet-platform:$gdxVersion:natives-x86"
natives "com.badlogicgames.gdx:gdx-bullet-platform:$gdxVersion:natives-x86_64"
}
}
project(":core") {
apply plugin: "java-library"
dependencies {
api "com.badlogicgames.gdx:gdx:$gdxVersion"
api "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
api "com.badlogicgames.gdx:gdx-bullet:$gdxVersion"
}
}
+13
View File
@@ -0,0 +1,13 @@
sourceCompatibility = 1.7
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
sourceSets.main.java.srcDirs = [ "src/" ]
eclipse.project.name = appName + "-core"
dependencies {
// Основное ядро LibGDX
api "com.badlogicgames.gdx:gdx:$gdxVersion"
}
+26
View File
@@ -0,0 +1,26 @@
package com.mygdx.game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Music;
public class AudioManager {
public boolean isMusicOn = true;
public static final String BACKGROUND_MUSIC_PATH = "bg.mp3";
public Music backgroundMusic;
public AudioManager() {
backgroundMusic = Gdx.audio.newMusic(Gdx.files.internal(BACKGROUND_MUSIC_PATH));
backgroundMusic.setVolume(1f);
backgroundMusic.setLooping(true);
updateSoundFlag();
updateMusicFlag();
}
private void updateSoundFlag() {
}
public void updateMusicFlag() {
if (isMusicOn) backgroundMusic.play();
else backgroundMusic.stop();
}
}
+16
View File
@@ -0,0 +1,16 @@
package com.mygdx.game;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.math.Vector3;
class Emitter {
public ModelInstance instance;
public Vector3 direction;
public Emitter(Model m, float x, float y, float z, float dx, float dy, float dz) {
instance = new ModelInstance(m, x, y, z);
direction = new Vector3(dx, dy, dz).nor();
instance.transform.setToLookAt(direction, Vector3.Y).inv().setTranslation(x, y, z);
}
}
+219
View File
@@ -0,0 +1,219 @@
package com.mygdx.game;
import com.badlogic.gdx.*;
import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.graphics.g3d.*;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
import com.badlogic.gdx.graphics.g3d.utils.CameraInputController;
import com.badlogic.gdx.math.*;
import com.badlogic.gdx.scenes.scene2d.*;
import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
public class GameScreen implements Screen {
private final MyGdxGame game;
private PerspectiveCamera cam;
private CameraInputController camCtrl;
private Environment env;
private SceneManager sm;
private LaserRenderer lr;
private float winTimer = 0;
private float levelTime = 0; // Общее время прохождения уровня
private final int level;
private Stage stage;
private Texture uiBtnTexture;
private BitmapFont font;
private HelpUI helpUI;
private Label timerLabel; // Визуальный элемент таймера
public GameScreen(MyGdxGame game, int level) {
this.game = game;
this.level = level;
}
@Override
public void show() {
cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.position.set(50, 60, 50);
cam.lookAt(0, 0, 0);
cam.near = 10f;
cam.far = 500f;
cam.update();
camCtrl = new CameraInputController(cam);
camCtrl.pinchZoomFactor = 50f;
camCtrl.scrollFactor = -0.5f;
stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(new InputMultiplexer(stage, camCtrl));
/* font = new BitmapFont();
font.getData().setScale(2f);
*/
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("Montserrat-Bold.ttf"));
FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
// 2. Устанавливаем нужный размер СРАЗУ (вместо setScale)
parameter.size = 20;
// 3. Указываем, какие символы нужно подготовить (обязательно добавляем русские!)
String RUSSIAN_CHARACTERS = "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
parameter.characters = FreeTypeFontGenerator.DEFAULT_CHARS + RUSSIAN_CHARACTERS;
// 4. Генерируем сам шрифт
font = generator.generateFont(parameter);
uiBtnTexture = createButtonTexture();
createMenuButton();
createTimerUI(); // Создаем интерфейс таймера
helpUI = new HelpUI(stage, font, game);
env = new Environment();
env.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
env.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
sm = new SceneManager();
sm.loadLevel(level);
lr = new LaserRenderer(game.shapeRenderer);
levelTime = 0; // Сброс таймера при старте
}
private void createTimerUI() {
timerLabel = new Label("ВРЕМЯ: 0.0", new Label.LabelStyle(font, Color.WHITE));
timerLabel.setPosition(20, Gdx.graphics.getHeight() - 150);
stage.addActor(timerLabel);
}
private void createMenuButton() {
Stack menuStack = new Stack();
Image btnImg = new Image(uiBtnTexture);
Label btnLbl = new Label("МЕНЮ", new Label.LabelStyle(font, Color.BLACK));
btnLbl.setAlignment(com.badlogic.gdx.utils.Align.center);
menuStack.add(btnImg);
menuStack.add(btnLbl);
menuStack.setSize(140, 70);
menuStack.setPosition(20, Gdx.graphics.getHeight() - 90);
menuStack.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
game.setScreen(new LevelSelectScreen(game));
}
});
stage.addActor(menuStack);
}
private Texture createButtonTexture() {
Pixmap pm = new Pixmap(128, 64, Pixmap.Format.RGBA8888);
pm.setColor(Color.BLACK);
pm.fillRectangle(0, 0, 128, 64);
pm.setColor(Color.WHITE);
pm.fillRectangle(3, 3, 122, 58);
Texture t = new Texture(pm);
pm.dispose();
return t;
}
@Override
public void render(float delta) {
// Обновляем таймер, только если уровень еще не пройден полностью (до начала winTimer)
boolean allHit = sm.targets.size > 0;
for (Target t : sm.targets) {
if (!t.hit) {
allHit = false;
break;
}
}
if (!allHit) {
levelTime += delta;
timerLabel.setText(String.format("ВРЕМЯ: %.1f", levelTime));
// Подсветка таймера золотым, если укладываемся в лимит
float timeLimit = 2.0f + (0.1f * level);
if (levelTime <= timeLimit) {
timerLabel.setColor(Color.GOLD);
} else {
timerLabel.setColor(Color.GRAY);
}
}
if (Gdx.input.justTouched()) {
boolean hitUI = stage.hit(Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY(), true) != null;
if (!hitUI) {
sm.checkClick(cam.getPickRay(Gdx.input.getX(), Gdx.input.getY()));
}
}
camCtrl.update();
lr.calculate(sm);
if (allHit) {
winTimer += delta;
if (winTimer > 2f) {
Preferences prefs = Gdx.app.getPreferences("LaserPuzzleSettings");
int reachedLevel = prefs.getInteger("reachedLevel", 1);
// Сохраняем прогресс уровней
if (level >= reachedLevel) {
prefs.putInteger("reachedLevel", level + 1);
}
// Проверяем на "золотую звезду" (лимит времени)
float timeLimit = 2.0f + (0.1f * level);
if (levelTime <= timeLimit) {
// Сохраняем флаг золотого уровня
prefs.putBoolean("gold_" + level, true);
}
prefs.flush();
// Переход на следующий уровень
if (level < 40) {
game.setScreen(new GameScreen(game, level + 1));
} else {
game.setScreen(new LevelSelectScreen(game));
}
}
} else {
winTimer = 0;
}
Gdx.gl.glClearColor(1f, 1f, 1f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
game.modelBatch.begin(cam);
sm.render(game.modelBatch, env);
game.modelBatch.end();
lr.render(cam);
stage.act(delta);
stage.draw();
}
@Override public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
timerLabel.setPosition(100, height - 150);
}
@Override public void dispose() {
if (sm != null) sm.dispose();
if (stage != null) stage.dispose();
if (uiBtnTexture != null) uiBtnTexture.dispose();
if (font != null) font.dispose();
if (helpUI != null) helpUI.dispose();
}
@Override public void pause() {}
@Override public void resume() {}
@Override public void hide() {}
}
+156
View File
@@ -0,0 +1,156 @@
package com.mygdx.game;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.Align;
public class HelpUI {
private final Stage stage;
private final Table helpMenu;
private Texture circleTexture;
private Texture rectTexture;
private Texture closeTexture;
private final Label musicStatusLabel;
public HelpUI(final Stage stage, BitmapFont font, final MyGdxGame game) {
this.stage = stage;
circleTexture = createCircleTexture(60, Color.WHITE);
rectTexture = createRectTexture(1, 1, new Color(0, 0, 0, 0.85f));
closeTexture = createRectTexture(40, 40, Color.RED);
float screenWidth = stage.getViewport().getWorldWidth();
float screenHeight = stage.getViewport().getWorldHeight();
// --- Кнопка Помощи (?) ---
Stack helpBtn = new Stack();
Image bgHelp = new Image(circleTexture);
Label symbolHelp = new Label("?", new Label.LabelStyle(font, Color.BLACK));
symbolHelp.setAlignment(Align.center);
helpBtn.add(bgHelp);
helpBtn.add(symbolHelp);
helpBtn.setSize(60, 60);
helpBtn.setPosition(screenWidth - 80, screenHeight - 80);
// --- Кнопка Музыки ---
Stack musicBtn = new Stack();
Image bgMusic = new Image(circleTexture);
musicStatusLabel = new Label(game.audioManager.isMusicOn ? "ON" : "OFF", new Label.LabelStyle(font, Color.BLACK));
musicStatusLabel.setFontScale(0.6f);
musicStatusLabel.setAlignment(Align.center);
musicBtn.add(bgMusic);
musicBtn.add(musicStatusLabel);
musicBtn.setSize(60, 60);
musicBtn.setPosition(screenWidth - 150, screenHeight - 80);
// --- Окно помощи ---
helpMenu = new Table();
helpMenu.setFillParent(true);
helpMenu.setVisible(false);
Image overlay = new Image(rectTexture);
overlay.setFillParent(true);
Table content = new Table();
// Устанавливаем темно-синий фон для контента
content.setBackground(new Image(createRectTexture(1, 1, new Color(0.1f, 0.1f, 0.15f, 1f))).getDrawable());
content.pad(50); // Увеличены отступы
Stack closeBtn = new Stack();
Image closeBg = new Image(closeTexture);
Label closeX = new Label("X", new Label.LabelStyle(font, Color.WHITE));
closeX.setAlignment(Align.center);
closeBtn.add(closeBg);
closeBtn.add(closeX);
Label title = new Label("КАК ИГРАТЬ", new Label.LabelStyle(font, Color.GOLD));
title.setFontScale(1.2f); // Увеличен заголовок
// Текст с правилами
Label description = new Label(
"1. Нажимай на зеркала, чтобы вращать их.\n\n" +
"2. Направляй лазер на все пирамиды-цели.\n\n" +
"3. Когда все цели станут зелеными, уровень пройден!\n\n\n" +
"[ СИСТЕМА ЗВЕЗД ]\n\n" +
"Пройди уровень быстро, чтобы получить Золотой Статус.\n" +
"Лимит времени = 2.0 сек + 0.1 сек за каждый уровень.\n" +
"Золотые уровни подсвечиваются желтым в меню!",
new Label.LabelStyle(font, Color.WHITE)
);
description.setWrap(true);
description.setAlignment(Align.left);
description.setFontScale(0.95f); // Масштаб текста возвращен к комфортному размеру
Table header = new Table();
header.add(title).expandX().left();
header.add(closeBtn).size(50, 50).right(); // Кнопка закрытия чуть больше
content.add(header).fillX().row();
content.add(new Label("", new Label.LabelStyle(font, Color.WHITE))).pad(15).row();
// Увеличена ширина текстового блока до 600 пикселей
content.add(description).width(600).padTop(10);
helpMenu.stack(overlay, content).center();
// --- Слушатели ---
helpBtn.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
helpMenu.setVisible(true);
}
});
closeBtn.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
helpMenu.setVisible(false);
}
});
musicBtn.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
game.audioManager.isMusicOn = !game.audioManager.isMusicOn;
game.audioManager.updateMusicFlag();
musicStatusLabel.setText(game.audioManager.isMusicOn ? "ON" : "OFF");
}
});
stage.addActor(helpBtn);
stage.addActor(musicBtn);
stage.addActor(helpMenu);
}
private Texture createCircleTexture(int size, Color color) {
Pixmap pixmap = new Pixmap(size, size, Pixmap.Format.RGBA8888);
pixmap.setColor(Color.BLACK);
pixmap.fillCircle(size / 2, size / 2, size / 2 - 1);
pixmap.setColor(color);
pixmap.fillCircle(size / 2, size / 2, size / 2 - 4);
Texture t = new Texture(pixmap);
pixmap.dispose();
return t;
}
private Texture createRectTexture(int w, int h, Color color) {
Pixmap pixmap = new Pixmap(w, h, Pixmap.Format.RGBA8888);
pixmap.setColor(color);
pixmap.fill();
Texture t = new Texture(pixmap);
pixmap.dispose();
return t;
}
public void dispose() {
if (circleTexture != null) circleTexture.dispose();
if (rectTexture != null) rectTexture.dispose();
if (closeTexture != null) closeTexture.dispose();
}
}
@@ -0,0 +1,97 @@
package com.mygdx.game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.*;
import com.badlogic.gdx.math.collision.Ray;
import com.badlogic.gdx.utils.Array;
public class LaserRenderer {
private final ShapeRenderer sr;
private final Array<Array<Vector3>> paths = new Array<>();
private final Vector3 tmpHit = new Vector3(), hitPoint = new Vector3(), normal = new Vector3();
private final Ray ray = new Ray();
public LaserRenderer(ShapeRenderer sr) { this.sr = sr; }
public void calculate(SceneManager sm) {
paths.clear();
for (Target t : sm.targets) t.hit = false;
for (Emitter e : sm.emitters) {
Array<Vector3> path = new Array<>();
Vector3 pos = e.instance.transform.getTranslation(new Vector3()).add(0, SceneManager.LASER_HEIGHT, 0);
Vector3 dir = new Vector3(e.direction).nor();
path.add(new Vector3(pos));
trace(pos, dir, path, sm);
paths.add(path);
}
}
private void trace(Vector3 pos, Vector3 dir, Array<Vector3> path, SceneManager sm) {
for (int i = 0; i < 25; i++) {
float minD = Float.MAX_VALUE;
Object hitObj = null;
ray.set(pos, dir);
for (Wall w : sm.walls) if (w.active && intersect(ray, w.instance.transform, tmpHit)) {
float d = pos.dst2(tmpHit);
if (d < minD) { minD = d; hitPoint.set(tmpHit); hitObj = w; }
}
for (Mirror m : sm.mirrors) if (intersect(ray, m.transform, tmpHit)) {
float d = pos.dst2(tmpHit);
if (d < minD) {
minD = d;
hitPoint.set(tmpHit);
hitObj = m;
normal.set(0, 0, 1).rot(m.transform).nor();
}
}
for (Target t : sm.targets) if (Intersector.intersectRaySphere(ray, t.getPos(), 3.5f, tmpHit)) {
float d = pos.dst2(tmpHit);
if (d < minD) { minD = d; hitPoint.set(tmpHit); hitObj = t; }
}
if (hitObj == null) {
path.add(new Vector3(pos).add(new Vector3(dir).scl(1000f)));
break;
}
path.add(new Vector3(hitPoint));
if (hitObj instanceof Target) {
((Target)hitObj).hit = true;
break;
}
if (hitObj instanceof Wall) break;
float dot = dir.dot(normal);
dir.sub(new Vector3(normal).scl(2 * dot)).nor();
pos.set(hitPoint).add(new Vector3(dir).scl(0.5f));
}
}
private boolean intersect(Ray r, Matrix4 transform, Vector3 out) {
Matrix4 inv = new Matrix4(transform).inv();
Ray localRay = new Ray(new Vector3(r.origin).mul(inv), new Vector3(r.direction).rot(inv));
if (Intersector.intersectRayBounds(localRay, Mirror.bounds, out)) {
out.mul(transform);
return true;
}
return false;
}
public void render(PerspectiveCamera cam) {
sr.setProjectionMatrix(cam.combined);
sr.begin(ShapeRenderer.ShapeType.Line);
Gdx.gl.glLineWidth(5);
sr.setColor(Color.RED);
for (Array<Vector3> p : paths) {
for (int i = 0; i < p.size - 1; i++) {
sr.line(p.get(i), p.get(i + 1));
}
}
sr.end();
Gdx.gl.glLineWidth(1);
}
}
@@ -0,0 +1,143 @@
package com.mygdx.game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
public class LevelSelectScreen implements Screen {
private final MyGdxGame game;
private Stage stage;
private BitmapFont font;
private Texture btnTex;
private Texture btnLockedTex;
private Texture btnGoldTex; // Текстура для золотого уровня
public LevelSelectScreen(MyGdxGame game) {
this.game = game;
}
@Override
public void show() {
stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(stage);
// ВМЕСТО ЭТИХ ДВУХ СТРОК:
/*
font = new BitmapFont();
font.getData().setScale(2f);
*/
// 1. Создаем генератор из нашего .ttf файла
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("Montserrat-Bold.ttf"));
FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
// 2. Устанавливаем нужный размер СРАЗУ (вместо setScale)
parameter.size = 20;
// 3. Указываем, какие символы нужно подготовить (обязательно добавляем русские!)
String RUSSIAN_CHARACTERS = "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
parameter.characters = FreeTypeFontGenerator.DEFAULT_CHARS + RUSSIAN_CHARACTERS;
// 4. Генерируем сам шрифт
font = generator.generateFont(parameter);
btnTex = createBtnTexture(Color.WHITE);
btnLockedTex = createBtnTexture(Color.GRAY);
btnGoldTex = createBtnTexture(Color.GOLD); // Создаем золотую текстуру
Table container = new Table();
container.setFillParent(true);
Table grid = new Table();
grid.pad(20);
Preferences prefs = Gdx.app.getPreferences("LaserPuzzleSettings");
int reachedLevel = prefs.getInteger("reachedLevel", 1);
for (int i = 1; i <= 40; i++) {
final int levelNum = i;
boolean isGold = prefs.getBoolean("gold_" + i, false); // Проверка на золото
TextButton.TextButtonStyle style = new TextButton.TextButtonStyle();
style.font = font;
if (i <= reachedLevel) {
// Если уровень пройден быстро, ставим золотую текстуру
style.up = new TextureRegionDrawable(isGold ? btnGoldTex : btnTex);
style.fontColor = Color.BLACK;
} else {
style.up = new TextureRegionDrawable(btnLockedTex);
style.fontColor = Color.DARK_GRAY;
}
TextButton btn = new TextButton(String.valueOf(i), style);
if (i <= reachedLevel) {
btn.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
game.setScreen(new GameScreen(game, levelNum));
}
});
}
grid.add(btn).size(120, 120).pad(10);
if (i % 5 == 0) grid.row();
}
ScrollPane scroll = new ScrollPane(grid);
container.add(new Label("ВЫБОР УРОВНЯ", new Label.LabelStyle(font, Color.WHITE))).padBottom(20).row();
container.add(scroll).expand().fill();
stage.addActor(container);
}
private Texture createBtnTexture(Color color) {
Pixmap pm = new Pixmap(128, 128, Pixmap.Format.RGBA8888);
pm.setColor(Color.BLACK);
pm.fillRectangle(0, 0, 128, 128);
pm.setColor(color);
pm.fillRectangle(4, 4, 120, 120);
Texture t = new Texture(pm);
pm.dispose();
return t;
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(delta);
stage.draw();
}
@Override public void resize(int width, int height) { stage.getViewport().update(width, height, true); }
@Override public void pause() {}
@Override public void resume() {}
@Override public void hide() {}
@Override public void dispose() {
stage.dispose();
font.dispose();
btnTex.dispose();
btnLockedTex.dispose();
btnGoldTex.dispose();
}
}
+116
View File
@@ -0,0 +1,116 @@
package com.mygdx.game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
public class MenuScreen implements Screen {
private final MyGdxGame game;
private SpriteBatch batch;
private ShapeRenderer sr;
private final OrthographicCamera cam;
private BitmapFont buttonFont;
private BitmapFont brandFont;
private GlyphLayout layout;
private final Rectangle btn = new Rectangle();
private final Vector3 touch = new Vector3();
private boolean initialized = false;
private Texture texture;
public MenuScreen(MyGdxGame game) {
this.game = game;
this.cam = new OrthographicCamera();
try {
texture = new Texture("menu_bg.png");
} catch (Exception e) {
texture = null;
}
layout = new GlyphLayout();
buttonFont = new BitmapFont();
buttonFont.getData().setScale(2.5f);
brandFont = new BitmapFont();
brandFont.getData().setScale(5.0f);
}
@Override
public void show() {
if (!initialized) {
this.batch = new SpriteBatch();
this.sr = new ShapeRenderer();
initialized = true;
}
resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
}
@Override
public void render(float delta) {
if (!initialized) return;
if (Gdx.input.justTouched()) {
cam.unproject(touch.set(Gdx.input.getX(), Gdx.input.getY(), 0));
if (btn.contains(touch.x, touch.y)) {
game.setScreen(new LevelSelectScreen(game));
}
}
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(cam.combined);
batch.begin();
if (texture != null) {
batch.draw(texture, 0, 0, cam.viewportWidth, cam.viewportHeight);
}
batch.end();
sr.setProjectionMatrix(cam.combined);
sr.begin(ShapeRenderer.ShapeType.Filled);
sr.setColor(Color.DARK_GRAY);
sr.rect(btn.x + 5, btn.y - 5, btn.width, btn.height);
sr.setColor(Color.FOREST);
sr.rect(btn.x, btn.y, btn.width, btn.height);
sr.end();
batch.begin();
drawButtonText(buttonFont, "START");
brandFont.setColor(Color.WHITE);
brandFont.draw(batch, "by Hikolit", 30, 80);
batch.end();
}
private void drawButtonText(BitmapFont font, String text) {
font.setColor(Color.WHITE);
layout.setText(font, text);
float x = btn.x + (btn.width - layout.width) / 2f;
float y = btn.y + (btn.height + layout.height) / 2f;
font.draw(batch, text, x, y);
}
@Override
public void resize(int w, int h) {
cam.setToOrtho(false, w, h);
btn.set(w / 2f - 200, h / 2f - 60, 400, 120);
}
@Override
public void dispose() {
if (texture != null) texture.dispose();
if (batch != null) batch.dispose();
if (sr != null) sr.dispose();
if (buttonFont != null) buttonFont.dispose();
if (brandFont != null) brandFont.dispose();
}
@Override public void pause() {}
@Override public void resume() {}
@Override public void hide() {}
}
+37
View File
@@ -0,0 +1,37 @@
package com.mygdx.game;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.math.Intersector;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.math.collision.BoundingBox;
import com.badlogic.gdx.math.collision.Ray;
class Mirror extends ModelInstance {
public float angle;
private final Matrix4 inv = new Matrix4();
public static final BoundingBox bounds = new BoundingBox(new Vector3(-2.2f, -4f, -0.4f), new Vector3(2.2f, 4f, 0.4f));
public Mirror(Model m, float x, float y, float z, float a) {
super(m);
transform.setToTranslation(x, y, z);
angle = a;
update();
}
public void rotate() {
angle = (angle + 45f) % 360f;
update();
}
private void update() {
Vector3 p = transform.getTranslation(new Vector3());
transform.setToRotation(Vector3.Y, angle).setTranslation(p);
inv.set(transform).inv();
}
public boolean intersect(Ray r) {
return Intersector.intersectRayBoundsFast(new Ray(new Vector3(r.origin).mul(inv), new Vector3(r.direction).rot(inv)), bounds);
}
}
+31
View File
@@ -0,0 +1,31 @@
package com.mygdx.game;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
public class MyGdxGame extends Game {
public ModelBatch modelBatch;
public ShapeRenderer shapeRenderer;
public AudioManager audioManager;
@Override
public void create() {
audioManager = new AudioManager();
modelBatch = new ModelBatch();
shapeRenderer = new ShapeRenderer();
setScreen(new MenuScreen(this));
}
@Override
public void render() {
super.render();
}
@Override
public void dispose() {
if (modelBatch != null) modelBatch.dispose();
if (shapeRenderer != null) shapeRenderer.dispose();
if (getScreen() != null) getScreen().dispose();
}
}
+135
View File
@@ -0,0 +1,135 @@
package com.mygdx.game;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.VertexAttributes;
import com.badlogic.gdx.graphics.g3d.*;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.utils.MeshPartBuilder;
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.math.collision.Ray;
import com.badlogic.gdx.utils.Array;
public class SceneManager {
public Array<Mirror> mirrors = new Array<>();
public Array<Emitter> emitters = new Array<>();
public Array<Target> targets = new Array<>();
public Array<Wall> walls = new Array<>();
public ModelInstance floor;
private final Model mirrorModel;
private final Model floorModel;
private final Model pyrModel;
private final Model boxModel;
private int currentLevel;
public static final float UNIT = 10.0f;
public static final float MIRROR_H = 10.0f;
public static final float LASER_HEIGHT = 5.0f;
public SceneManager() {
ModelBuilder mb = new ModelBuilder();
long attr = VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal;
mirrorModel = mb.createBox(6f, MIRROR_H, 1.0f, new Material(ColorAttribute.createDiffuse(Color.SKY)), attr);
floorModel = mb.createBox(400f, 0.5f, 400f, new Material(ColorAttribute.createDiffuse(Color.DARK_GRAY)), attr);
boxModel = mb.createBox(UNIT, UNIT, UNIT, new Material(ColorAttribute.createDiffuse(Color.GRAY)), attr);
mb.begin();
MeshPartBuilder mpb = mb.part("pyr", GL20.GL_TRIANGLES, attr, new Material(ColorAttribute.createDiffuse(Color.WHITE)));
Vector3 top = new Vector3(0, LASER_HEIGHT, 0), v1 = new Vector3(-2f,0,2f), v2 = new Vector3(2f,0,2f), v3 = new Vector3(2f,0,-2f), v4 = new Vector3(-2f,0,-2f);
mpb.triangle(top, v1, v2); mpb.triangle(top, v2, v3); mpb.triangle(top, v3, v4); mpb.triangle(top, v4, v1);
mpb.rect(v4, v3, v2, v1, new Vector3(0,-1,0));
pyrModel = mb.end();
floor = new ModelInstance(floorModel, 0, -0.25f, 0);
}
public void loadLevel(int lvl) {
this.currentLevel = lvl;
clearCurrentLevel();
switch (lvl) {
case 1: addEmitter(-2, 0, 1, 0, 0); addMirror(0, 0, 45); addTarget(0, 2); break;
case 2: addEmitter(-2, 0, 1, 0, 0); addWall(0, 0); addMirror(-1, 0, 45); addMirror(-1, 1, 45); addTarget(2, 1); break;
case 3: addEmitter(-2, -2, 1, 0, 0); addMirror(1, -2, 45); addMirror(1, 0, 135); addTarget(-2, 0); break;
case 4: addEmitter(-2, 2, 0, 0, -1); addWall(-1, 1); addWall(0, 1); addWall(1, 1); addMirror(-2, -1, 45); addMirror(2, -1, 45); addTarget(2, 2); break;
case 5: addEmitter(-1, -2, 0, 0, 1); addMirror(-1, 2, 45); addMirror(1, 2, 45); addTarget(1, -2); break;
case 6: addEmitter(-2, 0, 1, 0, 0); addEmitter(0, -2, 0, 0, 1); addMirror(1, 0, 45); addMirror(0, 1, 45); addTarget(1, 2); addTarget(2, 1); break;
case 7: addEmitter(-2, 1, 1, 0, 0); addEmitter(-2, -1, 1, 0, 0); addWall(0, 0); addMirror(1, 1, 45); addMirror(1, -1, 45); addTarget(1, 2); addTarget(1, -2); break;
case 8: addEmitter(-2, 2, 1, 0, 0); addEmitter(-2, -2, 1, 0, 0); addMirror(0, 2, 45); addMirror(0, -2, 45); addWall(0, 0); addTarget(2, 2); addTarget(2, -2); break;
case 9: for(int i=-1; i<=1; i++) addWall(i, 0); addEmitter(-2, 1, 0, 0, -1); addEmitter(2, 1, 0, 0, -1); addMirror(-2, -1, 45); addMirror(2, -1, 45); addTarget(-1, -1); addTarget(1, -1); break;
case 10: addEmitter(-1, -1, 1, 0, 0); addEmitter(1, 1, -1, 0, 0); addMirror(1, -1, 45); addMirror(-1, 1, 45); addTarget(1, 0); addTarget(-1, 0); break;
case 11: addEmitter(-2, 2, 1, 0, 0); addWall(-1, 1); addWall(1, 1); addWall(0, 0); addMirror(2, 2, 45); addMirror(2, -2, 45); addMirror(-2, -2, 45); addTarget(-2, 0); break;
case 12: addEmitter(0, 0, 1, 0, 0); addMirror(2, 0, 45); addMirror(2, 2, 135); addMirror(-2, 2, 45); addMirror(-2, -2, 135); addTarget(0, -2); break;
case 13: addEmitter(-2, 2, 1, 0, 0); addEmitter(-2, 0, 1, 0, 0); addEmitter(-2, -2, 1, 0, 0); addMirror(0, 2, 45); addMirror(0, 0, 45); addMirror(0, -2, 45); addTarget(2, 2); addTarget(2, 0); addTarget(2, -2); break;
case 14: for(int i=-1; i<=1; i++) for(int j=-1; j<=1; j++) addWall(i, j); addEmitter(-3, 0, 0, 0, 1); addMirror(-3, 3, 45); addMirror(3, 3, 45); addMirror(3, -3, 45); addMirror(-2, -3, 45); addMirror(-2, -2, 45); addTarget(0, -2); break;
case 15: addEmitter(-2, 2, 0, 0, -1); addMirror(-2, -2, 45); addMirror(-1, -2, 45); addMirror(-1, 2, 45); addMirror(0, 2, 45); addMirror(0, -2, 45); addMirror(1, -2, 45); addMirror(1, 2, 45); addMirror(2, 2, 45); addTarget(2, -2); break;
case 16: for(int x=-2; x<=2; x++) { addWall(x, 3); addWall(x, -3); } addEmitter(-1, 0, 0, 0, 1); addMirror(-1, 2, 45); addMirror(1, 2, 45); addMirror(1, -2, 45); addMirror(2, -2, 45); addMirror(2, 0, 45); addTarget(0, 0); break;
case 17: addEmitter(-4, -5, 0, 0, 1); addMirror(-4, -3, 45); addMirror(-2, -3, 135); addMirror(-2, -1, 45); addMirror(2, -1, 135); addMirror(2, 1, 45); addMirror(-2, 1, 135); addMirror(-2, 3, 45); addMirror(2, 3, 135); addTarget(2, 5); break;
case 18: addEmitter(-2, 1, 1, 0, 0); addEmitter(2, -1, -1, 0, 0); addMirror(0, 1, 45); addMirror(0, -1, 45); addMirror(-1, 0, 135); addMirror(1, 0, 135); addTarget(2, 1); addTarget(-2, -1); break;
case 19: addEmitter(-5, 0, 1, 0, 0); addMirror(-3, 0, 45); addMirror(-3, -3, 135); addMirror(1, -3, 45); addMirror(1, 3, 135); addMirror(3, 3, 45); addMirror(3, 0, 135); addTarget(5, 0); break;
case 20: int[][] heartWalls = {{0, -4}, {-1, -3}, {1, -3}, {-2, -2}, {2, -2}, {-3, -1}, {3, -1}, {-4, 0}, {4, 0}, {-4, 1}, {4, 1}, {-3, 2}, {3, 2}, {-2, 3}, {2, 3}, {-1, 3}, {1, 3}}; for(int[] p : heartWalls) addWall(p[0], p[1]); addEmitter(0, 5, 0, 0, -1); addMirror(0, 2, 45); addMirror(2, 2, 135); addMirror(2, -1, 45); addMirror(-2, -1, 135); addMirror(-2, 1, 45); addTarget(0, 0); break;
case 21: addEmitter(-4, -4, 1, 0, 0); for(int i=-2; i<=2; i++) { addWall(i, -1); addWall(i, 1); } addMirror(4, -4, 45); addMirror(4, 0, 45); addMirror(-4, 0, 45); addMirror(-4, 4, 45); addTarget(4, 4); break;
case 22: addEmitter(-5, -2, 1, 0, 0); for(int z=-5; z<=5; z++) { if(z != -2) addWall(-2, z); if(z != 2) addWall(2, z); } addMirror(0, -2, 45); addMirror(0, 2, 135); addTarget(5, 2); break;
case 23: addEmitter(-5, -5, 1, 0, 0); addMirror(-2, -5, 45); addMirror(-2, 0, 135); addMirror(2, 0, 45); addMirror(2, 5, 135); addTarget(5, 5); break;
case 24: for(int x=-1; x<=1; x++) for(int z=-1; z<=1; z++) addWall(x, z); addEmitter(-4, 0, 0, 0, 1); addMirror(-4, 4, 45); addMirror(4, 4, 135); addMirror(4, -4, 45); addMirror(0, -4, 135); addTarget(0, -2); break;
case 25: addEmitter(-5, 0, 1, 0, 0); for(int i=-1; i<=1; i++) { addWall(i, 0); addWall(0, i); } addMirror(-3, 0, 45); addMirror(-3, 3, 45); addMirror(3, 3, 45); addMirror(3, 0, 45); addTarget(5, 0); break;
case 26: addEmitter(-6, -3, 1, 0, 0); addEmitter(-6, 0, 1, 0, 0); addEmitter(-6, 3, 1, 0, 0); addMirror(0, -3, 45); addMirror(2, 0, 135); addMirror(4, 3, 45); addTarget(0, 6); addTarget(2, -4); addTarget(4, 8); break;
case 27: addEmitter(-4, 0, 1, 0, 0); addMirror(0, 0, 45); addMirror(0, 2, 135); addTarget(-4, 2); break;
case 28: addEmitter(-8, -4, 1, 0, 0); addEmitter(-8, 0, 1, 0, 0); addEmitter(-8, 4, 1, 0, 0); addMirror(-4, -4, 45); addMirror(0, 0, 135); addMirror(4, 4, 45); addTarget(-4, 2); addTarget(0, -6); addTarget(4, 10); break;
case 29: addEmitter(-6, -4, 1, 0, 0); addEmitter(-6, 0, 1, 0, 0); addEmitter(-6, 4, 1, 0, 0); addMirror(-2, -4, 45); addMirror(-2, -2, 135); addMirror(0, 0, 45); addMirror(0, 2, 135); addMirror(2, 4, 45); addMirror(2, 6, 135); addTarget(6, -2); addTarget(6, 2); addTarget(6, 6); break;
case 30: addEmitter(-6, -2, 1, 0, 0); addEmitter(-6, 2, 1, 0, 0); for(int x=-4; x<=4; x++) addWall(x, 0); addMirror(-2, -2, 45); addMirror(2, -2, 135); addMirror(-2, 2, 135); addMirror(2, 2, 45); addTarget(6, -2); addTarget(6, 2); break;
case 31: addEmitter(-7, -7, 1, 0, 1); addEmitter(7, -7, -1, 0, 1); addEmitter(0, -10, 0, 0, 1); addMirror(-3, -3, 45); addMirror(3, -3, 135); addMirror(0, 0, 90); addTarget(-5, 5); addTarget(5, 5); addTarget(0, 8); break;
case 32: addEmitter(-4, 0, 1, 0, 0); addEmitter(4, 0, -1, 0, 0); addEmitter(0, -4, 0, 0, 1); addMirror(-2, 0, 45); addMirror(2, 0, 135); addMirror(0, -2, 45); addTarget(-2, 5); addTarget(2, 5); addTarget(5, -2); break;
case 33: addEmitter(-7, -3, 1, 0, 0); addEmitter(-7, 0, 1, 0, 0); addEmitter(-7, 3, 1, 0, 0); for(int z=-5; z<=5; z++) if(z % 3 != 0) addWall(0, z); addMirror(-3, -3, 45); addMirror(-3, 0, 135); addMirror(-3, 3, 45); addTarget(3, -3); addTarget(3, 0); addTarget(3, 3); break;
case 34: addEmitter(-6, -6, 1, 0, 0); addEmitter(-6, 0, 1, 0, 0); addEmitter(-6, 6, 1, 0, 0); addMirror(0, -6, 45); addMirror(0, 0, 135); addMirror(0, 6, 45); addTarget(0, -3); addTarget(0, 3); addTarget(0, 9); break;
case 35: addEmitter(-5, 0, 1, 0, 0); addEmitter(5, 0, -1, 0, 0); addMirror(0, 0, 45); addTarget(0, 3); addTarget(0, -3); break;
case 36: addEmitter(-8, -4, 1, 0, 0); addEmitter(-8, 4, 1, 0, 0); for(int i=-2; i<=2; i++) addWall(0, i); addMirror(-4, -4, 45); addMirror(-4, 4, 135); addMirror(4, -4, 135); addMirror(4, 4, 45); addTarget(8, -4); addTarget(8, 4); break;
case 37: addEmitter(-8, 0, 1, 0, 0); addMirror(-6, 0, 45); addMirror(-6, 4, 135); addMirror(0, 4, 45); addMirror(0, -4, 135); addMirror(6, -4, 45); addMirror(6, 0, 135); addTarget(9, 0); break;
case 38: addEmitter(-7, -5, 1, 0, 0); addEmitter(-7, 0, 1, 0, 0); addEmitter(-7, 5, 1, 0, 0); addWall(-2, -2); addWall(-2, 2); addWall(2, -2); addWall(2, 2); addMirror(-4, -5, 45); addMirror(-4, 5, 135); addMirror(0, 0, 90); addTarget(7, -5); addTarget(7, 0); addTarget(7, 5); break;
case 39: addEmitter(-5, -5, 1, 0, 0); for(int i=-3; i<=3; i++) { addWall(i, -3); addWall(i, 3); addWall(3, i); } addMirror(5, -5, 45); addMirror(5, 5, 135); addMirror(-5, 5, 45); addMirror(-5, 0, 135); addTarget(0, 0); break;
case 40: addEmitter(-12, -12, 1, 0, 0);for(int i = -3; i <= 3; i++) {addWall(i, 0);addWall(0, i);}addMirror(-8, -12, 45);addMirror(-8, -8, 135);addMirror(-4, -8, 45);addMirror(-4, -4, 135);addMirror(4, -4, 45);addMirror(4, 4, 135);addMirror(8, 4, 45);addMirror(8, 8, 135);addMirror(12, 8, 45);addMirror(12, 12, 135);addMirror(-12, 12, 45);addMirror(-12, 0, 135);addTarget(12, 0);break; default: addEmitter(-1, 0, 1, 0, 0);addTarget(1, 0);break;
}
}
private void clearCurrentLevel() {
mirrors.clear(); emitters.clear(); targets.clear(); walls.clear();
}
private void addEmitter(int gx, int gz, float dx, float dy, float dz) {
emitters.add(new Emitter(pyrModel, gx * UNIT, 0, gz * UNIT, dx, dy, dz));
}
private void addTarget(int gx, int gz) {
targets.add(new Target(pyrModel, gx * UNIT, 0, gz * UNIT));
}
private void addMirror(int gx, int gz, float angle) {
mirrors.add(new Mirror(mirrorModel, gx * UNIT, MIRROR_H/2, gz * UNIT, angle));
}
private void addWall(int gx, int gz) {
walls.add(new Wall(boxModel, gx * UNIT, UNIT / 2f, gz * UNIT));
}
public void render(ModelBatch batch, Environment env) {
batch.render(floor, env);
for (Emitter e : emitters) batch.render(e.instance, env);
for (Target t : targets) {
t.updateVisual();
batch.render(t.instance, env);
}
for (Mirror m : mirrors) batch.render(m, env);
for (Wall w : walls) if(w.active) batch.render(w.instance, env);
}
public void checkClick(Ray ray) {
for (Mirror m : mirrors) if (m.intersect(ray)) { m.rotate(); break; }
}
public void dispose() {
mirrorModel.dispose(); floorModel.dispose(); pyrModel.dispose(); boxModel.dispose();
}
public void nextLevel() {
loadLevel((currentLevel % 40) + 1);
}
}
+24
View File
@@ -0,0 +1,24 @@
package com.mygdx.game;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.math.Vector3;
class Target {
public ModelInstance instance;
public boolean hit = false;
public Target(Model m, float x, float y, float z) {
instance = new ModelInstance(m, x, y, z);
}
public Vector3 getPos() {
return instance.transform.getTranslation(new Vector3()).add(0, SceneManager.LASER_HEIGHT, 0);
}
public void updateVisual() {
instance.nodes.get(0).parts.get(0).material.set(ColorAttribute.createDiffuse(hit ? Color.GREEN : Color.WHITE));
}
}
+13
View File
@@ -0,0 +1,13 @@
package com.mygdx.game;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
class Wall {
public ModelInstance instance;
public boolean active = true;
public Wall(Model m, float x, float y, float z) {
instance = new ModelInstance(m, x, y, z);
}
}
Binary file not shown.
+49
View File
@@ -0,0 +1,49 @@
sourceCompatibility = 1.8
sourceSets.main.java.srcDirs = [ "src/" ]
sourceSets.main.resources.srcDirs = ["../assets"]
project.ext.mainClassName = "com.mygdx.game.DesktopLauncher"
project.ext.assetsDir = new File("../assets")
import org.gradle.internal.os.OperatingSystem
tasks.register('run', JavaExec) {
dependsOn classes
mainClass = project.mainClassName
classpath = sourceSets.main.runtimeClasspath
standardInput = System.in
workingDir = project.assetsDir
ignoreExitValue = true
if (OperatingSystem.current() == OperatingSystem.MAC_OS) {
// Required to run on macOS
jvmArgs += "-XstartOnFirstThread"
}
}
tasks.register('debug', JavaExec) {
dependsOn classes
mainClass = project.mainClassName
classpath = sourceSets.main.runtimeClasspath
standardInput = System.in
workingDir = project.assetsDir
ignoreExitValue = true
debug = true
}
tasks.register('dist', Jar) {
duplicatesStrategy(DuplicatesStrategy.EXCLUDE)
manifest {
attributes 'Main-Class': project.mainClassName
}
dependsOn configurations.runtimeClasspath
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
with jar
}
dist.dependsOn classes
eclipse.project.name = appName + "-desktop"
@@ -0,0 +1,14 @@
package com.mygdx.game;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
// Please note that on macOS your application needs to be started with the -XstartOnFirstThread JVM argument
public class DesktopLauncher {
public static void main (String[] arg) {
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
config.setForegroundFPS(60);
config.setTitle("My GDX Game");
new Lwjgl3Application(new MyGdxGame(), config);
}}
+5
View File
@@ -0,0 +1,5 @@
org.gradle.daemon=true
org.gradle.jvmargs=-Xms128m -Xmx1500m
org.gradle.configureondemand=false
android.useAndroidX=true
android.enableJetifier=true
Binary file not shown.
+6
View File
@@ -0,0 +1,6 @@
#Tue Dec 23 22:34:58 MSK 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+249
View File
@@ -0,0 +1,249 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# 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
#
# https://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.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+92
View File
@@ -0,0 +1,92 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
Binary file not shown.
@@ -0,0 +1 @@

Binary file not shown.
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
include 'desktop', 'android', 'core'