unity3d - Change Image.fillAmount - image

I have an image acting as a health bar, and i want to give it a cistume value more than 1:
public Image healthBar;
// Use this for initialization
void Start () {
float health = 4;
healthBar.fillAmount = health;
Debug.Log (gameObject + ""+ healthBar.fillAmount);
}
Problem is no matter what value I give health, the fillAmount always goes back to 1. Is there any way to make it higher ?

fillAmount is a value of 0-1, with at 1 the full image being shown. There is no behavior yet for numbers over 1.
You could change the width of the image based on the maximum health and calculate the percentage that needs to be filled.
healthBar.rectTransform.rect.width = maxHealth * healthBarWidth;
healthBar.fillAmount = health / maxHealth;
If you don't want one bar, but multiple images like hearts that still are filled partially, you might be able to do it with a tiled image which automatically truncates at the edges.

I think you made a spelling error when creating the heath float. You call health when you declared "healt"

healthBar.fillAmount += health;
Try to do the increment in the fillAmount value, as it will assign the value you want it, and then change the code little bit in order to reach the exact number.

Related

Terminal dashboard in golang using "termui"

I am working on drawing graphs on the terminal itself from inside a go code.I found this (https://github.com/gizak/termui) in golang. And used this(https://github.com/gizak/termui/blob/master/_example/gauge.go) to draw graph in my code.
Problem is this , as we can see in the code( https://github.com/gizak/termui/blob/master/_example/gauge.go ), they are passing g0,g1,g2,g3 all together in the end "termui.Render(g0, g1, g2, g3, g4)".
In my case I don't know how many gauges to draw before hand so I used a list to store gauge objects and then tried to pass list to render.
termui.Render(chartList...)
But it creates only one gauge.
This is how I am appending elements in the list.
for i := 0; i < 5; i++ {
g0 := termui.NewGauge()
g0.Percent = i
g0.Width = 50
g0.Height = 3
g0.BorderLabel = "Slim Gauge"
chartList = append(chartList, g0)
}
what I am getting is a gauge for i=4 only. when I am doing termui.Render(chartList...)
Am I doing something wrong?
PS - I have modified question based on the answer I got in this question.
Here is a good read on Variadic Functions
Take a look at the function signature of Render, https://github.com/gizak/termui/blob/master/render.go#L161
func Render(bs ...Bufferer) {
All you need to do is
termui.Render(chatList...)
assuming chartList is a []Bufferer
Edit
You are only seeing one because they are stacking on top of one-another. To see this add
g0.Height = 3
g0.Y = i * g0.Height // <-- add this line
g0.BorderLabel = "Slim Gauge"
From a quick review of the project, it appears there are ways for auto-arranging that have to do with creating rows (and probably columns). So you might want to explore that, or you will need to manually position your elements.

How to move an image in Lua?

I am new to Lua programming and I am having problems while trying to move an image from a set of coordinates to another.
What I am trying to create is to be used with the X-Plane flight simulator. There is a library called SASL (www.1-sim.com), that was created to make plugins (for X-Plane) creation easir, since the default language is C++ and many people find it difficult.
In general, SASL works as a bridge between Lua and X-Plane, in general lines, the scripts you write reads some data straight from X-Plane (DataRefs) while it is running and depending on the code you wrote its execute commands or many other things that it is possible.
So, when using SASL to create cockpit/panel gauges it uses a base file, named 'avionics.lua' that works as a class and loads all gauges you create for the specific aircraft you are working on. For example my avionics.lua file looks like this:
size = { 2048, 2048 }
components = {
flaps {};
};
where, 'size' is the size that will be used for things to be drawn and components is an array of gauges, in this case the flaps gauge.
The rest of the work is to create the gauge functionality and this is done in a separate file, in my case, called 'flaps.lua'.
Within flaps.lua, is where I need to code the flaps indicator functionality which is to load 2 images: one for the back ground and the second one for the flaps indicator.
The first image is a fixed image. The second one will move throught the 'y' axis based on the flaps indicator DataRef (flapsDegree property below).
The code below when X-Plane is running displays the background image and the flaps indicator on its first stage which is 0 as you can see on the image.
size = {78,100}
local flapsDegree = globalPropertyf("sim/cockpit2/controls/flap_ratio")
local background = loadImage("gfx/Flaps.png")
local indicator = loadImage("gfx/Flaps_Indicator.png")
local flaps = get(flapsPosition)
components = {
texture { position = {945, 1011, 60, 100}, image = background},
texture { position = {959, 1097, 30, 9}, image = indicator},
}
Image
Now, the problem comes when I need to implement the logic for moving the 'indicator' image through the 'y' axis.
I have tried this code without success:
if flaps == 0.333 then
indicator.position = {959, 1075, 30, 9}
end
So how could I accomplish that?
I am not familiar with the SALS library. I just had a quick look into it.
Everything you need to know is in the manuals on the website you linked.
In particular http://www.1-sim.com/files/SASL300.pdf
Everytime your screen is updated each components draw() function will be called.
So if you want to change something dynamically you have to put that into the component's draw function.
If you open the SALS sources you'll find basic components which show you how to use that stuff. One of them is needle.lua:
-- default angle
defineProperty("angle", 0)
-- no image
defineProperty("image")
function draw(self)
local w, h = getTextureSize(get(image))
local max = w
if h > max then
max = h
end
local rw = (w / max) * 100
local rh = (h / max) * 100
drawRotatedTexture(get(image), get(angle),
(100 - rw) / 2, (100 - rh) / 2, rw, rh)
end
If you check the manual you'll find that there is not only a drawRotatedTexture function but many other functions for drawing stuff. Just play around. Try drawTexture for your purpose.
If you don't know what you have to program, open every single lua file in the library and read it together with the Lua reference manual and the SALS documentation until you understand what is going on. Once you understand the existing code you can extend it with ease.

Game Maker - Mouse Click image_index Checking

I have this sprite: spr_meteoriteLv3, which has two sub-images with index image_index 0 and 1 respectively.
I have these objects: obj_meteoriteLv3, obj_tempMeteoriteLv3, and obj_score. Object obj_meteoriteLv3 spawns from above with random position, random amount, and random sub-image. Object obj_tempMeteoriteLv3 makes obj_meteoriteLv3s spawn. When player clicks on a meteorite, the program checks the value of image_index for that object.
obj_meteoriteLv3 has these events:
Create Event: change sprite_index into spr_meteoriteLv3, and start moving downwards.
Left-pressed Mouse Event: destroy the self instance, and check image_index: if image_index == 0 then score += 5; else score -= 5).
obj_tempMeteoriteLv3 has these events:
Create Event: set Alarm 0 to 3600, set variable exist to 1, and set variable add to 1.
Alarm 0: set variable add to 0, and destroy the obj_meteoriteLv3 instance.
Alarm 1: set variable exist to 1.
Step Event: if (exist == 1) then, if (add == 1) then create instance of obj_meteoriteLv3, set variable exist to 0, and set Alarm 1 to 10.
obj_score has these events:
Create Event: set score to 0.
Draw Event: draw the value of score.
The problem is, no matter which sub-image the meteorite image_index has when clicked, the score will always be incremented by 5 points. It's like the else condition isn't working. How can I fix this? Please explain your answer. Thanks.
I add some images for better understanding. Link 1. Link 2
In obj_meteoriteLv3 it's being destroyed before it can execute the rest of the code blocks. Move "Destroy Instance" to the bottom.
In obj_tempMeteoriteLv3 both variables "add" and "exist" are not necessary, instead have-
Create Event-
alarm[0] = 3600
alarm[1] = 10
Alarm[0] Event-
destroy_instance
Alarm[1] Event
Create_instance of obj_meteoriteLv3
alarm[1] = 10
Potentially, when you click, every single meteorite is triggered.
On the left click event of the meteorite, you did not check if the cursor was on the sprite. You have to use the position_meeting function, to which you pass the mouse position and the instance to click.
it would look like :
if (position_meeting(mouse_x, mouse_y, id))
{
//your destroy code
}
Moreover, when the instance_destroy(); line is read, the following code is ignored and the program jumps to the destroy_event. William explained it well and suggested to change the order of the lines of code, but you can also change the score in the destroy event directly.
I would like to add that checking for clicks in every instance of the meteorites is not optimal for performances.
My recommendation would be to use a single object to check for clicks (your player or your meteorite spawner, for example), in which you would check for clicks, and if a meteorite is touched, you would trigger it's destroy event. And in this event, you would increment the score and check the sprite.
Your click event would look like :
with (instance_position(mouse_x, mouse_y, obj_meteoriteLv3))
{
instance_destroy();
}
and in the meteorite destroy event, you would check the image_index and change the score accordingly.
EDIT : why the score doesn't change
I believe you didn't declare the score as a global variable, but as an instance variable. So when you write "score = ..." in an other object, it creates a new score variable, unrelated to the precedent.
You have 2 options :
1 - Declare the score a global variable in the create event of obj_score:
globalvar score;
score = //your starting score
Be aware that a global variable can't be set on it's initialisation line.
2 - Change the score through the score object :
whenever the score has to change :
obj_score.score = ...

1-2-3 star level awards algorithm

What I am trying to do is to have individual star counts per level based on player performance. (1-2-3 star awards.) This will be based on what region the player reaches. I know how to award the stars but keeping track of it all is throwing me problems. First lets say a player plays level 2 and receives 1 star for their performance. Then at a later time, s/he returns to the level and gets a 2 star. I would like the star count for that specific scene to update to two stars, while only adding 1 star ( The one extra s/he got this time) to the totalStarCount.
My initial plan was to have variables:
OldStarCount
NewStarCount
TotalStarCount
Then when a player reaches say region1, and is awarded one star, then NewStarCount would be set to one, then
TotalStarCount = TotalStarCount + (NewStarCount - OldStarCount);
Then update OldStarCount = NewStarCount;
Set NewStarCount = 0;
Move On to next Scene;
Am I approaching this the correct way? Any help would be greatly appreciated.
You could have something like this
int result = 0;
int totalStars = 0;
int[] starCounts = new int[NumberOfRegions};
...
currentRegion = 42;
result = play(currentRegion);
if(result > starCounts[currentRegion]){
totalStars += result - starCounts[currentRegion];
starCounts[currentRegion] = result;
}
This is just an example of what you could do. There are obvious scalability issues with this (what happens when you want to add new regions, etc), but you get the gist.

string/number from TextField to be used for calculation?

sorry for my question and for the long explanation following here, probably there's a simple solution for someone who is experienced in Cocoa and Objective-C, but I'm just starting few weeks ago and I can't figure out how to get this thing working, Grrrrrrr!!
OK, let's put it like this, in my window I have the following:
2 TextField(NSTextField) called:
blockOffText
blockOnText
1 Label(NSTextField) called:
flightTimeText
1 button(NSButton) called:
updateButton
What I want to do is all about time calculation I guess, get the "start-time" in one TextField and the "end-time" in the other.
One is supposed to be the "takeoff-time" and the other the "landing-time" or for example the "duty-startTime" and "duty-endTime"...it's the same!
Then I want to calculate the "flight-time" or "duty-time" and show it in the Label.
At the end I will also need to store the value or the time in a database as an integer, the value should be represented by all minutes corresponding to each time, but the database part is not a problem at the moment.
Maybe I can write the number in the TextField without the format but just the number and get the time show-up formatted in some way?
I would like to write for example "1245" and "1525" without having the needs to put the ":" between the hours and minutes, then can I get the value formatted "12:45" "15:25" in the TextField in some way? Maybe after pressing the button?
Ok, that is a second problem anyway, my real problem is I need to get the value I wrote in the TextField ("1245" and "1525") to be assigned to some variables in the program that I called "BlockOff" and "BlockOn".
I need to transform them in an integer that represent the minutes corresponding to their value..example:
The 1245 will become 765 minutes...(12 times 60 + 45)
and 1525 will become 925 minutes...(15 times 60 + 25)
HOW CAN I DO THIS?
In this way I can use the minutes to calculate the difference to get the flight time or even add flight time to other flight time.
At the moment my program works a little bit differently... like this:
If I directly assign the value to the two variables:
int blockOff = 765;
int blockOn = 925;
then I can calculate and show in the two TextField the takeOff and landing time formatted like I want: "12:45" "15:25"...I use other 2 variables to do so:
int oreBlkOff, minBlkOff = 0;
minBlkOff = blockOff % 60;
oreBlkOff = (blockOff - minBlkOff) / 60;
Then I can show the value in the TextField:
[blockOffText setStringValue:[NSString stringWithFormat: #"%d:%d", oreBlkOff, minBlkOff]];
Same with blockOnText and flightTimeText, so there is no problem there, but this is not really what I need right?
HOW CAN I GET THE VALUE OF THE TEXTFIELD AND STORE THE VALUE IN VARIABLES THAT CAN BE USED TO DO CALCULATION?
HOW DO I GET THE FIRST TO DIGITS AND LAST TO DIGITS FROM THE VARIABLES SO I CAN USE THEM AS HOURS AND MINUTES FOR MY CALCULATION?
I WOULD LIKE TO BE ABLE TO TYPE THE VALUE IN THE TEXTFIELD, PRESS "ENTER" OR "RETURN" AND GET THE VALUE ASSIGNED IN THE VARIABLE.
IS THIS THE CORRECT WAY OR I'M JUST GOING THE WRONG WAY IN THIS.
IN ANOTHER PROGRAM I DID IN VISUAL BASIC THAT WAS THE WAY I USED.
THANK YOU VERY MUCH IN ADVANCE FOR YOU HELP!
Gianluca
To get the int value from text field you'd use integerValue or floatValue for float. But you should definitely check out the date/time controls in cocoa.
Ok, if I didn't miss the point of your long question...
You have a text field with something like #"2345:8743" and you want to get the two numbers in int variables (a=2345, b=8743).
First you need to get these two text representations of your numbers in two NSStrings. You can do it like this:
NSString * yourString = #"2345:8743";
NSString *stringA = [yourString substringToIndex:4]; //stringA = #"2345"
NSString *stringB = [yourString substringFromIndex:5]; //stringB = #"8743";
Now to get the in values, just do:
int a = [stringA intValue];
int b = [stringB intValue];
Let me know if that is helpful to you.

Resources