Game dev -Finding img sprites coords Haxe + Haxeflixel - haxe

I'm trying to make a combat system in haxe I made my sprites and now I need to find out the uv coordinates for them how do I achieve that ?
Example from my existing code :
animation.add("lr", [3, 4, 3, 5], 6, false);
animation.add("u", [6, 7, 6, 8], 6, false);
animation.add("d", [0, 1, 0, 2], 6, false);
I tried :
if (FlxG.mouse.justPressed) {
// Attack code here
}

Haxeflixel's sprite sheet system doesn't use UV coordinates, it assumes all sprites in the sheet are the same size and consistently spaced apart.
Look at the API reference for FlxSprite.loadGraphic. The animation tutorial uses that function like this:
loadGraphic(AssetPaths.player__png, true, 16, 16);
This means the sprites are in a 16x16 grid, and they're indexed from left to right, top to bottom (with the left-most being index 0).
Here's a visual example of how the coordinates map to indices:
And here's that same sprite, but with two rows instead of one:
Compare those indices to the values in the sample code:
animation.add("lr", [3, 4, 3, 5], 6, false);
animation.add("u", [6, 7, 6, 8], 6, false);
animation.add("d", [0, 1, 0, 2], 6, false);
The second parameter to add is an array of indices that make up the animation.
So to add a punch animation, just put the frames into the existing grid, and reference them using their indices in the overall spritesheet.
As far as implementing a "combat system", that's a more involved thing. If you just want to play an attack animation, you can make it a non-looping animation, and use a callback function to detect when it ends. Example:
//...defined somewhere in your sprite class
var is_punching:Bool = false;
//...somewhere inside your constructor maybe
animation.finishCallback = function(name:String){
switch(name){
case "punch-u", "punch-lr", "punch-d":
is_punching = false;
default:
trace("Some other animation finished: " + name);
}
}
//...somewhere in your update function
if (FlxG.mouse.justPressed && !is_punching) {
is_punching = true;
switch (facing)
{
case LEFT, RIGHT:
animation.play("punch-lr");
case UP:
animation.play("punch-u");
case DOWN:
animation.play("punch-d");
case _:
}
}
Then you can check if is_punching is true to prevent the player from walking while punching, or to damage an enemy if they collide with the player while they're punching.

Related

Crossover and mutation in Differential Evolution

I'm trying to solve Traveling Salesman problem using Differential Evolution. For example, if I have vectors:
[1, 4, 0, 3, 2, 5], [1, 5, 2, 0, 3, 5], [4, 2, 0, 5, 1, 3]
how can I make crossover and mutation? I saw something like a+Fx(b-c), but I have no idea how to use this.
I ran into this question when looking for papers on solving the TSP problem using evolutionary computing. I have been working on a similar project and can provide a modified version of my written code.
For mutation, we can swap two indices in a vector. I assume that each vector represents an order of nodes you will visit.
def swap(lst):
n = len(lst)
x = random.randint(0, n)
y = random.randint(0, n)
# store values to be swapped
old_x = lst[x]
old_y = lst[y]
# do swap
lst[y] = old_x
lst[x] = old_y
return lst
For the case of crossover in respect to the TSP problem, we would like to keep the general ordering of values in our permutations (we want a crossover with a positional bias). By doing so, we will preserve good paths in good permutations. For this reason, I believe single-point crossover is the best option.
def singlePoint(parent1, parent2):
point = random.randint(1, len(parent1)-2)
def helper(v1, v2):
# this is a helper function to save with code duplication
points = [i1.getPoint(i) for i in range(0, point)]
# add values from right of crossover point in v2
# that are not already in points
for i in range(point, len(v2)):
pt = v2[i]
if pt not in points:
points.append(pt)
# add values from head of v2 which are not in points
# this ensures all values are in the vector.
for i in range(0, point):
pt = v2[i]
if pt not in points:
points.append(pt)
return points
# notice how I swap parent1 and parent2 on the second call
offspring_1 = helper(parent1, parent2)
offspring_2 = helper(parent2, parent1)
return offspring_1, offspring_2
I hope this helps! Even if your project is done, this could come in handy GA's are great ways to solve optimization problems.
if F=0.6, a=[1, 4, 0, 3, 2, 5], b=[1, 5, 2, 0, 3, 5], c=[4, 2, 0, 5, 1, 3]
then a+Fx(b-c)=[-0.8, 5.8, 1.2, 0, 3.2, 6.2]
then change the smallest number in the array to 0, change the second smallest number in the array to 1, and so on.
so it return [0, 4, 2, 1, 3, 5].
This method is inefficient when used to solve the jsp problems.

Creating a for loop to find mean for a specific section of list

I would like to loop a list to find the mean for a specific window.
What I mean by this is for example:
num_list=[1,2,3,4,5]
window=3
Thus, I would find the mean for [1,2,3] , [2,3,4] and [3,4,5].
How I approached this was as the following:
average_list=[]
first_list=num_list[0:window]
def mean(data):
n=len(data)
mean=sum(data)/n
return mean
for i in first_list:
first_value=mean(i)
average_list.append(first_value)
I am not quite sure how to incorporate the other two lists without typing it individually. Any help would be greatly appreciated!!
You can use list comprehension to iterate num_list taking slices of length window.
Try this:
mean_lst = [sum(num_list[i:i+window])/window for i in range(len(num_list)-window + 1)]
Result is
[2.0, 3.0, 4.0]
Here's the most obvious solution to your problem:
for i in range(list_len-window+1):
average_list.append(mean(num_list[i:i+window]))
It does work properly, but it isn't optimal. Consider num_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and window = 5. Using obvious method, the code will first calculate the sum of [1, 2, 3, 4, 5], then divide by 5, then it will calculate the sum of [2, 3, 4, 5, 6], then divide by 5, and so on.
This code is clearly doing a lot more calculations than it needs to. An optimal way would be to calculate the mean of first window and then for calculating mean of every consecutive window remove the first_element_of_previous_window/window_size (1/5 for 2nd window) and add last_element_of_current_window/window_size (6/5 for 2nd window) to the mean of previous window. This approach avoids a lot of unnecessary calculations.
Code Implementation:
prev_mean = mean(num_list[:window])
average_list = [prev_mean]
for i in range(1, list_len-window+1):
prev_mean -= num_list[i-1] / window
prev_mean += num_list[i+window-1] / window
average_list.append(prev_mean)

