unity float and object error in android platform - android

i write this code and i don't know how to fix all error of this code but this code work correctly in pc mode but give error in android mode this is my code :
var background : Texture2D;
var splash : Texture2D;
var font : Font;
private var showADPresents = 3.0;
var size = null;
static var virtualScreen : Vector2 = Vector2(800, 600);
function Update()
{
showADPresents -= Time.deltaTime;
if (Application.CanStreamedLevelBeLoaded(1) && Input.anyKeyDown)
Application.LoadLevel(1);
}
function OnGUI()
{
GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3(Screen.width / virtualScreen.x, Screen.height / virtualScreen.y, 1));
GUI.DrawTexture(Rect(0, 0, virtualScreen.x, virtualScreen.y), splash);
if (showADPresents > 0)
{
var alpha = Mathf.Clamp01(showADPresents);
var color = Color.white;
color.a = alpha;
GUI.color = color;
GUI.DrawTexture(Rect(0, 0, virtualScreen.x, virtualScreen.y), background);
var presentsStyle = new GUIStyle(GUI.skin.label);
presentsStyle.font = font;
presentsStyle.fontSize = 48;
size = 300;
color = Color.black;
color.a = alpha;
GUI.color = color;
GUI.Label(Rect(( virtualScreen.x - size) * 0.5, (virtualScreen.y - size) * 0.5, size, size), "Autodesk Presents:", presentsStyle);
}
else
{
var notificationStyle = new GUIStyle(GUI.skin.label);
notificationStyle.font = font;
notificationStyle.fontSize = 16;
GUI.color = Color.black;
var content = null;
if (Application.CanStreamedLevelBeLoaded(1))
content = new GUIContent("Click Screen to Continue");
else
content = new GUIContent("Loading...");
size = notificationStyle.CalcSize(content);
GUI.Label(Rect((virtualScreen.x - size.x) * 0.5, virtualScreen.y - size.y - 80, size.x, size.y),
content, notificationStyle);
}
}
and unity give me this error i cant solve this error plz help to me help :'(
http://upload.ghashang.com/images/gm214joveg1z354rkli.jpg
plz Belief i cant solve this error plz help me
plz solve all error

This is because size is not a static type. It is dynamic, and because there is no operator for a object subtracted from a float, this error is thrown. You have two options. One, you can cast as a float before you subtract.
GUI.Label(Rect(( virtualScreen.x - (float)size) * 0.5, (virtualScreen.y - (float)size) * 0.5, size, size), "Autodesk Presents:", presentsStyle);
The other, is to declare size as a float or int in the declaration.
float size = 0.0f;
//or
int size = 0;
However, later you try to reference size as though it was a Rect, which causes other errors. I would a)declare size as a Rect b)access the respective members of size. Your code will look like:
Rect size;
...
//remove the size = 300; line and replace it with a constructor
GUI.Label(Rect(( virtualScreen.x - size.x) * 0.5, (virtualScreen.y - size.y) * 0.5, size, size), "Autodesk Presents:", presentsStyle);
This will solve your issue, and I recommend you read more about static classes

Related

How to fix this error "The non-nullable variable '_mediaQueryData' must be initialized. "

