I am trying to use LibGDX to make a simple game in which once i clicked on the screen the Texture "eggs" should change to the next one in line. Yet every time i touch the screen the app crashes
Texture[] eggs = new Texture[5];
}
#Override
public void render() {
if (Gdx.input.justTouched()) {
eggs[i] = new Texture(String.format("pic_%d.png", i++));
batch.begin();
batch.draw(eggs[i], Gdx.graphics.getWidth() / 2 - eggs[i].getWidth() / 2, Gdx.graphics.getHeight() / 2 - eggs[i].getHeight() / 2);
batch.end();
}
}}
eggs[i]=... gets evaluated first and gets a Texture object, i is incremented afterwards. Therefore taking it as the index actually refers to an uninitialized Texture element in your array.
Related
We own two objects in the scene. One follows the mouse position on the screen, and the object 2 in turn follows the route object 1 did. We are storing the positions covered by the object 1 and causing the object 2 play them.
When you run the game, an object follows the other quietly, reproducing the stored position ... but when one object's speed is changed (on mouse click increase velocity) the object 2 can not keep up, as this still following the positions already be cached in the array (including the calculations speed). Please, watch the shot video below:
YouTube: https://youtu.be/_HbP09A3cFA
public class Play : MonoBehaviour
{
public Transform obj;
private List<Recorder> recordList;
private float velocity = 10.0f;
private Transform clone;
void Start()
{
recordList = new List<Recorder>();
clone = obj;
}
void Update()
{
if (Input.GetMouseButton(0))
{
velocity = 20.0f;
}
else {
velocity = 10.0f;
}
var dir = Input.mousePosition - Camera.main.WorldToScreenPoint(transform.position);
var angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.AngleAxis(angle, Vector3.forward), 180 * Time.deltaTime);
transform.position += transform.right * Time.deltaTime * velocity;
Camera.main.transform.position = new Vector3(transform.position.x, transform.position.y, Camera.main.transform.position.z);
recordList.Insert(0, new Recorder
{
Position = transform.position,
Rotation = transform.rotation,
Velocity = velocity
});
var x = 8;
if (x < recordList.Count)
{
clone.position = recordList[x].Position;
clone.rotation = recordList[x].Rotation;
clone.position += clone.right * Time.deltaTime * velocity;
}
if (recordList.Count > x)
recordList.RemoveRange(x, recordList.Count - x);
}
}
public class Recorder
{
public Vector3 Position{get;set;}
public Quaternion Rotation{get;set;}
public float Velocity{get;set;}
}
How can we play the positions stored always with the speed of the object 1?
Summary:
If the object 1 is slowly moving object 2 as well;
If the object 2 is running, the object 2 should do the route at a faster speed to always follow the object 1;
Thanks in advance.
If i understood correctly you might want to consider using Queue<T> instead of List<T>. I think it would be a better suited datatype as it represents a FIFO collection (first in, first out), which is how you use List anyway. You can add elements with Enqueue(T) to the end of the queue and always get the first item with Dequeue() (it also removes it). As for Stack<T> (the opposite), there is also a Peek() function which lets you "preview" the next element.
Another thing, it depends on distance and speed, but i have the feeling that storing the position of every frame could become a bit excessive (maybe im just overly concerned though)
I think the issue with your code is that you always get the 8th element of the List.
I am using AndEngine to create Physics Simulations of projectiles being launched. As it simulates, I want to draw the parable's track.
To do so, I am drawing a square every second according to the position of the projectile(sPlayer).
time_handler=new TimerHandler(1, true, new ITimerCallback() {
#Override
public void onTimePassed(TimerHandler pTimerHandler) {
if(simulationOn){ // every 1 second if the simulation is on
int px=(int)sPlayer.getSceneCenterCoordinates()[0];
int py=(int)sPlayer.getSceneCenterCoordinates()[1];
parabola_point=new Rectangle(px, py,4, 4,getVertexBufferObjectManager());
parabola_point.setColor(Color.WHITE);
if(!highest_point_found){ //if highest point not found, check it
float difY = (float) Math.floor(Math.abs(body.getLinearVelocity().y)) ;
if(Float.compare(0f, difY) == 0){ // if it is the highest point
highest_point_found=true;
drawPointText(); //draw the positions on the scene
parabola_point=new Rectangle(px, py,16, 16,getVertexBufferObjectManager());
parabola_point.setColor(Color.RED); // paint this point red
}
}
parabola.add(parabola_point);
scene.attachChild(parabola_point);
}
// pTimerHandler.reset();
}
});
I am using a FixedStepEngine:
#Override
public Engine onCreateEngine(final EngineOptions pEngineOptions) {
return new FixedStepEngine(pEngineOptions, 50);
}
THE PROBLEM IS:
I don't know why onTimePassed is being called faster than 1 second interval.It happens after some seconds.
I read that problaby the FixedStepEngine is changing the interval that 'onTimePassed' is called. How to fix it?
It seems to me that you are not unregistering your timer handlers which causes them to intersect with one another. Try unregistering pTimerHandler
I have created a from which takes the user input and compares it to 100 randomly generated numbers. Once they click the guess button the result is shown. To aid the user I am supposed to give them a hint when they hover the mouse over a label, the hint should be either 3 higher or 3 lower than the actual number. I cannot figure out how to get the random number generated when the user hits the guess button to equal the number as the hover event. Sorry for all the code, any help would be appreciated.
Here is how I am creating my random number:
public partial class Form1 : Form
{
int[] rndArray = new int[100];
public void getNumbers()
{
Random random = new Random();
for (int x = 0; x < rndArray.Length; x++)
{
rndArray[x] = random.Next(1, 100);
}
}
Here is the guss button event:
private void Guess_Click(object sender, EventArgs e)
{
getNumbers();
for (int x = 0; x < rndArray.Length; x++)
{
if (Convert.ToInt32(textBox1.Text) == rndArray[x])
{
result.Text = "You Win!";
correct.Text = "Correct: ";
}
else
{
result.Text = "Sorry - you loose; the number is: " + rndArray[x];
incorrect.Text = "Incorrect: ";
}
}
And the mouse hover event:
private void mouseHere_MouseHover(object sender, EventArgs e)
{
getNumbers();
for (int x = 0; x < rndArray.Length; x++)
hint.Text = "It's not " + (rndArray[x] +- 3);
}
I see three possible issues.
First, at the beginning of your mouse hover and guess click functions, you call GetNumbers, which generates 100 numbers and assigns them to the array. You should only generate them once per game. I would recommend calling it once at the beginning of each game (perhaps in the FormShown or FormLoad event handlers), and not calling it again until the next game begins. Otherwise, the numbers will keep changing.
Second, inside your mouse hover function, you have a for loop that assigns the text to "hint" 100 times. The first 99 hints will probably not be accurate, as the end of your mouse hover event will display the hint for the very last number. You will need to identify which array element to give a hint for, and assign it to the appropriate hint display.
Third, the +- operator is not an actual operator in C#. If this is actually compiling and running, it's probably interpreting it in a manner such as hint.Text = "It's not " + (rndArray[x] + (-3); I would recommend using a Random object to generate a number, then using whether it's odd or even to determine whether to add or subtract. Just make sure you don't reassign the array.
EDIT: With regards to figuring out whether to add or subtract from the hint, make sure you don't randomly generate a hint each time you hover; do it once for that number and store the hint. Otherwise, hovering over it a few times will show both possible hints.
I have a sprite called food which adds to the screen via the use of a timer. more food items are added to the screen over time. How would i hit test all these food sprites with another object?
(the makeItem function creates the sprite btw)
private function placeFood(event:TimerEvent = null):void{
var rndI:uint = Math.floor(Math.random() * DIM); //sets a random integer based on the the floor
var rndJ:uint = Math.floor(Math.random() * DIM);
var rndX:Number = grid[rndI][rndJ].x; // sets a grid position for the food item to go
var rndY:Number = grid[rndI][rndJ].y;
food = makeItem(Math.random() * 0xFFFFFF);// random color
food.x = rndX;
food.y = rndY;
var foodArray:Array = new Array();
foodArray.push(food);
trace(foodArray.length)
addChild(food); //adds the food to the board
for (var i:uint = 0; i < snake.length; i++){
if (rndY == snake[i].y && rndX == snake[i].x){
placeFood();
}
}
}
Add the food items to an array and loop through that array doing hitTestObject. Something like:
var foods:Array = new Array();
foods.push(makeItem(blah));
...
for each (food in foods) {
food.hitTestObject(object);
}
It looks like you're putting items on a fixed grid. Do the food items move around? Your food does not move, and your snake (or whatever collides with the food) does, you can greatly optimize your collision detection by figuring out what grid square(s) the moving object occupies and only checking against food in that local area.
Generally speaking, when you need to do collision detection between many objects, you do it in multiple passes. The first pass would consist of the least computationally expensive checks to cull things that could not possibly be colliding such as objects that are very far apart, moving away from each other, etc. Your next pass might be something like simple boundary box or circle tests. Lastly, when you're down to the few items that pass all the cheap tests, you can use more expensive and accurate hit tests like pixel-by-pixel ones between hit masks.
Another way avoiding arrays is to use a sprite that contains all food. Every sprite is a collection of sprites and therefore a tree. That's what I use for hit detection: 1 special sprite contains only enemies / food. Run through all children and you don't even need to check the types of them. Cast them if needed.
// begin
var foodCollection: Sprite = new Sprite();
// time passes, food is added
foodCollection.addChild(food);
// hit test
for (var i:int = 0; i < foodCollection.NumChildren; i++)
{
var food: Sprite = foodCollection.getChildAt(i);
// test
}
I have a WPF Canvas with some Ellipse objects on it (displayed as circles). Each circle is from a collection class instance which is actually a custom hole pattern class. Each pattern has a certain number of circles, and each circle then gets added to the canvas using an iteration over the collection using the code below.
So, the canvas is populated with a bunch of circles and each circle belongs to a certain pattern instance. You can see a screenshot here: http://twitpic.com/1f2ci/full
Now I want to add the ability to click on a circle on the canvas, and be able to determine the collection it belongs to, so that I can then do some more work on the selected pattern to which that circle belongs.
public void DrawHoles()
{
// Iterate over each HolePattern in the HolePatterns collection...
foreach (HolePattern HolePattern in HolePatterns)
{
// Now iterate over each Hole in the HoleList of the current HolePattern...
// This code adds the HoleEntity, HoleDecorator, and HoleLabel to the canvas
foreach (Hole Hole in HolePattern.HoleList)
{
Hole.CanvasX = SketchX0 + (Hole.AbsX * _ZoomScale);
Hole.CanvasY = SketchY0 - (Hole.AbsY * _ZoomScale);
canvas1.Children.Add(Hole.HoleEntity);
}
}
}
All FrameworkElements have a Tag property which is of type object that can be used to hold arbitrary information. You could assign the HolePattern to the Tag property and easily use that later to get the associated collection.
i.e.:
...
Hole.HoleEntity.Tag = HolePattern as object;
canvas1.Children.Add(Hole.HoleEntity);
later on in the click event:
event(object sender,....)
{
Ellipse e = sender as Ellipse;
HolePattern hp = e.Tag as HolePattern;
...
}
So you probably already read my reply where I said I had it working. And it does work perfectly, (except that it requires great precision with the mouse), but I want to ask this: is it really smart to add an event handler to EVERY ellipse that gets added to a canvas? Now I don't know what kind of memory bog that could be, or maybe it is a piece of cake for WPF and Windows to handle.
In a practical case, I guess there would be not more that 30-50 holes even on a screen that had multiple patterns, but still; FIFTY event handlers? It just seems scary. And actually, each "Hole" is visually represented by two concentric circles and a text label (see the screenshow here: http://twitpic.com/1f2ci/full ), and I know the user would expect to be able to click on any one of those elements to select a hole. That means an event handler on 3 elements for every hole. Now we could be talking about 100 or more event handlers.
It seems like there should be a solution where you could have just one event handler on the Canvas and read the element reference under the mouse, then work off of that to get the .Tag property of that elment, and so on.
I thought I'd post my final and more refined solution in case it helps anyone else.
void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
int ClickMargin = 2;// Adjust here as desired. Span is in both directions of selected point.
var ClickMarginPointList = new Collection<Point>();
Point ClickedPoint = e.GetPosition(canvas1);
Point ClickMarginPoint=new Point();
for (int x = -1 * ClickMargin; x <= ClickMargin; x++)
{
for (int y = -1 * ClickMargin; y <= ClickMargin; y++)
{
ClickMarginPoint.X = ClickedPoint.X + x;
ClickMarginPoint.Y = ClickedPoint.Y + y;
ClickMarginPointList.Add(ClickMarginPoint);
}
}
foreach (Point p in ClickMarginPointList)
{
HitTestResult SelectedCanvasItem = System.Windows.Media.VisualTreeHelper.HitTest(canvas1, p);
if (SelectedCanvasItem.VisualHit.GetType().BaseType == typeof(Shape))
{
var SelectedShapeTag = SelectedCanvasItem.VisualHit.GetValue(Shape.TagProperty);
if (SelectedShapeTag!=null && SelectedShapeTag.GetType().BaseType == typeof(Hole))
{
Hole SelectedHole = (Hole)SelectedShapeTag;
SetActivePattern(SelectedHole.ParentPattern);
SelectedHole.ParentPattern.CurrentHole = SelectedHole;
return; //Get out, we're done.
}
}
}
}