Can't receive value from another class on XNA Framework C# - xna

I have several classes on my project: Game1(main class(default)), Animation and Enemy:
public class Animation
{
public int currentFrameHit;
public Animation ()
{
}
public void Update(GameTime gameTime)
{
timeElapsedHit += gameTime.ElapsedGameTime.Milliseconds;
if (timeElapsedHit > 100)
{
timeElapsedHit = 0;
currentFrameHit = (currentFrameHit + 1) % 9;
}
}
}
How can i get value from variable in Animation class?
In Enemy class i can't receive this value from Animation. I tried that:
Animation animation = new Animation();
Console.WriteLine(animation.currentFrameHit);
But i'm getting null, however in main class Game1 i receive right values with same code.

The problem is that you're making a new Animation() without assigning it to anything. so it'll keep returning it's default value.
So far there isn't enough information given on what the number should be though. Do you have the Animation() class inside the Enemy Class, or do you find the Enemy Class within Animation()?

You need to reference to an existing animation value.
Create an instance in your desire class (here it is Game1) and don't forget to make it public.
public static Animation animationGame1 = new Animation();
Then in your second class:
In LoadContent(): reference it to Game1's variable:
Animation animationNewClass = Game1.animationGame1;
In Update(): do what you want to achieve:
Console.WriteLine(animationNewClass.currentFrameHit);
Hope this helps.

Related

Passing values between classes in Vaadin

This might be more of a Java question, but how would you access values (say from a textfield) of a given view/class from a different class? For example if there was a TextField t1 that is in the MainView, and I wanted to get its current value for a computation in a different class. And is there a more Vaadin-specific approach here?
That can depend on the use case specifically. Since you mentioned a TextField value I assume the value is not yet stored in the DB, it's just on the UI yet -> I rule out singleton spring services.
A few ideas:
If the MainView and the different class are nested components and it's viable and not really complicated across a lot of classes... then probably passing it down the way when creating the sub-component. This is a naive solution - it can get pretty messy.
MainView() {
var t1 = new TextField();
var d = new Different(t1);
}
Fire and listen to Vaadin Component events. If you want really loose coupling, the most universal would be to use the UI instance as the event bus.
// listen in different class
ComponentUtil.addListener(attachEvent.getUI(), CloseMenuEvent.class, e -> closeMenu());
// fire change in MainView
ComponentUtil.fireEvent(ui, new CloseMenuEvent(ui))
A more specific version of number 2. is to pass the ValueChangeListener of the MainView's t1 to the different class.
MainView() {
var t1 = new TextField();
var d = new DifferentClass();
t1.addValueChangeListener(d::t1Changed)
add(t1, d);
}
Extract the common field to a third party, to a third class. Use a #UIScoped spring bean (#SpringComponent, #Service, ...) that will hold that field, and inject it to both MainView and the different class.
#Route
public class MainView extends VerticalLayout {
public MainView(Model m, Different d) {
add(m.t1, d);
}
}
#Scope(SCOPE_PROTOTYPE)
public class Different extends Component {
public Different(Model m) {
// something with m.t1
}
}
#UIScoped
public class Model {
public final TextField t1 = new TextField(); // TODO use getter
}
You could change the 4th approach by keeping String in Model and having a value change listener that updates it.

How do I delete a GameComponent from Game.Components?

Basically my game is to stop the rocks falling from the sky using a plank.
I'm not sure what is not functioning correctly, but here is my code:
In the RockManager class
public void CheckForPlankCollision(Plank plank)
{
foreach (GameComponent component in Game.Components)
{
if (component is FallingRock rock)
{
if (plank.Bounds.Intersects(rock.Bounds))
{
rock.HandleCollision();
Rectangle bounds = rock.Bounds;
}
}
}
}
In the Rocks class
public void HandleCollision()
{
//rockPosition = rockAfterImpactPosition; // I tried to move it offscreen
//rockPosition = Vector2.Zero; //I tried for any reaction
//this.Enabled = false; // tried this
//Game.Components.Remove(this); //tried this
}
I'm also trying to implement a scoring system. (add 1 point if the rock hits the plank, subtract a point if it hits the ground)
Try casting this as an IGameComponent or GameComponent object.
public void HandleCollision()
{
Game.Components.Remove((GameComponent)this);
}
Tell me if this works for you !
EDIT: You might also want to defer the deletion of your game object to later, when it isn't used by the foreach (GameComponent component in Game.Components) loop, which might have a lock on removing elements during that time.

Extend UIView with new properties