When I created my size config file I encountered this error. I am new to flutter and I was trying to build an E-commerce App. Even though I searched online I didn't find any solution to this problem.
import 'package:flutter/material.dart';
class SizeConfig {
static MediaQueryData _mediaQueryData;
static double screenWidth;
static double screenHeight;
static double defaultSize;
static Orientation orientation;
void init(BuildContext context) {
_mediaQueryData = MediaQuery.of(context);
screenWidth = _mediaQueryData.size.width;
screenHeight = _mediaQueryData.size.height;
orientation = _mediaQueryData.orientation;
}
}
// Get the proportionate height as per screen size
double getProportionateScreenHeight(double inputHeight) {
double screenHeight = SizeConfig.screenHeight;
// 812 is the layout height that designer use
return (inputHeight / 812.0) * screenHeight;
}
// Get the proportionate height as per screen size
double getProportionateScreenWidth(double inputWidth) {
double screenWidth = SizeConfig.screenWidth;
// 375 is the layout width that designer use
return (inputWidth / 375.0) * screenWidth;
}
You've been probably following tutorials from the past year where this was possible, but for now, you have to add "?" at the currently empty variables as "double screenWidth".
In Dart, all variables are non-nullable by default. We cannot assign a null value to a variable because it’ll throw a compilation error, that's why we use the "?" sign.
Also - Appending ! to any variable tells the compiler that the variable is not null, and can be used safely.
The solution you're looking for would probably go something like this:
import 'package:flutter/material.dart';
class SizeConfig {
static MediaQueryData? _mediaQueryData;
static double? screenWidth;
static double? screenHeight;
static double? defaultSize;
static Orientation? orientation;
void init(BuildContext context) {
_mediaQueryData = MediaQuery.of(context);
screenWidth = _mediaQueryData!.size.width;
screenHeight = _mediaQueryData!.size.height;
orientation = _mediaQueryData!.orientation;
defaultSize = orientation == Orientation.landscape
? screenHeight! * 0.024
: screenWidth! * 0.024;
}
}

Why is my TextField so small on the screen when targeting Android?

Read that the default size should be 12px. Is this something about DPI? How to solve?
EDIT
Thank you folks, but this doesn't seams to be something related to the font size. It looks like its something about handling DPI because it happens with simple Sprites too and weirdly the colors on Android seams to use an inversed RGB sequence 🤔
The Main.hx:
package;
import openfl.display.DisplayObjectContainer;
import openfl.display.Sprite;
import openfl.display.StageAlign;
import openfl.display.StageScaleMode;
import openfl.events.Event;
import openfl.system.Capabilities;
import openfl.text.TextField;
import ru.stablex.ui.UIBuilder;
class Main extends Sprite
{
private var size: Float = 100;
private var r: Sprite;
private var g: Sprite;
private var b: Sprite;
public function new()
{
super();
addEventListener(Event.ADDED_TO_STAGE, addedToStage, false, 0, true);
}
private function addedToStage(event: Event): Void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
r = createSquare(this, 0x00FF0000, size);
g = createSquare(this, 0x0000FF00, size);
b = createSquare(this, 0x000000FF, size);
stage.addEventListener(Event.RESIZE, resize, false, 0, true);
resize(null);
}
private function resize(event: Event): Void
{
r.x = 0;
r.y = 0;
g.x = (stage.stageWidth / 2) - (size / 2);
g.y = (stage.stageHeight / 2) - (size / 2);
b.x = stage.stageWidth - size;
b.y = stage.stageHeight - size;
}
private function createSquare(parent: DisplayObjectContainer, color: Int, size: Float): Sprite
{
var box: Sprite = new Sprite();
box.graphics.beginFill(color);
box.graphics.drawRect(0, 0, size, size);
box.graphics.endFill();
parent.addChild(box);
return box;
}
}
You can use sp size unit, which always seems the same size on different dpi screens.
Please try this.
text.autoSize = "center";
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/TextFieldAutoSize.html
You can size Sprite size to 100%.
Auto size text field with Actionscript 3 -- This link can help you.

Converting inputFrame from Camera to HSI using OpenCV in Android

