Cocos2d js Chipmunk collision filter - cocos2d-x

I'm using cocos2d js 3.8 with chipmunk physics, I'm trying to filter collision but it's not work, i have set
shape.categoryBits =1;shape.maskBits =2;
for player and shape.categoryBits =3;shape.maskBits =4; for enemies
but they're still colliding. Did i do something wrong?

I'm not sure about js, but I think collision detection the same as in Cocos2d-x.
So, try set shape.categoryBits = 1; shape.maskBits = 1; for player and shape.categoryBits = 2; shape.maskBits = 2; for enemies. In this case, the hero should not collide the enemies, but the enemies should collide each other.
The basic idea is the condition for the non-colliding objects:
(shapeA.categoryBits & shapeB.maskBits == 0) || (shapeB.categoryBits & shapeA.maskBits == 0)
But now you have (0001 & 0100 == 0) || (0011 & 0010 == 0) is false because 0011 & 0010 = 0010, and condition is not met.

Related

Control timeline with pinchzoom in Actionscript 3.0

I'm using Actionscript 3.0 in Flash. Is there a way to control the timeline with pinching (so instead of zooming out/in you are moving the timeline back/forth)? I'm working on an story app where the player is in control of the story.
You could do something like the following:
import flash.events.TransformGestureEvent;
Multitouch.inputMode = MultitouchInputMode.GESTURE;
stop();
//listen on whatever object you want to be able zoom on
stage.addEventListener(TransformGestureEvent.GESTURE_ZOOM , zoomGestureHandler);
function zoomGestureHandler(e:TransformGestureEvent):void{
//get the zoom amount (since the last event fired)
//we average the two dimensions (x/y). 1 would mean no change, .5 would be half the size as before, 2 would twice the size etc.
var scaleAmount:Number = (e.scaleX + e.scaleY) * 0.5;
//set the value (how many frames) to skip ahead/back
//we want the value to be at least 1, so we use Math.max - which returns whichever value is hight
//we need a whole number, so we use Math.round to round the value of scaleAmount
//I'm multiplying scaleAmount by 1.25 to make the output potentially go a bit higher, tweak that until you get a good feel.
var val:int = Math.max(1, Math.round(scaleAmount * 1.25));
//determine if the zoom is actually backwards (smaller than before)
if(scaleAmount < 1){
val *= -1; //times the value by -1 to make it a negative number
}
//now assign val to the actual target frame
val = this.currentFrame + val;
//check if the target frame is out of range (less than 0 or more than the total)
if(val < 1) val = this.totalFrames + val; //if less than one, add (the negative number) to the totalFrames value to loop backwards
if(val > this.totalFrames) val = val - this.totalFrames; //if more than total, loop back to the start by the difference
//OR
if(val < 1) val = 0; //hard stop at the first frame (don't loop)
if(val > this.totalFrames) val = this.totalFrames; //hard stop at the last frame (don't loop)
//now move the playhead to the desired frame
gotoAndStop(val);
}

Cocos2dx - Unable to set velocity = 0.0