In my app I need to add to a bunch of UIKit objects some properties; my original thought was to create a subclass of each element I needed and create the properties inside the new class but I realized that this means to write a new class for each UI element type I'm using.
In my specific case, I wanna add to some different views, such as UIImageView and UILabel, two properties called initial position and final position of type CGRect to store the initial and final position in order to use it inside a method which translates this views.
Is there any way to accomplish this without creating lots of classes?
You can do the following:
protocol Position {
var initialPosition: Int { get set }
}
It is not possible to just declare properties in extensions, so you'd need to set your get and set. You can just associate a value:
private var initialPositionKey: UInt = 0
extension Position {
var initialPosition: Int {
get {
return objc_getAssociatedObject(self, &initialPositionKey) as! Int
}
set {
objc_setAssociatedObject(self, &initialPositionKey, newValue, .OBJC_ASSOCIATION_RETAIN)
}
}
}
Then you extend your UIView like this:
extension UIView: Position {}
And the following works:
var view = UIView()
view.initialPosition = 5
print (view.initialPosition) // 5

Actionscript 2 Proper way to define function on MovieClip

I'm trying to write a function on a MovieClip, and call it from the root clip. What works fine in ActionScript 3 doesn't seem to be working properly in ActionScript 2.
Frame 1 of the _root MovieClip:
var newMovieClip:MovieClip = _root.attachMovie('Notification', id, 0);
newMovieClip.SetNotificationText("Test text");
Frame 1 of the Notification MovieClip:
function SetNotificationText(inputText : String){
notificationText.text = inputText;
}
The result is that the MovieClip is created but the text is not changed.
Am I doing this wrong?
To add functions to a MovieClip in AS2, you need to use one of these methods:
Add the method to the prototype of MovieClip:
MovieClip.prototype.SetNotificationText = function(inputText:String):Void
{
if(this["notificationText"] !== undefined)
{
// If we're going to use the prototype, at least do some checks
// to make sure the caller MovieClip has the text field we expect.
this.notificationText.text = inputText;
}
}
newMovieClip.SetNotificationText("Test text");
Make the MovieClip and argument of the function:
function SetNotificationText(mc:MovieClip, inputText:String):Void
{
mc.notificationText.text = inputText;
}
SetNotificationText(newMovieClip, "Test text");
Add the method directly to the newly created MovieClip:
var newMovieClip:MovieClip = _root.attachMovie('Notification', id, 0);
newMovieClip.SetNotificationText(inputText:String):Void
{
notificationText.text = inputText;
}
newMovieClip.SetNotificationText("Test text");
Option 2 is best overall - it's the cleanest and avoids overhead of creating a new function for every new MovieClip. It also avoids messing around with the prototype, which at best should be used to add generic methods, like a removeItem() method on Array.

Actionscript, objects and event listeners

Say I have an object
var my_obj = new Object();
my_obj['key'] = value;
Is there a way to add an event listener to the value, like
my_obj['key'].addEventListener(Blah Blah);
I have a long(ish) list of buttons on the timeline (the layout is so different from section to section that just makes more sense to do on the timeline rather than trying to build the layouts via actionscript).
button1 = plays "frame label 1"
button2 = plays "frame label 2"
and so on....so I was just thinking of storing everything in an array
obj["button1"] = "framelabel1"
arr.push(obj);
Then I could just have one event handler for all of the buttons and use target to get the frame label value...
Yes, you can do exactly what you're asking in the exact way you've mentioned, here's an example:
var value:Sprite = new Sprite();
var my_obj = new Object();
my_obj['key'] = value;
So calling:
my_obj['key'].addEventListener(Event.ENTER_FRAME, _onEnterFrameHandler);
is exactly the same as calling:
value.addEventListener(Event.ENTER_FRAME, _onEnterFrameHandler);
If the value is an IEventDispatcher or extends EventDispatcher you can add a listener to it.
The question is rather obscure to me. My guess is that you need something triggered every time a value is set. If this is the case, then you have to create a custom class, and declare a getter-setter property there.
For instance:
package
{
import flash.display.Sprite;
public class TestAccessor extends Sprite
{
private var someVarValue:uint = 0;
public function TestAccessor()
{
super();
}
public function get someVar():uint
{
return someVarValue;
}
public function set someVar(value:uint):*
{
someVarValue = value;
// this is the place where someVar is set.
// do whatever else you like here,
// you may choose to dispatch an event from here if you need.
}
}
}
Back in AS1-AS2 era we had watch() and addProperty() for that purpose, but these times are long since gone. For good. :)

Resources