I want to convert an image from Android camera to HSI format using OpenCV.
The problem is when I use the following method
private Mat rgb2hsi(Mat rgbFrame) {
Mat hsiFrame = rgbFrame.clone();
for( int i = 0; i < rgbFrame.rows(); ++i ) {
for( int j = 0; j < rgbFrame.cols(); ++j ) {
double[] rgb = rgbFrame.get(i, j);
Log.d(MAINTAG, "rgbFrame.get(i, j) array size = " + rgb.length);
double colorR = rgb[0];
double colorG = rgb[1];
double colorB = rgb[2];
double minRGB = min(colorR, colorG, colorB);
double colorI = (colorR + colorG + colorB) / 3;
double colorS = 0.0;
if(colorI > 0) colorS = 1.0 - (minRGB / colorI);
double colorH;
double const1 = colorR - (colorG / 2) - (colorB / 2);
double const2 = Math.sqrt(Math.pow(colorR, 2) + Math.pow(colorG, 2) + Math.pow(colorR, 2)
- (colorR * colorG) - (colorR * colorB) - (colorG * colorB));
colorH = Math.acos(const1 / const2);
if(colorB > colorG) colorH = 360 - colorH;
double[] hsi = {colorH, colorS, colorI};
hsiFrame.put(i, j, hsi);
}
}
return hsiFrame;
}
It shows an error
java.lang.UnsupportedOperationException: Provided data element number (3) should be multiple of the Mat channels count (4)
I search for a while to figure out the cause of this error.
I found that I put an array of size 3 instead of 4.
Android convert byte array from Camera API to color Mat object openCV
I wonder what Type of image receive from Android Camera.
Why when I get an array of size 4?
How to convert an image received from Android camera to HSI and preview on the screen?
The following is the overrided method onCameraFrame
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
Mat outputFrame = inputFrame.rgba();
/* Get RGB color from the pixel at [index_row, index_column] */
int index_row = 0;
int index_column = 0;
final double[] mRgb_pixel = outputFrame.get(index_row, index_column);
/* Show the result */
runOnUiThread(new Runnable() {
#Override
public void run() {
int r = (int) mRgb_pixel[0];
int g = (int) mRgb_pixel[1];
int b = (int) mRgb_pixel[2];
/* Set RGB color */
mRred_textview.setText("Red\n" + Double.toString(mRgb_pixel[0]));
mGreen_textview.setText("Green\n" + Double.toString(mRgb_pixel[1]));
mBlue_textview.setText("Blue\n" + Double.toString(mRgb_pixel[2]));
mColor_textview.setBackgroundColor(Color.rgb(r, g, b));
}
});
if(mPreviewType == PreviewType.GB) {
outputFrame.convertTo(outputFrame, CvType.CV_64FC3);
return getGBColor(rgb2hsi(outputFrame));
} else if (mPreviewType == PreviewType.HSI) {
outputFrame.convertTo(outputFrame, CvType.CV_64FC3);
return rgb2hsi(outputFrame);
} else {
return outputFrame;
}
}
My MainActivity implements CameraBridgeViewBase.CvCameraViewListener2
[Edit]
I think that the reason why it return an array of size 4 is because the frame is in RGBA format, not RGB format.
Therefore, how to convert RGBA to HSI and preview the frame on the screen?
The problem here is that your hsiFrame is a 4 channel image and your hsi array has only 3 values. You need to add one term corresponding to alpha channel to your hsi array. Making either of the following changes should work for you:
1. double[] hsi = {colorH, colorS, colorI, rgb[3]};
2. Mat hsiFrame = new Mat(rgbFrame.size(), CvType.CV_8UC3);
Hope this helps.

libgdx pixel issues between desktop and android projects