After making a copy of a matrix (list of lists), why does double indexing the copy change the original but indexing does not?

I have a matrix defined as a global variable:
BOARD = [
[0, 0, 3],
[2, 0, 0],
[0, 0, 0]
]
However, when manipulating this matrix, I want to leave the original untouched and instead work on a copy. So I did this in the main function in order to make an independent copy:
board = BOARD[:]
As expected, the results of board == BOARD and board is BOARD are True and False, respectively. So when I make an edit like so board[0] = [1, 0, 3], then only board is changed, which is fine. However, if I do board[0][0] = 1, then BOARD also changes, which is not what I expected. And stranger still, board is BOARD is still False.
Why is there this inconsistent behaviour and any suggestions on how I can get around it?
EDIT:
If I run:
board = BOARD[:]
board[0] = [1, 0, 3]
board[0][0] = 2
then BOARD does not change.
But I only added the single indexing for comparison. In the real program I want to be able to do this:
board = BOARD[:]
board[0][0] = 2
But this is where BOARD does change, even though I would like it to stay constant.
I'm not getting this error. Here is my code:
BOARD = [
[0, 0, 3],
[2, 0, 0],
[0, 0, 0]
]
board = BOARD[:]
print(board == BOARD) # prints True
board[0] = [1,0,3]
print(board == BOARD) # prints False
board[0][0] = 1
print(board == BOARD) # still prints False
After reading AkThao's clarification I understood what was going on.
Python uses pointers to implement lists.
For example, if you set a = [1,2,3] and b = a. If you then modify b[0] = 5, a will also be modified because both a and b are pointers to the same memory location.
2D lists are implemented using a pointer to pointers (double pointer), i.e. a list of pointers like [p1, p2, p3].
When you do board = BOARD[:], it creates a copy of the list, but it does not change the actual value of the pointers (the elements of the list). So, the list board will is essentially just a copy of the 3 different pointer values.
This is why when you do board[0][0] = 1, it changes the value of BOARD as well (because the actual pointer stored by board is unchanged).
When you do board[0] = [1, 0, 3] as I have done, you are changing the actual value of the pointer, which is why the original BOARD does not change afterwards.
Why does BOARD change at all?
BOARD and b are both references.
When coding vec = b you assign b address to BOARD. Therefore changing data in b will also "change" BOARD.
I have also tried every method to copy a list ,but one method was succesful,
b=copy.deepcopy(BOARD)
although the deepcopy is time consuming for large lists you can try it.
import copy
B = [
[0, 0, 3],
[2, 0, 0],
[0, 0, 0]
]
print(B)
b=copy.deepcopy(B)
b[0][0] = 2
print(b)
print(B)
output:
[[0, 0, 3], [2, 0, 0], [0, 0, 0]]
[[2, 0, 3], [2, 0, 0], [0, 0, 0]]
[[0, 0, 3], [2, 0, 0], [0, 0, 0]]
hope this helps you!

GPUImage and Syphon

I have implemented a syphon server within a GPUImage application. However it produces a triangular area as seen in the attached image.
Can anyone say what’s wrong looking at the image?
Or Code?
In MyView#viewDidLoad
NSOpenGLContext *ctx = [[GPUImageContext sharedImageProcessingContext] context];
syphonServer = [[SyphonServer alloc] initWithName:#”MyServer” context:ctx.CGLContextObj options:[NSDictionary dictionaryWithObject:SyphonImageFormatRGBA8 forKey:SyphonServerOptionImageFormat]];
At the end of the myFilter#renderToTextureWithVertices
[myServer publishFrameTexture:[firstInputFramebuffer texture] textureTarget:GL_TEXTURE_RECTANGLE_EXT imageRegion:NSMakeRect(0, 0, size.width, size.height) textureDimensions:size flipped:YES];
Thanks for the input.
My hypothesis is that two things are wrong:
You're not clearing the back buffer before drawing the texture, leading to the garbled text you see.
The full screen rectangle you draw uses the wrong indices for the second triangle. If numbered 0, 1, 2, 3 (clockwise, starting at top left), it looks like the indices are [0, 1, 3] and [0, 2, 3], instead of [0, 1, 3] and [1, 3, 2].

Set certain position of FlxSprite's loadgraphic method

I have a 122 * 16 image.
It has seven colors, and I use only one color per block.
But, loadGraphic() in the FlxSprite class just uses width and height.
How do I use certain position of image?
For example, if I choose 0, loadGraphic() picks up the position width, height(0 to 15, 16), choose 1, (17 ~ 31, 16)
Could you use an animation but change the current frame manually? Something like this:
var sprite = new FlxSprite(100, 100);
sprite.loadGraphic("assets/image.png", true, 122, 16);
sprite.animation.add("my_animation", [0, 1, 2, 3, 4, 5, 6], 0, false);
sprite.animation.play("my_animation", true, 0);
//sprite.animation.paused = true;
sprite.animation.frameIndex = 2; // The frame you want to display

Resources