Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
i want to detect collision of a sprite with another sprite. but i want to check whether the sprite is touched with left part of other sprite or touched with right part of sprite.
i am using below code for detecting collision. but this detect the overall collision(sprite touched to at any point of other sprite). but want to count is as collision if the sprite is touched to front side of other sprite.
if (CGRectIntersectsRect(sprite1.boundingBox, sprite2.boundingBox)) {
NSLog(#"sprite1 to delete");
}
any one know how to do this?
Would you be able to compare the positions of the sprites at the time of collision?
Assume sprite1.anchorpoint, sprite2.anchorpoint = ccp(0,0). At time when collision is detected:
// left part of sprite 1 touched right part of sprite 2
if (sprite1.position.x == sprite2.position.x + sprite2.contentSize.width.x) {
}
// right part of sprite 1 touched left part of sprite 2
else if (sprite1.position.x + sprite1.contentSize.width.x == sprite2.position.x) {
}
By default in cocos2d the anchorpoint of a CCSprite is ccp(0.5, 0.5) which modifies the comparison of sprite positions.
Comparing positions for the purpose to check relative distance between sprites in a gameloop, I think the equality operator is not the best choice, greater/less than equal is better to prepare different position situations, sprite moving steps.
To understand better I included the sprite situations for example:
To check the relative position (to detect a sprite is on what side of the other sprite) you have different choices to program in your collision detection check:
1)
if (CGRectIntersectsRect(sprite1.boundingBox, sprite2.boundingBox)) {
CGPoint diff = ccpSub(sprite1.position, sprite2.position)
if (diff.x<=0) {
// sprite1 is on the left side
} else {
// sprite1 is on the right side
}
}
2)
if (CGRectIntersectsRect(sprite1.boundingBox, sprite2.boundingBox)) {
if (sprite1.position.x <= sprite2.position.x) {
// sprite1 is on the left side
} else {
// sprite1 is on the right side
}
}
Related
I am using tilemaps and animated tiles from the 2dExtras in unity.
My tiles have 6 frames, at speed=2f, and my tilemap frame rate is 2.
New tiles placed always start on frame 1 and then immediately jump to the current frame of the other tiles already placed, the tilemap is keeping every tile at the same pace, which is working as I want.
However I would like the newly placed tiles to start at the frame the others are currently on,(instead of placing a tile that jumps from frame 1 to frame 4) I would like the new tile to start on frame 4
I've found how to pick the frame I want to start on, however I am having trouble retrieving which frame the animation is currently on, so I was wondering how exactly can I access the current frame of animation of a given tilemap ( Or a given tile, I can create a dummy tile and just read the info out of it, how can I get the current frame of an animated tile? )
The animated tilemaps feature seems to lack the feature to retrieve this information, also when I try tilemap.getsprite it always returns the first frame of the sequence(does not return the sprite currently displayed), and there doesn't seem to be any method to poll info from tilemap.animationFrameRate.
I thought another method would be to set a clock and sync it to the rate of the animation but since I can't get the exact framerate duration the clock eventually goes out of sync.
Any help would be appreciated!
I found a way to solve this question. But it's not 100% insurance.
First of all, I used SuperTile2Unity. That doesn't seem to be the point.
private void LateUpdate()
{
// I use this variable to monitor the run time of the game
this.totalTime += Time.deltaTime;
}
private void func()
{
// ...
TileBase[] currentTiles = tilemap.GetTilesBlock(new BoundsInt(new Vector3Int(0, 0, 0), new Vector3Int(x, y, 1)));
Dictionary<string, Sprite> tempTiles = new Dictionary<string, Sprite>();
//I use SuperTiled2Unity. But it doesn't matter, the point is to find animated tile
foreach (SuperTiled2Unity.SuperTile tile in currentTiles)
{
if (tile == null)
{
continue;
}
if (tile.m_AnimationSprites.Length > 1 && !tempTiles.ContainsKey(tile.name))
{
// find animated tile current frame
// You can easily find that the way SuperTile2Unity is used to process animation is to generate a sprite array based on the time of each frame set by Tiled animation and the value of AnimationFrameRate parameter.
// The length of array is always n times of AnimationFrameRate. You can debug to find this.
tempTiles.Add(tile.name, tile.m_AnimationSprites[GetProbablyFrameIndex(tile.m_AnimationSprites.Length)]);
}
}
//...
}
private int GetProbablyFrameIndex(int totalFrame)
{
//According to the total running time and the total length of tile animation and AnimationFrameRate, the approximate frame index can be deduced.
int overFrameTime = (int)(totalTime * animationFrameRate);
return overFrameTime % totalFrame;
}
I have done some tests. At least in 30 minutes, there will be no deviation in animations, but there may be a critical value. If the critical time is exceeded, there may be errors. It depends on the size of AnimationFrameRate and the accumulation mode of totalTime. After all, we don't know when and how the unity deals with animatedTile.
You could try using implementation presented in [1] which looks as follows:
MyAnimator.GetCurrentAnimatorClipInfo(0)[0].clip.length * (MyAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime % 1) * MyAnimator.GetCurrentAnimatorClipInfo(0)[0].clip.frameRate;
[1] https://gamedev.stackexchange.com/questions/165289/how-to-fetch-a-frame-number-from-animation-clip
I have an obj_roulette, which contains 4 subimages, with value 2-5 and image_number 0-3. The value result from roulette stored as var global.roulette.
Then, I make many obj_meteorite, which contains 4 subimages too, spawn from above with random x value and random image_number. Player can shoot them with left-mouse click.
This is what I want:
If image_number obj_roulette is 0, and player shoot obj_meteorite with image_number 0, score +10.
If image_number obj_roulette is 0, and player shoot obj_meteorite with image_number 1, score -10.
I don't know how to check collision between mouse_x/mouse_y and object image_number, and how to match obj_roulette image_number and obj_meteorite image_number.
Is it using collision checking? If it yes, then maybe the examples in these links can help:
link 1
link 2
Please explain your answer. Thanks.
I assume this is the kind of game where you click with your mouse and hit exactly where the mouse was clicked. And as I understand it from your question. If the mouse is clicked and obj_roulette's image_index is the same as obj_meteorite, you want to add 10 to the score. If not, you want to subtract 10 from the score. And you need help converting your pseudo-code into gml.
// Check if obj_meteorite was clicked
if (mouse_check_button_released(mb_left) && position_meeting(mouse_x, mouse_y, obj_meteorite))
{
// Check wheter or not obj_meteorite's and obj_roulette's image_index is the same
if (obj_meteorite.image_index == obj_roulette.image_index)
{
// Add 10 to the score
score += 10;
}
else
{
// Subtract 10 from the score
score -= 10;
}
}
If this is not what you want, I suggest editing your question to make it more clear. Preferably explain shortly what your game is actually about.
So first off, what I'm trying to do but clearly failing to is prevent a sprite "the player" from moving off the edge of the map "400x400px img".
The controls on the game are buttons for moving right, left, up and down.
I have it so when the buttons are pressed it runs a function that checks if the player's destination is off the map's area.
****Note That the Map is a 5x5 grid map, each square of the grid is 80x80 inside map image****
Here's the function that checks if the player's destination is off the map:
func checkBordersDownPlayer() {
if player.position.y - 80 == map.position.y - 80 {
print("Node cannot move. Map borders are stopping the Node from moving past it's boundaries.")
}
else {
player.runAction(moveDown)
print("Player was able to move!")
}
}
Now what troubles me is that the player automatically ignores the print() functions and the if function but still runs the SKAction to move it.
What I could asses from your post is that perhaps you are not clear about the position concept of sprite node.
Unlike UIKit in which position of a frame is at the top left corner of the Rectangle, in Spritekit a node's position is at its center by default unless you will play with its anchor point.
Again taking your situation into consideration, you should use the tools provided by Spritekit for efficiently handling such tasks, You should use Physics body around the map image and make your player another physics body assigning them different physics categories.
In your case you don't need to assign any contact test bit mask or collision bit mask untill you are not interested in getting informed when the player touches the boundary set by you. You can refer to this tutorial for more https://www.raywenderlich.com/123393/how-to-create-a-breakout-game-with-sprite-kit-and-swift
Hope this helps.
Without knowing more of how you calculate movement the best I can do is guess this is your problem.
player.position.y - 80 == map.position.y - 80
Instead you probably want something like this...
player.position.y - 80 <= map.position.y - 80
Hopefully that helps
edit
One step further would be to reset the players position too...
func checkBordersDownPlayer() {
if player.position.y - 80 <= map.position.y - 80 {
player.position.y = map.position.y - 80
print("Node cannot move. Map borders are stopping the Node from moving past it's boundaries.")
}
else {
player.runAction(moveDown)
print("Player was able to move!")
}
}
Alright I'm offically stumped. I've been able to figure out my problems myself in the past but I'm lost on this one.
I'm trying to flip a child sprite's xscale. I want the flip to occur when the child's x position is negative. With the code below, the sprite does flip, every time the sprite reaches negative position, it loops back and forth flipping until reaching positive again.
I've tried numerous variations, but this is the code in it's simplest form. Any help or alternatives would be appreciative.
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
let pin = childNodeWithName(Pin1) as SKSpriteNode!
let guyPoint = guy.convertPoint(guy.position, fromNode: pin)
if guyPoint.x <= 0 {
guy.xScale = -1
}
else {
guy.xScale = 1
}
}
So if it is constantly flipping it's probably an issue of coordinate space. So check to make sure your convertPoint method is accurately returning the point you want. I would use println() to see what's going on there.
Probably what's happening is you want to flip the xScale when the child node is negative in the scene space or something (i.e. when the child is off the screen) but instead guyPoint might be the position of the child in its parent's coordinate space (so relative to the parent).
Also try with and without the else{} part to see if that changes anything.
i want to determine if the sprite is in the screen or not in cocos2d.
am using the code some thing like these.
CGSize winSize = [CCDirector sharedDirector].winSize;
if (_SmallBlueAlien1.position.x> 0 || _SmallBlueAlien1.position.x > winSize.width || _SmallBlueAlien1.position.y> 0 || _SmallBlueAlien1.position.y > winSize.height)
{
//Sprite is not in the screen)
}
but not working properly. were am mistaking.
correct me
Unless you changed the anchor point of the sprite this is only testing if half of the sprite is on the screen. To fix this you want to check if
_SmallBlueAlien1.position.x > [_SmallBlueAlien1 contentSize].texture.width / 2;
You can follow this process for all the other interactions.
//Edit
As phix23 noted this does not account for rotation or scale but should work if you are doing neither of those.
regardless of the semantics of 'position' in coco, your '>' should be '<' for both x and y, assuming your interpretation of the .position property holds. It is likely however that the 'sprite'.position is in reference to an enclosing object, thus even when your test is corrected, it may still not give you what you want to know ('visible on screen').