UPDATE Looks like this is a problem because of the static notification bar on tablet because of the lack of hardware buttons. I just didn't think about that. Anyway, in the case of the TF101 it returns a resolution of 1280x752 so about 1.702 (80 : 47) ratio. If I use a suitable unit size, like 33.5 or 11.75 vertically I get the proper scaling and this seems to fix the problem of skewed pixels.
END UPDATE
I've been setting up a game using 16x16 units for my tiled maps. I am using the resolution 1280x800 on both my desktop and android projects, I'm testing this to get a sense of how it will look on my TF101 asus tablet. I currently use a camera with units of 20x12.5 (wxh) and notice no pixel scaling on my desktop project, but when I run the game on my android I get weird scaling, and a green horizontal line. I can also move about quarter cell further along the x-axis on the tablet, shown in the screen shots. The pixels on the android project don't seem uniform at all.
I set the verticalTiles amount to 12.5f, then calculate the horizontalTiles amount as
verticalTiles = 12.5f;
...
horizontalTiles = (float) width / (float) height * verticalTiles;
camera = new OrthographicCamera(horizontalTiles, verticalTiles);
I'm aiming for devices with different aspect ratios to simply see more or less of the map, but can't seem to get working correctly. Any help would be appreciated.
Android Capture - http://imageshack.us/f/7/dsvg.png/ - notice the highlights on the roof edges, they are not uniform at all.
Desktop Capture - http://imageshack.us/f/853/5itv.png/
Current MainGame class
package com.bitknight.bqex;
/* Bunch of imports */
public class MainGame implements ApplicationListener {
private OrthographicCamera camera;
private SpriteBatch spriteBatch;
private TiledMap map;
private OrthogonalTiledMapRenderer mapRenderer;
private Texture texture;
private Texture clothArmor;
private Sprite sprite;
private BitmapFont font;
private float horizontalTiles = 0;
private float verticalTiles = 12.5f;
private int hoverTileX = 0;
private int hoverTileY = 0;
private TiledMapTileLayer layer;
private Cell cell;
private TiledMapTile canMoveToTile;
private TiledMapTile cannotMoveToTile;
private AnimatedTiledMapTile animatedStopTile;
private AnimatedTiledMapTile animatedGoTile;
private Texture spriteSheet;
private TextureRegion region;
private Player player;
float h, w;
float ppuX, ppuY;
#Override
public void create() {
// Setup the animated tiles
Array<StaticTiledMapTile> tileArray;
// Start position on the sheet
int startX = 192;
int startY = 1568;
spriteSheet = new Texture(Gdx.files.internal("data/maps/tilesheet.png"));
spriteSheet.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
// We are trying to load two strips of 4 frames, 8 total
for( int i = 0; i < 2; ++i ) {
tileArray = new Array<StaticTiledMapTile>(4);
for( int j = 0; j < 4; ++j ) {
region = new TextureRegion(spriteSheet, startX, startY, 16, 16);
tileArray.add(new StaticTiledMapTile(region));
startX += 16;
}
if( i == 0 ) {
animatedStopTile = new AnimatedTiledMapTile(1/10f, tileArray);
} else {
animatedGoTile = new AnimatedTiledMapTile(1/10f, tileArray);
}
}
// Load the map
map = new TmxMapLoader().load("data/maps/base.tmx");
// Setup the two tiles that show movable and not movable sprites
canMoveToTile = map.getTileSets().getTileSet(0).getTile(1959);
canMoveToTile.setBlendMode(BlendMode.ALPHA);
cannotMoveToTile = map.getTileSets().getTileSet(0).getTile(1958);
cannotMoveToTile.setBlendMode(BlendMode.ALPHA);
// Manually create the layer used to show the cursor sprites
layer = new TiledMapTileLayer(100, 100, 16, 16);
layer.setName("display");
cell = new Cell();
cell.setTile(canMoveToTile);
layer.setOpacity(1f);
mapRenderer = new OrthogonalTiledMapRenderer(map, 1/16f);
spriteBatch = new SpriteBatch();
font = new BitmapFont(Gdx.files.internal("data/consolas.fnt"), false);
font.setScale(0.6f);
texture = new Texture(Gdx.files.internal("data/maps/tilesheet.png"));
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
clothArmor = new Texture(Gdx.files.internal("data/img/native/clotharmor.png"));
region = new TextureRegion(clothArmor, 32, 256, 32, 32);
sprite = new Sprite(region);
sprite.setOrigin(0.5f, 0.5f);
sprite.setPosition(0f - 0.5f, 0f);
sprite.setSize(2, 2);
// Setup player and associated animations
Array<TextureRegion> regions = new Array<TextureRegion>();
player = new Player();
}
#Override
public void dispose() {
spriteBatch.dispose();
texture.dispose();
clothArmor.dispose();
spriteSheet.dispose();
}
#Override
public void render() {
player.update(Gdx.graphics.getDeltaTime());
camera.update();
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if( Gdx.input.isKeyPressed(Input.Keys.ESCAPE) ) {
Gdx.app.exit();
}
// Clear the last cell
layer.setCell(hoverTileX, hoverTileY, null);
// Convert screen coordinates to world coordinates
Vector3 worldCoordinates = new Vector3(Gdx.input.getX(0), Gdx.input.getY(0), 0);
camera.unproject(worldCoordinates);
hoverTileX = (int)(worldCoordinates.x);
hoverTileY = (int)(worldCoordinates.y);
TiledMapTileLayer layer = (TiledMapTileLayer)map.getLayers().get("collision");
if( Gdx.input.isTouched(0) ) {
//sprite.setPosition(hoverTileX - 0.5f, hoverTileY);
player.pos.x = hoverTileX - 0.5f;
player.pos.y = hoverTileY - 0.25f;
cell.setTile(animatedGoTile);
} else {
if (layer.getCell(hoverTileX, hoverTileY) != null) {
cell.setTile(cannotMoveToTile);
} else {
cell.setTile(canMoveToTile);
}
}
layer.setCell(hoverTileX, hoverTileY, cell);
mapRenderer.setView(camera);
mapRenderer.render();
mapRenderer.getSpriteBatch().begin();
mapRenderer.renderTileLayer(layer);
mapRenderer.getSpriteBatch().end();
spriteBatch.setProjectionMatrix(camera.combined);
spriteBatch.begin();
player.render(spriteBatch);
spriteBatch.end();
}
#Override
public void resize(int width, int height) {
horizontalTiles = (float) width / (float) height * verticalTiles;
camera = new OrthographicCamera(horizontalTiles, verticalTiles);
w = width;
h = height;
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
Looks like this is a problem because of the static notification bar on tablet because of the lack of hardware buttons. I just didn't think about that. Anyway, in the case of the TF101 it returns a resolution of 1280x752 so about 1.702 (80 : 47) ratio. If I use a suitable unit size, like 33.5 or 11.75 vertically I get the proper scaling and this seems to fix the problem of skewed pixels.
Also, while this is good for the TF101 tablet in my case it's not really a great solution. Here is a Gemserk series that talks about a nice solution.
http://blog.gemserk.com/2013/01/22/our-solution-to-handle-multiple-screen-sizes-in-android-part-one/

How to get programmatically a list of colors from a gradient on Android

in Android I would like to draw a PieChart with a dynamically number of pies. Each pie should have a different color from a gradient.
For example I would like to have a gradient from light brown to dark brown. If I need to draw five pies, I need five volors from the start to the end of this gradient.
How can I do that in Java with the Android framework?
I found out that I can create a LinearGradient for a line, i.e.:
LinearGradient lg = new LinearGradient(1, 1, 5, 5, toRGB("lightbrown"), toRGB("darkbrown"), TileMode.REPEAT);
But I did not found any function to get a color from this line, i.e.:
// for the five needed RGB colors from the gradient line
lg.getRGBColor(1, 1);
lg.getRGBColor(2, 2);
lg.getRGBColor(3, 3);
lg.getRGBColor(4, 4);
lg.getRGBColor(5, 5);
Do you have any ideas how I can get this?
Thanks!
You cannot get these values directly from the LinearGradient. The gradient doesn't contain the actual drawing. To get these values, you can paint them to a canvas and pull the colors out of the canvas, or what I'd suggest would be to calculate the values yourself.
It's a repeating linear gradient in five steps and you have the RGB values for the first and last color. The rest is just math. Here's the pseudo code:
int r1 = startColor.red;
int g1 = startColor.green;
int b1 = startColor.blue;
int r2 = endColor.red;
int g2 = endColor.green;
int b2 = endColor.blue;
int redStep = r2 - r1 / 4;
int greenStep = g2 - g1 / 4;
int blueStep = b2 - b1 / 4;
firstColor = new Color(r1, g1, b1);
secondColor = new Color(r1 + redStep, g1 + greenStep, b1 + blueStep);
thirdColor = new Color(r1 + redStep * 2, g1 + greenStep * 2, b1 + blueStep * 2);
fourthColor = new Color(r1 + redStep * 3, g1 + greenStep * 3, b1 + blueStep * 3);
fifthColor = new Color(r1 + redStep * 4, g1 + greenStep * 4, b1 + blueStep * 4);
Another approach that is a little more reusable (I seem to bump into this problem all the time). It's a bit more code. Here is the usage:
int[] colors = {toRGB("lightbrown"), toRGB("darkbrown")};//assuming toRGB : String -> Int
float[] positions = {1, 5};
getColorFromGradient( colors, positions, 1 )
//...
getColorFromGradient( colors, positions, 5 )
Supporting functions
public static int getColorFromGradient(int[] colors, float[] positions, float v ){
if( colors.length == 0 || colors.length != positions.length ){
throw new IllegalArgumentException();
}
if( colors.length == 1 ){
return colors[0];
}
if( v <= positions[0]) {
return colors[0];
}
if( v >= positions[positions.length-1]) {
return colors[positions.length-1];
}
for( int i = 1; i < positions.length; ++i ){
if( v <= positions[i] ){
float t = (v - positions[i-1]) / (positions[i] - positions[i-1]);
return lerpColor(colors[i-1], colors[i], t);
}
}
//should never make it here
throw new RuntimeException();
}
public static int lerpColor( int colorA, int colorB, float t){
int alpha = (int)Math.floor(Color.alpha(colorA) * ( 1 - t ) + Color.alpha(colorB) * t);
int red = (int)Math.floor(Color.red(colorA) * ( 1 - t ) + Color.red(colorB) * t);
int green = (int)Math.floor(Color.green(colorA) * ( 1 - t ) + Color.green(colorB) * t);
int blue = (int)Math.floor(Color.blue(colorA) * ( 1 - t ) + Color.blue(colorB) * t);
return Color.argb(alpha, red, green, blue);
}
I have wrote the util class for calculate colors gradient.
via very, very simple Kotlin code:
val pink = Colar(245, 9, 253)
val lime = Colar(0, 253, 32)
lp_1.colors = (pink toColor lime).run {
gradient { 0 upTo 3 }
}
lp_2.colors = (pink toColor lime).run {
gradient { 0 upTo 9 }
}
lp_3.colors = (pink toColor lime).run {
gradient { 3 upTo 9}
}
Supporting util class
class StepGradientUtil(private var colar1: Colar?, private var colar2: Colar?) {
private var mSteps: Int = 0
infix fun StepGradientUtil.gradient(f: () -> IntRange): IntArray {
val result = f.invoke().map {
it.colorStep()
}.toIntArray()
recycler()
return result
}
infix fun Int.upTo(steps: Int): IntRange {
mSteps = steps
return (this until steps)
}
private fun recycler() {
mSteps = 0
colar1 = null
colar2 = null
}
private fun Int.colorStep() = Color.rgb(
(colar1!!.r * (mSteps - this) + colar2!!.r * this) / mSteps,
(colar1!!.g * (mSteps - this) + colar2!!.g * this) / mSteps,
(colar1!!.b * (mSteps - this) + colar2!!.b * this) / mSteps
)
}
data class Colar(
val r: Int,
val g: Int,
val b: Int
)
infix fun Colar.toColor(colar: Colar) = StepGradientUtil(colar1 = this, colar2 = colar)
See full source code sample on repo

Categories

Resources