I was searching through the Unity manual to see what they had for gradient effects and I found this:
Here is the link:
http://docs.unity3d.com/Manual/EditingValueProperties.html
However, I can't find this editor anywhere inside of Unity. I want to use this to apply a gradient to my background for a game. Does it exist!?
You do not have access to arbitrarily use color picker or gradient editor. For your purpose of making the background you have several options,
Change the Camera background color from the editor.
Use a Skybox, you can make your own skybox too.
If your game has a limited view, use a plane with a custom material.
Maybe this script shows how you can use Gradients. You need to add this script to one of your GameObject in your scene. And your Camera's tag is MainCamera .
This code based on this.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GradientHandler : MonoBehaviour {
public Camera camera;
public Gradient gradient;
// Use this for initialization
void Start () {
camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>() as Camera; //Gets Camera script from MainCamera object(Object's tag is MainCamera).
GradientColorKey[] colorKey = new GradientColorKey[2];
GradientAlphaKey[] alphaKey = new GradientAlphaKey[2];
// Populate the color keys at the relative time 0 and 1 (0 and 100%)
colorKey[0].color = Color.red;
colorKey[0].time = 0.0f;
colorKey[1].color = Color.blue;
colorKey[1].time = 1.0f;
// Populate the alpha keys at relative time 0 and 1 (0 and 100%)
alphaKey[0].alpha = 1.0f;
alphaKey[0].time = 0.0f;
alphaKey[1].alpha = 0.0f;
alphaKey[1].time = 1.0f;
gradient.SetKeys(colorKey, alphaKey);
}
// Update is called once per frame
void Update () {
Debug.Log ("Time: "+Time.deltaTime);
camera.backgroundColor = gradient.Evaluate(Time.time%1);
}
}
Related
When I was creating my first tiled map creator in libGDX, I noticed a very strange bug. I creating grid of objects like this:
private static final int GRID_WIDTH=2400;
private static final int GRID_HEIGHT=2400;
private static final int CELL_SIZE=60;
so you can see there are 2400/60x2400/60 objects or cells. I am creating my map like this:
private void createMap(){
cells = new Cell[GRID_WIDTH/CELL_SIZE][GRID_HEIGHT/CELL_SIZE];
for(int i=0;i<GRID_WIDTH/CELL_SIZE;++i){
for(int j=0;j<GRID_HEIGHT/CELL_SIZE;++j){
cells[i][j]=new Cell(textures[0],i*CELL_SIZE,j*CELL_SIZE);
}
}
}
I also have coordinates for my debug in the screen so I know where they started to disappear. Y coordinate is ok there are from 0 to 2400, but on the X they started to disappear at 1500. When I start to draw there some texture every column will be visible to that texture for example (when I start to write texture at x=2100 every disappeared column will be visible to 2100) and when I will delete that texture every column will disappear again to 1500. So the objects are there but they are not visible. It is so annoying does anyone know about this bug?
As you can see coordinates are at the bottom left this is at the beginning:
and this is when I will add there some texture
[Edited] Code with camera:
private float x=GRID_WIDTH/2,y=GRID_HEIGHT/2;
#Override
public void render(float delta) {
batch = new SpriteBatch();
camera=new OrthographicCamera(CAM_WIDTH,CAM_HEIGHT);
viewPos = new Vector3();
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
viewPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(viewPos);
batch.begin();
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT) || Gdx.input.isKeyPressed(Input.Keys.D))
x+=SPEED*Gdx.graphics.getDeltaTime();
if(Gdx.input.isKeyPressed(Input.Keys.LEFT) || Gdx.input.isKeyPressed(Input.Keys.A))
x-=SPEED*Gdx.graphics.getDeltaTime();
if(Gdx.input.isKeyPressed(Input.Keys.UP) || Gdx.input.isKeyPressed(Input.Keys.W))
y+=SPEED*Gdx.graphics.getDeltaTime();
if(Gdx.input.isKeyPressed(Input.Keys.DOWN) || Gdx.input.isKeyPressed(Input.Keys.S))
y-=SPEED*Gdx.graphics.getDeltaTime();
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
camera.position.set(x,y,0);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.end();
}
The camera is correct. The problem is the batch.begin() and batch.end(). As you might know you cannot do batch.begin() and then shaperenderer.begin() directly after each others without closing one of them. Reason for this I am not 100% about. stage works similar. This means we have to close the batch before drawing the stage
batch.end();
stage.draw();
batch.begin();
// draw your batch stuff here
Also it's terrible to do this
batch = new SpriteBatch();
camera=new OrthographicCamera(CAM_WIDTH,CAM_HEIGHT);
inside the render method. Instead, put it into the create() method or some of your own initialize method. The important thing is to not create a new SpriteBatch every frame as the batch isn't collected by the GC. So you have to manually dispose it using batch.dispose() or it will leak so much memory your RAM will be gone in no time.
I hope this helped you out, good luck.
My ImageView is matching screen size on x-axis and is using remaining space on y-axis in my layout. I want to create bitmap into this ImageView with exactly the same size as the ImageView is. How to make it please? Can it be done by some automatic setting, should I call some measure function?
I tried SetAdjustViewBounds() but it didn't work for me.
Creating Bitmap big enough (I don't like much such a memory wasting) and setting SetScaleType(ImageView.ScaleType.Matrix) works, but still when I'm making drawing operations on canvas, I don't know real size of area I should paint into, both canvas and bitmap height are equal to yScreen while imgWeekView height is pretending to be 0, even though it paints whole desired area with gray color.
imgWeekView = new ImageView(context);
//imgWeekView.SetAdjustViewBounds(true);
imgWeekView.SetScaleType(ImageView.ScaleType.Matrix);
layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MatchParent, LinearLayout.LayoutParams.WrapContent,1f);
layoutParams.Height = 0;
imgWeekView.LayoutParameters = layoutParams;
Bitmap bitmap = Bitmap.CreateBitmap((int)xScreen, (int)yScreen, Bitmap.Config.Argb8888);
cnvWeekView = new Canvas(bitmap);
imgWeekView.SetImageBitmap(bitmap);
linearLayout.AddView(imgWeekView); //whole activity layout
//Test
cnvWeekView.DrawColor(new Color(128, 128, 128));
Paint paint = new Paint(PaintFlags.AntiAlias);
paint.Color = new Color(255, 255,0);
cnvWeekView.DrawCircle(50, 50, 40, paint);
Finally I found a way how to measure my ImageView and here I will post my answer.
I believed that there should be much easier solution, but maybe there isn't. From this question I took most of the important data:
How to get the width and height of an android.widget.ImageView?
Things look however a little different in my android application and I'm not experienced enough to tell why. I had to change things a little. I had to learn a bit about interfaces and this question helped too.
Implementing the View.IOnTouchListener interface
Here is how I combined things. First I created class that will do the measure.
public class MyPredrawListener : Java.Lang.Object, ViewTreeObserver.IOnPreDrawListener
{
ImageView imageView;
public MyPredrawListener(ImageView img)
{
imageView = img;
}
public bool OnPreDraw()
{
imageView.ViewTreeObserver.RemoveOnPreDrawListener(this);
int finalHeight = imageView.MeasuredHeight;
int finalWidth = imageView.MeasuredWidth;
Bitmap bitmap = Bitmap.CreateBitmap(finalWidth, finalHeight, Bitmap.Config.Argb8888);
imageView.SetImageBitmap(bitmap);
//Test to see result
Canvas cnv = new Canvas(bitmap);
Paint paint = new Paint();
paint.Color = new Color(255, 255, 0);
cnv.DrawColor(new Color(128, 128, 128));
cnv.DrawCircle(finalWidth-50, finalHeight-50, 50, paint);
return true;
}
}
And in code where I create my imageView I set the listener like this.
imgWeekView = new ImageView(context);
MyPredrawListener listener=new MyPredrawListener(imgWeekView);
imgWeekView.ViewTreeObserver.AddOnPreDrawListener(listener);
In OnPreDraw function I put test code to see the result graphically, clearing bitmap to gray color and painting yellow circle to bottom right of a view.
I would like when i create all my sprites to get centred in the screen, but that is not the case, i have a sprite when i set it's position to CGPointMake(self.size.width / 2, self.size.height / 2) it gets centred vertically but not horizontally, when i set it to CGPointMake(0, 0) it sets at the bottom of the screen with only half of it's body visible ( which is what you expect) but horizontally it doesn't get positioned right ( half his vertical body appears ) until i set it's X to 300.
How come the sprite's Y position gets set right but the X doesn't ?
scene.scaleMode = .AspectFill
and i haven't set any anchorPoint, 4' screen.
UPDATE:
I'm using Portrait, played around with different scaleMode and found out that the perfect (0, 0) that sets the sprite on the bottom left is:
scene.scaleMode = .ResizeFill
It also works fine with different screen sizes,but (self.size.width / 2) puts it further to the left.Do you think it's the best setting for all SpriteKit Portrait projects?
I tried to reproduce what you are saying, but I couldn't, either using .sks file or not for loading the scene. Also I've produced good results on both 7.1 and 8.1 simulators...The thing is that simulators sometimes could be tricky and not 100% reliable, so you should not trust them much.
I don't know if this will help you, but you should consider it...In Xcode 5 projects scene is programmatically created to have a size of the view. Basically it's done in viewDidLoad method like this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
// Create and configure the scene.
GameScene * scene = [GameScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:scene];
}
Or using viewWillLayoutSubviews like LearnCocos2D pointed:
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
skView.showsDrawCount = YES;
//skView.showsQuadCount = YES;
skView.showsPhysics = YES;
skView.ignoresSiblingOrder = YES;
if(!skView.scene){
// Create and configure the scene.
GameScene * scene = [GameScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:scene];
}
}
But Xcode 6 uses an SKS file:
override func viewDidLoad() {
super.viewDidLoad()
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
// Configure the view.
let skView = self.view as SKView
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
/* Set the scale mode to scale to fit the window */
scene.scaleMode = .AspectFill
}
}
If you look at the GameScene.sks you can see that the default scene size is 1024x768.
Try to print your scene size as well as view's bounds size to see actuall sizes. You can use something like:
println("view.bounds\(view.bounds), self.size\(self.size)")
I don't know if any of this helped, but I hope it will lead you somewhere. Goodluck!
Is there any way to make fullscreen(and if possible resizing too) to instead of rearranging everything (actually what it does is to rearrange the elements like resizing but to the whole screen) to make an actual fullscreen mode? (like games that what usually do is change screen resolution), so that buttons and text grows accordingly to the size of the screen/window
Also how can I remove the message and the effect on click the "esc" key to exit the fullscreen mode?
EDIT: use this way to make resizeable
#Override public void start(Stage stage) throws Exception{
final int initWidth = 720; //initial width
final int initHeight = 1080; //initial height
final Pane root = new Pane(); //necessary evil
Pane controller = new CtrlMainMenu(); //initial view
controller.setPrefWidth(initWidth); //if not initialized
controller.setPrefHeight(initHeight); //if not initialized
root.getChildren().add(controller); //necessary evil
Scale scale = new Scale(1, 1, 0, 0);
scale.xProperty().bind(root.widthProperty().divide(initWidth)); //must match with the one in the controller
scale.yProperty().bind(root.heightProperty().divide(initHeight)); //must match with the one in the controller
root.getTransforms().add(scale);
final Scene scene = new Scene(root, initWidth, initHeight);
stage.setScene(scene);
stage.setResizable(true);
stage.show();
//add listener for the use of scene.setRoot()
scene.rootProperty().addListener(new ChangeListener<Parent>(){
#Override public void changed(ObservableValue<? extends Parent> arg0, Parent oldValue, Parent newValue){
scene.rootProperty().removeListener(this);
scene.setRoot(root);
((Region)newValue).setPrefWidth(initWidth); //make sure is a Region!
((Region)newValue).setPrefHeight(initHeight); //make sure is a Region!
root.getChildren().clear();
root.getChildren().add(newValue);
scene.rootProperty().addListener(this);
}
});
}
There are a couple of ways to resize your UI.
Scale by Font Size
You can scale all controls by setting -fx-font-size in the .root of your scene's style sheet.
For example, if you apply the following stylesheet to your scene, then all controls will be doubled in size (because the default font size is 13px).
.root {
-fx-font-size: 26px;
}
The above will work to scale controls, which is fine for things which are completely control based, but not so good for things which are graphic and shape based.
Scale by Transform
Apply a Scale transform pivoted at (0,0) to your scene's root node.
Scale scale = new Scale(scaleFactor, scaleFactor);
scale.setPivotX(0);
scale.setPivotY(0);
scene.getRoot().getTransforms().setAll(scale);
To scale a game I developed which includes graphics and various shapes, I used a letter boxing technique which sized the game window to a constant aspect ratio, (similar to the letter boxing you see when you watch a 4:3 tv show on a 16:9 screen).
The SceneSizeChangeListener in the code below listens for changes to the scene size and scales the content of the scene appropriate to the available scene size.
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.transform.Scale;
import javafx.stage.Stage;
import org.jewelsea.games.supersnake.layout.LayoutController;
import java.io.IOException;
import java.util.ResourceBundle;
/* Main JavaFX application class */
public class SuperSnake extends Application {
public static void main(String[] args) { launch(args); }
#Override public void start(final Stage stage) throws IOException {
FXMLLoader loader = new FXMLLoader(
getClass().getResource("layout/layout.fxml"),
ResourceBundle.getBundle("org.jewelsea.games.supersnake.layout.text")
);
Pane root = (Pane) loader.load();
GameManager.instance().setLayoutController(loader.<LayoutController>getController());
Scene scene = new Scene(new Group(root));
stage.setScene(scene);
stage.show();
GameManager.instance().showMenu();
letterbox(scene, root);
stage.setFullScreen(true);
}
private void letterbox(final Scene scene, final Pane contentPane) {
final double initWidth = scene.getWidth();
final double initHeight = scene.getHeight();
final double ratio = initWidth / initHeight;
SceneSizeChangeListener sizeListener = new SceneSizeChangeListener(scene, ratio, initHeight, initWidth, contentPane);
scene.widthProperty().addListener(sizeListener);
scene.heightProperty().addListener(sizeListener);
}
private static class SceneSizeChangeListener implements ChangeListener<Number> {
private final Scene scene;
private final double ratio;
private final double initHeight;
private final double initWidth;
private final Pane contentPane;
public SceneSizeChangeListener(Scene scene, double ratio, double initHeight, double initWidth, Pane contentPane) {
this.scene = scene;
this.ratio = ratio;
this.initHeight = initHeight;
this.initWidth = initWidth;
this.contentPane = contentPane;
}
#Override
public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, Number newValue) {
final double newWidth = scene.getWidth();
final double newHeight = scene.getHeight();
double scaleFactor =
newWidth / newHeight > ratio
? newHeight / initHeight
: newWidth / initWidth;
if (scaleFactor >= 1) {
Scale scale = new Scale(scaleFactor, scaleFactor);
scale.setPivotX(0);
scale.setPivotY(0);
scene.getRoot().getTransforms().setAll(scale);
contentPane.setPrefWidth (newWidth / scaleFactor);
contentPane.setPrefHeight(newHeight / scaleFactor);
} else {
contentPane.setPrefWidth (Math.max(initWidth, newWidth));
contentPane.setPrefHeight(Math.max(initHeight, newHeight));
}
}
}
}
Here is a screenshot where you can see the letterboxing and scaling taking effect. The green grass in the middle is the main game content screen and scales up and down to fit the available screen area. The wood texture around the outside provides a flexibly sized border which fills in the area where the black letterbox bars would normally be if you were watching a tv program at a different aspect ratio to your screen. Note that the background in the screenshot below is blurry at the title page because I make it so, when the game starts, the blur effect is removed and the view is crisp regardless of the size.
Windowed version:
Scaled full screen version:
You might think that the scaling method above might make everything go all blocky and pixelated, but it doesn't. All font's and controls scale smoothly. All standard drawing and graphic commands and css based styles scale smoothly as they are all vector based. Even bitmapped images scale well because JavaFX uses fairly high quality filters when scaling the images.
One trick to get good scaling on images is to provide high resolution images, so that when the screen scales up, the JavaFX system has more raw data to work from. For example, if the preferred window size for an app is quarter of the screen size and it contains a 64x64 icon, instead use a 128x128 icon, so that when the app is put in full screen and all elements scaled, the scaler has more raw pixel data samples to use for interpolating values.
The scaling is also fast as it is hardware accelerated.
how can I remove the message and the effect on click the "esc" key to exit the fullscreen mode?
It's not possible to remove the full screen exit message in JavaFX 2.2, it will be possible in JavaFX 8:
RT-15314 Allow trusted apps to disable the fullscreen overlay warning and disable the "Exit on ESC" behavior
It will be nice when that is done, because then my games won't have that "look at me - I look like a beta" feel about them.
"Also how can I remove the message and the effect on click the "esc" key to exit the fullscreen mode?"
Use this code :
stage.setFullScreenExitHint("");
It will change the string message "Press Esc to quit Fullscreen mode" into empty string so it will not show up.
You may copy this into JavaFXApplication
Dimension resolution = Toolkit.getDefaultToolkit().getScreenSize();
double width = resolution.getWidth();
double height = resolution.getHeight();
double w = width/1280; // your window width
double h = height/720; // your window height
Scale scale = new Scale(w, h, 0, 0);
root.getTransforms().add(scale);
I have prepared a screen in which I am allowing user to create an account. as shown in the first image I have used an image(bg_BB.png image) as MainScreen Background, after that i have taken another VFM and painting that white Background (white_bg2.png)on that vertical field manager and ADDING ALL MY FIELD ON THAT VFM.
But the problem arises when the keyboard is pops-up. All the fields apears to be floating over the background as shown in the second pic.
Below is the code which I am using:
Bitmap backGroundImage = Bitmap.getBitmapResource("bg_BB.png");
((VerticalFieldManager) getMainManager()).setBackground(BackgroundFactory.createBitmapBackground(backGroundImage));
final Bitmap tabBackGroundImage = Bitmap.getBitmapResource("white_bg2.png");
_mainVfm = new VerticalFieldManager(Field.USE_ALL_WIDTH) {
protected void paint(Graphics graphics) {
int y = CreateUserAccountScreen.this.getMainManager().getVerticalScroll();
graphics.drawBitmap(0, y,
tabBackGroundImage.getWidth(),
tabBackGroundImage.getHeight(),
tabBackGroundImage,
0, 0 );
super.paint( graphics );
}
};
replace your code with:
Bitmap tabBackGroundImage = Bitmap.getBitmapResource("white_bg2.png");
VerticalFieldManager _mainVfm = new VerticalFieldManager(Manager.VERTICAL_SCROLL |
Manager.VERTICAL_SCROLLBAR|
Manager.USE_ALL_WIDTH);
_mainVfm.setBorder( BorderFactory.createBitmapBorder(
new XYEdges(12,12,12,12), tabBackGroundImage
)
);
make sure that your border image have white background.
i use this method and it works perfectly.