/
arti4
/
IndividualProject
Обзор
Документация
Войти
/
arti4
/
IndividualProject
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
MyGame/app/src/main/java/com/example/mygame/MapSelectionActivity.java
542 строки
21 KB
arti4
upload files
18 ноя 2025, 12:41
18 ноя 2025, 12:41
f3a2f8a
Код
Авторство
О чём код?
package com.example.mygame; import android.content.Context; import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.text.Spannable; import android.text.SpannableString; import android.text.style.ImageSpan; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.Button; import android.widget.GridLayout; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import androidx.activity.OnBackPressedCallback; import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; public class MapSelectionActivity extends AppCompatActivity { private static final String PREF_NAME = "MapPrefs"; private static final String KEY_SELECTED_MAP = "selected_map"; private static final String KEY_UNLOCKED_MAPS = "unlocked_maps"; private int selectedMap = 0; private CompactMapPreview[] mapPreviews; private int totalCrystals = 0; private int[] unlockPrices = {0, 50, 100, 150, 200, 250, 300, 350, 400, 450}; private BackgroundLayer backgroundLayer; private MenuBackgroundView backgroundView; private MenuThread menuThread; private float cameraX = 0f; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_map_selection); RelativeLayout rootLayout = findViewById(R.id.rootLayout); if (rootLayout != null) { backgroundView = new MenuBackgroundView(this); rootLayout.addView(backgroundView, 0); } DisplayMetrics displayMetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); int screenWidth = displayMetrics.widthPixels; int screenHeight = displayMetrics.heightPixels; backgroundLayer = new BackgroundLayer(this, screenWidth, screenHeight, 1.0f); if (backgroundView != null) { backgroundView.setBackgroundLayer(backgroundLayer); } loadSelectedMap(); loadCrystals(); setupMapGrid(); setupBackButton(); displayCrystals(); setupBackPressedHandler(); } private void loadCrystals() { SharedPreferences prefs = getSharedPreferences("GamePrefs", Context.MODE_PRIVATE); totalCrystals = prefs.getInt("collected_crystals", 0); } private void displayCrystals() { TextView crystalsText = findViewById(R.id.crystalsText); if (crystalsText != null) { SpannableString spannable = new SpannableString(" " + totalCrystals); Drawable crystalDrawable = ContextCompat.getDrawable(this, R.drawable.ic_crystal); if (crystalDrawable != null) { crystalDrawable.setBounds(0, 0, dpToPx(20), dpToPx(20)); ImageSpan imageSpan = new ImageSpan(crystalDrawable, ImageSpan.ALIGN_BASELINE); spannable.setSpan(imageSpan, 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } crystalsText.setText(spannable); } } private int dpToPx(int dp) { float density = getResources().getDisplayMetrics().density; return Math.round(dp * density); } private boolean isMapUnlocked(int mapType) { SharedPreferences prefs = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); String unlockedString = prefs.getString(KEY_UNLOCKED_MAPS, "0"); String[] unlockedArray = unlockedString.split(","); for (String unlocked : unlockedArray) { if (unlocked.equals(String.valueOf(mapType))) { return true; } } return false; } private void unlockMap(int mapType) { SharedPreferences prefs = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); String unlockedString = prefs.getString(KEY_UNLOCKED_MAPS, "0"); if (!unlockedString.contains(String.valueOf(mapType))) { unlockedString += "," + mapType; prefs.edit().putString(KEY_UNLOCKED_MAPS, unlockedString).apply(); } } private void purchaseMap(int mapType) { int price = unlockPrices[mapType]; if (totalCrystals >= price) { totalCrystals -= price; saveCrystals(); unlockMap(mapType); selectMap(mapType); displayCrystals(); setupMapGrid(); Toast.makeText(this, "Карта разблокирована!", Toast.LENGTH_SHORT).show(); } else { int needed = price - totalCrystals; Toast.makeText(this, "Недостаточно кристаллов! Нужно ещё: " + needed, Toast.LENGTH_LONG).show(); } } private void saveCrystals() { SharedPreferences prefs = getSharedPreferences("GamePrefs", Context.MODE_PRIVATE); prefs.edit().putInt("collected_crystals", totalCrystals).apply(); } protected void onResume() { super.onResume(); startMenuAnimation(); } @Override protected void onPause() { super.onPause(); stopMenuAnimation(); if (backgroundLayer != null) { backgroundLayer.release(); } stopMenuAnimation(); } @Override protected void onDestroy() { super.onDestroy(); } private void startMenuAnimation() { if (menuThread == null) { menuThread = new MenuThread(); menuThread.setRunning(true); menuThread.start(); } } private void stopMenuAnimation() { if (menuThread != null) { menuThread.setRunning(false); menuThread = null; } } private class MenuThread extends Thread { private boolean running; private long lastTime = System.currentTimeMillis(); public void setRunning(boolean running) { this.running = running; } @Override public void run() { while (running) { long currentTime = System.currentTimeMillis(); long elapsedTime = currentTime - lastTime; cameraX += 0.5f; if (backgroundLayer != null) { backgroundLayer.update(cameraX); } runOnUiThread(new Runnable() { @Override public void run() { if (backgroundView != null) { backgroundView.setCameraX(cameraX); backgroundView.invalidate(); } } }); try { Thread.sleep(16); } catch (InterruptedException e) { e.printStackTrace(); } lastTime = currentTime; } } } private static class MenuBackgroundView extends View { private BackgroundLayer backgroundLayer; private float cameraX = 0f; public MenuBackgroundView(Context context) { super(context); } public MenuBackgroundView(Context context, AttributeSet attrs) { super(context, attrs); } public MenuBackgroundView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setBackgroundLayer(BackgroundLayer backgroundLayer) { this.backgroundLayer = backgroundLayer; } public void setCameraX(float cameraX) { this.cameraX = cameraX; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (backgroundLayer != null) { backgroundLayer.draw(canvas, cameraX); } } } private void loadSelectedMap() { SharedPreferences prefs = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); selectedMap = prefs.getInt(KEY_SELECTED_MAP, 0); } private void saveSelectedMap() { SharedPreferences prefs = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); prefs.edit().putInt(KEY_SELECTED_MAP, selectedMap).apply(); } private void selectMap(int mapIndex) { selectedMap = mapIndex; saveSelectedMap(); for (int i = 0; i < mapPreviews.length; i++) { mapPreviews[i].setSelected(i == mapIndex); } updateMapInfo(); } private void updateMapInfo() { TextView infoText = findViewById(R.id.mapInfo); if (infoText != null) { String[] fullNames = { "Стандартная трасса", "Городская гонка", "Горный серпантин", "Пустынный спринт", "Лесной трек", "Прибрежный маршрут", "Ночная трасса", "Дождевая гонка", "Зимний заезд", "Экстрим парк" }; String info = String.format("%s", fullNames[selectedMap]); infoText.setText(info); } } private void setupBackButton() { Button backButton = findViewById(R.id.backButton); backButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { goBackToMainMenu(); } }); } private void setupBackPressedHandler() { getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { goBackToMainMenu(); } }); } private void goBackToMainMenu() { finish(); overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); } private void setupMapGrid() { GridLayout gridLayout = findViewById(R.id.mapGrid); gridLayout.removeAllViews(); String[] mapNames = {"Станд", "Город", "Горы", "Пустыня", "Лес", "Берег", "Ночь", "Дождь", "Зима", "Экстрим"}; int[][] mapColors = { {Color.BLACK, Color.GRAY}, {Color.WHITE, Color.LTGRAY}, {Color.rgb(52, 207, 190), Color.rgb(255, 108, 0)}, {Color.rgb(255, 0, 0), Color.rgb(0, 204, 0)}, {Color.rgb(53, 94, 59), Color.rgb(100, 130, 100)}, {Color.rgb(8, 16, 115), Color.rgb(166, 122, 0)}, {Color.rgb(0, 250, 51), Color.rgb(80, 80, 80)}, {Color.rgb(243, 253, 0), Color.rgb(121, 8, 170)}, {Color.rgb(132, 0, 77), Color.rgb(180, 205, 61)}, {Color.rgb(139, 0, 0), Color.BLACK} }; mapPreviews = new CompactMapPreview[10]; for (int i = 0; i < 10; i++) { boolean unlocked = isMapUnlocked(i); CompactMapPreview preview = new CompactMapPreview(this, i, mapNames[i], mapColors[i], unlocked, unlockPrices[i]); mapPreviews[i] = preview; GridLayout.LayoutParams params = new GridLayout.LayoutParams(); params.width = 0; params.height = ViewGroup.LayoutParams.WRAP_CONTENT; params.columnSpec = GridLayout.spec(i % 2, 1f); params.rowSpec = GridLayout.spec(i / 2); params.setMargins(4, 4, 4, 4); preview.setLayoutParams(params); preview.setSelected(i == selectedMap); final int mapIndex = i; preview.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isMapUnlocked(mapIndex)) { selectMap(mapIndex); } else { purchaseMap(mapIndex); } } }); gridLayout.addView(preview); } updateMapInfo(); } private static class CompactMapPreview extends View { private int mapType; private String mapName; private int[] mapColors; private boolean isSelected; private boolean isUnlocked; private int unlockPrice; private Paint paint; private Paint lockPaint; private Paint pricePaint; private android.graphics.Bitmap lockBitmap; private Bitmap crystalBitmap; public CompactMapPreview(Context context, int type, String name, int[] colors, boolean unlocked, int price) { super(context); this.mapType = type; this.mapName = name; this.mapColors = colors; this.isUnlocked = unlocked; this.unlockPrice = price; this.paint = new Paint(); this.paint.setAntiAlias(true); this.lockPaint = new Paint(); this.lockPaint.setAntiAlias(true); this.lockPaint.setColor(Color.argb(180, 0, 0, 0)); this.pricePaint = new Paint(); this.pricePaint.setAntiAlias(true); this.pricePaint.setColor(Color.YELLOW); this.pricePaint.setTextSize(38f); this.pricePaint.setTextAlign(Paint.Align.CENTER); this.pricePaint.setShadowLayer(3, 1, 1, Color.BLACK); loadCrystalBitmap(context); loadLockBitmap(context); setBackground(ContextCompat.getDrawable(context, R.drawable.compact_motorcycle_bg)); } private void loadLockBitmap(Context context) { try { android.graphics.drawable.Drawable lockDrawable = ContextCompat.getDrawable(context, R.drawable.ic_lock); if (lockDrawable != null) { int size = dpToPx(48); lockBitmap = android.graphics.Bitmap.createBitmap(size, size, android.graphics.Bitmap.Config.ARGB_8888); android.graphics.Canvas canvas = new android.graphics.Canvas(lockBitmap); lockDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); lockDrawable.draw(canvas); } } catch (Exception e) { e.printStackTrace(); lockBitmap = createFallbackLockBitmap(); } } private void loadCrystalBitmap(Context context) { try { int resourceId = context.getResources().getIdentifier("ic_crystal", "drawable", context.getPackageName()); if (resourceId != 0) { Bitmap originalBitmap = BitmapFactory.decodeResource(context.getResources(), resourceId); int size = dpToPx(36); crystalBitmap = Bitmap.createScaledBitmap(originalBitmap, size, size, true); } else { crystalBitmap = createFallbackCrystalBitmap(); } } catch (Exception e) { e.printStackTrace(); crystalBitmap = createFallbackCrystalBitmap(); } } private Bitmap createFallbackCrystalBitmap() { int size = dpToPx(36); Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(); paint.setAntiAlias(true); float centerX = size / 2f; float centerY = size / 2f; float diamondSize = size * 0.7f; android.graphics.Path diamond = new android.graphics.Path(); diamond.moveTo(centerX, centerY - diamondSize/2); diamond.lineTo(centerX + diamondSize/2, centerY); diamond.lineTo(centerX, centerY + diamondSize/2); diamond.lineTo(centerX - diamondSize/2, centerY); diamond.close(); paint.setColor(Color.argb(255, 0, 200, 255)); paint.setStyle(Paint.Style.FILL); canvas.drawPath(diamond, paint); paint.setColor(Color.argb(255, 0, 150, 255)); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(2f); canvas.drawPath(diamond, paint); return bitmap; } private android.graphics.Bitmap createFallbackLockBitmap() { int size = dpToPx(48); android.graphics.Bitmap bitmap = android.graphics.Bitmap.createBitmap(size, size, android.graphics.Bitmap.Config.ARGB_8888); android.graphics.Canvas canvas = new android.graphics.Canvas(bitmap); Paint lockPaint = new Paint(); lockPaint.setAntiAlias(true); lockPaint.setColor(Color.YELLOW); lockPaint.setStyle(Paint.Style.STROKE); lockPaint.setStrokeWidth(3f); float centerX = size / 2f; float centerY = size / 2f; float lockSize = size * 0.6f; canvas.drawCircle(centerX, centerY, lockSize / 2, lockPaint); lockPaint.setStyle(Paint.Style.FILL); canvas.drawCircle(centerX, centerY, lockSize * 0.15f, lockPaint); lockPaint.setStyle(Paint.Style.STROKE); lockPaint.setStrokeWidth(2f); canvas.drawLine(centerX, centerY - lockSize * 0.2f, centerX, centerY + lockSize * 0.2f, lockPaint); return bitmap; } public void setSelected(boolean selected) { this.isSelected = selected; invalidate(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int desiredSize = dpToPx(100); setMeasuredDimension(desiredSize, desiredSize); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getWidth(); int height = getHeight(); if (isSelected) { paint.setColor(Color.YELLOW); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(4f); canvas.drawRect(2, 2, width - 2, height - 2, paint); } float topMargin = 30f; float bottomMargin = 30f; float availableHeight = height - topMargin - bottomMargin; float leftMargin = 30f; float rightMargin = 30f; float availableWidth = width - leftMargin - rightMargin; paint.setStyle(Paint.Style.FILL); paint.setColor(mapColors[0]); canvas.drawRect( leftMargin, topMargin, leftMargin + availableWidth, topMargin + availableHeight, paint ); paint.setStyle(Paint.Style.STROKE); paint.setColor(mapColors[1]); paint.setStrokeWidth(35f); canvas.drawRect( leftMargin, topMargin, leftMargin + availableWidth, topMargin + availableHeight, paint ); if (!isUnlocked) { canvas.drawRect(0, 0, width, height, lockPaint); if (lockBitmap != null) { float lockLeft = (width - lockBitmap.getWidth()) / 2f; float lockTop = height * 0.3f - lockBitmap.getHeight() / 2f + 30f; canvas.drawBitmap(lockBitmap, lockLeft, lockTop, paint); } if (crystalBitmap != null) { float crystalLeft = (width - crystalBitmap.getWidth()) / 2f - dpToPx(15); float crystalTop = height * 0.75f - 28; canvas.drawBitmap(crystalBitmap, crystalLeft, crystalTop, paint); pricePaint.setColor(Color.YELLOW); pricePaint.setTextSize(36f); String priceText = String.valueOf(unlockPrice); float textX = crystalLeft + crystalBitmap.getWidth() + dpToPx(15); float textY = crystalTop + crystalBitmap.getHeight() / 2 + 15; canvas.drawText(priceText, textX, textY, pricePaint); } else { pricePaint.setColor(Color.YELLOW); canvas.drawText(unlockPrice + " 💎", width / 2f, height * 0.85f, pricePaint); } } } private int dpToPx(int dp) { float density = getContext().getResources().getDisplayMetrics().density; return Math.round(dp * density); } } }