I'm making an pool game with cocos2dx.
First, i setup the edgeBox with this parameters PhysicsMaterial(1.0f, 1.0f, 0.8f)
And then these 2 balls PhysicsMaterial(1.0f, 1.0f, 0.5f)
On the update function, i want slow down balls time by time without gravity (like making ground friction) by adding
physicsBody->setLinearDamping(0.3);
On the update function, i set the minimum velocity, if the velocity of each ball reaches lower than 15, reset velocity to 0,0
auto MV = 15;
auto v1 = player1->getPhysicsBody()->getVelocity();
auto v2 = player2->getPhysicsBody()->getVelocity();
if (v1.x > MV || v1.x < -MV ||
v1.y > MV || v1.y < -MV) {
} else if(v1 != Vec2(0,0)) {
player1->getPhysicsBody()->setVelocity(Vec2(0,0));
CCLOG("sx 1 : %f %f",v1.x,v1.y);
}
if (v2.x > MV || v2.x < -MV ||
v2.y > MV || v2.y < -MV) {
} else if(v2 != Vec2(0,0)) {
player2->getPhysicsBody()->setVelocity(Vec2(0,0));
CCLOG("sx 2 : %f %f",v2.x,v2.y);
}
Everything works fine except when the balls stand next to the wall or each other. I see the small blue glue to these objects, this is when the contact has been made.
And in these situation, i can't set the velocity to 0,0.
I think there is some kind of force constantly changing the velocity. You can see the image below to see the blue glue and keep setting velocity = 0.0 like forever.
Firstly reset forces before setting velocity to zero: player2->getPhysicsBody()->resetForces();
Also gravity can be a cause that bodies continue to move.
So you can set gravity to zero for whole physics world. For example:
auto scene = Scene::createWithPhysics();
scene->getPhysicsWorld()->setGravity(Vec2(0, 0));
or just for one particular body:
player2->getPhysicsBody()->setGravityEnable(false);
or you can customize velocity function:
#include "chipmunk.h"
cocos2d::PhysicsBody * pBody = player2->getPhysicsBody();
pBody->getCPBody()->velocity_func = customVelFunc;
where customVelFunc could be defined as:
void customVelFunc(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
{
cpBodyUpdateVelocity(body, cpvzero, damping, dt);
}

Multiple conditions for an if statement? (code doesn't work)

This is for a jigsaw-like puzzle game. I want it so it goes directly to the next scene after all the pieces are in place. So beside each "map piece" is the coordinate where it will be in its proper place.
BUT //surprise surprise// it doesn't work :c is it even possible to put so many conditions in the first place?
Thank you for reading c: (justABeginner)
if (map1.x== 259.45 &&
map1.y== 77.05 &&
map2.x== 368.3 &&
map2.y== 69.45 &&
map3.x== 445.30 &&
map3.y== 90.4 &&
map4.x== 288.5 &&
map4.y== 207.15 &&
map5.x== 325.75 &&
map5.y== 164.65 &&
map6.x== 436.20 &&
map6.y== 187.65)
{
gotoAndStop (1, "Scene 3");
}
The code looks fine to me. If the condition doesn't evaluate to true, then it might actually be the values which are different. How about a simple debugging step before the If statement like printf to check if the values are exactly the same.
Sometimes, the precision will play a large role in such If statements.
Happy coding :)
You'll probably find its not working because its particularly difficult to align an object with sub pixel accuracy. Because of this, you may want to consider "flooring" or "rounding" your numbers. I would suggest flooring to avoid it being rounded up to the next value.
if (Math.floor(map1.x) == 259 && Math.floor(map1.y) == 77 &&
Math.floor(map2.x) == 368 && Math.floor(map2.y) == 69 &&
Math.floor(map3.x) == 445 && Math.floor(map3.y) == 90 &&
Math.floor(map4.x) == 288 && Math.floor(map4.y) == 207 &&
Math.floor(map5.x) == 325 && Math.floor(map5.y) == 164 &&
Math.floor(map6.x) == 436 && Math.floor(map6.y) == 187)
{
gotoAndStop (1, "Scene 3");
}
Doing something like this will give you a more "fuzzy" comparison and should be easier to line up the puzzle pieces. Also, you may want to consider perhaps helping the user by adding a "snap to place" feature ...
function inrange(targetX, targetY, mapX, mapY, strength) {
targetX -= (strength / 2);
targetY -= (strength / 2);
return (mapX >= targetX && mapX <= (targetX+strength) &&
mapY >= targetY && mapY <= (targetY+strength));
}
//snap map piece into place if within 3 pixels
if (inrange(259, 77, map1.x, map1.y, 3)) {
map1.x = 259;
map1.y = 77;
}
As a general piece of advice, you should never use an equality check (==) with a floating point number. At some point you will find that you can't trust that 0.5 + 0.2 would equal 0.7. it may end up equalling 0.70000000001 or 0.6999999999999
As others have mentioned, try rounding your numbers, or better yet, try a small range, within which the piece is snapped into position, say plus or minus 10 pixels either way?

IDs and SubIDs for collision in AS3 SHMUP

My collision process involves checking simple hitbox and pixel perfect bitmap overlap before using object variables to determine if things SHOULD hit. Weapons, enemies, and objects have an ID number and collisionID array that say what should be able to affect what eg. ID = 1, collisionID = [2,3,4], ID 1 collision with ID 2, 3, or 4 are valid.
I want enemy bullets (which share an ID number with all other Weapon objects) to only be affected by a shield weapon. I figured I could make a subID variable, but I can't figure a concise way for that to be referenced. Below is the function that uses the current IDs.
private function compareHitID(object1:WorldObject, object2:WorldObject):Boolean{
var included:Boolean = false;
if(object1 != null && object2 != null){
for(var i:int = 0; i <= object1.collisionID.length - 1; i++){
if(object1.collisionID[i] == object2.gameID)
included = true;
}
}
return included;
}
Any ideas on how to include subIDs, and store and reference them neatly would be greatly appreciated.

Need help creating game close to "Pong" (Pygame)

As you read from the description (or not), I need help creating a game close to Pong.
I am really new in programming, and I am learning all by myself. The game you help me create will be my first game ever.
My version of game, explained:
Picture (Can't post a picture here since I am new):
http://www.upload.ee/image/3307299/test.png (THIS LINK IS SAFE)
So, number 1 stands for walls (black ones)
Number 2 marks the area, where time stops (game over)
3 is your time survived.
Number 4 is the ball that bounces (like they do in Pong).
Code:
import pygame
import random
pygame.init()
screen = pygame.display.set_mode([640, 480])
paddle = pygame.image.load("pulgake.png")
pygame.display.set_caption("PONG!")
back = pygame.image.load("taust.png")
screen.blit(back, (0, 0))
screen.blit(paddle, (600, 240))
pygame.display.flip()
xpaddle = 600
ypaddle = 240
delay = 10
interval = 10
pygame.key.set_repeat(delay, interval)
while True:
screen.blit(back, (0,0))
screen.blit(paddle, (xpaddle, ypaddle))
pygame.display.flip()
pygame.time.delay(20)
for i in pygame.event.get():
if i.type == pygame.QUIT:
sys.exit()
elif i.type == pygame.KEYDOWN:
if i.key == pygame.K_UP:
ypaddle = ypaddle - 10
if ypaddle < 10:
ypaddle = 10
elif i.key == pygame.K_DOWN:
ypaddle = ypaddle + 10
if ypaddle > 410:
ypaddle = 410
I would like to have a bouncing ball, but i don't have the knowledge to create it.
It doesn't have to be really difficult(maybe using pygame.draw.circle?)
Actually it has to be simple, because sprites are maybe too much for me.
My idea was to change coordinates every time ball gets to specific coordinates.
I am not just asking somebody to make a game I like, it's for educational purposes.
I would love to see some comments with the code you provide.
As I told, i just started learning it.
My english isn't best. Sorry about that.
Thanks in advance!
(I know that my post is a bit confusing and unspecific)
If needed, I will upload the background and paddle picture too.
You could create a Ball class, that will have 2 methods:
update() - that will move the ball according to speed_x and speed_y and
check if any collisions are detected
draw() - that will blit the surface/ or draw a circle at ball position.
another thing you have to think about, is collisions.
You can find if a point is in a rectangle like this:
We have a rectangle with points : p1,p2,p3,p4, p0 is our testing point.
p0 is in the rectangle if dist(p0,p1) + disp(p0,p2) + ... + disp(p0,p4) == WIDTH+HEIGHT
you can try to figure out the equation for a circle. Hint: radius is what you need.
EDIT: The class example:
class Ball:
def __init__(self):
self.pos = [0,0]
self.velocity = [1,0]
def move():
self.pos[0] += self.velocity[0]
self.pos[1] += self.velocity[1]
def draw(screen):
pygame.draw.circle(screen,WHITE,self.pos,5)
To extend on #Bartlomiej Lewandowski, To make the ball you need to
Every loop ball.update() will do:
ball.x += ball.xvel
ball.y += ball.yvel`
Then
if you collide with left/right walls ball.x *= -1
if you collide with top/bot walls ball.y *= -1
Using pygame.Rect will simplfy logic
# bounce on right side
ball.rect.right >= screen.rect.right:
ball.yvel *= -1
# bounce top
ball.rect.top <= screen.rect.top:
# bot
ball.rect.bottom >= screen.rect.bot:
# etc...
edit: Bart added different names but it's the same thing.