diff --git a/app/src/main/java/helloandroid/ut3/chauvequipeut/CollisionManager.java b/app/src/main/java/helloandroid/ut3/chauvequipeut/CollisionManager.java new file mode 100644 index 0000000..f9af473 --- /dev/null +++ b/app/src/main/java/helloandroid/ut3/chauvequipeut/CollisionManager.java @@ -0,0 +1,48 @@ +package helloandroid.ut3.chauvequipeut; + +import android.graphics.PointF; + +public class CollisionManager { + + + public static boolean checkForCollision(int[][] bat, float[][] ob) { + boolean toReturn = intersects(new PointF(bat[0][0],bat[0][1]), new PointF(bat[1][0],bat[1][1]), // verif collision haut bat avec gauche obstacle + new PointF(ob[0][0],ob[0][1]), new PointF(ob[2][0],ob[2][1])) || + + intersects(new PointF(bat[1][0],bat[1][1]), new PointF(bat[3][0],bat[3][1]),// verif collision droite bat avec gauche obstacle + new PointF(ob[0][0],ob[0][1]), new PointF(ob[2][0],ob[2][1])) || + + intersects(new PointF(bat[0][0],bat[0][1]), new PointF(bat[2][0],bat[2][1]),// verif collision gauche bat avec droite obstacle + new PointF(ob[1][0],ob[1][1]), new PointF(ob[2][0],ob[2][1])) || + + intersects(new PointF(bat[2][0],bat[2][1]), new PointF(bat[3][0],bat[3][1]),// verif collision bas bat avec droite obstacle + new PointF(ob[1][0],ob[1][1]), new PointF(ob[2][0],ob[2][1])); + + return toReturn; + } + static boolean intersects(PointF a1, PointF a2, PointF b1, PointF b2) { + PointF intersection = new PointF(); + + PointF b = new PointF(a2.x - a1.x, a2.y - a1.y); + PointF d = new PointF(b2.x - b1.x, b2.y - b1.y); + float bDotDPerp = b.x * d.y - b.y * d.x; + + // if b dot d == 0, it means the lines are parallel so have infinite intersection points + if (bDotDPerp == 0) + return false; + + PointF c = new PointF(b1.x - a1.x, b1.y - a1.y); + float t = (c.x * d.y - c.y * d.x) / bDotDPerp; + if (t < 0 || t > 1) + return false; + + float u = (c.x * b.y - c.y * b.x) / bDotDPerp; + if (u < 0 || u > 1) + return false; + + intersection.set(a1.x + b.x * t, a1.y + b.y * t); + + return true; + } + +} diff --git a/app/src/main/java/helloandroid/ut3/chauvequipeut/GameView.java b/app/src/main/java/helloandroid/ut3/chauvequipeut/GameView.java index 3ddd3a7..5402691 100644 --- a/app/src/main/java/helloandroid/ut3/chauvequipeut/GameView.java +++ b/app/src/main/java/helloandroid/ut3/chauvequipeut/GameView.java @@ -36,52 +36,44 @@ import android.media.MediaPlayer; public class GameView extends SurfaceView implements SurfaceHolder.Callback, SensorEventListener, View.OnTouchListener { + + private ObstacleManager obstacleManager; + private MediaPlayerManager mediaPlayerManager; + + private VibrationManager vibrationManager; + + private NightTimeManager nightTimeManager; private final GameThread thread; - private MediaPlayer mediaPlayer; - private List obstacles; private final Random random; private Bitmap background; private Bitmap scaled; - private boolean touched; private float accelerationX; private SensorManager sensorManager; private Sensor accelerometer; private Sensor lightSensor; - private boolean isNightTime = false; private Bitmap upArrowBitmap; private Bitmap downArrowBitmap; private Rect upArrowRect; private Rect downArrowRect; - private static final float ARROW_SCALE_FACTOR = 5f; private Handler moveHandler = new Handler(); private boolean moveUpPressed = false; private boolean moveDownPressed = false; private ChauveSouris chauveSouris; - // Ajouter un membre pour le rayon initial du cercle - private float initialRadius; - // Ajouter un membre pour le taux d'augmentation du rayon - private float growthRate; - // Ajouter un membre pour le rayon actuel du cercle - private float currentRadius; - private Paint textPaint; private long startTimeMillis; private long elapsedTimeMillis; - private boolean stopped = false; - private String time; public GameView(Context context, MediaPlayer mediaPlayer) { super(context); - this.mediaPlayer = mediaPlayer; + mediaPlayerManager = new MediaPlayerManager(mediaPlayer); getHolder().addCallback(this); setFocusable(true); setOnTouchListener(this); // Set onTouchListener for handling button clicks thread = new GameThread(getHolder(), this); - obstacles = new ArrayList<>(); - touched = false; + random = new Random(); textPaint = new Paint(); @@ -93,13 +85,13 @@ public GameView(Context context, MediaPlayer mediaPlayer) { sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); + vibrationManager = new VibrationManager((Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE)); // Initialize ChauveSouris object chauveSouris = new ChauveSouris(context); - touched = false; accelerationX = 0.0f; - isNightTime = false; + nightTimeManager.setNightTime(false); // Charger les images des flèches upArrowBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.uparrow); @@ -116,11 +108,9 @@ public GameView(Context context, MediaPlayer mediaPlayer) { background = BitmapFactory.decodeResource(getResources(),R.drawable.cavebackground); - initialRadius = chauveSouris.getTailleLongueur(); - // Initialiser le taux d'augmentation du rayon - growthRate = 1.1f; - // Initialiser le rayon actuel - currentRadius = initialRadius; + nightTimeManager.setInitialRadius(chauveSouris.getTailleLongueur()); + nightTimeManager.setGrowthRate(1.1f); + nightTimeManager.setCurrentRadius(nightTimeManager.getInitialRadius()); } @Override @@ -128,8 +118,9 @@ public void surfaceCreated(SurfaceHolder holder) { thread.setRunning(true); thread.start(); // Generate initial obstacles - generateInitialObstacles(); // Register accelerometer listener + obstacleManager = new ObstacleManager(getContext(), getWidth(), getHeight()); + obstacleManager.generateInitialObstacles(); sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME); sensorManager.registerListener(this, lightSensor, SensorManager.SENSOR_DELAY_NORMAL); @@ -168,59 +159,9 @@ public void update() { newX = getWidth() - chauveSouris.getTailleLargeur(); // Clamp to right edge } chauveSouris.setX((int) newX); - // Déplacer les obstacles vers la gauche - for (Obstacle obstacle : obstacles) { - obstacle.moveLeft(12); - } - - // Vérifier si un nouveau obstacle doit être généré - if (obstacles.get(obstacles.size() - 1).getX() <= getWidth() * 0.75) { - generateNewObstacle(); - } + obstacleManager.updateObstacle(); } - private void generateNewObstacle() { - int obstacleWidth = getWidth() / 4; // Largeur de chaque obstacle - int obstacleHeight; // Hauteur de chaque obstacle - int minHeight = getHeight() / 5; // Hauteur minimale - - // Facteur de variation pour la hauteur des obstacles - float heightFactor = 0.5f; // Modifier selon vos préférences - - // Variables pour suivre les positions x précédemment générées - Set topXPositions = new HashSet<>(); - Set bottomXPositions = new HashSet<>(); - - // Générer une position x aléatoire avec un léger décalage - float randomX = getWidth() + random.nextInt(getWidth() / 4); // Léger décalage supplémentaire - - // Déterminer si obstacle en haut ou en bas - boolean top = random.nextBoolean(); - - // Vérifier si la position x générée se chevauche avec les obstacles précédents dans la même rangée - if (top) { - if (!isOverlapping(topXPositions, randomX, obstacleWidth)) { - // Calculer la hauteur de l'obstacle - obstacleHeight = (int) (getHeight() * (heightFactor + random.nextFloat() * 0.4f)); - // Appliquer la hauteur minimale si nécessaire - obstacleHeight = Math.max(obstacleHeight, minHeight); - obstacles.add(new Obstacle(getContext(), randomX, 0, obstacleWidth, obstacleHeight, true)); - topXPositions.add(randomX); - } - } else { - if (!isOverlapping(bottomXPositions, randomX, obstacleWidth)) { - // Calculer la hauteur de l'obstacle - obstacleHeight = (int) (getHeight() * heightFactor * random.nextFloat()); - // Appliquer la hauteur minimale si nécessaire - obstacleHeight = Math.max(obstacleHeight, minHeight); - obstacles.add(new Obstacle(getContext(), randomX, getHeight() - obstacleHeight, obstacleWidth, obstacleHeight, false)); - bottomXPositions.add(randomX); - } - } - } - - - @Override @@ -236,55 +177,23 @@ public void draw(Canvas canvas) { if (canvas != null && !stopped) { canvas.drawBitmap(scaled,-200,0,null); // Draw the obstacles - for (Obstacle obstacle : obstacles) { + for (Obstacle obstacle : obstacleManager.getObstacles()) { obstacle.draw(canvas); int[][] bat = chauveSouris.getCornerCoordinates(); float[][] ob = obstacle.getTrianglePoints(); - if(intersects(new PointF(bat[0][0],bat[0][1]), new PointF(bat[1][0],bat[1][1]), // verif collision haut bat avec gauche obstacle - new PointF(ob[0][0],ob[0][1]), new PointF(ob[2][0],ob[2][1])) || - - intersects(new PointF(bat[1][0],bat[1][1]), new PointF(bat[3][0],bat[3][1]),// verif collision droite bat avec gauche obstacle - new PointF(ob[0][0],ob[0][1]), new PointF(ob[2][0],ob[2][1])) || + if(CollisionManager.checkForCollision(bat, ob)){ + mediaPlayerManager.resetMediaPlayer(); + // Faire vibrer le téléphone - intersects(new PointF(bat[0][0],bat[0][1]), new PointF(bat[2][0],bat[2][1]),// verif collision gauche bat avec droite obstacle - new PointF(ob[1][0],ob[1][1]), new PointF(ob[2][0],ob[2][1])) || + vibrationManager.vibrate(); - intersects(new PointF(bat[2][0],bat[2][1]), new PointF(bat[3][0],bat[3][1]),// verif collision bas bat avec droite obstacle - new PointF(ob[1][0],ob[1][1]), new PointF(ob[2][0],ob[2][1])) - ){ - mediaPlayer.stop(); - mediaPlayer.release(); - mediaPlayer = null; - // Faire vibrer le téléphone - Vibrator vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE); - if (vibrator != null) { - vibrator.vibrate(VibrationEffect.createOneShot(1000, VibrationEffect.DEFAULT_AMPLITUDE)); - } - Log.d("COLLISION" , "COLL"); - - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this.getContext()); - boolean isSoundEnabled = preferences.getBoolean("sound_enabled", true); - MediaPlayer collisionSound = MediaPlayer.create(this.getContext(), R.raw.hurt); - collisionSound.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { - @Override - public void onCompletion(MediaPlayer mp) { - mp.release(); - } - }); - - if (isSoundEnabled) { - collisionSound.start(); - }; + mediaPlayerManager.playMediaPlayer(getContext()); Intent intent = new Intent(getContext(), EndGameActivity.class); intent.putExtra("score", time); // Passer le score getContext().startActivity(intent); - - mediaPlayer.stop(); - mediaPlayer.release(); - mediaPlayer = null; + mediaPlayerManager.resetMediaPlayer(); break; - } } chauveSouris.draw(canvas); @@ -293,37 +202,7 @@ public void onCompletion(MediaPlayer mp) { canvas.drawBitmap(downArrowBitmap, null, downArrowRect, null); // Dessiner le cercle supplémentaire lorsque c'est la nuit - if (isNightTime) { - Paint circlePaint = new Paint(); - circlePaint.setColor(Color.YELLOW); // Couleur du cercle - circlePaint.setStyle(Paint.Style.STROKE); - circlePaint.setStrokeWidth(5); - - // Calculer le centre de la chauve-souris - float centerX = chauveSouris.getX() + chauveSouris.getTailleLargeur() / 2; - float centerY = chauveSouris.getY() + chauveSouris.getTailleLongueur() / 2; - - // Dessiner le cercle concentrique autour de la chauve-souris - canvas.drawCircle(centerX, centerY, currentRadius, circlePaint); - - for (Obstacle obstacle : obstacles) { - if (obstacle.collidesWithCircle(centerX, centerY, currentRadius)) { - obstacle.setStrokeColor(Color.YELLOW); // Changer la couleur de l'obstacle en jaune - } - } - - // Augmenter le rayon actuel pour la prochaine mise à jour - currentRadius *= growthRate; - - // Vérifier si le cercle a dépassé la taille de l'écran - if (currentRadius > Math.max(canvas.getWidth(), canvas.getHeight())) { - // Si oui, réinitialiser le rayon pour la prochaine fois - currentRadius = initialRadius; - } - } else { - // Si c'est le jour, réinitialiser le rayon du cercle - currentRadius = initialRadius; - } + nightTimeManager.drawNightMode(canvas, chauveSouris, obstacleManager); chauveSouris.draw(canvas); // Dessiner la chauve-souris String timeString = String.format("%02d:%02d", minutes, seconds); @@ -334,90 +213,6 @@ public void onCompletion(MediaPlayer mp) { } - - - static boolean intersects(PointF a1, PointF a2, PointF b1, PointF b2) { - PointF intersection = new PointF(); - - PointF b = new PointF(a2.x - a1.x, a2.y - a1.y); - PointF d = new PointF(b2.x - b1.x, b2.y - b1.y); - float bDotDPerp = b.x * d.y - b.y * d.x; - - // if b dot d == 0, it means the lines are parallel so have infinite intersection points - if (bDotDPerp == 0) - return false; - - PointF c = new PointF(b1.x - a1.x, b1.y - a1.y); - float t = (c.x * d.y - c.y * d.x) / bDotDPerp; - if (t < 0 || t > 1) - return false; - - float u = (c.x * b.y - c.y * b.x) / bDotDPerp; - if (u < 0 || u > 1) - return false; - - intersection.set(a1.x + b.x * t, a1.y + b.y * t); - - return true; - } - - private void generateInitialObstacles() { - int obstacleCount = 4; // Nombre d'obstacles à générer initialement - int obstacleWidth = getWidth() / 4; // Largeur de chaque obstacle - - // Facteur de variation pour la hauteur des obstacles - float heightFactor = 0.5f; // Modifier selon vos préférences - - // Variables pour suivre les positions x précédemment générées - Set topXPositions = new HashSet<>(); - Set bottomXPositions = new HashSet<>(); - - for (int i = 0; i < obstacleCount; i++) { - // Générer une hauteur d'obstacle aléatoire - int obstacleHeight; - - // Générer une position x aléatoire - float randomX = random.nextInt(getWidth() - obstacleWidth); - - // Déterminer si obstacle en haut ou en bas - boolean top = (i % 2 == 0); - - // Vérifier si la position x générée se chevauche avec les obstacles précédents dans la même rangée - if (top && !isOverlapping(topXPositions, randomX, obstacleWidth)) { - // Si le triangle du haut et du bas se chevauchent en termes de position x, réduire la hauteur - if (bottomXPositions.contains(randomX)) { - obstacleHeight = (int) (getHeight() * heightFactor * random.nextFloat() * 0.5); // Hauteur réduite - } else { - obstacleHeight = (int) (getHeight() * heightFactor * random.nextFloat()); - } - obstacles.add(new Obstacle(getContext(), randomX, 0, obstacleWidth, obstacleHeight, true)); - topXPositions.add(randomX); - } else if (!top && !isOverlapping(bottomXPositions, randomX, obstacleWidth)) { - // Si le triangle du haut et du bas se chevauchent en termes de position x, réduire la hauteur - if (topXPositions.contains(randomX)) { - obstacleHeight = (int) (getHeight() * heightFactor * random.nextFloat() * 0.5); // Hauteur réduite - } else { - obstacleHeight = (int) (getHeight() * heightFactor * random.nextFloat()); - } - obstacles.add(new Obstacle(getContext(), randomX, getHeight() - obstacleHeight, obstacleWidth, obstacleHeight, false)); - bottomXPositions.add(randomX); - } - } - } - - - - // Helper method to check if a new obstacle overlaps with previous obstacles - private boolean isOverlapping(Set positions, float newX, float obstacleWidth) { - for (float position : positions) { - // Check if the new obstacle's x position is within the range of previous obstacles - if (Math.abs(newX - position) < obstacleWidth) { - return true; // Overlapping - } - } - return false; // Not overlapping - } - @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { @@ -426,9 +221,9 @@ public void onSensorChanged(SensorEvent event) { } else if (event.sensor.getType() == Sensor.TYPE_LIGHT) { float lux = event.values[0]; if(lux < 30){ - isNightTime = true; + nightTimeManager.setNightTime(true); }else { - isNightTime = false; + nightTimeManager.setNightTime(false); } } } diff --git a/app/src/main/java/helloandroid/ut3/chauvequipeut/MediaPlayerManager.java b/app/src/main/java/helloandroid/ut3/chauvequipeut/MediaPlayerManager.java new file mode 100644 index 0000000..9bc1fa4 --- /dev/null +++ b/app/src/main/java/helloandroid/ut3/chauvequipeut/MediaPlayerManager.java @@ -0,0 +1,38 @@ +package helloandroid.ut3.chauvequipeut; + +import android.content.Context; +import android.content.SharedPreferences; +import android.media.MediaPlayer; +import android.preference.PreferenceManager; + +public class MediaPlayerManager { + + private MediaPlayer mediaPlayer; + + public MediaPlayerManager(MediaPlayer mediaPlayer) { + this.mediaPlayer = mediaPlayer; + } + + public void resetMediaPlayer() { + mediaPlayer.stop(); + mediaPlayer.release(); + mediaPlayer = null; + } + + public void playMediaPlayer(Context context) { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + boolean isSoundEnabled = preferences.getBoolean("sound_enabled", true); + MediaPlayer collisionSound = MediaPlayer.create(context, R.raw.hurt); + collisionSound.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + @Override + public void onCompletion(MediaPlayer mp) { + mp.release(); + } + }); + + if (isSoundEnabled) { + collisionSound.start(); + }; + } + +} diff --git a/app/src/main/java/helloandroid/ut3/chauvequipeut/NightTimeManager.java b/app/src/main/java/helloandroid/ut3/chauvequipeut/NightTimeManager.java new file mode 100644 index 0000000..5174c16 --- /dev/null +++ b/app/src/main/java/helloandroid/ut3/chauvequipeut/NightTimeManager.java @@ -0,0 +1,86 @@ +package helloandroid.ut3.chauvequipeut; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.content.Context; +import android.content.Intent; + +public class NightTimeManager { + private boolean isNightTime; + private float initialRadius; + private float currentRadius; + private float growthRate; + + public boolean isNightTime() { + return isNightTime; + } + + public float getInitialRadius() { + return initialRadius; + } + + public void setInitialRadius(float initialRadius) { + this.initialRadius = initialRadius; + } + + public float getCurrentRadius() { + return currentRadius; + } + + public void setCurrentRadius(float currentRadius) { + this.currentRadius = currentRadius; + } + + public float getGrowthRate() { + return growthRate; + } + + public void setGrowthRate(float growthRate) { + this.growthRate = growthRate; + } + + public Paint getCirclePaint() { + return circlePaint; + } + + public void setCirclePaint(Paint circlePaint) { + this.circlePaint = circlePaint; + } + + private Paint circlePaint; + private Context context; + + public NightTimeManager(Context context) { + this.context = context; + circlePaint = new Paint(); + circlePaint.setColor(Color.YELLOW); + circlePaint.setStyle(Paint.Style.STROKE); + circlePaint.setStrokeWidth(5); + // Initialize other necessary variables + } + + public void drawNightMode(Canvas canvas, ChauveSouris chauveSouris, ObstacleManager obstacleManager) { + if (isNightTime) { + // Draw night mode components + float centerX = chauveSouris.getX() + chauveSouris.getTailleLargeur() / 2; + float centerY = chauveSouris.getY() + chauveSouris.getTailleLongueur() / 2; + canvas.drawCircle(centerX, centerY, currentRadius, circlePaint); + for (Obstacle obstacle : obstacleManager.getObstacles()) { + if (obstacle.collidesWithCircle(centerX, centerY, currentRadius)) { + obstacle.setStrokeColor(Color.YELLOW); + } + } + currentRadius *= growthRate; + if (currentRadius > Math.max(canvas.getWidth(), canvas.getHeight())) { + currentRadius = initialRadius; + } + } else { + currentRadius = initialRadius; + } + } + + public void setNightTime(boolean isNightTime) { + this.isNightTime = isNightTime; + } +} diff --git a/app/src/main/java/helloandroid/ut3/chauvequipeut/ObstacleManager.java b/app/src/main/java/helloandroid/ut3/chauvequipeut/ObstacleManager.java new file mode 100644 index 0000000..5a1079c --- /dev/null +++ b/app/src/main/java/helloandroid/ut3/chauvequipeut/ObstacleManager.java @@ -0,0 +1,138 @@ +package helloandroid.ut3.chauvequipeut; + +import android.content.Context; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; + +public class ObstacleManager { + + private final Random random ; + private Context context; + private List obstacles; + + private int viewWidth; + + private int viewHeight; + + public ObstacleManager(Context context, int viewWidth, int viewHeight) { + obstacles = new ArrayList<>(); + this.context = context; + random = new Random(); + this.viewWidth = viewWidth; + this.viewHeight = viewHeight; + } + + public void generateInitialObstacles() { + int obstacleCount = 4; // Nombre d'obstacles à générer initialement + int obstacleWidth = viewWidth / 4; // Largeur de chaque obstacle + + // Facteur de variation pour la hauteur des obstacles + float heightFactor = 0.5f; // Modifier selon vos préférences + + // Variables pour suivre les positions x précédemment générées + Set topXPositions = new HashSet<>(); + Set bottomXPositions = new HashSet<>(); + + for (int i = 0; i < obstacleCount; i++) { + // Générer une hauteur d'obstacle aléatoire + int obstacleHeight; + + // Générer une position x aléatoire + float randomX = random.nextInt(viewWidth - obstacleWidth); + + // Déterminer si obstacle en haut ou en bas + boolean top = (i % 2 == 0); + + // Vérifier si la position x générée se chevauche avec les obstacles précédents dans la même rangée + if (top && !isOverlapping(topXPositions, randomX, obstacleWidth)) { + // Si le triangle du haut et du bas se chevauchent en termes de position x, réduire la hauteur + if (bottomXPositions.contains(randomX)) { + obstacleHeight = (int) (viewHeight * heightFactor * random.nextFloat() * 0.5); // Hauteur réduite + } else { + obstacleHeight = (int) (viewHeight * heightFactor * random.nextFloat()); + } + obstacles.add(new Obstacle(context, randomX, 0, obstacleWidth, obstacleHeight, true)); + topXPositions.add(randomX); + } else if (!top && !isOverlapping(bottomXPositions, randomX, obstacleWidth)) { + // Si le triangle du haut et du bas se chevauchent en termes de position x, réduire la hauteur + if (topXPositions.contains(randomX)) { + obstacleHeight = (int) (viewHeight * heightFactor * random.nextFloat() * 0.5); // Hauteur réduite + } else { + obstacleHeight = (int) (viewHeight * heightFactor * random.nextFloat()); + } + obstacles.add(new Obstacle(context, randomX, viewHeight- obstacleHeight, obstacleWidth, obstacleHeight, false)); + bottomXPositions.add(randomX); + } + } + } + + + public void updateObstacle() { + for (Obstacle obstacle : obstacles) { + obstacle.moveLeft(12); + } + if (obstacles.get(obstacles.size() - 1).getX() <= viewWidth * 0.75) { + generateNewObstacle(); + } + } + + + // Helper method to check if a new obstacle overlaps with previous obstacles + private boolean isOverlapping(Set positions, float newX, float obstacleWidth) { + for (float position : positions) { + // Check if the new obstacle's x position is within the range of previous obstacles + if (Math.abs(newX - position) < obstacleWidth) { + return true; // Overlapping + } + } + return false; // Not overlapping + } + + private void generateNewObstacle() { + int obstacleWidth = viewWidth / 4; // Largeur de chaque obstacle + int obstacleHeight; // Hauteur de chaque obstacle + int minHeight = viewHeight / 5; // Hauteur minimale + + // Facteur de variation pour la hauteur des obstacles + float heightFactor = 0.5f; // Modifier selon vos préférences + + // Variables pour suivre les positions x précédemment générées + Set topXPositions = new HashSet<>(); + Set bottomXPositions = new HashSet<>(); + + // Générer une position x aléatoire avec un léger décalage + float randomX = viewWidth + random.nextInt(viewWidth / 4); // Léger décalage supplémentaire + + // Déterminer si obstacle en haut ou en bas + boolean top = random.nextBoolean(); + + // Vérifier si la position x générée se chevauche avec les obstacles précédents dans la même rangée + if (top) { + if (!isOverlapping(topXPositions, randomX, obstacleWidth)) { + // Calculer la hauteur de l'obstacle + obstacleHeight = (int) (viewHeight * (heightFactor + random.nextFloat() * 0.4f)); + // Appliquer la hauteur minimale si nécessaire + obstacleHeight = Math.max(obstacleHeight, minHeight); + obstacles.add(new Obstacle(context, randomX, 0, obstacleWidth, obstacleHeight, true)); + topXPositions.add(randomX); + } + } else { + if (!isOverlapping(bottomXPositions, randomX, obstacleWidth)) { + // Calculer la hauteur de l'obstacle + obstacleHeight = (int) (viewHeight * heightFactor * random.nextFloat()); + // Appliquer la hauteur minimale si nécessaire + obstacleHeight = Math.max(obstacleHeight, minHeight); + obstacles.add(new Obstacle(context, randomX, viewHeight - obstacleHeight, obstacleWidth, obstacleHeight, false)); + bottomXPositions.add(randomX); + } + } + } + + public List getObstacles() { + return obstacles; + } +} diff --git a/app/src/main/java/helloandroid/ut3/chauvequipeut/VibrationManager.java b/app/src/main/java/helloandroid/ut3/chauvequipeut/VibrationManager.java new file mode 100644 index 0000000..b23dd62 --- /dev/null +++ b/app/src/main/java/helloandroid/ut3/chauvequipeut/VibrationManager.java @@ -0,0 +1,19 @@ +package helloandroid.ut3.chauvequipeut; + +import android.os.VibrationEffect; +import android.os.Vibrator; + +public class VibrationManager { + + private Vibrator vibrator; + + public VibrationManager(Vibrator vibrator) { + this.vibrator = vibrator; + } + + public void vibrate(){ + if (vibrator != null) { + vibrator.vibrate(VibrationEffect.createOneShot(1000, VibrationEffect.DEFAULT_AMPLITUDE)); + } + } +} diff --git a/app/src/main/res/drawable/minichauve.gif b/app/src/main/res/drawable/minichauve.gif deleted file mode 100644 index b78ef86..0000000 Binary files a/app/src/main/res/drawable/minichauve.gif and /dev/null differ