diff --git a/app/src/main/java/com/iutlaval/myapplication/Game/Cards/Card.java b/app/src/main/java/com/iutlaval/myapplication/Game/Cards/Card.java index 808960c..991f0e7 100644 --- a/app/src/main/java/com/iutlaval/myapplication/Game/Cards/Card.java +++ b/app/src/main/java/com/iutlaval/myapplication/Game/Cards/Card.java @@ -4,7 +4,6 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; -import android.util.Log; import com.iutlaval.myapplication.Game.Board; import com.iutlaval.myapplication.Game.Player.Player; diff --git a/app/src/main/java/com/iutlaval/myapplication/Game/GameLogicThread.java b/app/src/main/java/com/iutlaval/myapplication/Game/GameLogicThread.java index a1a2316..196f315 100644 --- a/app/src/main/java/com/iutlaval/myapplication/Game/GameLogicThread.java +++ b/app/src/main/java/com/iutlaval/myapplication/Game/GameLogicThread.java @@ -4,7 +4,6 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; -import android.util.Log; import com.iutlaval.myapplication.Game.Cards.Card; import com.iutlaval.myapplication.Game.Cards.DemoCard; @@ -18,28 +17,33 @@ import com.iutlaval.myapplication.Video.Renderer; public class GameLogicThread extends Thread{ - Context cont; - Renderer renderer; + private Context cont; + private Renderer renderer; + private boolean ready; public GameLogicThread(Context cont, Renderer renderer) { + ready=false; this.cont = cont; this.renderer = renderer; + renderer.setEngine(this); } + private float i=0; + private float increm = 1F; + + @Override public void run() { - Bitmap bm = BitmapFactory.decodeResource(cont.getResources(), R.drawable.debug_card); - try { renderer.addToDraw(new Drawable(new Rectangle(0,0,100,100),"background", Color.BLUE)); //renderer.addToDraw(new Drawable(bm,0.0F,0.0F,"running",8F,16F)); //renderer.addToDraw(new DrawableCard(new DemoCard(),0.0F,0.0F,"card2",cont)); Card card2 = new DemoCard("card3",cont); - if(!renderer.addToDraw(card2.getDrawableCard())) Log.e("F","WTF"); + renderer.addToDraw(card2.getDrawableCard()); Card card1 = new DemoCard("card1",cont); - if(!renderer.addToDraw(card1.getDrawableCard())) Log.e("F","WTF"); + renderer.addToDraw(card1.getDrawableCard()); } catch (InvalidDataException e) { //cette erreur est lance si un carre est invalid System.err.println(e.getDetail()); @@ -47,26 +51,38 @@ public class GameLogicThread extends Thread{ } - int i=0; - int increm = 1; + ready=true; while(true) { - if(i < 100) - { - i+=increm; - }else{ - increm=-increm; - i+=increm; - } - if(i==0)increm=-increm; - - //TODO get x,y coordinate form name - //r.moveToDraw(i,i,"card2"); - renderer.moveToDraw(1,1,"card3"); + //Do Stuff renderer.moveToDraw(20,1,"card1"); - FpsTime.waitFrameTime(); + break; } } + public void onFrameDoneRendering() + { + if(i < 100) + { + i+=increm; + //((DrawableCard)renderer.getDrawAble("card3")).setOnBoard(increm <= 0); + }else{ + increm=-increm; + i+=increm; + //((DrawableCard)renderer.getDrawAble("card3")).setOnBoard(increm > 0); + } + if(i==0)increm=-increm; + + ((DrawableCard)renderer.getDrawAble("card3")).setOnBoard(false); + //TODO get x,y coordinate form name + //r.moveToDraw(i,i,"card2"); + //renderer.moveToDraw(i,i,"card3"); + + } + + public boolean isReady() { + return ready; + } + //placeOnBoard() } diff --git a/app/src/main/java/com/iutlaval/myapplication/GameActivity.java b/app/src/main/java/com/iutlaval/myapplication/GameActivity.java index 06a7dc4..1fc8d68 100644 --- a/app/src/main/java/com/iutlaval/myapplication/GameActivity.java +++ b/app/src/main/java/com/iutlaval/myapplication/GameActivity.java @@ -3,6 +3,7 @@ package com.iutlaval.myapplication; //N'oubliez pas de déclarer le bon package dans lequel se trouve le fichier ! import android.app.Activity; +import android.content.Intent; import android.content.pm.ActivityInfo; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -33,6 +34,9 @@ public class GameActivity extends Activity { return false;//TODO implement it } + Renderer renderer; + GameLogicThread t; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -55,11 +59,10 @@ public class GameActivity extends Activity { screenHeight = size.y; } - Thread t = new GameLogicThread(this,renderer); + t = new GameLogicThread(this,renderer); t.start(); setContentView(renderer); } - } diff --git a/app/src/main/java/com/iutlaval/myapplication/Video/Drawable.java b/app/src/main/java/com/iutlaval/myapplication/Video/Drawable.java index efb485c..ee7db01 100644 --- a/app/src/main/java/com/iutlaval/myapplication/Video/Drawable.java +++ b/app/src/main/java/com/iutlaval/myapplication/Video/Drawable.java @@ -4,6 +4,7 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; +import android.graphics.Rect; import android.util.Log; import androidx.annotation.NonNull; @@ -51,10 +52,6 @@ public class Drawable { float x_scaled_size = x_size* GameActivity.screenWidth/100; float y_scaled_size = y_size* GameActivity.screenHeight/100; - System.out.println(x_scaled_size + " y: " + y_scaled_size); - System.out.println(y_size); - - if(x_scaled_size <=0 || y_scaled_size <=0) { Log.e("TEXTURE :","ERREUR DE MISE A L'ECHELLE"); @@ -76,32 +73,75 @@ public class Drawable { public Drawable(String text,float x_pos,float y_pos,String name, float x_size,float y_size,float textSize) { this(x_pos,y_pos,name); - //this ratio is used to dial the quality of the text; - - List linesOfText = cutText(20,text); - - Log.i("bitmap"," : h:" + 40*linesOfText.size() + " w: "+text.length()*textSize / linesOfText.size()); - - bitmap = Bitmap.createBitmap((int)(text.length()*textSize / linesOfText.size()), (int) 40*linesOfText.size(), Bitmap.Config.ARGB_8888); + int x_scaled_size = (int)x_size* GameActivity.screenWidth/100; + int y_scaled_size = (int)y_size* GameActivity.screenHeight/100; checkPaint(); - p.setTextSize(textSize*2); + p.setColor(Color.BLACK); + + + + List linesOfText = cutText(20,text); + p.setTextSize(textSize); + /*float size = 0; + for(String str : linesOfText) + { + float i; + if((i = getTextSizeForWidth(p,x_scaled_size,y_scaled_size,str)) > size) + { + size = i; + } + } + p.setTextSize(size);*/ + + //+10 permet d'e prendre en compte les p,q,j qui dessende plus bas que les autres + bitmap = Bitmap.createBitmap(x_scaled_size, y_scaled_size+10, Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(bitmap); + + /*List linesOfText = cutText(20,text); + + bitmap = Bitmap.createBitmap((int)(textSize * 9), (int) 40*linesOfText.size(), Bitmap.Config.ARGB_8888); + + checkPaint(); + p.setTextSize(textSize); p.setColor(Color.BLACK); Canvas c = new Canvas(bitmap); - +*/ int index = 1; for(String line : linesOfText) { - c.drawText(line ,0,textSize*2*index,p); + c.drawText(line ,0,index*y_scaled_size/linesOfText.size(),p); index++; } - +/* float x_scaled_size = x_size* GameActivity.screenWidth/100; float y_scaled_size = y_size* GameActivity.screenHeight/100; - bitmap = Bitmap.createScaledBitmap(bitmap, (int)x_scaled_size, (int)y_scaled_size, GameActivity.bilinearFiltering); + bitmap = Bitmap.createScaledBitmap(bitmap, (int)x_scaled_size, (int)y_scaled_size, GameActivity.bilinearFiltering);*/ } + private String arrangeText(int charPerLines, String text) { + //TODO cut text in lines + StringBuilder nextLine = new StringBuilder(text); + int index = 0; + int size=0; + for (String word : text.split(" ")) { + if(word.length() < charPerLines) + { + if(word.length() + size +1 < charPerLines) + { + index +=word.length(); + size += word.length(); + }else{ + size=0; + nextLine.insert(index++,'\n'); + } + }else{ + Log.e("TextRender","ERROR WORD TOO LONG :" + word); + } + } + return nextLine.toString(); + } /** @@ -152,9 +192,10 @@ public class Drawable { * @param c canevas sur le quel dessiner * @param p pinceau */ - public void drawOn(Canvas c, Paint p) + public void drawOn(@NonNull Canvas c,@NonNull Paint p) { //drawings + if(c != null) c.drawBitmap(getBitmap(),x* GameActivity.screenWidth/100,y* GameActivity.screenHeight/100,p); } @@ -223,22 +264,61 @@ public class Drawable { { List output = new ArrayList<>(); //TODO cut text in lines - String nextLine = ""; + StringBuilder nextLine = new StringBuilder(charPerLines); for (String word : text.split(" ")) { if(word.length() < charPerLines) { - if(word.length() + nextLine.length() +1 < charPerLines) + if(word.length() + nextLine.toString().length() +1 < charPerLines) { - nextLine += " " + word; + nextLine.append(" " + word); }else{ - output.add(nextLine); - nextLine=""; + //fillWithSpace(nextLine,charPerLines); + output.add(nextLine.toString()); + nextLine.delete(0,charPerLines-1); } }else{ Log.e("TextRender","ERROR WORD TOO LONG :" + word); } } - if(!nextLine.equals(""))output.add(nextLine); + if(!nextLine.toString().equals("")) + { + //fillWithSpace(nextLine,charPerLines); + output.add(nextLine.toString()); + } return output; } + + private void fillWithSpace(StringBuilder nextLine, int charPerLines) { + for(int i=0 ; i < charPerLines-nextLine.length();i++) + { + nextLine.append(' '); + } + } + + /** + * https://stackoverflow.com/questions/12166476/android-canvas-drawtext-set-font-size-from-width + * @param paint + * @param desiredWidth + * @param text + */ + private static float getTextSizeForWidth(Paint paint, float desiredWidth, + String text) { + + // Pick a reasonably large value for the test. Larger values produce + // more accurate results, but may cause problems with hardware + // acceleration. But there are workarounds for that, too; refer to + // http://stackoverflow.com/questions/6253528/font-size-too-large-to-fit-in-cache + final float testTextSize = 48f; + + // Get the bounds of the text, using our testTextSize. + paint.setTextSize(testTextSize); + Rect bounds = new Rect(); + paint.getTextBounds(text, 0, text.length(), bounds); + + // Calculate the desired size as a proportion of our testTextSize. + float desiredTextWidth = testTextSize * desiredWidth / bounds.width(); + + // Set the paint for that size. + return desiredTextWidth; + } } diff --git a/app/src/main/java/com/iutlaval/myapplication/Video/DrawableCard.java b/app/src/main/java/com/iutlaval/myapplication/Video/DrawableCard.java index 119a0bc..feafcb3 100644 --- a/app/src/main/java/com/iutlaval/myapplication/Video/DrawableCard.java +++ b/app/src/main/java/com/iutlaval/myapplication/Video/DrawableCard.java @@ -16,8 +16,8 @@ public class DrawableCard extends Drawable{ private static final int CARD_WITH = 14; private static final int CARD_HEIGHT = 32; - private static final float HP_ATK_FONT_SIZE_BIG_CARD =10F; - private static final float HP_ATK_FONT_SIZE_BOARD =20F; + private static final float HP_ATK_FONT_SIZE_BIG_CARD =50F; + private static final float HP_ATK_FONT_SIZE_BOARD =80F; private String color; @@ -31,6 +31,10 @@ public class DrawableCard extends Drawable{ private Drawable cardHpDrawable; private Drawable cardAtkDrawable; + //DEPENDANCE CIRCULAIRE NE PAS CHANGER DE GC NON Tracing + //https://www.baeldung.com/java-gc-cyclic-references + private Card card; + /** * ce constructeur permet de crée un drawable simplifier pour les carte qui integre : * _le supoort de la description @@ -50,9 +54,11 @@ public class DrawableCard extends Drawable{ public DrawableCard(Card c, float x, float y, String name, Context context){ super(c.getFrameBitmap(context),x,y,name,CARD_WITH,CARD_HEIGHT); - onBoard=false; + card=c; - cardDescription = new Drawable(c.getDescription(),x+1F,y+CARD_HEIGHT/2,toString()+"description",CARD_WITH,CARD_HEIGHT/2,10F); + onBoard=true; + + cardDescription = new Drawable(c.getDescription(),x+CARD_WITH*0.07F,y+CARD_HEIGHT/2.2F,toString()+"description",CARD_WITH*0.8F,CARD_HEIGHT*0.35F,30F); updateHpAndAtk(c.getAttack(),c.getHealth()); color = c.getColor();//CARD_WITH+x @@ -77,18 +83,18 @@ public class DrawableCard extends Drawable{ cardOnBoardFrame.scaleRectangleToScreen(); int offset = CARD_HEIGHT/2 - CARD_HEIGHT/8; - Rectangle cardOnBoardHp = new Rectangle(x,offset,CARD_WITH/2,CARD_HEIGHT/8); - cardOnBoardHp.scaleRectangleToScreen(); - Rectangle cardOnBoardAtk = new Rectangle(CARD_WITH/2,offset,CARD_WITH/2,CARD_HEIGHT/8); + Rectangle cardOnBoardAtk = new Rectangle(x,offset,CARD_WITH/2,CARD_HEIGHT/8); cardOnBoardAtk.scaleRectangleToScreen(); + Rectangle cardOnBoardHp = new Rectangle(CARD_WITH/2,offset,CARD_WITH/2,CARD_HEIGHT/8); + cardOnBoardHp.scaleRectangleToScreen(); //creation de la bitmap qui va être rendu Bitmap cardOnBoardBitmap= Bitmap.createBitmap((int)cardOnBoardFrame.getWidth(),(int)cardOnBoardFrame.getHeight(), Bitmap.Config.ARGB_8888); //on dessine nos rectangle sur la bitmap cardOnBoardFrame.bitmapRectangleBuilder(cardOnBoardBitmap,Color.parseColor(removeAlpha(c.getColor()))); - cardOnBoardHp.bitmapRectangleBuilder(cardOnBoardBitmap,Color.parseColor("#FF00FF00")); cardOnBoardAtk.bitmapRectangleBuilder(cardOnBoardBitmap,Color.parseColor("#FFFF0000")); + cardOnBoardHp.bitmapRectangleBuilder(cardOnBoardBitmap,Color.parseColor("#FF00FF00")); cardOnBardDrawable = new Drawable(cardOnBoardBitmap,x,y,toString()+"BOARD",CARD_WITH,CARD_HEIGHT*2/3); @@ -110,9 +116,9 @@ public class DrawableCard extends Drawable{ cardHpDrawable = new Drawable(hp + " ", getX() + 2.4F + CARD_WITH / 2, getY() + CARD_HEIGHT/2, toString() + "hp", CARD_WITH / 2, CARD_HEIGHT / 8, HP_ATK_FONT_SIZE_BOARD); }else{ if (atk != null) - cardAtkDrawable = new Drawable(atk + " ", getX() + 0.6F, getY() + CARD_HEIGHT - 5F, toString() + "atk", CARD_WITH / 2, CARD_HEIGHT / 8, HP_ATK_FONT_SIZE_BIG_CARD); + cardAtkDrawable = new Drawable(atk + " ", getX() + 1F, getY() +CARD_HEIGHT-6F, toString() + "atk", CARD_WITH / 2, CARD_HEIGHT / 8, HP_ATK_FONT_SIZE_BIG_CARD); if (hp != null) - cardHpDrawable = new Drawable(hp + " ", getX() + 2.4F + CARD_WITH / 2, getY() + CARD_HEIGHT - 5F, toString() + "hp", CARD_WITH / 2, CARD_HEIGHT / 8, HP_ATK_FONT_SIZE_BIG_CARD); + cardHpDrawable = new Drawable(hp + " ", getX() + 2.8F + CARD_WITH / 2, getY() + CARD_HEIGHT - 6F, toString() + "hp", CARD_WITH / 2, CARD_HEIGHT / 8, HP_ATK_FONT_SIZE_BIG_CARD); } } @@ -166,9 +172,9 @@ public class DrawableCard extends Drawable{ super.setCoordinates(x, y); OpacityRectangleDrawable.setCoordinates(x, y); PictureDrawable.setCoordinates(x + 1.1F, y + 2.5F); - cardDescription.setCoordinates(x+CARD_WITH*0.1F,y+CARD_HEIGHT/2); - cardAtkDrawable.setCoordinates(x + 0.6F,y+CARD_HEIGHT-5F); - cardHpDrawable.setCoordinates(x+ 2.4F+CARD_WITH/2,y+CARD_HEIGHT-5F); + cardDescription.setCoordinates(x+CARD_WITH*0.07F,y+CARD_HEIGHT/2.2F); + cardAtkDrawable.setCoordinates(x + 1F,y+CARD_HEIGHT-6F); + cardHpDrawable.setCoordinates(x+ 3F+CARD_WITH/2,y+CARD_HEIGHT-6F); } } @@ -181,5 +187,6 @@ public class DrawableCard extends Drawable{ this.onBoard = onBoard; //force recalculate coodinates setCoordinates(getX(), getY()); + updateHpAndAtk(card.getAttack(),card.getHealth()); } } diff --git a/app/src/main/java/com/iutlaval/myapplication/Video/FpsTime.java b/app/src/main/java/com/iutlaval/myapplication/Video/FpsTime.java index 28d2a7f..637c7b1 100644 --- a/app/src/main/java/com/iutlaval/myapplication/Video/FpsTime.java +++ b/app/src/main/java/com/iutlaval/myapplication/Video/FpsTime.java @@ -18,6 +18,14 @@ public class FpsTime { /** * atten exactement la durée d'une image a l'ecran a la vitesse optimal de l'ecran */ + public static void waitFrameTime(long time){ + time = (System.nanoTime()-time)/1000; + if(time >= frametime)return; + try { + Thread.sleep((frametime-time)); + } catch (InterruptedException e) {} + } + public static void waitFrameTime(){ try { Thread.sleep((frametime)); diff --git a/app/src/main/java/com/iutlaval/myapplication/Video/Renderer.java b/app/src/main/java/com/iutlaval/myapplication/Video/Renderer.java index 25bb553..8209eca 100644 --- a/app/src/main/java/com/iutlaval/myapplication/Video/Renderer.java +++ b/app/src/main/java/com/iutlaval/myapplication/Video/Renderer.java @@ -10,6 +10,8 @@ import android.view.SurfaceView; import androidx.annotation.NonNull; +import com.iutlaval.myapplication.Game.GameLogicThread; + import java.util.ArrayList; import java.util.List; @@ -18,6 +20,7 @@ public class Renderer extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder holder; private Paint p; private DrawingThread drawingThread; + private GameLogicThread engine; private List toDraw; @@ -42,7 +45,14 @@ public class Renderer extends SurfaceView implements SurfaceHolder.Callback { */ @Override public void surfaceCreated(@NonNull SurfaceHolder holder) { - drawingThread.start(); + this.holder=holder; + if(drawingThread.getState() == Thread.State.TERMINATED) + { + drawingThread = new DrawingThread(); + } + if(!drawingThread.isAlive()){ + drawingThread.start(); + } } /** @@ -60,6 +70,8 @@ public class Renderer extends SurfaceView implements SurfaceHolder.Callback { /** * on surface destruction stop the thread + * la surface ce fait detruire aussi quand le jeu est en pause + * TODO kill proprement le thread et ajouter une relance sur le GameActivity * @param surfaceHolder */ @Override @@ -96,6 +108,8 @@ public class Renderer extends SurfaceView implements SurfaceHolder.Callback { while (keepDrawing) { Canvas canvas = null; + long time = System.nanoTime(); + try { // On récupère le canvas pour dessiner dessus canvas = holder.lockCanvas(); @@ -112,7 +126,8 @@ public class Renderer extends SurfaceView implements SurfaceHolder.Callback { //empecher d'aller plus vite que le taux de rafraichissement de l'ecran //sauve de la baterie - FpsTime.waitFrameTime(); + FpsTime.waitFrameTime(time); + if(engine != null && engine.isReady())engine.onFrameDoneRendering(); } } } @@ -188,4 +203,8 @@ public class Renderer extends SurfaceView implements SurfaceHolder.Callback { } return drawable; } + + public void setEngine(GameLogicThread engine) { + this.engine = engine; + } }