[SOLVED]
I have 4 buttons, each with a flashing opacity animation that I have rigged up to play when the button is clicked. However when a second button is playing, the one first clicked, still plays and flashes on. And that continues when more buttons are clicked. I have tried using loops, animation components rather than animators and a few other methods. Here is the code, could someone please tell me how I can stop the animation playing when another button is pressed?
public EnemyBehavior enemyBehavior;
public bool[] difficultySelected;
public Animator easy;
public Animator normal;
public Animator hard;
public Animator expert;
public void DifficultySelected(int name){
difficultySelected[0] = false;
difficultySelected[1] = false;
difficultySelected[2] = false;
difficultySelected[3] = false;
difficultySelected[name] = true;
}
void Start () {
}
void Update () {
if(difficultySelected[0] == true){
enemyBehavior.shotsPerSecond = 0.2f;
easy.Play("Difficulty");
}else if(difficultySelected[1] == true){
enemyBehavior.shotsPerSecond = 0.5f;
normal.Play("Difficulty");
}else if(difficultySelected[2] == true){
enemyBehavior.shotsPerSecond = 1;
hard.Play("Difficulty");
}else if(difficultySelected[3] == true){
enemyBehavior.shotsPerSecond = 2;
expert.Play("Difficulty");
}
}
Update:
if(difficultySelected[0] == true){
enemyBehavior.shotsPerSecond = 0.2f;
normal.StopPlayback();
hard.StopPlayback();
expert.StopPlayback();
easy.Play("Difficulty");
}else if(difficultySelected[1] == true){
enemyBehavior.shotsPerSecond = 0.5f;
easy.StopPlayback();
hard.StopPlayback();
expert.StopPlayback();
normal.Play("Difficulty");
}else if(difficultySelected[2] == true){
enemyBehavior.shotsPerSecond = 1;
easy.StopPlayback();
normal.StopPlayback();
expert.StopPlayback();
hard.Play("Difficulty");
}else if(difficultySelected[3] == true){
enemyBehavior.shotsPerSecond = 2;
easy.StopPlayback();
normal.StopPlayback();
hard.StopPlayback();
Related
I have a player that can move when pressing the arrow keys. I would like to prevent the user to press multiple arrows at the same time.
This what I have tried:
boolean[] pressedKeys = new boolean[4];
canvas.setOnKeyPressed(event -> {
if (!Arrays.asList(pressedKeys).contains(true)){
if (event.getCode() == KeyCode.UP){
pressedKeys[0] = true;
} else if (event.getCode() == KeyCode.RIGHT){
pressedKeys[1] = true;
} else if (event.getCode() == KeyCode.DOWN){
pressedKeys[2] = true;
} else if (event.getCode() == KeyCode.LEFT){
pressedKeys[3] = true;
}
}
});
canvas.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.UP){
pressedKeys[0] = false;
} else if (event.getCode() == KeyCode.RIGHT){
pressedKeys[1] = false;
} else if (event.getCode() == KeyCode.DOWN){
pressedKeys[2] = false;
} else if (event.getCode() == KeyCode.LEFT){
pressedKeys[3] = false;
}
});
But it does not work, here I can still press the right and the up arrows for example.
Thanks for any help
I'd create an event handler implementation like this:
class InputHandler implements EventHandler<KeyEvent> {
final private Set<KeyCode> activeKeys = new HashSet<>();
#Override
public void handle(KeyEvent event) {
if (activeKeys.isEmpty() && KeyEvent.KEY_PRESSED.equals(event.getEventType())) {
activeKeys.add(event.getCode());
} else if (KeyEvent.KEY_RELEASED.equals(event.getEventType())) {
activeKeys.remove(event.getCode());
}
}
public Set<KeyCode> getActiveKeys() {
return Collections.unmodifiableSet(activeKeys);
}
}
The check activeKeys.isEmpty() ensures that we don't register a new keypress until a prior key is released.
A single value for the activeKey could be used instead of the activeKeys HashSet, I just adapted this from a prior solution which works in a more general case.
To use it:
InputHandler inputHandler = new InputHandler();
scene.setOnKeyPressed(inputHandler);
scene.setOnKeyReleased(inputHandler);
Then, if it is something like a game where the input is checked on each frame update of an AnimationTimer, in the update method you can check the current active keys for the frame and action them, like this:
private AnimationTimer createGameLoop() {
return new AnimationTimer() {
public void handle(long now) {
update(now, inputHandler.getActiveKeys());
if (isGameOver()) {
this.stop();
}
}
};
I am not sure if your chosen strategy will result in a desirable user experience, you will need to try it out and see how well it works in your application.
I found a solution, thanks to #kleopatra
This is what I made:
boolean pressedKeys = false, releasedKeys = true;
canvas.setOnKeyPressed(event -> {
if (releasedKeys){
// Code goes here
pressedKeys = true;
releasedKeys = false;
}
});
canvas.setOnKeyReleased(event -> {
if (pressedKeys){
pressedKeys = false;
releasedKeys = true;
}
});
Like this, its not possible to press multiple keys at one time
Im searching for a solution represented here as a gif from my designer: enter link description here
Basically, I need a list, with a header, or with a another view (grid, or stacklayout). On a scroll, I need to catch event (scrolling down, scrolling up) and to move list with that header.
Can you suggest me some referrals?
Here is the example code from syncfusion:
https://www.syncfusion.com/downloads/support/directtrac/general/ze/AnimateHeaderOnScroll1119606059
You can achieve your requirement by handling Scrolled event as below,
public MainPage()
{
InitializeComponent();
container = _listView.GetVisualContainer();
_scrollView = _listView.GetScrollView();
_scrollView.Scrolled += ScrollView_Scrolled;
}
private void ScrollView_Scrolled(object sender, ScrolledEventArgs e)
{
scrollOffet = (double)container.GetType().GetRuntimeProperties().First(p => p.Name == "ScrollOffset").GetValue(container);
if (e.ScrollY == 0)
(BindingContext as MainViewModel).CanPassTouch = true;
}
private void PanGestureRecognizer_PanUpdated(object sender, PanUpdatedEventArgs e)
{
if(e.StatusType == GestureStatus.Running)
{
var y = e.TotalY;
//Up scroll
if (y < 0)
{
if (!_originalHeaderHeight.HasValue)
{
_originalHeaderHeight = _headerView.Height;
}
var newHeight = _originalHeaderHeight.Value + y;
_headerView.HeightRequest = newHeight > MIN_HEADER_HEIGHT ? newHeight : MIN_HEADER_HEIGHT;
}
//Down scroll
else
{
if (!_originalHeaderHeight.HasValue)
{
_originalHeaderHeight = _headerView.Height;
}
var newHeight = _originalHeaderHeight.Value + y;
_headerView.HeightRequest = newHeight < MAX_HEADER_HEIGHT ? newHeight : MAX_HEADER_HEIGHT;
}
//Enable InputTransparent for SfListView, to enable the ListView scrolling
//after reaching the Header min/max heights based on scrolling.
if (_headerView.HeightRequest == MIN_HEADER_HEIGHT && y < 0)
(BindingContext as MainViewModel).CanPassTouch = false;
if (_headerView.HeightRequest == MAX_HEADER_HEIGHT && scrollOffet > 0)
(BindingContext as MainViewModel).CanPassTouch = false;
}
}
Sample
I have written an app that switch on the Flashlight. My only issue is that every time i open my app, my phone camera option stops working - that is i can't open my camera anymore. The camera starts working only if i kill my application. Here is my code :
public static Camera camera = null;
I call TurnCameraOn() in my ON button and TurnCameraOff in my OFF button.
private void TurnCameraOn()
{
if (CameraAvailable() == true)
{
if (camera == null)
camera = Camera.Open();
Camera.Parameters parameters = camera.GetParameters();
parameters.FlashMode = Camera.Parameters.FlashModeTorch;
camera.SetParameters(parameters);
Android.Graphics.SurfaceTexture mPreviewTexture = new Android.Graphics.SurfaceTexture(0);
camera.SetPreviewTexture(mPreviewTexture);
camera.StartPreview();
cameraFlashLightOnThread = true;
}
}
private void TurnCameraOff()
{
if (CameraAvailable() == true)
{
if (camera == null)
camera = Camera.Open();
Camera.Parameters parameters = camera.GetParameters();
parameters.FlashMode = Camera.Parameters.FlashModeOff;
camera.SetParameters(parameters);
camera.StopPreview();
cameraFlashLightOnThread = false;
}
}
private bool CameraAvailable()
{
bool availale = true;
if (PackageManager.HasSystemFeature(Android.Content.PM.PackageManager.FeatureCamera) == false)
{
availale = false;
Toast.MakeText(this, "No back-facing camera available", ToastLength.Long);
}
if (PackageManager.HasSystemFeature(Android.Content.PM.PackageManager.FeatureCameraFlash) == false)
{
availale = false;
Toast.MakeText(this, "No camera flash available", ToastLength.Long);
}
return availale;
}
Your app is holding a reference to the camera and never releasing it. when you turn the LED/flash off, dispose of your camera instance so the camera may be used by other apps.
Something like:
private void TurnCameraOn()
{
if (CameraAvailable())
{
camera = camera ?? Camera.Open();
using (var parameters = camera.GetParameters())
{
parameters.FlashMode = Camera.Parameters.FlashModeTorch;
camera.SetParameters(parameters);
Android.Graphics.SurfaceTexture mPreviewTexture = new Android.Graphics.SurfaceTexture(0);
camera.SetPreviewTexture(mPreviewTexture);
camera.StartPreview();
}
cameraFlashLightOnThread = true;
}
}
private void TurnCameraOff()
{
if (CameraAvailable())
{
camera = camera ?? Camera.Open();
using (var parameters = camera.GetParameters())
{
parameters.FlashMode = Camera.Parameters.FlashModeOff;
camera.SetParameters(parameters);
camera.StopPreview();
camera.Dispose();
camera = null;
}
cameraFlashLightOnThread = false;
}
}
FYI: Your Toast statements are missing .Show() and thus would never been shown to the user.
I have included the following line to show a simple timer in the top left corner of a scene, which works of course, but when I tick the Virtual Reality Supported check-box and put on an Oculus Rift, it disappears.
void OnGUI()
{
GUI.Label(new Rect(10, 10, 100, 20), Time.time.ToString());
}
What am I missing? What should I do additionally to resolve this?
OnGUI() does not work in VR. Instead use world space canvas UI.
I did the following for the Gear-VR.
Add a canvas (or other UI elements containing "Canvas" component) to your scene. Set render mode to World Space. This can be found on the render mode drop down list for the UI Canvas object:
I ended up going for an 800 x 600 canvas.
For the timer itself I used Time.deltaTime.
Here is my whole PlayerController script:
void Start ()
{
timeLeft = 5;
rb = GetComponent<Rigidbody>();
count = 0;
winText.text = "";
SetCountText ();
}
void Update() {
if (gameOver) {
if (Input.GetMouseButtonDown(0)) {
Application.LoadLevel(0);
}
} else {
timeLeft -= Time.deltaTime;
timerText.text = timeLeft.ToString("0.00");
if (timeLeft < 0) {
winner = false;
GameOver(winner);
}
}
}
void GameOver(bool winner) {
gameOver = true;
timerText.text = "-- --";
string tryAgainString = "Tap the touch pad to try again.";
if (!winner) { // case A
winText.text = "Time's up.\n" + tryAgainString;
}
if (winner) { // case B
winText.text = "Well played!\n" + tryAgainString;
}
}
void FixedUpdate ()
{
float moveHorizontal = Input.GetAxis ("Mouse X");
float moveVertical = Input.GetAxis ("Mouse Y");
Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
rb.AddForce (movement * speed);
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag ( "Pick Up")){
other.gameObject.SetActive (false);
count = count + 1;
SetCountText ();
if (!gameOver) {
timeLeft += 3;
}
}
}
void SetCountText ()
{
if (!gameOver) {
countText.text = "Count: " + count.ToString ();
}
if (count >= 12) {
winner = true;
GameOver(winner);
}
}
OnGUI does not work in VR. You have to use world space canvas UI.
I want to use animation on a Button that I created in my BlackBerry App. The animation works fine the first time when I click the button. On first click, the button starts animation (blinking). On second click the blinking stops. However, when I click the button again (third time), the blinking should start again. However, I get an error:
App Error 104 Uncaught: IllegalStateException
The code for creating the Button and adding animation is as follows:
final Bitmap image000 = Bitmap.getBitmapResource("panic.png");
final Bitmap image001 = Bitmap.getBitmapResource("panicon.png");
final Timer animationTimer = new Timer();
final BitmapField animationField = new BitmapField(image000,BitmapField.FOCUSABLE){
protected boolean navigationClick(int status, int time)
{
if(flag){
animationTask.cancel();
flag=false;
}else{
animationTimer.scheduleAtFixedRate(animationTask, 0, 100);
flag=true;
}
return true;
}
};
animationTask = new TimerTask() {
public void run() {
if(counter == 0){
animationField.setBitmap(image000);
}
if(counter == 1){
animationField.setBitmap(image001);
counter = -1;
}
counter++;
}
};
add(animationField);
EDIT: I debugged my code and the error occurs in the loop that starts the thread. Cancelling the thread seems fine. I am lost what is the issue. Please guide.
try this -
TimerTask animationTask;
BitmapField animationField;
final Bitmap image000 = Bitmap.getBitmapResource("panic.png");
final Bitmap image001 = Bitmap.getBitmapResource("panicon.png");
final Timer animationTimer = new Timer();
animationField = new BitmapField(image000,BitmapField.FOCUSABLE){
protected boolean navigationClick(int status, int time)
{
if(flag){
animationTask.cancel();
flag=false;
}else{
animationTask = new TimerTask() {
public void run() {
if(counter == 0){
animationField.setBitmap(image000);
}
if(counter == 1){
animationField.setBitmap(image001);
counter = -1;
}
counter++;
}
};
animationTask.run();
animationTimer.scheduleAtFixedRate(animationTask, 0, 100);
flag=true;
}
return true;
}
};
animationTask = new TimerTask() {
public void run() {
if(counter == 0){
animationField.setBitmap(image000);
}
if(counter == 1){
animationField.setBitmap(image001);
counter = -1;
}
counter++;
}
};
add(animationField);