Code Outputs mulitple times instead of just once (Unity C#) - c#-4.0

Ok I am using Unity C# (MonoDevelop) and I am learning how to pull component variables from other components. Now I understand how to do that, but I am wondering why when I start the game and press the "F" key it prints "Hello I am a cube" and subtracts 1 from CubeTalkPoints at least 3-5 times. I want it to run the code once per key press.
void Update () {
if(Input.GetKey(KeyCode.F))
C_Talk(0);
}
void C_Talk(int SpellID = 0, int TalkPoint = 1)
{
CubeData CubeSub = GetComponent<CubeData>();
if (CubeSub.CubeTalkPoints >= TalkPoint)
{
CubeSub.CubeTalkPoints -= TalkPoint;
Debug.Log("Hello I am a Cube!");
}
}

Use GetKeyDown() instead of GetKey(). GetKeyDown() will only be true the first frame the button is down. GetKey() will be true every frame as long as the button is held down.

Related

Limit drag in gamemaker

Hello I am trying to limit how much a user can drag within Gamemaker.
I have created two views within a room.
The first view is the full room width and size 1250x768
The second view is the area which i would like the user to be able to zoom into and drag which is 955x465. x and y position is 40 by 170.
Currently i have set up the zoom for the second view which is:
vmx=(mouse_x-X)-omx;
omx=(mouse_x-X);
vmy=(mouse_y-Y)-omy;
omy=(mouse_y-Y);
if mouse_wheel_up() && view_wview[1] > 600 {
center_of_space_x=view_xview[1]+view_wview[1]/2;
center_of_space_y=view_yview[1]+view_hview[1]/2;
view_wview[1]-=view_wview[1]*0.15;
view_hview[1]-=view_hview[1]*0.15;
view_xview[1]=center_of_space_x-view_wview[1]/2;
view_yview[1]=center_of_space_y-view_hview[1]/2;
}
if mouse_wheel_down(){
view_xview[1] = 40;
view_yview[1] = 170;
view_wview[1] = 955;
view_hview[1] = 465;}
Below is the code for the drag:
if (mouse_check_button_pressed(mb_left)) {
drag_x = mouse_x
drag_y = mouse_y
}
// update:
if (mouse_check_button(mb_left)) && view_wview[1] < 700 {
// actual dragging logic:
view_xview[1] = drag_x - (mouse_x - view_xview[1])
view_yview[1] = drag_y - (mouse_y - view_yview[1])
// make sure view doesn't go outside the room:
view_xview[1] = max(0, min(view_xview[1], room_width - view_wport[1]))
view_yview[1] = max(0, min(view_yview[1], room_height - view_hview[1]))
So the limit works for the view to not leave the room but i want it not to leave the specific view which has been set up.
Please help
I have modified my code to use a clamp function which works but it is not a clean solution:
view_xview[1] = clamp(view_xview[1],40,400);
view_yview[1] = clamp(view_yview[1],170,500);
The user has to be fully zoomed in to have the view restricted. If he is not then they can still see other areas of the room :(
EDIT: I may have misunderstood your question, I will leave the below code for reference if it helps you solve the problem a bit differently.
I would probably check that mouse_x and mouse_y are not outside the view you want.
if (mouse_x > view_limit_x || mouse_y > view_limit_y)
{
return; // Or continue or break however your language of choice goes.
}
If you cannot do a return statement, wrapping your code in a reverse logic of above should work fine.
Old Post:
I am not 100% familiar with game maker. I would implement something like this by skipping the drag logic every x frames. Say you are updating at 60fps, and you want the drag to be 6 times slower, you just need to only update the logic 10 x per frame.
const int framesToSkip = 6;
int frameCount = 0;
update()
{
// Will only call when framecount = 0, 6, 12, 18 etc.
if (frameCount % framesToSkip == 0)
{
// Drag Logic.
}
frameCount++;
}
This way drag logic only occurs 1/6 the rate as before. You could also change this around to happen the first x amount of frames and then skip for the rest (but this may appear a bit choppy).

Getting Barcode Scanner MT2000 to Move to Next Focus

I am trying to move to the next focus of an application by transmit a TAB or ENTER character to the host from my Motorola MT2070 Barcode Scanner.
I have tried using the SendLabel method as follows
string barcode = "Hello";
int count = 1;
SendBarcode(new LabelData(barcode + "\t" + count.ToString(), Options.BarcodeType));
count++;
}
private bool SendBarcode(LabelData label)
{
RESULTCODE result = RESULTCODE.E_OK;
try
{
result = Program.ScannerServicesClient.SendLabel(label, 10000);
}
catch
{
result = RESULTCODE.E_HOST_NOT_READY;
}
if (result != RESULTCODE.E_OK)
{
MsgBox.Error(listForm, Properties.Resources.StrErrorCouldntSendBarcode);
}
return result == RESULTCODE.E_OK;
}
Unfortunately the "\t" does not translate into an actual TAB keystroke in Keyboard mode.
When scanning in NOTEPAD the 5 spaces of the tab show up, but it doesn't work to move the focus to the next field as hitting TAB does in Excel or other applications.
What should I be transmitting in place of the \t?
Thanks!
I assume this won't work, because it is not a normal/manual input from your keyboard. It is a value passed from a barcode to the text-property of your field. So you have to handle this different.

Controling do while loop with string

Hi folks this is my question for example i have 3 articles and user can chose any one of them or all of them. In the beginning i ask a user, "do you want to choose some articles?" and if he types yes than we start a while or do while loop that adds prices of all chosen articles and adds them to the total value,
for example article one price is 20 and article 3 price is 40 it should write you have chosen articles one and article three and total price is 60. And when user ends with his choosing he types no and the loop ends.
The real question is my do while loop is always endless i don't know how to stop the loop with a String. This my 10th version of code, i tried everything but really can't solve this problem.
public static void main(String[] args) {
Scanner tastatura = new Scanner(System.in);
System.out.println("Artikal 1\nArtikal 2\nArtikal 3");
System.out.println("Do you want to chose a new article");
String choiseString = tastatura.nextLine();
do {
System.out.println("Chose article ");
int choise = tastatura.nextInt();
switch (choise) {
case 1:
System.out.println("Artikal 1 ");
int price = 10;
break;
case 2:
System.out.println("Artikal 2 ");
price= 20;
break;
case 3:
System.out.println("Artikal 3");
price = 30;
break;
}
} while (choiseString.equalsIgnoreCase("yes") );
}
I believe your issue is that you never give the opportunity for the user to change the value of choiseString.
You allow the user to set the value before the loop begins, but once inside the loop it doesn't change.
Your while loop could instead do something like:
do {
System.out.println("Do you wish to continue?");
choiseString = tastatura.nextLine();
System.out.println("Chose article ");
int choise = tastatura.nextInt();
//rest of your logic here
} while (choiseString.equalsIgnoreCase("yes") );
In this case it would then ask for 1 more choice and then exit the loop (although I haven't tested this code).
I recommend to use a boolean.
This way you will only need to check for true or false, or 1/0.
But the important part is to in some point inside the loop, set that variable to true or false, because if you don't do that, the loop will be an infinite loop.
Once you set the variable to false or true in some point inside the loop, everything will goes fine ;)
I hope this helps

how to implement gesture-based menu

I am supposed to implement a gesture-based menu in which you scroll through a horizontal list of items by panning or flinging through them. This kind of menus is very common in smart phone games. Example case would be Cut the Rope where you select box (Cardboard box, Fabric box) or Angry Birds where you select the set of levels (Poached Eggs, Mighty Hoax).
What I am thinking is that I'll have to do some complex physics calculations and give velocities and accelerations to menu items based on the gestures. Any better solutions? I am using libgdx btw.
I don't think you'd need to go through all that to implement a simple menu! It's all about defining offsets for various items (I'll just assume you want Cut the Rope-style menus, with only one entry in sight at a given moment (excluding transitions)) and then tweening between those offsets whenever a flick is detected!
You seem to have the gesture system all wired up, so right now, we just need to figure out how to display the menu. For simplicity's sake, we'll just assume that we don't want the menu to wrap around.
We'll start by envisioning what this menu will look like, in our heads. It would be just like a filmstrip which passes through the phone and can be seen through the screen.
phone ("stuff" is currently selected)
========
|---------------| |-------|
| Start | About | Stuff | Quit |
|---------------| |-------|
| |
| |
| |
========
We'll just assume that the screen width is w and, consequently, all menu entries are exactly that width (think Cut the Rope again!).
Now, when "Start", is to be displayed, we should just render the flimstrip on the screen starting with the first element, "Start", while the rest would, theoretically, lie to the right of the screen. This will be considered the basic case, rendering the menu with the offset = 0.
Yes, yes, this offset will be the key to our little slidey-slidey menu! Now, it's pretty obvious that when about is selected, we'll just have to offset the "filmstrip" to the left by one "frame", and here offset = - 1 * frameWidth. Our example case illustrated by my brilliant ASCII art has the third menu item selected, and since the frames are indexed starting from 0, we'll just subtract two times the frameWidth and get the desired offset. We'll just render the menu starting at offset = -2 * frameWidth.
(Obviously you can just compute frameWidth in advance, by using the API to fetch the screen width, and then just drawing the menu element text/ graphic centered).
So this is pretty simple:
the user sweeps to the left, we need to get to the menu closer to offset 0, we reduce the index of the selected entity by one and the menu then jumps to the right position
the user sweeps to the right, we increase the index (obviously as long as it doesn't go over the number of menu elements - 1)
But what about smooth tweens?
Libgdx thankfully has interpolations all set for nice little tweens. We just need to take care of a few things so we don't shoot ourselves in the leg. I'll list them here.
One quick note:
The Cut the Rope level selector works a tad differently than what I'm saying here. It doesn't just react to flicks (pre-defined gestures), rather it's more sensitive. You can probably achieve a similar effect by playing with offsets and tracking the position of the finger on the screen. (If the user dragged a menu entry too much to the left/right, transition to the previous/next automatically) Friendly advice: just set up a simple, working menu, and leave details like this towards the end, since they can end up taking a lot of time! :P
Alright, back on track!
What we have now is a way to quickly switch between offsets. We just need to tween. There are some additional members that come into play, but I think they're pretty self-explanatory. While we're transitioning between two elements, we remember the "old" offset, and the one we're heading towards, as well as remembering the time we have left from the transition, and we use these four variables to compute the offset (using a libgdx interpolation, exp10 in this case) at the current moment, resulting in a smooth animation.
Let's see, I've created a quick'n'dirty mock-up. I've commented the code as best as I could, so I hope the following snippet speaks for itself! :D
import java.util.ArrayList;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Interpolation;
public class MenuManager {
// The list of the entries being iterated over
private ArrayList<MenuEntry> entries = new ArrayList<>();
// The current selected thingy
private int index;
// The menu offset
private float offset = 0.0f;
// Offset of the old menu position, before it started tweening to the new one
private float oldOffset = 0.0f;
// What we're tweening towards
private float targetOffset = 0.0f;
// Hardcoded, I know, you can set this in a smarter fashion to suit your
// needs - it's basically as wide as the screen in my case
private float entryWidth = 400.0f;
// Whether we've finished tweening
private boolean finished = true;
// How much time a single transition should take
private float transitionTimeTotal = 0.33f;
// How much time we have left from the current transition
private float transitionTimeLeft = 0.0f;
// libgdx helper to nicely interpolate between the current and the next
// positions
private Interpolation interpolation = Interpolation.exp10;
public void addEntry(MenuEntry entry) {
entries.add(entry);
}
// Called to initiate transition to the next element in the menu
public void selectNext() {
// Don't do anything if we're still animationg
if(!finished) return;
if(index < entries.size() - 1) {
index++;
// We need to head towards the next "frame" of the "filmstrip"
targetOffset = oldOffset + entryWidth;
finished = false;
transitionTimeLeft = transitionTimeTotal;
} else {
// (does nothing now, menu doesn't wrap around)
System.out.println("Cannot go to menu entry > entries.size()!");
}
}
// see selectNext()
public void selectPrevious() {
if(!finished) return;
if(index > 0) {
index --;
targetOffset = oldOffset - entryWidth;
finished = false;
transitionTimeLeft = transitionTimeTotal;
} else {
System.out.println("Cannot go to menu entry <0!");
}
}
// Called when the user selects someting (taps the menu, presses a button, whatever)
public void selectCurrent() {
if(!finished) {
System.out.println("Still moving, hold yer pants!");
} else {
entries.get(index).select();
}
}
public void update(float delta) {
if(transitionTimeLeft > 0.0f) {
// if we're still transitioning
transitionTimeLeft -= delta;
offset = interpolation.apply(oldOffset, targetOffset, 1 - transitionTimeLeft / transitionTimeTotal);
} else {
// Transition is over but we haven't handled it yet
if(!finished) {
transitionTimeLeft = 0.0f;
finished = true;
oldOffset = targetOffset;
}
}
}
// Todo make font belong to menu
public void draw(SpriteBatch spriteBatch, BitmapFont font) {
if(!finished) {
// We're animating, just iterate through everything and draw it,
// it's not like we're wasting *too* much CPU power
for(int i = 0; i < entries.size(); i++) {
entries.get(i).draw((int)(i * entryWidth - offset), 100, spriteBatch, font);
}
} else {
// We're not animating, just draw the active thingy
entries.get(index).draw(0, 100, spriteBatch, font);
}
}
}
And I believe a simple text-based menu entry that can draw itself would suffice! (do mind the dirty hard-coded text-wrap width!)
public class MenuEntry {
private String label;
// private RenderNode2D graphic;
private Action action;
public MenuEntry(String label, Action action) {
this.label = label;
this.action = action;
}
public void select() {
this.action.execute();
}
public void draw(int x, int y, SpriteBatch spriteBatch, BitmapFont font) {
font.drawMultiLine(spriteBatch, label, x, y, 400, HAlignment.CENTER);
}
}
Oh, and Action is just a thingy that has an execute method and, well, represents an action.
public interface Action {
abstract void execute();
}
Feel free to ask any related question in the comments, and I'll try to clarify what's needed.
Hope this helps!

Wrapping drawn image in XNA 4.0

As you see in the picture above, billy, our little orange dressed man, is going off the screen to the left and appearing on the right side.
This is what I want to happen, however, I can't seem to replicate this effect (I got the picture with some modifications in Paint.net).
Basically, if the players x position is negative, it should wrap to the other side. If the x is larger than the width, it should wrap over to the left side.
Draw it two times when you need it.
void Draw(SpriteBacth batch)
{
batch.Draw(Player.texture, Player.Position, player.Source, player.Color);
if (Player.X <0)
{
bacth.Draw(Player.texture, Player.Position + ScreenHorizontalSize, player.Source, Player.Color);
}
else if (Player.X + Player.Size.Width> ScreenHorizontalSize.Width)
{
bacth.Draw(Player.texture, Player.Position - ScreenHorizontalSize, player.Source, Player.Color);
}
}
void Update()
{
if (Player.X < -Player.Size.Width) Player.X += ScreenHorizontalSize.Width;
if (Player.X > ScreenHorizontalSize.Width) Player.X -= ScreenHorizontalSize.Width;
}
Of course you have to take in mind this when you check for colliding with player, you will have to check in the two positions too.

Resources