I am working on a painting tools with eraser.
I don't know why when i click eraser and start to clear up.
The whole stage will become lighter.After i set updateCache('destination-out').
wrapper.addEventListener("pressup", function(event) {
console.log("up");
dragging = false;
// real_wrapper.updateCache();
if (erase == true) {
drawStroke(real_draw);
real_wrapper.updateCache('destination-out');
} else {
drawStroke(real_draw);
real_wrapper.updateCache();
tmp_draw.graphics.clear();
wrapper.updateCache();
}
ppts = [];
});
My Code: https://jsfiddle.net/steven_wong/mnfupy5o/6/
Sorry for my bad english.
You need to clear your graphics between draws. Right now your code is redrawing all of the old strokes each time, so when you're using the pencil, all the old shapes are made darker, when you're using the eraser, they become lighter.
graphics.clear();
Here's a fixed version:
https://jsfiddle.net/mnfupy5o/7/
Related
I'm newbie with Unity3D.
here is my source, very simple
public void persp_ortho_Btn_Clicked()
{
if (!Camera_Controller.shared_instance.isOrthoCamera)
{
Camera_Controller.shared_instance.isOrthoCamera = true;
Camera.main.orthographic = true;
ui_camera.orthographic = true;
}
else
{
Camera_Controller.shared_instance.isOrthoCamera = false;
Camera.main.orthographic = false;
ui_camera.orthographic = false;
}
}
When i run with this code in Editor (Game simulate window)
this works well like below :
But, after build and run .exe,
main camera doesn't change to ortho camera, also like below :
it seems the "orthographic" property of main camera is change true to false, false to true in built runtime as well either. But maybe the view matrix is not changed.
Why this happen and how can i fix this ??
Your code should work unless something is forcing the camera to stay in the same perspective. I am not able to say what might be the cause with the details provided.
Just test out if the camera will switch without the if statement. Like this
public void persp_ortho_Btn_Clicked()
{
Camera.main.orthographic = !Camera.main.orthographic;
}
If so, then there is some issue with the condition check.
Alternatively, you can try using Unity cinemachine to get a smooth transition.
I am new to unity and for my project I need a gradient background which changes after a certain amount of time. I searched a lot and not able to get it . Can anyone please explain me step by step with respective coding and procedures. Reference to this type of background is the mobile game stack
I think you can make it normaly by create 2 background. After a certain amount of time just fade old background and enable new background. Code example:
void ChangeBackground()
{
newImage.gameObject.SetActive(true);
StartCoroutine(FadeImage(0.1f));
}
IEnumerator FadeImage(float speedStep)
{
Color newColor = oldImage.color;
while (newColor.a > 0)
{
newColor.a -= speedStep;
oldImage.color = newColor;
yield return null;
}
oldImage.gameObject.SetActive(false);
}
I'm trying to create a scroll grid view in which every cell object is tapable.
When a cell object is tapped I want to scale and traslate it to the center of the screen and render it above other cells.
I was able to make it tapable and scale it in its position. Now I want to move the cell object to the center of the screen and render it above other cells.
I've tried many solutions but none of them works.
This is my hierarchy:
This is the grid in normal state:
This is the grid when a cell was tapped:
I'm populating the grid from a C# script dynamically.
void Populate()
{
GameObject cardContainerInstance, cardInstance;
foreach (var c in cardsCollection.GetAll())
{
if (c.IsOwned)
{
cardContainerInstance = Instantiate(cardContainer, transform);
cardInstance = cardContainerInstance.transform.Find("Card").gameObject;
var cardManager = cardInstance.GetComponent<CardManager>();
cardManager.card = c;
cardManager.AddListener(this);
}
else
{
Instantiate(cardSlot, transform);
}
}
}
public void OnCardClick(GameObject cardObject, Card card)
{
Debug.Log("OnCardClick " + card.name);
if (openedCard != null) {
if (openedCard.Number == card.Number)
{
CloseCard(openedCardObject);
}
else
{
CloseCard(openedCardObject);
OpenCard(cardObject, card);
}
}
else
{
OpenCard(cardObject, card);
}
}
void OpenCard(GameObject cardObject, Card card)
{
//cardObject.GetComponent<Canvas>().sortingOrder = 1;
var animator = cardObject.GetComponent<Animator>();
animator.SetTrigger("Open");
openedCard = card;
openedCardObject = cardObject;
}
void CloseCard(GameObject cardObject)
{
var animator = cardObject.GetComponent<Animator>();
animator.SetTrigger("Close");
openedCard = null;
openedCardObject = null;
}
I can't figure out how to move the cell to the center and render it above others.
Note that all is animated using an animator attached to the object itself.
Could anyone help me please? Thank you very much!
EDIT: more details
All cell object have the following hierarchy:
where:
CardContainer is an empty object added to use animator on Card child object
Card is the object itself that has a script, a canvas renderer and an animator
StatsImage is the object that slide out when the card is tapped
Image is a calssic UIImage with Image script, Shadow script and canvas renderer
Other component are simple texts.
EDIT: fix in progress
Trying to apply this suggestions I was able to manage the rendering order (as you see on the image below) but it seems that prevent touch events to be detected on the game object.
I've added a GraphicsRaycaster too and now the bottom horizontal scroll view scrolls again but only if I click and drag a card.
Moreover, with the GraphicsRaycaster, the main grid card still are not clickable and it's possible to open the card only if it is behind the bottom panel (if I click on the red spot in the image below the card behind the panel receives che click)
This is the CardContainer at runtime(note that I'm attaching new Canvas and GraphicsRaycaster on the CardContainer, which is the "root" element):
You didn't clarify whether you are using a sprite renderer or some other method but here is an answer for each.
Sprite renderer:
this the simple one. In each sprite renderer, there is a variable called "sortingOrder" in script and "Order in layer" in the inspector. sprite renderer with sorting Orders that are higher is rendered first. All you would need to do is call:
cardObject.GetComponent<SpriteRenderer>().sortingOrder = 1;
when you click the card, and
cardObject.GetComponent<SpriteRenderer>().sortingOrder = 0;
when you unclick it. I hope that makes sense!
Other Method:
this one is a bit harder and I would suggest that you switch to sprite renderers and it will be much easier and more stable down the road, but I can understand if you have already written a lot of scripts and don't want to go back and change them.
Anyway, all you will need to do Is create two layers: cardLower and cardUpper. then create a new camera and call it topCamera. now under the top camera object in the inspector, change the culling mask (it's near the top) and make sure cardUpper is selected. then change the Clear flags (first one) to "Don't Clear" finally change the depth to 0 (if that doesn't work change it to -2). Now objects in the cardUpper will always be rendered above everything else. You can change the layer through script with
cardObject.layer = "cardUpper"
or
cardObject.layer = "cardLower"
I hope that helps!
Ok, so its pretty simple. So you are going to want to add another canvas component to the game object, and check the override sorting to true. Then use
cardObject.GetComponent<Canvas>().sortingOrder = 1;
to place it in the front and
cardObject.GetComponent<Canvas>().sortingOrder = 0;
to put it in the back.
you are also going to need to put a GraphicsRaycaster on to each of the cardObjects
Ignore my other answer about sprite renderers, they are not needed here
I've been working on switching my applications from Swing to JavaFX. I've been working on a room escape game which displays a description of the item on which the user clicks. In Swing, I'd subclass JComponent and override the paintComponent(Graphics) method. I could draw the text there, knowing that the method is constantly called to update the screen. However, using the JavaFX Canvas, there is no method that is called constantly, which makes this task harder. I attempted save()ing the GraphicsContext after I drew the images and called restore() when I wanted to remove the text, but to no avail. Here's the important code:
package me.nrubin29.jescape;
import javafx.application.Platform;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.shape.Rectangle;
import java.util.Timer;
import java.util.TimerTask;
public class RoomPane extends Canvas {
private Room room;
private Toast toast;
public RoomPane() {
super(640, 480);
setOnMouseClicked(e -> {
for (JObject o : room.getObjects()) {
if (o.getBounds().contains(e.getX(), e.getY())) {
toast = new Toast(o.getDescription());
}
}
});
new Timer().schedule(new TimerTask() {
#Override
public void run() {
if (toast == null) {
return;
}
if (toast.decrement()) { // Decrements the internal counter. If the count is 0, this method returns true.
toast = null;
Platform.runLater(() -> getGraphicsContext2D().restore());
}
else {
Platform.runLater(() -> getGraphicsContext2D().strokeText(toast.getText(), 300, 100));
}
}
}, 0, 1000);
}
public void changeRoom(Room room) {
this.room = room;
GraphicsContext g = getGraphicsContext2D();
g.drawImage(room.getBackground(), 0, 0);
for (JObject o : room.getObjects()) {
g.drawImage(o.getImage(), getCenterX(o.getBounds()), getCenterY(o.getBounds()));
}
g.save();
}
}
I attempted save()ing the GraphicsContext after I drew the images and called restore() when I wanted to remove the text, but to no avail.
save and restore have nothing to with removing things like text, what they do is save in a stack the state of various settings like a stroke or fill to use to draw shapes and allow them to be popped off the stack for application later. Those routines don't effect the pixels drawn on the canvas at all.
To remove something from a GraphicsContext, you can either draw over the of it, or clear it. For your code, what you could do is snapshot the canvas node where you are trying to save it, then draw your snapshot image onto the canvas where you are trying to restore it. It is probably not the most efficient way of handling drawing (a smarter routine which just draws only damaged area where the text is would be better, but probably not required for your simple game).
However, using the JavaFX Canvas, there is no method that is called constantly
Rather than using a timer to trigger canvas calls, use a AnimationTimer or a Timeline. The AnimationTimer has a callback method which is invoked every pulse (60 times a second, or as fast as JavaFX can render frames, whichever is the lesser), so it gives you an efficient hook into the JavaFX pulse based rendering system. The Timeline can have keyframes which are invoked at user specified durations and each keyframe can have an event handler callback which is invoked at that duration.
Using the built-in JavaFX animation framework, you don't have to worry about multi-threading issues and doing things like Platform.runLater which overly complicate your code and can easily lead to subtle and serious errors.
On a kind of unrelated note, for a simple game like this, IMO you are probably better off recoding it completely to use the JavaFX scene graph rather than a canvas. That way you will be working at a higher level of abstraction rather than clip areas and repainting damaged paint components.
I'm working in Eclipse and I want to know if I can make an if statement that checks to see if the BufferedImage has been painted/drawn onto the frame. For some reason, it's not painting the correct image because clickable regions are appearing on that picture when they are not supposed to.
For example, when I click the region to go from 4>5 everything is good. When I click from 5 to go to 4 I end up at 6 because the 'regions' from 4 are appearing in 5 (The image should always be painted before the clickable regions are shown) before it's even being painted. I want to restrict this to check if the image has been painted onto the frame first.
I really don't want to use anything else besides what I have right now (so no new classes being implemented to do this task), I really just want a simple yet effective way to resolve this. Here is what I'm talking about:
...
MouseAdapter mouseHandler = new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
repaint();
if(n==0)
{
if(e.getX()>=459 && e.getX()<491 && e.getY()>=111 && e.getY()<133
{
n = 4;
}
return;
}
if(n==5)
{
if(...)
{
n = 4;
}
return();
}
if(n==6)
{
if(...)
{
n = 5;
}
if(...)
{
n = 0;
}
if(...)
{
n = 6;
}
return();
}
}
...
I think you might need to give a little more information. The problem might lie in how you repaint, not whether it was painted.
If you are running another thread as your main program, you might instead want to send the mouse events synchronously to that so that the main thread can process the mouse click and then repaint.
Another solution might be to override the repaint method and paint the buffered images there, but you may have done that.
Also, a little off topic, I noticed that you used for loops to determine if the mouse was clicked in a specific area.
You could shorten the code:
for(int i=459; i<491; i++){
if(e.getX()==i){
for(int j=111; j<133; j++){
if(e.getY()==j){
//action taken
}
}
}
}
To:
if(e.getX()>=459 && e.getX()<491 && e.getY()>=111 && e.getY()<133{
//action taken
}
This would take up less space in your code and less time checking every pixel.
Back to your question.
I dont know of a function to tell if a buffered image has been painted. The ploblem that you are having though might of might not be in the code provided. Posting the rest of your code would be beneficial.
Okay I found the solution, I forgot to come back to this question and let you know. The problem was that the mouse was double clicking for some reason. You could almost say it was 'recursive'. I decided to move the mouseListener from inside the paintComponent to outside of it, and surely enough that fixed it.