BIEN meilleur qualite de texte + patch fps

This commit is contained in:
mmarc471@gmail.com
2020-09-10 20:05:41 +02:00
parent c47e61438d
commit c368f10e9d
7 changed files with 195 additions and 63 deletions
@@ -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;
@@ -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()
}
@@ -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);
}
}
@@ -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<String> 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<String> 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<String> 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<String> 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;
}
}
@@ -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());
}
}
@@ -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));
@@ -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<Drawable> 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;
}
}